Merge "Migrate GlusterFS to privsep style"

This commit is contained in:
Zuul 2022-10-10 15:05:30 +00:00 committed by Gerrit Code Review
commit b8fdf9b9e7
7 changed files with 115 additions and 79 deletions

View File

@ -28,6 +28,16 @@ def rmdir(dir_path):
processutils.execute('rmdir', dir_path) processutils.execute('rmdir', dir_path)
@manila.privsep.sys_admin_pctxt.entrypoint
def mkdir(dir_path):
processutils.execute('mkdir', dir_path)
@manila.privsep.sys_admin_pctxt.entrypoint
def recursive_forced_rm(dir_path):
processutils.execute('rm', '-rf', dir_path)
@manila.privsep.sys_admin_pctxt.entrypoint @manila.privsep.sys_admin_pctxt.entrypoint
def is_data_definition_direct_io_supported(src_str, dest_str): def is_data_definition_direct_io_supported(src_str, dest_str):
try: try:
@ -57,8 +67,9 @@ def umount(mount_path):
@manila.privsep.sys_admin_pctxt.entrypoint @manila.privsep.sys_admin_pctxt.entrypoint
def mount(device_name, mount_path): def mount(device_name, mount_path, mount_type=None):
processutils.execute('mount', device_name, mount_path) extra_args = ['-t', mount_type] if mount_type else []
processutils.execute('mount', device_name, mount_path, *extra_args)
@manila.privsep.sys_admin_pctxt.entrypoint @manila.privsep.sys_admin_pctxt.entrypoint
@ -70,3 +81,18 @@ def list_mounts():
@manila.privsep.sys_admin_pctxt.entrypoint @manila.privsep.sys_admin_pctxt.entrypoint
def chmod(permission_level_str, mount_path): def chmod(permission_level_str, mount_path):
processutils.execute('chmod', permission_level_str, mount_path) processutils.execute('chmod', permission_level_str, mount_path)
@manila.privsep.sys_admin_pctxt.entrypoint
def find(directory_to_find, min_depth='1', dirs_to_ignore=[], delete=False):
ignored_dirs = []
extra_args = []
for dir in dirs_to_ignore:
ignored_dirs += '!', '-path', dir
if delete:
extra_args.append('-delete')
processutils.execute(
'find', directory_to_find, '-mindepth', min_depth, *ignored_dirs,
*extra_args)

View File

@ -24,6 +24,7 @@ from oslo_log import log
from manila import exception from manila import exception
from manila.i18n import _ from manila.i18n import _
from manila.privsep import os as privsep_os
from manila.share.drivers.ganesha import utils as ganesha_utils from manila.share.drivers.ganesha import utils as ganesha_utils
from manila import utils from manila import utils
@ -387,9 +388,8 @@ def _mount_gluster_vol(execute, gluster_export, mount_path, ensure=False):
:param ensure: boolean to allow remounting a volume with a warning :param ensure: boolean to allow remounting a volume with a warning
""" """
execute('mkdir', '-p', mount_path) execute('mkdir', '-p', mount_path)
command = ['mount', '-t', 'glusterfs', gluster_export, mount_path]
try: try:
execute(*command, run_as_root=True) privsep_os.mount(gluster_export, mount_path, mount_type='glusterfs')
except exception.ProcessExecutionError as exc: except exception.ProcessExecutionError as exc:
if ensure and 'already mounted' in exc.stderr: if ensure and 'already mounted' in exc.stderr:
LOG.warning("%s is already mounted.", gluster_export) LOG.warning("%s is already mounted.", gluster_export)
@ -399,15 +399,14 @@ def _mount_gluster_vol(execute, gluster_export, mount_path, ensure=False):
) )
def _umount_gluster_vol(execute, mount_path): def _umount_gluster_vol(mount_path):
"""Unmount a GlusterFS volume at the specified mount path. """Unmount a GlusterFS volume at the specified mount path.
:param execute: command execution function
:param mount_path: path where volume is mounted :param mount_path: path where volume is mounted
""" """
try: try:
execute('umount', mount_path, run_as_root=True) privsep_os.umount(mount_path)
except exception.ProcessExecutionError as exc: except exception.ProcessExecutionError as exc:
msg = (_("Unable to unmount gluster volume. " msg = (_("Unable to unmount gluster volume. "
"mount_dir: %(mount_path)s, Error: %(error)s") % "mount_dir: %(mount_path)s, Error: %(error)s") %

View File

@ -24,6 +24,7 @@ import xml.etree.cElementTree as etree
from manila import exception from manila import exception
from manila.i18n import _ from manila.i18n import _
from manila.privsep import os as privsep_os
from manila.share.drivers.glusterfs import common from manila.share.drivers.glusterfs import common
from manila.share.drivers.glusterfs import layout from manila.share.drivers.glusterfs import layout
from manila import utils from manila import utils
@ -140,10 +141,9 @@ class GlusterfsDirectoryMappedLayout(layout.GlusterfsShareLayoutBase):
# probe into getting a NAS protocol helper for the share in order # probe into getting a NAS protocol helper for the share in order
# to facilitate early detection of unsupported protocol type # to facilitate early detection of unsupported protocol type
local_share_path = self._get_local_share_path(share) local_share_path = self._get_local_share_path(share)
cmd = ['mkdir', local_share_path]
try: try:
self.driver._execute(*cmd, run_as_root=True) privsep_os.mkdir(local_share_path)
self._set_directory_quota(share, share['size']) self._set_directory_quota(share, share['size'])
except Exception as exc: except Exception as exc:
if isinstance(exc, exception.ProcessExecutionError): if isinstance(exc, exception.ProcessExecutionError):
@ -164,9 +164,8 @@ class GlusterfsDirectoryMappedLayout(layout.GlusterfsShareLayoutBase):
def _cleanup_create_share(self, share_path, share_name): def _cleanup_create_share(self, share_path, share_name):
"""Cleanup share that errored out during its creation.""" """Cleanup share that errored out during its creation."""
if os.path.exists(share_path): if os.path.exists(share_path):
cmd = ['rm', '-rf', share_path]
try: try:
self.driver._execute(*cmd, run_as_root=True) privsep_os.recursive_forced_rm(share_path)
except exception.ProcessExecutionError as exc: except exception.ProcessExecutionError as exc:
LOG.error('Cannot cleanup share, %s, that errored out ' LOG.error('Cannot cleanup share, %s, that errored out '
'during its creation, but exists in GlusterFS ' 'during its creation, but exists in GlusterFS '
@ -176,9 +175,8 @@ class GlusterfsDirectoryMappedLayout(layout.GlusterfsShareLayoutBase):
def delete_share(self, context, share, share_server=None): def delete_share(self, context, share, share_server=None):
"""Remove a sub-directory/share from the GlusterFS volume.""" """Remove a sub-directory/share from the GlusterFS volume."""
local_share_path = self._get_local_share_path(share) local_share_path = self._get_local_share_path(share)
cmd = ['rm', '-rf', local_share_path]
try: try:
self.driver._execute(*cmd, run_as_root=True) privsep_os.recursive_forced_rm(local_share_path)
except exception.ProcessExecutionError: except exception.ProcessExecutionError:
LOG.exception('Unable to delete share %s', share['name']) LOG.exception('Unable to delete share %s', share['name'])
raise raise

View File

@ -28,6 +28,7 @@ from oslo_log import log
from manila import exception from manila import exception
from manila.i18n import _ from manila.i18n import _
from manila.privsep import os as privsep_os
from manila.share.drivers.glusterfs import common from manila.share.drivers.glusterfs import common
from manila.share.drivers.glusterfs import layout from manila.share.drivers.glusterfs import layout
from manila import utils from manila import utils
@ -352,17 +353,16 @@ class GlusterfsVolumeMappedLayout(layout.GlusterfsShareLayoutBase):
# delete the paths of the two directories, but delete their contents # delete the paths of the two directories, but delete their contents
# along with the rest of the contents of the volume. # along with the rest of the contents of the volume.
srvaddr = gluster_mgr.host_access srvaddr = gluster_mgr.host_access
if common.numreduct(self.glusterfs_versions[srvaddr]) < (3, 7): ignored_dirs = []
cmd = ['find', tmpdir, '-mindepth', '1', '-delete'] if common.numreduct(self.glusterfs_versions[srvaddr]) > (3, 6):
else:
ignored_dirs = map(lambda x: os.path.join(tmpdir, *x), ignored_dirs = map(lambda x: os.path.join(tmpdir, *x),
[('.trashcan', ), ('.trashcan', 'internal_op')]) [('.trashcan', ), ('.trashcan', 'internal_op')])
ignored_dirs = list(ignored_dirs) ignored_dirs = list(ignored_dirs)
cmd = ['find', tmpdir, '-mindepth', '1', '!', '-path', ignored_dirs = [ignored_dirs[0], ignored_dirs[1]]
ignored_dirs[0], '!', '-path', ignored_dirs[1], '-delete']
try: try:
self.driver._execute(*cmd, run_as_root=True) privsep_os.find(
tmpdir, dirs_to_ignore=ignored_dirs, delete=True)
except exception.ProcessExecutionError as exc: except exception.ProcessExecutionError as exc:
msg = (_("Error trying to wipe gluster volume. " msg = (_("Error trying to wipe gluster volume. "
"gluster_export: %(export)s, Error: %(error)s") % "gluster_export: %(export)s, Error: %(error)s") %
@ -371,7 +371,7 @@ class GlusterfsVolumeMappedLayout(layout.GlusterfsShareLayoutBase):
raise exception.GlusterfsException(msg) raise exception.GlusterfsException(msg)
finally: finally:
# Unmount. # Unmount.
common._umount_gluster_vol(self.driver._execute, tmpdir) common._umount_gluster_vol(tmpdir)
shutil.rmtree(tmpdir, ignore_errors=True) shutil.rmtree(tmpdir, ignore_errors=True)
def create_share(self, context, share, share_server=None): def create_share(self, context, share, share_server=None):

View File

@ -21,6 +21,7 @@ import ddt
from oslo_config import cfg from oslo_config import cfg
from manila import exception from manila import exception
from manila.privsep import os as privsep_os
from manila.share.drivers.glusterfs import common from manila.share.drivers.glusterfs import common
from manila import test from manila import test
from manila.tests import fake_utils from manila.tests import fake_utils
@ -764,14 +765,15 @@ class GlusterFSCommonTestCase(test.TestCase):
@staticmethod @staticmethod
def _mount_exec(vol, mnt): def _mount_exec(vol, mnt):
return ['mkdir -p %s' % mnt, return ['mkdir -p %s' % mnt]
'mount -t glusterfs %(exp)s %(mnt)s' % {'exp': vol,
'mnt': mnt}]
def test_mount_gluster_vol(self): def test_mount_gluster_vol(self):
expected_exec = self._mount_exec(fakeexport, fakemnt) expected_exec = self._mount_exec(fakeexport, fakemnt)
self.mock_object(privsep_os, 'mount')
ret = common._mount_gluster_vol(self._execute, fakeexport, fakemnt, ret = common._mount_gluster_vol(self._execute, fakeexport, fakemnt,
False) False)
privsep_os.mount.assert_called_once_with(
fakeexport, fakemnt, mount_type='glusterfs')
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec) self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
self.assertIsNone(ret) self.assertIsNone(ret)
@ -779,10 +781,13 @@ class GlusterFSCommonTestCase(test.TestCase):
def exec_runner(*ignore_args, **ignore_kwargs): def exec_runner(*ignore_args, **ignore_kwargs):
raise exception.ProcessExecutionError(stderr='already mounted') raise exception.ProcessExecutionError(stderr='already mounted')
expected_exec = self._mount_exec(fakeexport, fakemnt) expected_exec = self._mount_exec(fakeexport, fakemnt)
fake_utils.fake_execute_set_repliers([('mount', exec_runner)]) self.mock_object(
privsep_os, 'mount', mock.Mock(side_effect=exec_runner))
self.assertRaises(exception.GlusterfsException, self.assertRaises(exception.GlusterfsException,
common._mount_gluster_vol, common._mount_gluster_vol,
self._execute, fakeexport, fakemnt, False) self._execute, fakeexport, fakemnt, False)
privsep_os.mount.assert_called_once_with(
fakeexport, fakemnt, mount_type='glusterfs')
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec) self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
def test_mount_gluster_vol_mounted_ensure(self): def test_mount_gluster_vol_mounted_ensure(self):
@ -790,11 +795,14 @@ class GlusterFSCommonTestCase(test.TestCase):
raise exception.ProcessExecutionError(stderr='already mounted') raise exception.ProcessExecutionError(stderr='already mounted')
expected_exec = self._mount_exec(fakeexport, fakemnt) expected_exec = self._mount_exec(fakeexport, fakemnt)
common.LOG.warning = mock.Mock() common.LOG.warning = mock.Mock()
fake_utils.fake_execute_set_repliers([('mount', exec_runner)]) self.mock_object(
privsep_os, 'mount', mock.Mock(side_effect=exec_runner))
ret = common._mount_gluster_vol(self._execute, fakeexport, fakemnt, ret = common._mount_gluster_vol(self._execute, fakeexport, fakemnt,
True) True)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec) self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
self.assertIsNone(ret) self.assertIsNone(ret)
self.mock_object(
privsep_os, 'mount', mock.Mock(side_effect=exec_runner))
common.LOG.warning.assert_called_with( common.LOG.warning.assert_called_with(
"%s is already mounted.", fakeexport) "%s is already mounted.", fakeexport)
@ -803,15 +811,24 @@ class GlusterFSCommonTestCase(test.TestCase):
def exec_runner(*ignore_args, **ignore_kwargs): def exec_runner(*ignore_args, **ignore_kwargs):
raise RuntimeError('fake error') raise RuntimeError('fake error')
expected_exec = self._mount_exec(fakeexport, fakemnt) expected_exec = self._mount_exec(fakeexport, fakemnt)
fake_utils.fake_execute_set_repliers([('mount', exec_runner)]) self.mock_object(
self.assertRaises(RuntimeError, common._mount_gluster_vol, privsep_os, 'mount', mock.Mock(side_effect=exec_runner))
self._execute, fakeexport, fakemnt, ensure) self.assertRaises(
RuntimeError,
common._mount_gluster_vol,
self._execute,
fakeexport,
fakemnt,
ensure)
privsep_os.mount.assert_called_once_with(
fakeexport, fakemnt, mount_type='glusterfs')
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec) self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
def test_umount_gluster_vol(self): def test_umount_gluster_vol(self):
expected_exec = ['umount %s' % fakemnt] self.mock_object(privsep_os, 'umount')
ret = common._umount_gluster_vol(self._execute, fakemnt)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec) ret = common._umount_gluster_vol(fakemnt)
privsep_os.umount.assert_called_once_with(fakemnt)
self.assertIsNone(ret) self.assertIsNone(ret)
@ddt.data({'in_exc': exception.ProcessExecutionError, @ddt.data({'in_exc': exception.ProcessExecutionError,
@ -821,11 +838,10 @@ class GlusterFSCommonTestCase(test.TestCase):
def test_umount_gluster_vol_fail(self, in_exc, out_exc): def test_umount_gluster_vol_fail(self, in_exc, out_exc):
def exec_runner(*ignore_args, **ignore_kwargs): def exec_runner(*ignore_args, **ignore_kwargs):
raise in_exc('fake error') raise in_exc('fake error')
expected_exec = ['umount %s' % fakemnt] self.mock_object(privsep_os, 'umount',
fake_utils.fake_execute_set_repliers([('umount', exec_runner)]) mock.Mock(side_effect=exec_runner))
self.assertRaises(out_exc, common._umount_gluster_vol, self.assertRaises(out_exc, common._umount_gluster_vol, fakemnt)
self._execute, fakemnt) privsep_os.umount.assert_called_once_with(fakemnt)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
def test_restart_gluster_vol(self): def test_restart_gluster_vol(self):
gmgr = common.GlusterManager(fakeexport, self._execute, None, None) gmgr = common.GlusterManager(fakeexport, self._execute, None, None)

View File

@ -21,6 +21,7 @@ from oslo_config import cfg
from manila import context from manila import context
from manila import exception from manila import exception
from manila.privsep import os as privsep_os
from manila.share import configuration as config from manila.share import configuration as config
from manila.share.drivers.glusterfs import common from manila.share.drivers.glusterfs import common
from manila.share.drivers.glusterfs import layout_directory from manila.share.drivers.glusterfs import layout_directory
@ -234,8 +235,6 @@ class GlusterfsDirectoryMappedLayoutTestCase(test.TestCase):
@ddt.data((), (None,)) @ddt.data((), (None,))
def test_create_share(self, extra_args): def test_create_share(self, extra_args):
exec_cmd1 = 'mkdir %s' % fake_local_share_path
expected_exec = [exec_cmd1, ]
expected_ret = 'testuser@127.0.0.1:/testvol/fakename' expected_ret = 'testuser@127.0.0.1:/testvol/fakename'
self.mock_object( self.mock_object(
self._layout, '_get_local_share_path', self._layout, '_get_local_share_path',
@ -246,13 +245,14 @@ class GlusterfsDirectoryMappedLayoutTestCase(test.TestCase):
self.mock_object( self.mock_object(
self._layout.driver, '_setup_via_manager', self._layout.driver, '_setup_via_manager',
mock.Mock(return_value=expected_ret)) mock.Mock(return_value=expected_ret))
self.mock_object(privsep_os, 'mkdir')
ret = self._layout.create_share(self._context, self.share, *extra_args) ret = self._layout.create_share(self._context, self.share, *extra_args)
self._layout._get_local_share_path.called_once_with(self.share) self._layout._get_local_share_path.called_once_with(self.share)
self._layout.gluster_manager.gluster_call.assert_called_once_with( self._layout.gluster_manager.gluster_call.assert_called_once_with(
'volume', 'quota', 'testvol', 'limit-usage', '/fakename', '1GB') 'volume', 'quota', 'testvol', 'limit-usage', '/fakename', '1GB')
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log()) privsep_os.mkdir.assert_called_once_with(fake_local_share_path)
self._layout._glustermanager.assert_called_once_with( self._layout._glustermanager.assert_called_once_with(
{'user': 'testuser', 'host': '127.0.0.1', {'user': 'testuser', 'host': '127.0.0.1',
'volume': 'testvol', 'path': '/fakename'}) 'volume': 'testvol', 'path': '/fakename'})
@ -262,23 +262,20 @@ class GlusterfsDirectoryMappedLayoutTestCase(test.TestCase):
@ddt.data(exception.ProcessExecutionError, exception.GlusterfsException) @ddt.data(exception.ProcessExecutionError, exception.GlusterfsException)
def test_create_share_unable_to_create_share(self, trouble): def test_create_share_unable_to_create_share(self, trouble):
def exec_runner(*ignore_args, **ignore_kw):
raise trouble
self.mock_object( self.mock_object(
self._layout, '_get_local_share_path', self._layout, '_get_local_share_path',
mock.Mock(return_value=fake_local_share_path)) mock.Mock(return_value=fake_local_share_path))
self.mock_object(privsep_os, 'mkdir', mock.Mock(side_effect=trouble))
self.mock_object(self._layout, '_cleanup_create_share') self.mock_object(self._layout, '_cleanup_create_share')
self.mock_object(layout_directory.LOG, 'error') self.mock_object(layout_directory.LOG, 'error')
expected_exec = ['mkdir %s' % fake_local_share_path]
fake_utils.fake_execute_set_repliers([(expected_exec[0],
exec_runner)])
self.assertRaises( self.assertRaises(
exception.GlusterfsException, self._layout.create_share, exception.GlusterfsException, self._layout.create_share,
self._context, self.share) self._context, self.share)
self._layout._get_local_share_path.called_once_with(self.share) self._layout._get_local_share_path.called_once_with(self.share)
privsep_os.mkdir.assert_called_once_with(fake_local_share_path)
self._layout._cleanup_create_share.assert_called_once_with( self._layout._cleanup_create_share.assert_called_once_with(
fake_local_share_path, self.share['name']) fake_local_share_path, self.share['name'])
layout_directory.LOG.error.assert_called_once_with( layout_directory.LOG.error.assert_called_once_with(
@ -292,6 +289,8 @@ class GlusterfsDirectoryMappedLayoutTestCase(test.TestCase):
self._layout, '_get_local_share_path', self._layout, '_get_local_share_path',
mock.Mock(return_value=fake_local_share_path)) mock.Mock(return_value=fake_local_share_path))
self.mock_object(self._layout, '_cleanup_create_share') self.mock_object(self._layout, '_cleanup_create_share')
self.mock_object(
privsep_os, 'mkdir', mock.Mock(side_effect=exec_runner))
self.mock_object(layout_directory.LOG, 'error') self.mock_object(layout_directory.LOG, 'error')
expected_exec = ['mkdir %s' % fake_local_share_path] expected_exec = ['mkdir %s' % fake_local_share_path]
fake_utils.fake_execute_set_repliers([(expected_exec[0], fake_utils.fake_execute_set_repliers([(expected_exec[0],
@ -302,26 +301,26 @@ class GlusterfsDirectoryMappedLayoutTestCase(test.TestCase):
self._context, self.share) self._context, self.share)
self._layout._get_local_share_path.called_once_with(self.share) self._layout._get_local_share_path.called_once_with(self.share)
privsep_os.mkdir.assert_called_once_with(fake_local_share_path)
self.assertFalse(self._layout._cleanup_create_share.called) self.assertFalse(self._layout._cleanup_create_share.called)
def test_cleanup_create_share_local_share_path_exists(self): def test_cleanup_create_share_local_share_path_exists(self):
expected_exec = ['rm -rf %s' % fake_local_share_path] self.mock_object(privsep_os, 'recursive_forced_rm')
self.mock_object(os.path, 'exists', mock.Mock(return_value=True)) self.mock_object(os.path, 'exists', mock.Mock(return_value=True))
ret = self._layout._cleanup_create_share(fake_local_share_path, ret = self._layout._cleanup_create_share(fake_local_share_path,
self.share['name']) self.share['name'])
os.path.exists.assert_called_once_with(fake_local_share_path) os.path.exists.assert_called_once_with(fake_local_share_path)
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log()) privsep_os.recursive_forced_rm.assert_called_once_with(
fake_local_share_path)
self.assertIsNone(ret) self.assertIsNone(ret)
def test_cleanup_create_share_cannot_cleanup_unusable_share(self): def test_cleanup_create_share_cannot_cleanup_unusable_share(self):
def exec_runner(*ignore_args, **ignore_kw): def exec_runner(*ignore_args, **ignore_kw):
raise exception.ProcessExecutionError raise exception.ProcessExecutionError
self.mock_object(privsep_os, 'recursive_forced_rm',
expected_exec = ['rm -rf %s' % fake_local_share_path] mock.Mock(side_effect=exec_runner))
fake_utils.fake_execute_set_repliers([(expected_exec[0],
exec_runner)])
self.mock_object(layout_directory.LOG, 'error') self.mock_object(layout_directory.LOG, 'error')
self.mock_object(os.path, 'exists', mock.Mock(return_value=True)) self.mock_object(os.path, 'exists', mock.Mock(return_value=True))
@ -342,31 +341,34 @@ class GlusterfsDirectoryMappedLayoutTestCase(test.TestCase):
self.assertIsNone(ret) self.assertIsNone(ret)
def test_delete_share(self): def test_delete_share(self):
local_share_path = '/mnt/nfs/testvol/fakename'
self._layout._get_local_share_path = ( self._layout._get_local_share_path = (
mock.Mock(return_value='/mnt/nfs/testvol/fakename')) mock.Mock(return_value=local_share_path))
mock_force_rm = self.mock_object(privsep_os, 'recursive_forced_rm')
self._layout.delete_share(self._context, self.share) self._layout.delete_share(self._context, self.share)
self.assertEqual(['rm -rf /mnt/nfs/testvol/fakename'], mock_force_rm.assert_called_once_with(
fake_utils.fake_execute_get_log()) local_share_path)
def test_cannot_delete_share(self): def test_cannot_delete_share(self):
local_share_path = '/mnt/nfs/testvol/fakename'
self._layout._get_local_share_path = ( self._layout._get_local_share_path = (
mock.Mock(return_value='/mnt/nfs/testvol/fakename')) mock.Mock(return_value=local_share_path))
self.mock_object(
def exec_runner(*ignore_args, **ignore_kw): privsep_os, 'recursive_forced_rm', mock.Mock(
raise exception.ProcessExecutionError side_effect=exception.ProcessExecutionError))
expected_exec = ['rm -rf %s' % (self._layout._get_local_share_path())]
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
self.assertRaises(exception.ProcessExecutionError, self.assertRaises(exception.ProcessExecutionError,
self._layout.delete_share, self._context, self.share) self._layout.delete_share, self._context, self.share)
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log()) privsep_os.mkdir.assert_called_once_with = local_share_path
def test_delete_share_can_be_called_with_extra_arg_share_server(self): def test_delete_share_can_be_called_with_extra_arg_share_server(self):
self._layout._get_local_share_path = mock.Mock() local_share_path = '/mnt/nfs/testvol/fakename'
self._layout._get_local_share_path = mock.Mock(
return_value=local_share_path)
mock_force_rm = self.mock_object(privsep_os, 'recursive_forced_rm')
share_server = None share_server = None
ret = self._layout.delete_share(self._context, self.share, ret = self._layout.delete_share(self._context, self.share,
@ -374,6 +376,7 @@ class GlusterfsDirectoryMappedLayoutTestCase(test.TestCase):
self.assertIsNone(ret) self.assertIsNone(ret)
self._layout._get_local_share_path.assert_called_once_with(self.share) self._layout._get_local_share_path.assert_called_once_with(self.share)
mock_force_rm.assert_called_once_with(local_share_path)
def test_ensure_share(self): def test_ensure_share(self):
self.assertIsNone(self._layout.ensure_share(self._context, self.share)) self.assertIsNone(self._layout.ensure_share(self._context, self.share))

View File

@ -27,6 +27,7 @@ from oslo_config import cfg
from manila.common import constants from manila.common import constants
from manila import context from manila import context
from manila import exception from manila import exception
from manila.privsep import os as privsep_os
from manila.share import configuration as config from manila.share import configuration as config
from manila.share.drivers.glusterfs import common from manila.share.drivers.glusterfs import common
from manila.share.drivers.glusterfs import layout_volume from manila.share.drivers.glusterfs import layout_volume
@ -449,14 +450,12 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
self.glusterfs_target2) self.glusterfs_target2)
@ddt.data({'vers_minor': '6', @ddt.data({'vers_minor': '6',
'cmd': ['find', '/tmp/tmpKGHKJ', '-mindepth', '1', 'dirs_to_ignore': []},
'-delete']},
{'vers_minor': '7', {'vers_minor': '7',
'cmd': ['find', '/tmp/tmpKGHKJ', '-mindepth', '1', '!', 'dirs_to_ignore': ['/tmp/tmpKGHKJ/.trashcan',
'-path', '/tmp/tmpKGHKJ/.trashcan', '!', '-path', '/tmp/tmpKGHKJ/.trashcan/internal_op']})
'/tmp/tmpKGHKJ/.trashcan/internal_op', '-delete']})
@ddt.unpack @ddt.unpack
def test_wipe_gluster_vol(self, vers_minor, cmd): def test_wipe_gluster_vol(self, vers_minor, dirs_to_ignore):
tmpdir = '/tmp/tmpKGHKJ' tmpdir = '/tmp/tmpKGHKJ'
gmgr = common.GlusterManager gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None) gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
@ -466,6 +465,7 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
self.mock_object(tempfile, 'mkdtemp', self.mock_object(tempfile, 'mkdtemp',
mock.Mock(return_value=tmpdir)) mock.Mock(return_value=tmpdir))
self.mock_object(self.fake_driver, '_execute', mock.Mock()) self.mock_object(self.fake_driver, '_execute', mock.Mock())
self.mock_object(privsep_os, 'find')
self.mock_object(common, '_mount_gluster_vol', mock.Mock()) self.mock_object(common, '_mount_gluster_vol', mock.Mock())
self.mock_object(common, '_umount_gluster_vol', mock.Mock()) self.mock_object(common, '_umount_gluster_vol', mock.Mock())
self.mock_object(shutil, 'rmtree', mock.Mock()) self.mock_object(shutil, 'rmtree', mock.Mock())
@ -476,11 +476,10 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
common._mount_gluster_vol.assert_called_once_with( common._mount_gluster_vol.assert_called_once_with(
self.fake_driver._execute, gmgr1.export, self.fake_driver._execute, gmgr1.export,
tmpdir) tmpdir)
kwargs = {'run_as_root': True} privsep_os.find.assert_called_once_with(
self.fake_driver._execute.assert_called_once_with( tmpdir, dirs_to_ignore=dirs_to_ignore, delete=True)
*cmd, **kwargs)
common._umount_gluster_vol.assert_called_once_with( common._umount_gluster_vol.assert_called_once_with(
self.fake_driver._execute, tmpdir) tmpdir)
kwargs = {'ignore_errors': True} kwargs = {'ignore_errors': True}
shutil.rmtree.assert_called_once_with(tmpdir, shutil.rmtree.assert_called_once_with(tmpdir,
**kwargs) **kwargs)
@ -519,11 +518,10 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None) gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self._layout.glusterfs_versions = { self._layout.glusterfs_versions = {
self.glusterfs_server1: ('3', '6')} self.glusterfs_server1: ('3', '6')}
cmd = ['find', '/tmp/tmpKGHKJ', '-mindepth', '1', '-delete']
self.mock_object(tempfile, 'mkdtemp', self.mock_object(tempfile, 'mkdtemp',
mock.Mock(return_value=tmpdir)) mock.Mock(return_value=tmpdir))
self.mock_object( self.mock_object(
self.fake_driver, '_execute', privsep_os, 'find',
mock.Mock(side_effect=exception.ProcessExecutionError)) mock.Mock(side_effect=exception.ProcessExecutionError))
self.mock_object(common, '_mount_gluster_vol', mock.Mock()) self.mock_object(common, '_mount_gluster_vol', mock.Mock())
self.mock_object(common, '_umount_gluster_vol', mock.Mock()) self.mock_object(common, '_umount_gluster_vol', mock.Mock())
@ -537,11 +535,7 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
common._mount_gluster_vol.assert_called_once_with( common._mount_gluster_vol.assert_called_once_with(
self.fake_driver._execute, gmgr1.export, self.fake_driver._execute, gmgr1.export,
tmpdir) tmpdir)
kwargs = {'run_as_root': True} common._umount_gluster_vol.assert_called_once_with(tmpdir)
self.fake_driver._execute.assert_called_once_with(
*cmd, **kwargs)
common._umount_gluster_vol.assert_called_once_with(
self.fake_driver._execute, tmpdir)
kwargs = {'ignore_errors': True} kwargs = {'ignore_errors': True}
shutil.rmtree.assert_called_once_with(tmpdir, shutil.rmtree.assert_called_once_with(tmpdir,
**kwargs) **kwargs)