Merge "Move lvm handling to privsep."

This commit is contained in:
Zuul
2017-10-20 16:44:25 +00:00
committed by Gerrit Code Review
5 changed files with 78 additions and 64 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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:

View File

@@ -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.