Merge "Move lvm handling to privsep."
This commit is contained in:
@@ -152,18 +152,6 @@ mkfs.ext3: CommandFilter, mkfs.ext3, root
|
|||||||
mkfs.ext4: CommandFilter, mkfs.ext4, root
|
mkfs.ext4: CommandFilter, mkfs.ext4, root
|
||||||
mkfs.ntfs: CommandFilter, mkfs.ntfs, root
|
mkfs.ntfs: CommandFilter, mkfs.ntfs, root
|
||||||
|
|
||||||
# nova/virt/libvirt/driver.py:
|
|
||||||
lvremove: CommandFilter, lvremove, root
|
|
||||||
|
|
||||||
# nova/virt/libvirt/utils.py:
|
|
||||||
lvcreate: CommandFilter, lvcreate, root
|
|
||||||
|
|
||||||
# nova/virt/libvirt/utils.py:
|
|
||||||
lvs: CommandFilter, lvs, root
|
|
||||||
|
|
||||||
# nova/virt/libvirt/utils.py:
|
|
||||||
vgs: CommandFilter, vgs, root
|
|
||||||
|
|
||||||
# os-brick needed commands
|
# os-brick needed commands
|
||||||
read_initiator: ReadFileFilter, /etc/iscsi/initiatorname.iscsi
|
read_initiator: ReadFileFilter, /etc/iscsi/initiatorname.iscsi
|
||||||
multipath: CommandFilter, multipath, root
|
multipath: CommandFilter, multipath, root
|
||||||
|
@@ -36,3 +36,43 @@ def mount(fstype, device, mountpoint, options):
|
|||||||
@nova.privsep.sys_admin_pctxt.entrypoint
|
@nova.privsep.sys_admin_pctxt.entrypoint
|
||||||
def umount(mountpoint):
|
def umount(mountpoint):
|
||||||
processutils.execute('umount', mountpoint, attempts=3, delay_on_retry=True)
|
processutils.execute('umount', mountpoint, attempts=3, delay_on_retry=True)
|
||||||
|
|
||||||
|
|
||||||
|
@nova.privsep.sys_admin_pctxt.entrypoint
|
||||||
|
def lvcreate(size, lv, vg, preallocated=None):
|
||||||
|
cmd = ['lvcreate']
|
||||||
|
if not preallocated:
|
||||||
|
cmd.extend(['-L', '%db' % size])
|
||||||
|
else:
|
||||||
|
cmd.extend(['-L', '%db' % preallocated,
|
||||||
|
'--virtualsize', '%db' % size])
|
||||||
|
cmd.extend(['-n', lv, vg])
|
||||||
|
processutils.execute(*cmd, attempts=3)
|
||||||
|
|
||||||
|
|
||||||
|
@nova.privsep.sys_admin_pctxt.entrypoint
|
||||||
|
def vginfo(vg):
|
||||||
|
return processutils.execute('vgs', '--noheadings', '--nosuffix',
|
||||||
|
'--separator', '|', '--units', 'b',
|
||||||
|
'-o', 'vg_size,vg_free', vg)
|
||||||
|
|
||||||
|
|
||||||
|
@nova.privsep.sys_admin_pctxt.entrypoint
|
||||||
|
def lvlist(vg):
|
||||||
|
return processutils.execute('lvs', '--noheadings', '-o', 'lv_name', vg)
|
||||||
|
|
||||||
|
|
||||||
|
@nova.privsep.sys_admin_pctxt.entrypoint
|
||||||
|
def lvinfo(path):
|
||||||
|
return processutils.execute('lvs', '-o', 'vg_all,lv_all',
|
||||||
|
'--separator', '|', path)
|
||||||
|
|
||||||
|
|
||||||
|
@nova.privsep.sys_admin_pctxt.entrypoint
|
||||||
|
def lvremove(path):
|
||||||
|
processutils.execute('lvremove', '-f', path, attempts=3)
|
||||||
|
|
||||||
|
|
||||||
|
@nova.privsep.sys_admin_pctxt.entrypoint
|
||||||
|
def blockdev_size(path):
|
||||||
|
return processutils.execute('blockdev', '--getsize64', path)
|
||||||
|
@@ -19,44 +19,40 @@ from oslo_config import cfg
|
|||||||
|
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova import utils
|
|
||||||
from nova.virt.libvirt.storage import lvm
|
from nova.virt.libvirt.storage import lvm
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
|
||||||
|
|
||||||
class LvmTestCase(test.NoDBTestCase):
|
class LvmTestCase(test.NoDBTestCase):
|
||||||
@mock.patch('nova.utils.execute')
|
@mock.patch('nova.privsep.fs.blockdev_size')
|
||||||
def test_get_volume_size(self, mock_execute):
|
def test_get_volume_size(self, mock_blockdev_size):
|
||||||
mock_execute.return_value = 123456789, None
|
mock_blockdev_size.return_value = '123456789', None
|
||||||
size = lvm.get_volume_size('/dev/foo')
|
size = lvm.get_volume_size('/dev/foo')
|
||||||
mock_execute.assert_has_calls(
|
|
||||||
[mock.call('blockdev', '--getsize64', '/dev/foo',
|
|
||||||
run_as_root=True)])
|
|
||||||
self.assertEqual(123456789, size)
|
self.assertEqual(123456789, size)
|
||||||
|
|
||||||
@mock.patch.object(utils, 'execute',
|
@mock.patch('nova.privsep.fs.blockdev_size',
|
||||||
side_effect=processutils.ProcessExecutionError(
|
side_effect=processutils.ProcessExecutionError(
|
||||||
stderr=('blockdev: cannot open /dev/foo: '
|
stderr=('blockdev: cannot open /dev/foo: '
|
||||||
'No such device or address')))
|
'No such device or address')))
|
||||||
def test_get_volume_size_not_found(self, mock_execute):
|
def test_get_volume_size_not_found(self, mock_blockdev_size):
|
||||||
self.assertRaises(exception.VolumeBDMPathNotFound,
|
self.assertRaises(exception.VolumeBDMPathNotFound,
|
||||||
lvm.get_volume_size, '/dev/foo')
|
lvm.get_volume_size, '/dev/foo')
|
||||||
|
|
||||||
@mock.patch.object(utils, 'execute',
|
@mock.patch('nova.privsep.fs.blockdev_size',
|
||||||
side_effect=processutils.ProcessExecutionError(
|
side_effect=processutils.ProcessExecutionError(
|
||||||
stderr=('blockdev: cannot open /dev/foo: '
|
stderr=('blockdev: cannot open /dev/foo: '
|
||||||
'No such file or directory')))
|
'No such file or directory')))
|
||||||
def test_get_volume_size_not_found_file(self, mock_execute):
|
def test_get_volume_size_not_found_file(self, mock_blockdev_size):
|
||||||
self.assertRaises(exception.VolumeBDMPathNotFound,
|
self.assertRaises(exception.VolumeBDMPathNotFound,
|
||||||
lvm.get_volume_size, '/dev/foo')
|
lvm.get_volume_size, '/dev/foo')
|
||||||
|
|
||||||
@mock.patch('os.path.exists', return_value=True)
|
@mock.patch('os.path.exists', return_value=True)
|
||||||
@mock.patch.object(utils, 'execute',
|
@mock.patch('nova.privsep.fs.blockdev_size',
|
||||||
side_effect=processutils.ProcessExecutionError(
|
side_effect=processutils.ProcessExecutionError(
|
||||||
stderr='blockdev: i am sad in other ways'))
|
stderr='blockdev: i am sad in other ways'))
|
||||||
def test_get_volume_size_unexpectd_error(self, mock_execute,
|
def test_get_volume_size_unexpected_error(self, mock_blockdev_size,
|
||||||
mock_path_exists):
|
mock_path_exists):
|
||||||
self.assertRaises(processutils.ProcessExecutionError,
|
self.assertRaises(processutils.ProcessExecutionError,
|
||||||
lvm.get_volume_size, '/dev/foo')
|
lvm.get_volume_size, '/dev/foo')
|
||||||
|
|
||||||
@@ -117,18 +113,18 @@ class LvmTestCase(test.NoDBTestCase):
|
|||||||
lvm.clear_volume('/dev/vc')
|
lvm.clear_volume('/dev/vc')
|
||||||
mock_execute.assert_not_called()
|
mock_execute.assert_not_called()
|
||||||
|
|
||||||
@mock.patch.object(utils, 'execute',
|
@mock.patch('nova.privsep.fs.blockdev_size',
|
||||||
side_effect=processutils.ProcessExecutionError(
|
side_effect=processutils.ProcessExecutionError(
|
||||||
stderr=('blockdev: cannot open /dev/foo: '
|
stderr=('blockdev: cannot open /dev/foo: '
|
||||||
'No such file or directory')))
|
'No such file or directory')))
|
||||||
def test_lvm_clear_ignore_lvm_not_found(self, mock_execute):
|
def test_lvm_clear_ignore_lvm_not_found(self, mock_blockdev_size):
|
||||||
lvm.clear_volume('/dev/foo')
|
lvm.clear_volume('/dev/foo')
|
||||||
|
|
||||||
@mock.patch.object(lvm, 'clear_volume')
|
@mock.patch.object(lvm, 'clear_volume')
|
||||||
@mock.patch.object(utils, 'execute',
|
@mock.patch('nova.privsep.fs.lvremove',
|
||||||
side_effect=processutils.ProcessExecutionError('Error'))
|
side_effect=processutils.ProcessExecutionError('Error'))
|
||||||
def test_fail_remove_all_logical_volumes(self, mock_clear, mock_execute):
|
def test_fail_remove_all_logical_volumes(self, mock_clear, mock_lvremove):
|
||||||
self.assertRaises(exception.VolumesNotRemoved,
|
self.assertRaises(exception.VolumesNotRemoved,
|
||||||
lvm.remove_volumes,
|
lvm.remove_volumes,
|
||||||
['vol1', 'vol2', 'vol3'])
|
['vol1', 'vol2', 'vol3'])
|
||||||
self.assertEqual(3, mock_execute.call_count)
|
self.assertEqual(3, mock_lvremove.call_count)
|
||||||
|
@@ -29,6 +29,7 @@ import six
|
|||||||
import nova.conf
|
import nova.conf
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova.i18n import _
|
from nova.i18n import _
|
||||||
|
import nova.privsep.fs
|
||||||
from nova import utils
|
from nova import utils
|
||||||
|
|
||||||
CONF = nova.conf.CONF
|
CONF = nova.conf.CONF
|
||||||
@@ -72,13 +73,11 @@ def create_volume(vg, lv, size, sparse=False):
|
|||||||
'free_space': free_space,
|
'free_space': free_space,
|
||||||
'size': size,
|
'size': size,
|
||||||
'lv': lv})
|
'lv': lv})
|
||||||
|
nova.privsep.fs.lvcreate(size, lv, vg,
|
||||||
cmd = ('lvcreate', '-L', '%db' % preallocated_space,
|
preallocated=preallocated_space)
|
||||||
'--virtualsize', '%db' % size, '-n', lv, vg)
|
|
||||||
else:
|
else:
|
||||||
check_size(vg, lv, size)
|
check_size(vg, lv, size)
|
||||||
cmd = ('lvcreate', '-L', '%db' % size, '-n', lv, vg)
|
nova.privsep.fs.lvcreate(size, lv, vg)
|
||||||
utils.execute(*cmd, run_as_root=True, attempts=3)
|
|
||||||
|
|
||||||
|
|
||||||
def get_volume_group_info(vg):
|
def get_volume_group_info(vg):
|
||||||
@@ -91,10 +90,7 @@ def get_volume_group_info(vg):
|
|||||||
:used: How much space is used (in bytes)
|
:used: How much space is used (in bytes)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
out, err = utils.execute('vgs', '--noheadings', '--nosuffix',
|
out, err = nova.privsep.fs.vginfo(vg)
|
||||||
'--separator', '|',
|
|
||||||
'--units', 'b', '-o', 'vg_size,vg_free', vg,
|
|
||||||
run_as_root=True)
|
|
||||||
|
|
||||||
info = out.split('|')
|
info = out.split('|')
|
||||||
if len(info) != 2:
|
if len(info) != 2:
|
||||||
@@ -113,9 +109,7 @@ def list_volumes(vg):
|
|||||||
: Data format example
|
: Data format example
|
||||||
: ['volume-aaa', 'volume-bbb', 'volume-ccc']
|
: ['volume-aaa', 'volume-bbb', 'volume-ccc']
|
||||||
"""
|
"""
|
||||||
out, err = utils.execute('lvs', '--noheadings', '-o', 'lv_name', vg,
|
out, err = nova.privsep.fs.lvlist(vg)
|
||||||
run_as_root=True)
|
|
||||||
|
|
||||||
return [line.strip() for line in out.splitlines()]
|
return [line.strip() for line in out.splitlines()]
|
||||||
|
|
||||||
|
|
||||||
@@ -135,9 +129,7 @@ def volume_info(path):
|
|||||||
: ...
|
: ...
|
||||||
: 'LSize': '1.00g', '#PV': '1', '#VMdaCps': 'unmanaged'}
|
: 'LSize': '1.00g', '#PV': '1', '#VMdaCps': 'unmanaged'}
|
||||||
"""
|
"""
|
||||||
out, err = utils.execute('lvs', '-o', 'vg_all,lv_all',
|
out, err = nova.privsep.fs.lvinfo(path)
|
||||||
'--separator', '|', path, run_as_root=True)
|
|
||||||
|
|
||||||
info = [line.split('|') for line in out.splitlines()]
|
info = [line.split('|') for line in out.splitlines()]
|
||||||
|
|
||||||
if len(info) != 2:
|
if len(info) != 2:
|
||||||
@@ -155,8 +147,7 @@ def get_volume_size(path):
|
|||||||
:raises: exception.VolumeBDMPathNotFound if the volume path does not exist.
|
:raises: exception.VolumeBDMPathNotFound if the volume path does not exist.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
out, _err = utils.execute('blockdev', '--getsize64', path,
|
out, _err = nova.privsep.fs.blockdev_size(path)
|
||||||
run_as_root=True)
|
|
||||||
except processutils.ProcessExecutionError:
|
except processutils.ProcessExecutionError:
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
raise exception.VolumeBDMPathNotFound(path=path)
|
raise exception.VolumeBDMPathNotFound(path=path)
|
||||||
@@ -201,9 +192,8 @@ def remove_volumes(paths):
|
|||||||
errors = []
|
errors = []
|
||||||
for path in paths:
|
for path in paths:
|
||||||
clear_volume(path)
|
clear_volume(path)
|
||||||
lvremove = ('lvremove', '-f', path)
|
|
||||||
try:
|
try:
|
||||||
utils.execute(*lvremove, attempts=3, run_as_root=True)
|
nova.privsep.fs.lvremove(path)
|
||||||
except processutils.ProcessExecutionError as exp:
|
except processutils.ProcessExecutionError as exp:
|
||||||
errors.append(six.text_type(exp))
|
errors.append(six.text_type(exp))
|
||||||
if errors:
|
if errors:
|
||||||
|
@@ -7,5 +7,5 @@ upgrade:
|
|||||||
Calls to mount in the virt disk api no longer ignore the value of stderr.
|
Calls to mount in the virt disk api no longer ignore the value of stderr.
|
||||||
- |
|
- |
|
||||||
The following commands are no longer required to be listed in your rootwrap
|
The following commands are no longer required to be listed in your rootwrap
|
||||||
configuration: cat; chown; cryptsetup; dd; mkdir; mount; ploop;
|
configuration: cat; chown; cryptsetup; dd; lvcreate; lvremove; lvs; mkdir;
|
||||||
prl_disk_tool; readlink; tee; touch; and umount.
|
mount; ploop; prl_disk_tool; readlink; tee; touch; umount; and vgs.
|
||||||
|
Reference in New Issue
Block a user