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