glusterfs*: factor out common parts
GlusterManager and a few standalone management routines have been moved to the newly created glusterfs/common.py; both glusterfs and glusterfs_native drivers import these from there. The obnoxious import of glusterfs to glusterfs_native has been eliminated. Partially implements bp modular-glusterfs-share-layouts Change-Id: I6a94f1056bd45187c0268d75fa854b127b2b562d
This commit is contained in:
parent
d172f86df2
commit
6849f9e386
|
@ -28,7 +28,6 @@ import errno
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
import xml.etree.cElementTree as etree
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
|
@ -37,10 +36,10 @@ import six
|
|||
from manila import exception
|
||||
from manila.i18n import _
|
||||
from manila.i18n import _LE
|
||||
from manila.i18n import _LW
|
||||
from manila.share import driver
|
||||
from manila.share.drivers import ganesha
|
||||
from manila.share.drivers.ganesha import utils as ganesha_utils
|
||||
from manila.share.drivers.glusterfs import common
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
@ -89,142 +88,6 @@ NFS_EXPORT_VOL = 'nfs.export-volumes'
|
|||
GLUSTERFS_VERSION_MIN = (3, 5)
|
||||
|
||||
|
||||
class GlusterManager(object):
|
||||
"""Interface with a GlusterFS volume."""
|
||||
|
||||
scheme = re.compile('\A(?:(?P<user>[^:@/]+)@)?'
|
||||
'(?P<host>[^:@/]+)'
|
||||
'(?::/(?P<vol>.+))?')
|
||||
|
||||
def __init__(self, address, execf, path_to_private_key=None,
|
||||
remote_server_password=None, has_volume=True):
|
||||
"""Initialize a GlusterManager instance.
|
||||
|
||||
:param address: the Gluster URI (in [<user>@]<host>:/<vol> format).
|
||||
:param execf: executor function for management commands.
|
||||
:param path_to_private_key: path to private ssh key of remote server.
|
||||
:param remote_server_password: ssh password for remote server.
|
||||
:param has_volume: instruction to uri parser regarding how to deal
|
||||
with the optional volume part (True: require its
|
||||
presence, False: require its absence, None: don't
|
||||
require anything about volume).
|
||||
"""
|
||||
m = self.scheme.search(address)
|
||||
if m:
|
||||
self.volume = m.group('vol')
|
||||
if (has_volume is True and not self.volume) or (
|
||||
has_volume is False and self.volume):
|
||||
m = None
|
||||
if not m:
|
||||
raise exception.GlusterfsException(
|
||||
_('Invalid gluster address %s.') % address)
|
||||
self.remote_user = m.group('user')
|
||||
self.host = m.group('host')
|
||||
self.management_address = '@'.join(
|
||||
filter(None, (self.remote_user, self.host)))
|
||||
self.qualified = address
|
||||
if self.volume:
|
||||
self.export = ':/'.join([self.host, self.volume])
|
||||
else:
|
||||
self.export = None
|
||||
self.path_to_private_key = path_to_private_key
|
||||
self.remote_server_password = remote_server_password
|
||||
self.gluster_call = self.make_gluster_call(execf)
|
||||
|
||||
def make_gluster_call(self, execf):
|
||||
"""Execute a Gluster command locally or remotely."""
|
||||
if self.remote_user:
|
||||
gluster_execf = ganesha_utils.SSHExecutor(
|
||||
self.host, 22, None, self.remote_user,
|
||||
password=self.remote_server_password,
|
||||
privatekey=self.path_to_private_key)
|
||||
else:
|
||||
gluster_execf = ganesha_utils.RootExecutor(execf)
|
||||
return lambda *args, **kwargs: gluster_execf(*(('gluster',) + args),
|
||||
**kwargs)
|
||||
|
||||
def get_gluster_vol_option(self, option):
|
||||
"""Get the value of an option set on a GlusterFS volume."""
|
||||
args = ('--xml', 'volume', 'info', self.volume)
|
||||
try:
|
||||
out, err = self.gluster_call(*args)
|
||||
except exception.ProcessExecutionError as exc:
|
||||
LOG.error(_LE("Error retrieving volume info: %s"), exc.stderr)
|
||||
raise exception.GlusterfsException("gluster %s failed" %
|
||||
' '.join(args))
|
||||
|
||||
if not out:
|
||||
raise exception.GlusterfsException(
|
||||
'gluster volume info %s: no data received' %
|
||||
self.volume
|
||||
)
|
||||
|
||||
vix = etree.fromstring(out)
|
||||
if int(vix.find('./volInfo/volumes/count').text) != 1:
|
||||
raise exception.InvalidShare('Volume name ambiguity')
|
||||
for e in vix.findall(".//option"):
|
||||
o, v = (e.find(a).text for a in ('name', 'value'))
|
||||
if o == option:
|
||||
return v
|
||||
|
||||
def get_gluster_version(self):
|
||||
"""Retrieve GlusterFS version.
|
||||
|
||||
:returns: version (as tuple of strings, example: ('3', '6', '0beta2'))
|
||||
"""
|
||||
try:
|
||||
out, err = self.gluster_call('--version')
|
||||
except exception.ProcessExecutionError as exc:
|
||||
raise exception.GlusterfsException(
|
||||
_("'gluster version' failed on server "
|
||||
"%(server)s: %(message)s") %
|
||||
{'server': self.host, 'message': six.text_type(exc)})
|
||||
try:
|
||||
owords = out.split()
|
||||
if owords[0] != 'glusterfs':
|
||||
raise RuntimeError
|
||||
vers = owords[1].split('.')
|
||||
# provoke an exception if vers does not start with two numerals
|
||||
int(vers[0])
|
||||
int(vers[1])
|
||||
except Exception:
|
||||
raise exception.GlusterfsException(
|
||||
_("Cannot parse version info obtained from server "
|
||||
"%(server)s, version info: %(info)s") %
|
||||
{'server': self.host, 'info': out})
|
||||
return vers
|
||||
|
||||
def check_gluster_version(self, minvers):
|
||||
"""Retrieve and check GlusterFS version.
|
||||
|
||||
:param minvers: minimum version to require
|
||||
(given as tuple of integers, example: (3, 6))
|
||||
"""
|
||||
vers = self.get_gluster_version()
|
||||
if self.numreduct(vers) < minvers:
|
||||
raise exception.GlusterfsException(_(
|
||||
"Unsupported GlusterFS version %(version)s on server "
|
||||
"%(server)s, minimum requirement: %(minvers)s") % {
|
||||
'server': self.host,
|
||||
'version': '.'.join(vers),
|
||||
'minvers': '.'.join(six.text_type(c) for c in minvers)})
|
||||
|
||||
@staticmethod
|
||||
def numreduct(vers):
|
||||
"""The numeric reduct of a tuple of strings.
|
||||
|
||||
That is, applying an integer conversion map on the longest
|
||||
initial segment of vers which consists of numerals.
|
||||
"""
|
||||
numvers = []
|
||||
for c in vers:
|
||||
try:
|
||||
numvers.append(int(c))
|
||||
except ValueError:
|
||||
break
|
||||
return tuple(numvers)
|
||||
|
||||
|
||||
class GlusterfsShareDriver(driver.ExecuteMixin, driver.GaneshaMixin,
|
||||
driver.ShareDriver,):
|
||||
"""Execute commands relating to Shares."""
|
||||
|
@ -244,7 +107,7 @@ class GlusterfsShareDriver(driver.ExecuteMixin, driver.GaneshaMixin,
|
|||
raise exception.GlusterfsException(
|
||||
_('glusterfs_target configuration that specifies the GlusterFS'
|
||||
' volume to be mounted on the Manila host is not set.'))
|
||||
self.gluster_manager = GlusterManager(
|
||||
self.gluster_manager = common.GlusterManager(
|
||||
self.configuration.glusterfs_target,
|
||||
self._execute,
|
||||
self.configuration.glusterfs_path_to_private_key,
|
||||
|
@ -296,35 +159,13 @@ class GlusterfsShareDriver(driver.ExecuteMixin, driver.GaneshaMixin,
|
|||
return os.path.join(self.configuration.glusterfs_mount_point_base,
|
||||
self.gluster_manager.volume)
|
||||
|
||||
def _do_mount(self, cmd, ensure):
|
||||
"""Execute the mount command based on 'ensure' parameter.
|
||||
|
||||
:param cmd: command to do the actual mount
|
||||
:param ensure: boolean to allow remounting a volume with a warning
|
||||
"""
|
||||
try:
|
||||
self._execute(*cmd, run_as_root=True)
|
||||
except exception.ProcessExecutionError as exc:
|
||||
if ensure and 'already mounted' in exc.stderr:
|
||||
LOG.warn(_LW("%s is already mounted"),
|
||||
self.gluster_manager.export)
|
||||
else:
|
||||
raise exception.GlusterfsException(
|
||||
'Unable to mount Gluster volume'
|
||||
)
|
||||
|
||||
def _mount_gluster_vol(self, mount_path, ensure=False):
|
||||
"""Mount GlusterFS volume at the specified mount path."""
|
||||
self._execute('mkdir', '-p', mount_path)
|
||||
command = ['mount', '-t', 'glusterfs', self.gluster_manager.export,
|
||||
mount_path]
|
||||
self._do_mount(command, ensure)
|
||||
|
||||
def _ensure_gluster_vol_mounted(self):
|
||||
"""Ensure GlusterFS volume is native-mounted on Manila host."""
|
||||
mount_path = self._get_mount_point_for_gluster_vol()
|
||||
try:
|
||||
self._mount_gluster_vol(mount_path, ensure=True)
|
||||
common._mount_gluster_vol(self._execute,
|
||||
self.gluster_manager.export, mount_path,
|
||||
ensure=True)
|
||||
except exception.GlusterfsException:
|
||||
LOG.error(_LE('Could not mount the Gluster volume %s'),
|
||||
self.gluster_manager.volume)
|
||||
|
@ -555,7 +396,7 @@ class GaneshaNFSHelper(ganesha.GaneshaNASHelper):
|
|||
def _default_config_hook(self):
|
||||
"""Callback to provide default export block."""
|
||||
dconf = super(GaneshaNFSHelper, self)._default_config_hook()
|
||||
conf_dir = ganesha_utils.path_from(__file__, "glusterfs", "conf")
|
||||
conf_dir = ganesha_utils.path_from(__file__, "conf")
|
||||
ganesha_utils.patch(dconf, self._load_conf_dir(conf_dir))
|
||||
return dconf
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
# Copyright (c) 2015 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Common GlussterFS routines."""
|
||||
|
||||
|
||||
import re
|
||||
import xml.etree.cElementTree as etree
|
||||
|
||||
from oslo_log import log
|
||||
import six
|
||||
|
||||
from manila import exception
|
||||
from manila.i18n import _
|
||||
from manila.i18n import _LE
|
||||
from manila.i18n import _LW
|
||||
from manila.share.drivers.ganesha import utils as ganesha_utils
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class GlusterManager(object):
|
||||
"""Interface with a GlusterFS volume."""
|
||||
|
||||
scheme = re.compile('\A(?:(?P<user>[^:@/]+)@)?'
|
||||
'(?P<host>[^:@/]+)'
|
||||
'(?::/(?P<vol>.+))?')
|
||||
|
||||
def __init__(self, address, execf, path_to_private_key=None,
|
||||
remote_server_password=None, has_volume=True):
|
||||
"""Initialize a GlusterManager instance.
|
||||
|
||||
:param address: the Gluster URI (in [<user>@]<host>:/<vol> format).
|
||||
:param execf: executor function for management commands.
|
||||
:param path_to_private_key: path to private ssh key of remote server.
|
||||
:param remote_server_password: ssh password for remote server.
|
||||
:param has_volume: instruction to uri parser regarding how to deal
|
||||
with the optional volume part (True: require its
|
||||
presence, False: require its absence, None: don't
|
||||
require anything about volume).
|
||||
"""
|
||||
m = self.scheme.search(address)
|
||||
if m:
|
||||
self.volume = m.group('vol')
|
||||
if (has_volume is True and not self.volume) or (
|
||||
has_volume is False and self.volume):
|
||||
m = None
|
||||
if not m:
|
||||
raise exception.GlusterfsException(
|
||||
_('Invalid gluster address %s.') % address)
|
||||
self.remote_user = m.group('user')
|
||||
self.host = m.group('host')
|
||||
self.management_address = '@'.join(
|
||||
filter(None, (self.remote_user, self.host)))
|
||||
self.qualified = address
|
||||
if self.volume:
|
||||
self.export = ':/'.join([self.host, self.volume])
|
||||
else:
|
||||
self.export = None
|
||||
self.path_to_private_key = path_to_private_key
|
||||
self.remote_server_password = remote_server_password
|
||||
self.gluster_call = self.make_gluster_call(execf)
|
||||
|
||||
def make_gluster_call(self, execf):
|
||||
"""Execute a Gluster command locally or remotely."""
|
||||
if self.remote_user:
|
||||
gluster_execf = ganesha_utils.SSHExecutor(
|
||||
self.host, 22, None, self.remote_user,
|
||||
password=self.remote_server_password,
|
||||
privatekey=self.path_to_private_key)
|
||||
else:
|
||||
gluster_execf = ganesha_utils.RootExecutor(execf)
|
||||
return lambda *args, **kwargs: gluster_execf(*(('gluster',) + args),
|
||||
**kwargs)
|
||||
|
||||
def get_gluster_vol_option(self, option):
|
||||
"""Get the value of an option set on a GlusterFS volume."""
|
||||
args = ('--xml', 'volume', 'info', self.volume)
|
||||
try:
|
||||
out, err = self.gluster_call(*args)
|
||||
except exception.ProcessExecutionError as exc:
|
||||
LOG.error(_LE("Error retrieving volume info: %s"), exc.stderr)
|
||||
raise exception.GlusterfsException("gluster %s failed" %
|
||||
' '.join(args))
|
||||
|
||||
if not out:
|
||||
raise exception.GlusterfsException(
|
||||
'gluster volume info %s: no data received' %
|
||||
self.volume
|
||||
)
|
||||
|
||||
vix = etree.fromstring(out)
|
||||
if int(vix.find('./volInfo/volumes/count').text) != 1:
|
||||
raise exception.InvalidShare('Volume name ambiguity')
|
||||
for e in vix.findall(".//option"):
|
||||
o, v = (e.find(a).text for a in ('name', 'value'))
|
||||
if o == option:
|
||||
return v
|
||||
|
||||
def get_gluster_version(self):
|
||||
"""Retrieve GlusterFS version.
|
||||
|
||||
:returns: version (as tuple of strings, example: ('3', '6', '0beta2'))
|
||||
"""
|
||||
try:
|
||||
out, err = self.gluster_call('--version')
|
||||
except exception.ProcessExecutionError as exc:
|
||||
raise exception.GlusterfsException(
|
||||
_("'gluster version' failed on server "
|
||||
"%(server)s: %(message)s") %
|
||||
{'server': self.host, 'message': six.text_type(exc)})
|
||||
try:
|
||||
owords = out.split()
|
||||
if owords[0] != 'glusterfs':
|
||||
raise RuntimeError
|
||||
vers = owords[1].split('.')
|
||||
# provoke an exception if vers does not start with two numerals
|
||||
int(vers[0])
|
||||
int(vers[1])
|
||||
except Exception:
|
||||
raise exception.GlusterfsException(
|
||||
_("Cannot parse version info obtained from server "
|
||||
"%(server)s, version info: %(info)s") %
|
||||
{'server': self.host, 'info': out})
|
||||
return vers
|
||||
|
||||
def check_gluster_version(self, minvers):
|
||||
"""Retrieve and check GlusterFS version.
|
||||
|
||||
:param minvers: minimum version to require
|
||||
(given as tuple of integers, example: (3, 6))
|
||||
"""
|
||||
vers = self.get_gluster_version()
|
||||
if self.numreduct(vers) < minvers:
|
||||
raise exception.GlusterfsException(_(
|
||||
"Unsupported GlusterFS version %(version)s on server "
|
||||
"%(server)s, minimum requirement: %(minvers)s") % {
|
||||
'server': self.host,
|
||||
'version': '.'.join(vers),
|
||||
'minvers': '.'.join(six.text_type(c) for c in minvers)})
|
||||
|
||||
@staticmethod
|
||||
def numreduct(vers):
|
||||
"""The numeric reduct of a tuple of strings.
|
||||
|
||||
That is, applying an integer conversion map on the longest
|
||||
initial segment of vers which consists of numerals.
|
||||
"""
|
||||
numvers = []
|
||||
for c in vers:
|
||||
try:
|
||||
numvers.append(int(c))
|
||||
except ValueError:
|
||||
break
|
||||
return tuple(numvers)
|
||||
|
||||
|
||||
def _mount_gluster_vol(execute, gluster_export, mount_path, ensure=False):
|
||||
"""Mount a GlusterFS volume at the specified mount path.
|
||||
|
||||
:param execute: command exectution function
|
||||
:param gluster_export: GlusterFS export to mount
|
||||
:param mount_path: path to mount at
|
||||
:param ensure: boolean to allow remounting a volume with a warning
|
||||
"""
|
||||
execute('mkdir', '-p', mount_path)
|
||||
command = ['mount', '-t', 'glusterfs', gluster_export, mount_path]
|
||||
try:
|
||||
execute(*command, run_as_root=True)
|
||||
except exception.ProcessExecutionError as exc:
|
||||
if ensure and 'already mounted' in exc.stderr:
|
||||
LOG.warn(_LW("%s is already mounted"), gluster_export)
|
||||
else:
|
||||
raise exception.GlusterfsException(
|
||||
'Unable to mount Gluster volume'
|
||||
)
|
||||
|
||||
|
||||
def _umount_gluster_vol(execute, mount_path):
|
||||
"""Unmount a GlusterFS volume at the specified mount path.
|
||||
|
||||
:param execute: command exectution function
|
||||
:param mount_path: path where volume is mounted
|
||||
"""
|
||||
|
||||
try:
|
||||
execute('umount', mount_path, run_as_root=True)
|
||||
except exception.ProcessExecutionError as exc:
|
||||
msg = (_("Unable to unmount gluster volume. "
|
||||
"mount_dir: %(mount_path)s, Error: %(error)s") %
|
||||
{'mount_path': mount_path, 'error': exc.stderr})
|
||||
LOG.error(msg)
|
||||
raise exception.GlusterfsException(msg)
|
||||
|
||||
|
||||
def _restart_gluster_vol(gluster_mgr):
|
||||
"""Restart a GlusterFS volume through its manager.
|
||||
|
||||
:param gluster_mgr: GlusterManager instance
|
||||
"""
|
||||
|
||||
try:
|
||||
# TODO(csaba): '--mode=script' ensures that the Gluster CLI runs in
|
||||
# script mode. This seems unnecessary as the Gluster CLI is
|
||||
# expected to run in non-interactive mode when the stdin is not
|
||||
# a terminal, as is the case below. But on testing, found the
|
||||
# behaviour of Gluster-CLI to be the contrary. Need to investigate
|
||||
# this odd-behaviour of Gluster-CLI.
|
||||
gluster_mgr.gluster_call(
|
||||
'volume', 'stop', gluster_mgr.volume, '--mode=script')
|
||||
except exception.ProcessExecutionError as exc:
|
||||
msg = (_("Error stopping gluster volume. "
|
||||
"Volume: %(volname)s, Error: %(error)s") %
|
||||
{'volname': gluster_mgr.volume, 'error': exc.stderr})
|
||||
LOG.error(msg)
|
||||
raise exception.GlusterfsException(msg)
|
||||
|
||||
try:
|
||||
gluster_mgr.gluster_call(
|
||||
'volume', 'start', gluster_mgr.volume)
|
||||
except exception.ProcessExecutionError as exc:
|
||||
msg = (_("Error starting gluster volume. "
|
||||
"Volume: %(volname)s, Error: %(error)s") %
|
||||
{'volname': gluster_mgr.volume, 'error': exc.stderr})
|
||||
LOG.error(msg)
|
||||
raise exception.GlusterfsException(msg)
|
|
@ -44,7 +44,7 @@ from manila.i18n import _LE
|
|||
from manila.i18n import _LI
|
||||
from manila.i18n import _LW
|
||||
from manila.share import driver
|
||||
from manila.share.drivers import glusterfs
|
||||
from manila.share.drivers.glusterfs import common
|
||||
from manila import utils
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
@ -177,7 +177,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
','.join(exceptions.keys())))
|
||||
notsupp_servers = []
|
||||
for srvaddr, vers in six.iteritems(glusterfs_versions):
|
||||
if glusterfs.GlusterManager.numreduct(
|
||||
if common.GlusterManager.numreduct(
|
||||
vers) < GLUSTERFS_VERSION_MIN:
|
||||
notsupp_servers.append(srvaddr)
|
||||
if notsupp_servers:
|
||||
|
@ -225,7 +225,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
def _glustermanager(self, gluster_address, has_volume=True):
|
||||
"""Create GlusterManager object for gluster_address."""
|
||||
|
||||
return glusterfs.GlusterManager(
|
||||
return common.GlusterManager(
|
||||
gluster_address, self._execute,
|
||||
self.configuration.glusterfs_native_path_to_private_key,
|
||||
self.configuration.glusterfs_native_server_password,
|
||||
|
@ -308,37 +308,9 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
|
||||
# TODO(deepakcs) Remove this once ssl options can be
|
||||
# set dynamically.
|
||||
self._restart_gluster_vol(gluster_mgr)
|
||||
common._restart_gluster_vol(gluster_mgr)
|
||||
return gluster_mgr
|
||||
|
||||
@staticmethod
|
||||
def _restart_gluster_vol(gluster_mgr):
|
||||
try:
|
||||
# TODO(csaba): '--mode=script' ensures that the Gluster CLI runs in
|
||||
# script mode. This seems unnecessary as the Gluster CLI is
|
||||
# expected to run in non-interactive mode when the stdin is not
|
||||
# a terminal, as is the case below. But on testing, found the
|
||||
# behaviour of Gluster-CLI to be the contrary. Need to investigate
|
||||
# this odd-behaviour of Gluster-CLI.
|
||||
gluster_mgr.gluster_call(
|
||||
'volume', 'stop', gluster_mgr.volume, '--mode=script')
|
||||
except exception.ProcessExecutionError as exc:
|
||||
msg = (_("Error stopping gluster volume. "
|
||||
"Volume: %(volname)s, Error: %(error)s") %
|
||||
{'volname': gluster_mgr.volume, 'error': exc.stderr})
|
||||
LOG.error(msg)
|
||||
raise exception.GlusterfsException(msg)
|
||||
|
||||
try:
|
||||
gluster_mgr.gluster_call(
|
||||
'volume', 'start', gluster_mgr.volume)
|
||||
except exception.ProcessExecutionError as exc:
|
||||
msg = (_("Error starting gluster volume. "
|
||||
"Volume: %(volname)s, Error: %(error)s") %
|
||||
{'volname': gluster_mgr.volume, 'error': exc.stderr})
|
||||
LOG.error(msg)
|
||||
raise exception.GlusterfsException(msg)
|
||||
|
||||
@utils.synchronized("glusterfs_native", external=False)
|
||||
def _pop_gluster_vol(self, size=None):
|
||||
"""Pick an unbound volume.
|
||||
|
@ -444,30 +416,6 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
LOG.error(msg)
|
||||
raise exception.GlusterfsException(msg)
|
||||
|
||||
def _do_mount(self, gluster_export, mntdir):
|
||||
|
||||
cmd = ['mount', '-t', 'glusterfs', gluster_export, mntdir]
|
||||
try:
|
||||
self._execute(*cmd, run_as_root=True)
|
||||
except exception.ProcessExecutionError as exc:
|
||||
msg = (_("Unable to mount gluster volume. "
|
||||
"gluster_export: %(export)s, Error: %(error)s") %
|
||||
{'export': gluster_export, 'error': exc.stderr})
|
||||
LOG.error(msg)
|
||||
raise exception.GlusterfsException(msg)
|
||||
|
||||
def _do_umount(self, mntdir):
|
||||
|
||||
cmd = ['umount', mntdir]
|
||||
try:
|
||||
self._execute(*cmd, run_as_root=True)
|
||||
except exception.ProcessExecutionError as exc:
|
||||
msg = (_("Unable to unmount gluster volume. "
|
||||
"mount_dir: %(mntdir)s, Error: %(error)s") %
|
||||
{'mntdir': mntdir, 'error': exc.stderr})
|
||||
LOG.error(msg)
|
||||
raise exception.GlusterfsException(msg)
|
||||
|
||||
def _wipe_gluster_vol(self, gluster_mgr):
|
||||
|
||||
# Reset the SSL options.
|
||||
|
@ -497,13 +445,13 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
LOG.error(msg)
|
||||
raise exception.GlusterfsException(msg)
|
||||
|
||||
self._restart_gluster_vol(gluster_mgr)
|
||||
common._restart_gluster_vol(gluster_mgr)
|
||||
|
||||
# Create a temporary mount.
|
||||
gluster_export = gluster_mgr.export
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
try:
|
||||
self._do_mount(gluster_export, tmpdir)
|
||||
common._mount_gluster_vol(self._execute, gluster_export, tmpdir)
|
||||
except exception.GlusterfsException:
|
||||
shutil.rmtree(tmpdir, ignore_errors=True)
|
||||
raise
|
||||
|
@ -517,8 +465,8 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
# delete the paths of the two directories, but delete their contents
|
||||
# along with the rest of the contents of the volume.
|
||||
srvaddr = gluster_mgr.management_address
|
||||
if glusterfs.GlusterManager.numreduct(self.glusterfs_versions[srvaddr]
|
||||
) < (3, 7):
|
||||
if common.GlusterManager.numreduct(self.glusterfs_versions[srvaddr]
|
||||
) < (3, 7):
|
||||
cmd = ['find', tmpdir, '-mindepth', '1', '-delete']
|
||||
else:
|
||||
ignored_dirs = map(lambda x: os.path.join(tmpdir, *x),
|
||||
|
@ -537,7 +485,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
raise exception.GlusterfsException(msg)
|
||||
finally:
|
||||
# Unmount.
|
||||
self._do_umount(tmpdir)
|
||||
common._umount_gluster_vol(self._execute, tmpdir)
|
||||
shutil.rmtree(tmpdir, ignore_errors=True)
|
||||
|
||||
# Set the SSL options.
|
||||
|
@ -567,7 +515,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
LOG.error(msg)
|
||||
raise exception.GlusterfsException(msg)
|
||||
|
||||
self._restart_gluster_vol(gluster_mgr)
|
||||
common._restart_gluster_vol(gluster_mgr)
|
||||
|
||||
def get_network_allocations_number(self):
|
||||
return 0
|
||||
|
@ -652,7 +600,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
# a version check.
|
||||
vers = self.glusterfs_versions[old_gmgr.management_address]
|
||||
minvers = (3, 7)
|
||||
if glusterfs.GlusterManager.numreduct(vers) < minvers:
|
||||
if common.GlusterManager.numreduct(vers) < minvers:
|
||||
minvers_str = '.'.join(six.text_type(c) for c in minvers)
|
||||
vers_str = '.'.join(vers)
|
||||
msg = (_("GlusterFS version %(version)s on server %(server)s does "
|
||||
|
@ -748,7 +696,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
|
||||
if opret == -1:
|
||||
vers = self.glusterfs_versions[gluster_mgr.management_address]
|
||||
if glusterfs.GlusterManager.numreduct(vers) > (3, 6):
|
||||
if common.GlusterManager.numreduct(vers) > (3, 6):
|
||||
# This logic has not yet been implemented in GlusterFS 3.6
|
||||
if operrno == 0:
|
||||
self.gluster_nosnap_vols_dict[vol] = operrstr
|
||||
|
@ -846,7 +794,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
|
||||
# TODO(deepakcs) Remove this once ssl options can be
|
||||
# set dynamically.
|
||||
self._restart_gluster_vol(gluster_mgr)
|
||||
common._restart_gluster_vol(gluster_mgr)
|
||||
|
||||
@utils.synchronized("glusterfs_native_access", external=False)
|
||||
def deny_access(self, context, share, access, share_server=None):
|
||||
|
@ -891,7 +839,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
|
||||
# TODO(deepakcs) Remove this once ssl options can be
|
||||
# set dynamically.
|
||||
self._restart_gluster_vol(gluster_mgr)
|
||||
common._restart_gluster_vol(gluster_mgr)
|
||||
|
||||
def _update_share_stats(self):
|
||||
"""Send stats info for the GlusterFS volume."""
|
||||
|
|
|
@ -0,0 +1,408 @@
|
|||
# Copyright (c) 2015 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Test cases for GlusterFS common routines."""
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
|
||||
from manila import exception
|
||||
from manila.share.drivers.glusterfs import common
|
||||
from manila import test
|
||||
from manila.tests import fake_utils
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
fake_gluster_manager_attrs = {
|
||||
'export': '127.0.0.1:/testvol',
|
||||
'host': '127.0.0.1',
|
||||
'qualified': 'testuser@127.0.0.1:/testvol',
|
||||
'remote_user': 'testuser',
|
||||
'volume': 'testvol',
|
||||
'path_to_private_key': '/fakepath/to/privatekey',
|
||||
'remote_server_password': 'fakepassword',
|
||||
}
|
||||
fake_args = ('foo', 'bar')
|
||||
fake_kwargs = {'key1': 'value1', 'key2': 'value2'}
|
||||
fake_path_to_private_key = '/fakepath/to/privatekey'
|
||||
fake_remote_server_password = 'fakepassword'
|
||||
NFS_EXPORT_DIR = 'nfs.export-dir'
|
||||
|
||||
fakehost = 'example.com'
|
||||
fakevol = 'testvol'
|
||||
fakeexport = ':/'.join((fakehost, fakevol))
|
||||
fakemnt = '/mnt/glusterfs'
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class GlusterManagerTestCase(test.TestCase):
|
||||
"""Tests GlusterManager."""
|
||||
|
||||
def setUp(self):
|
||||
super(GlusterManagerTestCase, self).setUp()
|
||||
self.fake_execf = mock.Mock()
|
||||
self.fake_executor = mock.Mock(return_value=('', ''))
|
||||
with mock.patch.object(common.GlusterManager, 'make_gluster_call',
|
||||
return_value=self.fake_executor):
|
||||
self._gluster_manager = common.GlusterManager(
|
||||
'testuser@127.0.0.1:/testvol', self.fake_execf,
|
||||
fake_path_to_private_key, fake_remote_server_password)
|
||||
|
||||
def test_gluster_manager_init(self):
|
||||
self.assertEqual(fake_gluster_manager_attrs['remote_user'],
|
||||
self._gluster_manager.remote_user)
|
||||
self.assertEqual(fake_gluster_manager_attrs['host'],
|
||||
self._gluster_manager.host)
|
||||
self.assertEqual(fake_gluster_manager_attrs['volume'],
|
||||
self._gluster_manager.volume)
|
||||
self.assertEqual(fake_gluster_manager_attrs['qualified'],
|
||||
self._gluster_manager.qualified)
|
||||
self.assertEqual(fake_gluster_manager_attrs['export'],
|
||||
self._gluster_manager.export)
|
||||
self.assertEqual(fake_gluster_manager_attrs['path_to_private_key'],
|
||||
self._gluster_manager.path_to_private_key)
|
||||
self.assertEqual(fake_gluster_manager_attrs['remote_server_password'],
|
||||
self._gluster_manager.remote_server_password)
|
||||
self.assertEqual(self.fake_executor,
|
||||
self._gluster_manager.gluster_call)
|
||||
|
||||
@ddt.data(None, True)
|
||||
def test_gluster_manager_init_has_vol(self, has_volume):
|
||||
test_gluster_manager = common.GlusterManager(
|
||||
'testuser@127.0.0.1:/testvol', self.fake_execf,
|
||||
has_volume=has_volume)
|
||||
self.assertEqual('testvol', test_gluster_manager.volume)
|
||||
|
||||
@ddt.data(None, False)
|
||||
def test_gluster_manager_init_no_vol(self, has_volume):
|
||||
test_gluster_manager = common.GlusterManager(
|
||||
'testuser@127.0.0.1', self.fake_execf, has_volume=has_volume)
|
||||
self.assertIsNone(test_gluster_manager.volume)
|
||||
|
||||
def test_gluster_manager_init_has_shouldnt_have_vol(self):
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
common.GlusterManager,
|
||||
'testuser@127.0.0.1:/testvol',
|
||||
self.fake_execf, has_volume=False)
|
||||
|
||||
def test_gluster_manager_hasnt_should_have_vol(self):
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
common.GlusterManager, 'testuser@127.0.0.1',
|
||||
self.fake_execf, has_volume=True)
|
||||
|
||||
def test_gluster_manager_invalid(self):
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
common.GlusterManager, '127.0.0.1:vol',
|
||||
'self.fake_execf')
|
||||
|
||||
def test_gluster_manager_make_gluster_call_local(self):
|
||||
fake_obj = mock.Mock()
|
||||
fake_execute = mock.Mock()
|
||||
with mock.patch.object(common.ganesha_utils, 'RootExecutor',
|
||||
mock.Mock(return_value=fake_obj)):
|
||||
gluster_manager = common.GlusterManager(
|
||||
'127.0.0.1:/testvol', self.fake_execf)
|
||||
gluster_manager.make_gluster_call(fake_execute)(*fake_args,
|
||||
**fake_kwargs)
|
||||
common.ganesha_utils.RootExecutor.assert_called_with(
|
||||
fake_execute)
|
||||
fake_obj.assert_called_once_with(
|
||||
*(('gluster',) + fake_args), **fake_kwargs)
|
||||
|
||||
def test_gluster_manager_make_gluster_call_remote(self):
|
||||
fake_obj = mock.Mock()
|
||||
fake_execute = mock.Mock()
|
||||
with mock.patch.object(common.ganesha_utils, 'SSHExecutor',
|
||||
mock.Mock(return_value=fake_obj)):
|
||||
gluster_manager = common.GlusterManager(
|
||||
'testuser@127.0.0.1:/testvol', self.fake_execf,
|
||||
fake_path_to_private_key, fake_remote_server_password)
|
||||
gluster_manager.make_gluster_call(fake_execute)(*fake_args,
|
||||
**fake_kwargs)
|
||||
common.ganesha_utils.SSHExecutor.assert_called_with(
|
||||
gluster_manager.host, 22, None, gluster_manager.remote_user,
|
||||
password=gluster_manager.remote_server_password,
|
||||
privatekey=gluster_manager.path_to_private_key)
|
||||
fake_obj.assert_called_once_with(
|
||||
*(('gluster',) + fake_args), **fake_kwargs)
|
||||
|
||||
def test_get_gluster_vol_option_empty_volinfo(self):
|
||||
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(return_value=('', {})))
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._gluster_manager.get_gluster_vol_option,
|
||||
NFS_EXPORT_DIR)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(
|
||||
*args)
|
||||
|
||||
def test_get_gluster_vol_option_failing_volinfo(self):
|
||||
|
||||
def raise_exception(*ignore_args, **ignore_kwargs):
|
||||
raise RuntimeError('fake error')
|
||||
|
||||
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
self.assertRaises(RuntimeError,
|
||||
self._gluster_manager.get_gluster_vol_option,
|
||||
NFS_EXPORT_DIR)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(
|
||||
*args)
|
||||
|
||||
def test_get_gluster_vol_option_ambiguous_volinfo(self):
|
||||
|
||||
def xml_output(*ignore_args, **ignore_kwargs):
|
||||
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<cliOutput>
|
||||
<volInfo>
|
||||
<volumes>
|
||||
<count>0</count>
|
||||
</volumes>
|
||||
</volInfo>
|
||||
</cliOutput>""", ''
|
||||
|
||||
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(side_effect=xml_output))
|
||||
self.assertRaises(exception.InvalidShare,
|
||||
self._gluster_manager.get_gluster_vol_option,
|
||||
NFS_EXPORT_DIR)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(*args)
|
||||
|
||||
def test_get_gluster_vol_option_trivial_volinfo(self):
|
||||
|
||||
def xml_output(*ignore_args, **ignore_kwargs):
|
||||
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<cliOutput>
|
||||
<volInfo>
|
||||
<volumes>
|
||||
<volume>
|
||||
</volume>
|
||||
<count>1</count>
|
||||
</volumes>
|
||||
</volInfo>
|
||||
</cliOutput>""", ''
|
||||
|
||||
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(side_effect=xml_output))
|
||||
ret = self._gluster_manager.get_gluster_vol_option(NFS_EXPORT_DIR)
|
||||
self.assertIsNone(ret)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(*args)
|
||||
|
||||
def test_get_gluster_vol_option(self):
|
||||
|
||||
def xml_output(*ignore_args, **ignore_kwargs):
|
||||
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<cliOutput>
|
||||
<volInfo>
|
||||
<volumes>
|
||||
<volume>
|
||||
<options>
|
||||
<option>
|
||||
<name>nfs.export-dir</name>
|
||||
<value>/foo(10.0.0.1|10.0.0.2),/bar(10.0.0.1)</value>
|
||||
</option>
|
||||
</options>
|
||||
</volume>
|
||||
<count>1</count>
|
||||
</volumes>
|
||||
</volInfo>
|
||||
</cliOutput>""", ''
|
||||
|
||||
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(side_effect=xml_output))
|
||||
ret = self._gluster_manager.get_gluster_vol_option(NFS_EXPORT_DIR)
|
||||
self.assertEqual('/foo(10.0.0.1|10.0.0.2),/bar(10.0.0.1)', ret)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(*args)
|
||||
|
||||
def test_get_gluster_version(self):
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(return_value=('glusterfs 3.6.2beta3', '')))
|
||||
ret = self._gluster_manager.get_gluster_version()
|
||||
self.assertEqual(['3', '6', '2beta3'], ret)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(
|
||||
'--version')
|
||||
|
||||
@ddt.data("foo 1.1.1", "glusterfs 3-6", "glusterfs 3.6beta3")
|
||||
def test_get_gluster_version_exception(self, versinfo):
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(return_value=(versinfo, '')))
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._gluster_manager.get_gluster_version)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(
|
||||
'--version')
|
||||
|
||||
def test_get_gluster_version_process_error(self):
|
||||
def raise_exception(*args, **kwargs):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._gluster_manager.get_gluster_version)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(
|
||||
'--version')
|
||||
|
||||
def test_check_gluster_version(self):
|
||||
self.mock_object(self._gluster_manager, 'get_gluster_version',
|
||||
mock.Mock(return_value=('3', '6')))
|
||||
|
||||
ret = self._gluster_manager.check_gluster_version((3, 5, 2))
|
||||
self.assertIsNone(ret)
|
||||
self._gluster_manager.get_gluster_version.assert_called_once_with()
|
||||
|
||||
def test_check_gluster_version_unmet(self):
|
||||
self.mock_object(self._gluster_manager, 'get_gluster_version',
|
||||
mock.Mock(return_value=('3', '5', '2')))
|
||||
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._gluster_manager.check_gluster_version, (3, 6))
|
||||
self._gluster_manager.get_gluster_version.assert_called_once_with()
|
||||
|
||||
@ddt.data(('3', '6'),
|
||||
('3', '6', '2beta'),
|
||||
('3', '6', '2beta', '4'))
|
||||
def test_numreduct(self, vers):
|
||||
ret = common.GlusterManager.numreduct(vers)
|
||||
self.assertEqual((3, 6), ret)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class GlusterFSCommonTestCase(test.TestCase):
|
||||
"""Tests common GlusterFS utility functions."""
|
||||
|
||||
def setUp(self):
|
||||
super(GlusterFSCommonTestCase, self).setUp()
|
||||
fake_utils.stub_out_utils_execute(self)
|
||||
self._execute = fake_utils.fake_execute
|
||||
self.addCleanup(fake_utils.fake_execute_set_repliers, [])
|
||||
self.addCleanup(fake_utils.fake_execute_clear_log)
|
||||
self.mock_object(common.GlusterManager, 'make_gluster_call')
|
||||
|
||||
@staticmethod
|
||||
def _mount_exec(vol, mnt):
|
||||
return ['mkdir -p %s' % mnt,
|
||||
'mount -t glusterfs %(exp)s %(mnt)s' % {'exp': vol,
|
||||
'mnt': mnt}]
|
||||
|
||||
def test_mount_gluster_vol(self):
|
||||
expected_exec = self._mount_exec(fakeexport, fakemnt)
|
||||
ret = common._mount_gluster_vol(self._execute, fakeexport, fakemnt,
|
||||
False)
|
||||
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
|
||||
self.assertIsNone(ret)
|
||||
|
||||
def test_mount_gluster_vol_mounted_noensure(self):
|
||||
def exec_runner(*ignore_args, **ignore_kwargs):
|
||||
raise exception.ProcessExecutionError(stderr='already mounted')
|
||||
expected_exec = self._mount_exec(fakeexport, fakemnt)
|
||||
fake_utils.fake_execute_set_repliers([('mount', exec_runner)])
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
common._mount_gluster_vol,
|
||||
self._execute, fakeexport, fakemnt, False)
|
||||
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
|
||||
|
||||
def test_mount_gluster_vol_mounted_ensure(self):
|
||||
def exec_runner(*ignore_args, **ignore_kwargs):
|
||||
raise exception.ProcessExecutionError(stderr='already mounted')
|
||||
expected_exec = self._mount_exec(fakeexport, fakemnt)
|
||||
common.LOG.warn = mock.Mock()
|
||||
fake_utils.fake_execute_set_repliers([('mount', exec_runner)])
|
||||
ret = common._mount_gluster_vol(self._execute, fakeexport, fakemnt,
|
||||
True)
|
||||
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
|
||||
self.assertIsNone(ret)
|
||||
common.LOG.warn.assert_called_with(
|
||||
"%s is already mounted", fakeexport)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_mount_gluster_vol_fail(self, ensure):
|
||||
def exec_runner(*ignore_args, **ignore_kwargs):
|
||||
raise RuntimeError('fake error')
|
||||
expected_exec = self._mount_exec(fakeexport, fakemnt)
|
||||
fake_utils.fake_execute_set_repliers([('mount', exec_runner)])
|
||||
self.assertRaises(RuntimeError, common._mount_gluster_vol,
|
||||
self._execute, fakeexport, fakemnt, ensure)
|
||||
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
|
||||
|
||||
def test_umount_gluster_vol(self):
|
||||
expected_exec = ['umount %s' % fakemnt]
|
||||
ret = common._umount_gluster_vol(self._execute, fakemnt)
|
||||
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
|
||||
self.assertIsNone(ret)
|
||||
|
||||
@ddt.data({'in_exc': exception.ProcessExecutionError,
|
||||
'out_exc': exception.GlusterfsException},
|
||||
{'in_exc': RuntimeError, 'out_exc': RuntimeError})
|
||||
@ddt.unpack
|
||||
def test_umount_gluster_vol_fail(self, in_exc, out_exc):
|
||||
def exec_runner(*ignore_args, **ignore_kwargs):
|
||||
raise in_exc('fake error')
|
||||
expected_exec = ['umount %s' % fakemnt]
|
||||
fake_utils.fake_execute_set_repliers([('umount', exec_runner)])
|
||||
self.assertRaises(out_exc, common._umount_gluster_vol,
|
||||
self._execute, fakemnt)
|
||||
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
|
||||
|
||||
def test_restart_gluster_vol(self):
|
||||
gmgr = common.GlusterManager(fakeexport, self._execute, None, None)
|
||||
test_args = [('volume', 'stop', fakevol, '--mode=script'),
|
||||
('volume', 'start', fakevol)]
|
||||
|
||||
common._restart_gluster_vol(gmgr)
|
||||
self.assertEqual(
|
||||
[mock.call(*test_args[0]), mock.call(*test_args[1])],
|
||||
gmgr.gluster_call.call_args_list)
|
||||
|
||||
def test_restart_gluster_vol_excp1(self):
|
||||
gmgr = common.GlusterManager(fakeexport, self._execute, None, None)
|
||||
test_args = ('volume', 'stop', fakevol, '--mode=script')
|
||||
|
||||
def raise_exception(*args, **kwargs):
|
||||
if(args == test_args):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
self.mock_object(gmgr, 'gluster_call',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
common._restart_gluster_vol, gmgr)
|
||||
self.assertEqual(
|
||||
[mock.call(*test_args)],
|
||||
gmgr.gluster_call.call_args_list)
|
||||
|
||||
def test_restart_gluster_vol_excp2(self):
|
||||
gmgr = common.GlusterManager(fakeexport, self._execute, None, None)
|
||||
test_args = [('volume', 'stop', fakevol, '--mode=script'),
|
||||
('volume', 'start', fakevol)]
|
||||
|
||||
def raise_exception(*args, **kwargs):
|
||||
if(args == test_args[1]):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
self.mock_object(gmgr, 'gluster_call',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
common._restart_gluster_vol, gmgr)
|
||||
self.assertEqual(
|
||||
[mock.call(*test_args[0]), mock.call(*test_args[1])],
|
||||
gmgr.gluster_call.call_args_list)
|
|
@ -17,7 +17,6 @@ import copy
|
|||
import errno
|
||||
import os
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
|
||||
|
@ -25,6 +24,7 @@ from manila import context
|
|||
from manila import exception
|
||||
from manila.share import configuration as config
|
||||
from manila.share.drivers import glusterfs
|
||||
from manila.share.drivers.glusterfs import common
|
||||
from manila import test
|
||||
from manila.tests import fake_share
|
||||
from manila.tests import fake_utils
|
||||
|
@ -45,8 +45,6 @@ fake_gluster_manager_attrs = {
|
|||
|
||||
fake_local_share_path = '/mnt/nfs/testvol/fakename'
|
||||
|
||||
fake_args = ('foo', 'bar')
|
||||
fake_kwargs = {'key1': 'value1', 'key2': 'value2'}
|
||||
fake_path_to_private_key = '/fakepath/to/privatekey'
|
||||
fake_remote_server_password = 'fakepassword'
|
||||
fake_share_name = 'fakename'
|
||||
|
@ -54,242 +52,6 @@ NFS_EXPORT_DIR = 'nfs.export-dir'
|
|||
NFS_EXPORT_VOL = 'nfs.export-volumes'
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class GlusterManagerTestCase(test.TestCase):
|
||||
"""Tests GlusterManager."""
|
||||
|
||||
def setUp(self):
|
||||
super(GlusterManagerTestCase, self).setUp()
|
||||
self.fake_execf = mock.Mock()
|
||||
self.fake_executor = mock.Mock(return_value=('', ''))
|
||||
with mock.patch.object(glusterfs.GlusterManager, 'make_gluster_call',
|
||||
return_value=self.fake_executor):
|
||||
self._gluster_manager = glusterfs.GlusterManager(
|
||||
'testuser@127.0.0.1:/testvol', self.fake_execf,
|
||||
fake_path_to_private_key, fake_remote_server_password)
|
||||
|
||||
def test_gluster_manager_init(self):
|
||||
self.assertEqual(fake_gluster_manager_attrs['remote_user'],
|
||||
self._gluster_manager.remote_user)
|
||||
self.assertEqual(fake_gluster_manager_attrs['host'],
|
||||
self._gluster_manager.host)
|
||||
self.assertEqual(fake_gluster_manager_attrs['volume'],
|
||||
self._gluster_manager.volume)
|
||||
self.assertEqual(fake_gluster_manager_attrs['qualified'],
|
||||
self._gluster_manager.qualified)
|
||||
self.assertEqual(fake_gluster_manager_attrs['export'],
|
||||
self._gluster_manager.export)
|
||||
self.assertEqual(fake_gluster_manager_attrs['path_to_private_key'],
|
||||
self._gluster_manager.path_to_private_key)
|
||||
self.assertEqual(fake_gluster_manager_attrs['remote_server_password'],
|
||||
self._gluster_manager.remote_server_password)
|
||||
self.assertEqual(self.fake_executor,
|
||||
self._gluster_manager.gluster_call)
|
||||
|
||||
@ddt.data(None, True)
|
||||
def test_gluster_manager_init_has_vol(self, has_volume):
|
||||
test_gluster_manager = glusterfs.GlusterManager(
|
||||
'testuser@127.0.0.1:/testvol', self.fake_execf,
|
||||
has_volume=has_volume)
|
||||
self.assertEqual('testvol', test_gluster_manager.volume)
|
||||
|
||||
@ddt.data(None, False)
|
||||
def test_gluster_manager_init_no_vol(self, has_volume):
|
||||
test_gluster_manager = glusterfs.GlusterManager(
|
||||
'testuser@127.0.0.1', self.fake_execf, has_volume=has_volume)
|
||||
self.assertIsNone(test_gluster_manager.volume)
|
||||
|
||||
def test_gluster_manager_init_has_shouldnt_have_vol(self):
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
glusterfs.GlusterManager,
|
||||
'testuser@127.0.0.1:/testvol',
|
||||
self.fake_execf, has_volume=False)
|
||||
|
||||
def test_gluster_manager_hasnt_should_have_vol(self):
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
glusterfs.GlusterManager, 'testuser@127.0.0.1',
|
||||
self.fake_execf, has_volume=True)
|
||||
|
||||
def test_gluster_manager_invalid(self):
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
glusterfs.GlusterManager, '127.0.0.1:vol',
|
||||
'self.fake_execf')
|
||||
|
||||
def test_gluster_manager_make_gluster_call_local(self):
|
||||
fake_obj = mock.Mock()
|
||||
fake_execute = mock.Mock()
|
||||
with mock.patch.object(glusterfs.ganesha_utils, 'RootExecutor',
|
||||
mock.Mock(return_value=fake_obj)):
|
||||
gluster_manager = glusterfs.GlusterManager(
|
||||
'127.0.0.1:/testvol', self.fake_execf)
|
||||
gluster_manager.make_gluster_call(fake_execute)(*fake_args,
|
||||
**fake_kwargs)
|
||||
glusterfs.ganesha_utils.RootExecutor.assert_called_with(
|
||||
fake_execute)
|
||||
fake_obj.assert_called_once_with(
|
||||
*(('gluster',) + fake_args), **fake_kwargs)
|
||||
|
||||
def test_gluster_manager_make_gluster_call_remote(self):
|
||||
fake_obj = mock.Mock()
|
||||
fake_execute = mock.Mock()
|
||||
with mock.patch.object(glusterfs.ganesha_utils, 'SSHExecutor',
|
||||
mock.Mock(return_value=fake_obj)):
|
||||
gluster_manager = glusterfs.GlusterManager(
|
||||
'testuser@127.0.0.1:/testvol', self.fake_execf,
|
||||
fake_path_to_private_key, fake_remote_server_password)
|
||||
gluster_manager.make_gluster_call(fake_execute)(*fake_args,
|
||||
**fake_kwargs)
|
||||
glusterfs.ganesha_utils.SSHExecutor.assert_called_with(
|
||||
gluster_manager.host, 22, None, gluster_manager.remote_user,
|
||||
password=gluster_manager.remote_server_password,
|
||||
privatekey=gluster_manager.path_to_private_key)
|
||||
fake_obj.assert_called_once_with(
|
||||
*(('gluster',) + fake_args), **fake_kwargs)
|
||||
|
||||
def test_get_gluster_vol_option_empty_volinfo(self):
|
||||
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(return_value=('', {})))
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._gluster_manager.get_gluster_vol_option,
|
||||
NFS_EXPORT_DIR)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(
|
||||
*args)
|
||||
|
||||
def test_get_gluster_vol_option_failing_volinfo(self):
|
||||
|
||||
def raise_exception(*ignore_args, **ignore_kwargs):
|
||||
raise RuntimeError('fake error')
|
||||
|
||||
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
self.assertRaises(RuntimeError,
|
||||
self._gluster_manager.get_gluster_vol_option,
|
||||
NFS_EXPORT_DIR)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(
|
||||
*args)
|
||||
|
||||
def test_get_gluster_vol_option_ambiguous_volinfo(self):
|
||||
|
||||
def xml_output(*ignore_args, **ignore_kwargs):
|
||||
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<cliOutput>
|
||||
<volInfo>
|
||||
<volumes>
|
||||
<count>0</count>
|
||||
</volumes>
|
||||
</volInfo>
|
||||
</cliOutput>""", ''
|
||||
|
||||
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(side_effect=xml_output))
|
||||
self.assertRaises(exception.InvalidShare,
|
||||
self._gluster_manager.get_gluster_vol_option,
|
||||
NFS_EXPORT_DIR)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(*args)
|
||||
|
||||
def test_get_gluster_vol_option_trivial_volinfo(self):
|
||||
|
||||
def xml_output(*ignore_args, **ignore_kwargs):
|
||||
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<cliOutput>
|
||||
<volInfo>
|
||||
<volumes>
|
||||
<volume>
|
||||
</volume>
|
||||
<count>1</count>
|
||||
</volumes>
|
||||
</volInfo>
|
||||
</cliOutput>""", ''
|
||||
|
||||
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(side_effect=xml_output))
|
||||
ret = self._gluster_manager.get_gluster_vol_option(NFS_EXPORT_DIR)
|
||||
self.assertIsNone(ret)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(*args)
|
||||
|
||||
def test_get_gluster_vol_option(self):
|
||||
|
||||
def xml_output(*ignore_args, **ignore_kwargs):
|
||||
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<cliOutput>
|
||||
<volInfo>
|
||||
<volumes>
|
||||
<volume>
|
||||
<options>
|
||||
<option>
|
||||
<name>nfs.export-dir</name>
|
||||
<value>/foo(10.0.0.1|10.0.0.2),/bar(10.0.0.1)</value>
|
||||
</option>
|
||||
</options>
|
||||
</volume>
|
||||
<count>1</count>
|
||||
</volumes>
|
||||
</volInfo>
|
||||
</cliOutput>""", ''
|
||||
|
||||
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(side_effect=xml_output))
|
||||
ret = self._gluster_manager.get_gluster_vol_option(NFS_EXPORT_DIR)
|
||||
self.assertEqual('/foo(10.0.0.1|10.0.0.2),/bar(10.0.0.1)', ret)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(*args)
|
||||
|
||||
def test_get_gluster_version(self):
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(return_value=('glusterfs 3.6.2beta3', '')))
|
||||
ret = self._gluster_manager.get_gluster_version()
|
||||
self.assertEqual(['3', '6', '2beta3'], ret)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(
|
||||
'--version')
|
||||
|
||||
@ddt.data("foo 1.1.1", "glusterfs 3-6", "glusterfs 3.6beta3")
|
||||
def test_get_gluster_version_exception(self, versinfo):
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(return_value=(versinfo, '')))
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._gluster_manager.get_gluster_version)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(
|
||||
'--version')
|
||||
|
||||
def test_get_gluster_version_process_error(self):
|
||||
def raise_exception(*args, **kwargs):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
self.mock_object(self._gluster_manager, 'gluster_call',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._gluster_manager.get_gluster_version)
|
||||
self._gluster_manager.gluster_call.assert_called_once_with(
|
||||
'--version')
|
||||
|
||||
def test_check_gluster_version(self):
|
||||
self.mock_object(self._gluster_manager, 'get_gluster_version',
|
||||
mock.Mock(return_value=('3', '6')))
|
||||
|
||||
ret = self._gluster_manager.check_gluster_version((3, 5, 2))
|
||||
self.assertIsNone(ret)
|
||||
self._gluster_manager.get_gluster_version.assert_called_once_with()
|
||||
|
||||
def test_check_gluster_version_unmet(self):
|
||||
self.mock_object(self._gluster_manager, 'get_gluster_version',
|
||||
mock.Mock(return_value=('3', '5', '2')))
|
||||
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._gluster_manager.check_gluster_version, (3, 6))
|
||||
self._gluster_manager.get_gluster_version.assert_called_once_with()
|
||||
|
||||
@ddt.data(('3', '6'),
|
||||
('3', '6', '2beta'),
|
||||
('3', '6', '2beta', '4'))
|
||||
def test_numreduct(self, vers):
|
||||
ret = glusterfs.GlusterManager.numreduct(vers)
|
||||
self.assertEqual((3, 6), ret)
|
||||
|
||||
|
||||
class GlusterfsShareDriverTestCase(test.TestCase):
|
||||
"""Tests GlusterfsShareDriver."""
|
||||
|
||||
|
@ -325,7 +87,7 @@ class GlusterfsShareDriverTestCase(test.TestCase):
|
|||
methods = ('_ensure_gluster_vol_mounted', '_setup_helpers')
|
||||
for method in methods:
|
||||
self.mock_object(self._driver, method)
|
||||
self.mock_object(glusterfs, 'GlusterManager',
|
||||
self.mock_object(common, 'GlusterManager',
|
||||
mock.Mock(return_value=fake_gluster_manager))
|
||||
expected_exec = ['mount.glusterfs']
|
||||
exec_cmd1 = 'mount.glusterfs'
|
||||
|
@ -333,7 +95,7 @@ class GlusterfsShareDriverTestCase(test.TestCase):
|
|||
args = ('volume', 'quota', 'testvol', 'enable')
|
||||
self._driver.do_setup(self._context)
|
||||
self.assertEqual(fake_gluster_manager, self._driver.gluster_manager)
|
||||
glusterfs.GlusterManager.assert_called_once_with(
|
||||
common.GlusterManager.assert_called_once_with(
|
||||
self._driver.configuration.glusterfs_target, self._execute,
|
||||
self._driver.configuration.glusterfs_path_to_private_key,
|
||||
self._driver.configuration.glusterfs_server_password)
|
||||
|
@ -368,7 +130,7 @@ class GlusterfsShareDriverTestCase(test.TestCase):
|
|||
methods = ('_ensure_gluster_vol_mounted', '_setup_helpers')
|
||||
for method in methods:
|
||||
self.mock_object(self._driver, method)
|
||||
self.mock_object(glusterfs, 'GlusterManager',
|
||||
self.mock_object(common, 'GlusterManager',
|
||||
mock.Mock(return_value=fake_gluster_manager))
|
||||
expected_exec = ['mount.glusterfs']
|
||||
exec_cmd1 = 'mount.glusterfs'
|
||||
|
@ -377,7 +139,7 @@ class GlusterfsShareDriverTestCase(test.TestCase):
|
|||
self.assertRaises(exception.GlusterfsException, self._driver.do_setup,
|
||||
self._context)
|
||||
self.assertEqual(fake_gluster_manager, self._driver.gluster_manager)
|
||||
glusterfs.GlusterManager.assert_called_once_with(
|
||||
common.GlusterManager.assert_called_once_with(
|
||||
self._driver.configuration.glusterfs_target, self._execute,
|
||||
self._driver.configuration.glusterfs_path_to_private_key,
|
||||
self._driver.configuration.glusterfs_server_password)
|
||||
|
@ -399,7 +161,7 @@ class GlusterfsShareDriverTestCase(test.TestCase):
|
|||
methods = ('_ensure_gluster_vol_mounted', '_setup_helpers')
|
||||
for method in methods:
|
||||
self.mock_object(self._driver, method)
|
||||
self.mock_object(glusterfs, 'GlusterManager',
|
||||
self.mock_object(common, 'GlusterManager',
|
||||
mock.Mock(return_value=fake_gluster_manager))
|
||||
expected_exec = ['mount.glusterfs']
|
||||
exec_cmd1 = 'mount.glusterfs'
|
||||
|
@ -407,7 +169,7 @@ class GlusterfsShareDriverTestCase(test.TestCase):
|
|||
args = ('volume', 'quota', 'testvol', 'enable')
|
||||
self._driver.do_setup(self._context)
|
||||
self.assertEqual(fake_gluster_manager, self._driver.gluster_manager)
|
||||
glusterfs.GlusterManager.assert_called_once_with(
|
||||
common.GlusterManager.assert_called_once_with(
|
||||
self._driver.configuration.glusterfs_target, self._execute,
|
||||
self._driver.configuration.glusterfs_path_to_private_key,
|
||||
self._driver.configuration.glusterfs_server_password)
|
||||
|
@ -431,69 +193,13 @@ class GlusterfsShareDriverTestCase(test.TestCase):
|
|||
self.assertEqual(self._helper_nfs, self._driver._helpers['NFS'])
|
||||
self._driver._helpers['NFS'].init_helper.assert_called_once_with()
|
||||
|
||||
def test_do_mount(self):
|
||||
expected_exec = ['true']
|
||||
ret = self._driver._do_mount(expected_exec, False)
|
||||
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
|
||||
self.assertIsNone(ret)
|
||||
|
||||
def test_do_mount_mounted_noensure(self):
|
||||
def exec_runner(*ignore_args, **ignore_kwargs):
|
||||
raise exception.ProcessExecutionError(stderr='already mounted')
|
||||
expected_exec = ['true']
|
||||
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
|
||||
self.assertRaises(exception.GlusterfsException, self._driver._do_mount,
|
||||
expected_exec, False)
|
||||
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
|
||||
|
||||
def test_do_mount_mounted_ensure(self):
|
||||
def exec_runner(*ignore_args, **ignore_kwargs):
|
||||
raise exception.ProcessExecutionError(stderr='already mounted')
|
||||
expected_exec = ['true']
|
||||
glusterfs.LOG.warn = mock.Mock()
|
||||
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
|
||||
ret = self._driver._do_mount(expected_exec, True)
|
||||
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
|
||||
self.assertIsNone(ret)
|
||||
glusterfs.LOG.warn.assert_called_with(
|
||||
"%s is already mounted", self._driver.gluster_manager.export)
|
||||
|
||||
def test_do_mount_fail_noensure(self):
|
||||
def exec_runner(*ignore_args, **ignore_kwargs):
|
||||
raise RuntimeError('fake error')
|
||||
expected_exec = ['true']
|
||||
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
|
||||
self.assertRaises(RuntimeError, self._driver._do_mount,
|
||||
expected_exec, False)
|
||||
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
|
||||
|
||||
def test_do_mount_fail_ensure(self):
|
||||
def exec_runner(*ignore_args, **ignore_kwargs):
|
||||
raise RuntimeError('fake error')
|
||||
expected_exec = ['true']
|
||||
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
|
||||
self.assertRaises(RuntimeError, self._driver._do_mount,
|
||||
expected_exec, True)
|
||||
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
|
||||
|
||||
def test_mount_gluster_vol(self):
|
||||
mount_path = '/mnt/nfs/testvol'
|
||||
self._driver._do_mount = mock.Mock()
|
||||
cmd = ['mount', '-t', 'glusterfs',
|
||||
fake_gluster_manager_attrs['export'], mount_path]
|
||||
expected_exec = ['mkdir -p %s' % (mount_path)]
|
||||
|
||||
self._driver._mount_gluster_vol(mount_path)
|
||||
self._driver._do_mount.assert_called_with(cmd, False)
|
||||
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
|
||||
|
||||
def test_ensure_gluster_vol_mounted(self):
|
||||
self._driver._mount_gluster_vol = mock.Mock()
|
||||
common._mount_gluster_vol = mock.Mock()
|
||||
self._driver._ensure_gluster_vol_mounted()
|
||||
self.assertTrue(self._driver._mount_gluster_vol.called)
|
||||
self.assertTrue(common._mount_gluster_vol.called)
|
||||
|
||||
def test_ensure_gluster_vol_mounted_error(self):
|
||||
self._driver._mount_gluster_vol =\
|
||||
common._mount_gluster_vol =\
|
||||
mock.Mock(side_effect=exception.GlusterfsException)
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._driver._ensure_gluster_vol_mounted)
|
||||
|
@ -987,7 +693,7 @@ class GaneshaNFSHelperTestCase(test.TestCase):
|
|||
glusterfs.ganesha.GaneshaNASHelper._default_config_hook.\
|
||||
assert_called_once_with()
|
||||
glusterfs.ganesha_utils.path_from.assert_called_once_with(
|
||||
glusterfs.__file__, 'glusterfs', 'conf')
|
||||
glusterfs.__file__, 'conf')
|
||||
self._helper._load_conf_dir.assert_called_once_with(
|
||||
'/fakedir/glusterfs/conf')
|
||||
glusterfs.ganesha_utils.patch.assert_called_once_with(
|
||||
|
|
|
@ -30,7 +30,7 @@ from manila.common import constants
|
|||
from manila import context
|
||||
from manila import exception
|
||||
from manila.share import configuration as config
|
||||
from manila.share.drivers import glusterfs
|
||||
from manila.share.drivers.glusterfs import common
|
||||
from manila.share.drivers import glusterfs_native
|
||||
from manila import test
|
||||
from manila.tests import fake_utils
|
||||
|
@ -88,7 +88,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self.share2 = new_share(
|
||||
export_location=self.glusterfs_target2,
|
||||
status=constants.STATUS_AVAILABLE)
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
self.gmgr1 = gmgr(self.glusterfs_server1, self._execute, None, None,
|
||||
has_volume=False)
|
||||
self.gmgr2 = gmgr(self.glusterfs_server2, self._execute, None, None,
|
||||
|
@ -110,7 +110,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self.fake_conf = config.Configuration(None)
|
||||
self.mock_object(tempfile, 'mkdtemp',
|
||||
mock.Mock(return_value='/tmp/tmpKGHKJ'))
|
||||
self.mock_object(glusterfs.GlusterManager, 'make_gluster_call')
|
||||
self.mock_object(common.GlusterManager, 'make_gluster_call')
|
||||
|
||||
with mock.patch.object(glusterfs_native.GlusterfsNativeShareDriver,
|
||||
'_glustermanager',
|
||||
|
@ -128,11 +128,11 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
@ddt.unpack
|
||||
def test_glustermanager(self, test_kwargs, has_volume):
|
||||
fake_obj = mock.Mock()
|
||||
self.mock_object(glusterfs, 'GlusterManager',
|
||||
self.mock_object(common, 'GlusterManager',
|
||||
mock.Mock(return_value=fake_obj))
|
||||
ret = self._driver._glustermanager(self.glusterfs_target1,
|
||||
**test_kwargs)
|
||||
glusterfs.GlusterManager.assert_called_once_with(
|
||||
common.GlusterManager.assert_called_once_with(
|
||||
self.glusterfs_target1, self._execute,
|
||||
self._driver.configuration.glusterfs_native_path_to_private_key,
|
||||
self._driver.configuration.glusterfs_native_server_password,
|
||||
|
@ -238,9 +238,9 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
('volume', 'set', 'gv1', 'nfs.export-volumes', 'off'),
|
||||
('volume', 'set', 'gv1', 'client.ssl', 'on'),
|
||||
('volume', 'set', 'gv1', 'server.ssl', 'on')]
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self._driver._glustermanager = mock.Mock(return_value=gmgr1)
|
||||
self.mock_object(gmgr1, 'get_gluster_vol_option',
|
||||
|
@ -253,7 +253,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
mock.call(*test_args[1]),
|
||||
mock.call(*test_args[2]))
|
||||
self.assertEqual(gmgr1, ret)
|
||||
self.assertTrue(self._driver._restart_gluster_vol.called)
|
||||
self.assertTrue(common._restart_gluster_vol.called)
|
||||
|
||||
@ddt.data(0, 1, 2)
|
||||
def test_setup_gluster_vols_excp(self, idx):
|
||||
|
@ -266,9 +266,9 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
if(args == test_args[idx]):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self._driver._glustermanager = mock.Mock(return_value=gmgr1)
|
||||
self.mock_object(gmgr1, 'get_gluster_vol_option',
|
||||
|
@ -281,12 +281,12 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
|
||||
self.assertTrue(
|
||||
mock.call(*test_args[idx]) in gmgr1.gluster_call.call_args_list)
|
||||
self.assertFalse(self._driver._restart_gluster_vol.called)
|
||||
self.assertFalse(common._restart_gluster_vol.called)
|
||||
|
||||
def test_setup_gluster_vol_no_ssl_allow(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self._driver._glustermanager = mock.Mock(return_value=gmgr1)
|
||||
self.mock_object(gmgr1, 'get_gluster_vol_option',
|
||||
|
@ -296,55 +296,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._driver._setup_gluster_vol, gmgr1.volume)
|
||||
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
|
||||
self.assertFalse(gmgr1.gluster_call.called)
|
||||
self.assertFalse(self._driver._restart_gluster_vol.called)
|
||||
|
||||
def test_restart_gluster_vol(self):
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
test_args = [('volume', 'stop', 'gv1', '--mode=script'),
|
||||
('volume', 'start', 'gv1')]
|
||||
|
||||
self._driver._restart_gluster_vol(gmgr1)
|
||||
self.assertEqual(
|
||||
[mock.call(*test_args[0]), mock.call(*test_args[1])],
|
||||
gmgr1.gluster_call.call_args_list)
|
||||
|
||||
def test_restart_gluster_vol_excp1(self):
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
test_args = ('volume', 'stop', 'gv1', '--mode=script')
|
||||
|
||||
def raise_exception(*args, **kwargs):
|
||||
if(args == test_args):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
self.mock_object(gmgr1, 'gluster_call',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._driver._restart_gluster_vol, gmgr1)
|
||||
self.assertEqual(
|
||||
[mock.call(*test_args)],
|
||||
gmgr1.gluster_call.call_args_list)
|
||||
|
||||
def test_restart_gluster_vol_excp2(self):
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
test_args = [('volume', 'stop', 'gv1', '--mode=script'),
|
||||
('volume', 'start', 'gv1')]
|
||||
|
||||
def raise_exception(*args, **kwargs):
|
||||
if(args == test_args[1]):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
self.mock_object(gmgr1, 'gluster_call',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._driver._restart_gluster_vol, gmgr1)
|
||||
self.assertEqual(
|
||||
[mock.call(*test_args[0]), mock.call(*test_args[1])],
|
||||
gmgr1.gluster_call.call_args_list)
|
||||
self.assertFalse(common._restart_gluster_vol.called)
|
||||
|
||||
@ddt.data({"voldict": {"host:/share2G": {"size": 2}}, "used_vols": {},
|
||||
"size": 1, "expected": "host:/share2G"},
|
||||
|
@ -374,7 +326,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
"expected": "host:/share"})
|
||||
@ddt.unpack
|
||||
def test_pop_gluster_vol(self, voldict, used_vols, size, expected):
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(expected, self._execute, None, None)
|
||||
self._driver._fetch_gluster_volumes = mock.Mock(return_value=voldict)
|
||||
self._driver.gluster_used_vols_dict = used_vols
|
||||
|
@ -403,7 +355,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self.assertFalse(self._driver._setup_gluster_vol.called)
|
||||
|
||||
def test_push_gluster_vol(self):
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
gmgr2 = gmgr(self.glusterfs_target2, self._execute, None, None)
|
||||
|
||||
|
@ -417,7 +369,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self.glusterfs_target2 in self._driver.gluster_used_vols_dict)
|
||||
|
||||
def test_push_gluster_vol_excp(self):
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
|
||||
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
|
||||
|
@ -427,50 +379,6 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._driver._push_gluster_vol,
|
||||
self.glusterfs_target2)
|
||||
|
||||
def test_do_mount(self):
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
tmpdir = '/tmp/tmpKGHKJ'
|
||||
expected_exec = ['mount -t glusterfs host1:/gv1 /tmp/tmpKGHKJ']
|
||||
|
||||
self._driver._do_mount(gmgr1.export, tmpdir)
|
||||
|
||||
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
|
||||
|
||||
def test_do_mount_excp(self):
|
||||
def exec_runner(*ignore_args, **ignore_kwargs):
|
||||
raise exception.ProcessExecutionError
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
tmpdir = '/tmp/tmpKGHKJ'
|
||||
expected_exec = ['mount -t glusterfs host1:/gv1 /tmp/tmpKGHKJ']
|
||||
|
||||
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
|
||||
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._driver._do_mount, gmgr1.export, tmpdir)
|
||||
|
||||
def test_do_umount(self):
|
||||
tmpdir = '/tmp/tmpKGHKJ'
|
||||
expected_exec = ['umount /tmp/tmpKGHKJ']
|
||||
|
||||
self._driver._do_umount(tmpdir)
|
||||
|
||||
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
|
||||
|
||||
def test_do_umount_excp(self):
|
||||
def exec_runner(*ignore_args, **ignore_kwargs):
|
||||
raise exception.ProcessExecutionError
|
||||
|
||||
tmpdir = '/tmp/tmpKGHKJ'
|
||||
expected_exec = ['umount /tmp/tmpKGHKJ']
|
||||
|
||||
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
|
||||
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
self._driver._do_umount, tmpdir)
|
||||
|
||||
@ddt.data({'vers_minor': '6',
|
||||
'cmd': 'find /tmp/tmpKGHKJ -mindepth 1 -delete'},
|
||||
{'vers_minor': '7',
|
||||
|
@ -479,9 +387,9 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
'/tmp/tmpKGHKJ/.trashcan/internal_op -delete'})
|
||||
@ddt.unpack
|
||||
def test_wipe_gluster_vol(self, vers_minor, cmd):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
self._driver._do_mount = mock.Mock()
|
||||
self._driver._do_umount = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
common._mount_gluster_vol = mock.Mock()
|
||||
common._umount_gluster_vol = mock.Mock()
|
||||
shutil.rmtree = mock.Mock()
|
||||
test_args = [
|
||||
('volume', 'set', 'gv1', 'client.ssl', 'off'),
|
||||
|
@ -489,7 +397,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
('volume', 'set', 'gv1', 'client.ssl', 'on'),
|
||||
('volume', 'set', 'gv1', 'server.ssl', 'on')]
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self._driver.glusterfs_versions = {
|
||||
self.glusterfs_server1: ('3', vers_minor)}
|
||||
|
@ -497,21 +405,21 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
|
||||
self._driver._wipe_gluster_vol(gmgr1)
|
||||
|
||||
self.assertEqual(2, self._driver._restart_gluster_vol.call_count)
|
||||
self.assertEqual(2, common._restart_gluster_vol.call_count)
|
||||
self.assertEqual(
|
||||
[mock.call(*test_args[0]), mock.call(*test_args[1]),
|
||||
mock.call(*test_args[2]), mock.call(*test_args[3])],
|
||||
gmgr1.gluster_call.call_args_list)
|
||||
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
|
||||
self.assertTrue(tempfile.mkdtemp.called)
|
||||
self.assertTrue(self._driver._do_mount.called)
|
||||
self.assertTrue(self._driver._do_umount.called)
|
||||
self.assertTrue(common._mount_gluster_vol.called)
|
||||
self.assertTrue(common._umount_gluster_vol.called)
|
||||
self.assertTrue(shutil.rmtree.called)
|
||||
|
||||
def test_wipe_gluster_vol_excp1(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
self._driver._do_mount = mock.Mock()
|
||||
self._driver._do_umount = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
common._mount_gluster_vol = mock.Mock()
|
||||
common._umount_gluster_vol = mock.Mock()
|
||||
shutil.rmtree = mock.Mock()
|
||||
test_args = ('volume', 'set', 'gv1', 'client.ssl', 'off')
|
||||
|
||||
|
@ -519,7 +427,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
if(args == test_args):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self.mock_object(gmgr1, 'gluster_call',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
|
@ -528,16 +436,16 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._driver._wipe_gluster_vol, gmgr1)
|
||||
self.assertEqual(
|
||||
[mock.call(*test_args)], gmgr1.gluster_call.call_args_list)
|
||||
self.assertFalse(self._driver._restart_gluster_vol.called)
|
||||
self.assertFalse(common._restart_gluster_vol.called)
|
||||
self.assertFalse(tempfile.mkdtemp.called)
|
||||
self.assertFalse(self._driver._do_mount.called)
|
||||
self.assertFalse(self._driver._do_umount.called)
|
||||
self.assertFalse(common._mount_gluster_vol.called)
|
||||
self.assertFalse(common._umount_gluster_vol.called)
|
||||
self.assertFalse(shutil.rmtree.called)
|
||||
|
||||
def test_wipe_gluster_vol_excp2(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
self._driver._do_mount = mock.Mock()
|
||||
self._driver._do_umount = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
common._mount_gluster_vol = mock.Mock()
|
||||
common._umount_gluster_vol = mock.Mock()
|
||||
shutil.rmtree = mock.Mock()
|
||||
test_args = [
|
||||
('volume', 'set', 'gv1', 'client.ssl', 'off'),
|
||||
|
@ -547,7 +455,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
if(args == test_args[1]):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self.mock_object(gmgr1, 'gluster_call',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
|
@ -557,16 +465,16 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self.assertEqual(
|
||||
[mock.call(*test_args[0]), mock.call(*test_args[1])],
|
||||
gmgr1.gluster_call.call_args_list)
|
||||
self.assertFalse(self._driver._restart_gluster_vol.called)
|
||||
self.assertFalse(common._restart_gluster_vol.called)
|
||||
self.assertFalse(tempfile.mkdtemp.called)
|
||||
self.assertFalse(self._driver._do_mount.called)
|
||||
self.assertFalse(self._driver._do_umount.called)
|
||||
self.assertFalse(common._mount_gluster_vol.called)
|
||||
self.assertFalse(common._umount_gluster_vol.called)
|
||||
self.assertFalse(shutil.rmtree.called)
|
||||
|
||||
def test_wipe_gluster_vol_excp3(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
self._driver._do_mount = mock.Mock()
|
||||
self._driver._do_umount = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
common._mount_gluster_vol = mock.Mock()
|
||||
common._umount_gluster_vol = mock.Mock()
|
||||
shutil.rmtree = mock.Mock()
|
||||
test_args = [
|
||||
('volume', 'set', 'gv1', 'client.ssl', 'off'),
|
||||
|
@ -577,7 +485,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
if(args == test_args[2]):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self.mock_object(gmgr1, 'gluster_call',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
|
@ -591,16 +499,16 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
mock.call(*test_args[2])],
|
||||
gmgr1.gluster_call.call_args_list)
|
||||
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
|
||||
self.assertTrue(self._driver._restart_gluster_vol.called)
|
||||
self.assertTrue(common._restart_gluster_vol.called)
|
||||
self.assertTrue(tempfile.mkdtemp.called)
|
||||
self.assertTrue(self._driver._do_mount.called)
|
||||
self.assertTrue(self._driver._do_umount.called)
|
||||
self.assertTrue(common._mount_gluster_vol.called)
|
||||
self.assertTrue(common._umount_gluster_vol.called)
|
||||
self.assertTrue(shutil.rmtree.called)
|
||||
|
||||
def test_wipe_gluster_vol_excp4(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
self._driver._do_mount = mock.Mock()
|
||||
self._driver._do_umount = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
common._mount_gluster_vol = mock.Mock()
|
||||
common._umount_gluster_vol = mock.Mock()
|
||||
shutil.rmtree = mock.Mock()
|
||||
test_args = [
|
||||
('volume', 'set', 'gv1', 'client.ssl', 'off'),
|
||||
|
@ -612,7 +520,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
if(args == test_args[3]):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self.mock_object(gmgr1, 'gluster_call',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
|
@ -626,19 +534,19 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
mock.call(*test_args[2]), mock.call(*test_args[3])],
|
||||
gmgr1.gluster_call.call_args_list)
|
||||
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
|
||||
self.assertTrue(self._driver._restart_gluster_vol.called)
|
||||
self.assertTrue(common._restart_gluster_vol.called)
|
||||
self.assertTrue(tempfile.mkdtemp.called)
|
||||
self.assertTrue(self._driver._do_mount.called)
|
||||
self.assertTrue(self._driver._do_umount.called)
|
||||
self.assertTrue(common._mount_gluster_vol.called)
|
||||
self.assertTrue(common._umount_gluster_vol.called)
|
||||
self.assertTrue(shutil.rmtree.called)
|
||||
|
||||
def test_wipe_gluster_vol_excp5(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
self._driver._do_mount = mock.Mock()
|
||||
self._driver._do_umount = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
common._mount_gluster_vol = mock.Mock()
|
||||
common._umount_gluster_vol = mock.Mock()
|
||||
shutil.rmtree = mock.Mock()
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
|
||||
test_args = [
|
||||
|
@ -658,20 +566,20 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self.assertEqual(
|
||||
[mock.call(*test_args[0]), mock.call(*test_args[1])],
|
||||
gmgr1.gluster_call.call_args_list)
|
||||
self.assertTrue(self._driver._restart_gluster_vol.called)
|
||||
self.assertTrue(common._restart_gluster_vol.called)
|
||||
self.assertTrue(tempfile.mkdtemp.called)
|
||||
self.assertTrue(self._driver._do_mount.called)
|
||||
self.assertTrue(self._driver._do_umount.called)
|
||||
self.assertTrue(common._mount_gluster_vol.called)
|
||||
self.assertTrue(common._umount_gluster_vol.called)
|
||||
self.assertTrue(shutil.rmtree.called)
|
||||
|
||||
def test_wipe_gluster_vol_mount_fail(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
self._driver._do_mount = mock.Mock()
|
||||
self._driver._do_mount.side_effect = exception.GlusterfsException
|
||||
self._driver._do_umount = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
common._mount_gluster_vol = mock.Mock()
|
||||
common._mount_gluster_vol.side_effect = exception.GlusterfsException
|
||||
common._umount_gluster_vol = mock.Mock()
|
||||
shutil.rmtree = mock.Mock()
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
|
||||
test_args = [
|
||||
|
@ -683,20 +591,20 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self.assertEqual(
|
||||
[mock.call(*test_args[0]), mock.call(*test_args[1])],
|
||||
gmgr1.gluster_call.call_args_list)
|
||||
self.assertTrue(self._driver._restart_gluster_vol.called)
|
||||
self.assertTrue(common._restart_gluster_vol.called)
|
||||
self.assertTrue(tempfile.mkdtemp.called)
|
||||
self.assertTrue(self._driver._do_mount.called)
|
||||
self.assertFalse(self._driver._do_umount.called)
|
||||
self.assertTrue(common._mount_gluster_vol.called)
|
||||
self.assertFalse(common._umount_gluster_vol.called)
|
||||
self.assertTrue(shutil.rmtree.called)
|
||||
|
||||
def test_wipe_gluster_vol_umount_fail(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
self._driver._do_mount = mock.Mock()
|
||||
self._driver._do_umount = mock.Mock()
|
||||
self._driver._do_umount.side_effect = exception.GlusterfsException
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
common._mount_gluster_vol = mock.Mock()
|
||||
common._umount_gluster_vol = mock.Mock()
|
||||
common._umount_gluster_vol.side_effect = exception.GlusterfsException
|
||||
shutil.rmtree = mock.Mock()
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
|
||||
test_args = [
|
||||
|
@ -711,10 +619,10 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
[mock.call(*test_args[0]), mock.call(*test_args[1])],
|
||||
gmgr1.gluster_call.call_args_list)
|
||||
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
|
||||
self.assertTrue(self._driver._restart_gluster_vol.called)
|
||||
self.assertTrue(common._restart_gluster_vol.called)
|
||||
self.assertTrue(tempfile.mkdtemp.called)
|
||||
self.assertTrue(self._driver._do_mount.called)
|
||||
self.assertTrue(self._driver._do_umount.called)
|
||||
self.assertTrue(common._mount_gluster_vol.called)
|
||||
self.assertTrue(common._umount_gluster_vol.called)
|
||||
self.assertFalse(shutil.rmtree.called)
|
||||
|
||||
def test_create_share(self):
|
||||
|
@ -742,7 +650,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
def test_delete_share(self):
|
||||
self._driver._push_gluster_vol = mock.Mock()
|
||||
self._driver._wipe_gluster_vol = mock.Mock()
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
|
||||
self._driver.delete_share(self._context, self.share1)
|
||||
|
@ -765,7 +673,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._driver._wipe_gluster_vol.side_effect = (
|
||||
exception.GlusterfsException)
|
||||
self._driver._push_gluster_vol = mock.Mock()
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
|
||||
self.assertRaises(exception.GlusterfsException,
|
||||
|
@ -778,7 +686,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._driver.gluster_nosnap_vols_dict = {}
|
||||
self._driver.glusterfs_versions = {self.glusterfs_server1: ('3', '6')}
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
|
||||
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
|
||||
|
@ -800,7 +708,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._driver.gluster_nosnap_vols_dict = {}
|
||||
self._driver.glusterfs_versions = {self.glusterfs_server1: ('3', '6')}
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
|
||||
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
|
||||
|
@ -828,7 +736,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._driver.glusterfs_versions = {
|
||||
self.glusterfs_server1: ('3', vers_minor)}
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
|
||||
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
|
||||
|
@ -856,7 +764,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._driver.glusterfs_versions = {
|
||||
self.glusterfs_server1: ('3', vers_minor)}
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
|
||||
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
|
||||
|
@ -870,7 +778,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
snapshot)
|
||||
|
||||
def test_find_actual_backend_snapshot_name(self):
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.share1['export_location'], self._execute, None, None)
|
||||
self.mock_object(gmgr1, 'gluster_call',
|
||||
mock.Mock(return_value=('fake_snap_id_xyz', '')))
|
||||
|
@ -886,7 +794,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
|
||||
@ddt.data('this is too bad', 'fake_snap_id_xyx\nfake_snap_id_pqr')
|
||||
def test_find_actual_backend_snapshot_name_bad_snap_list(self, snaplist):
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.share1['export_location'], self._execute, None, None)
|
||||
self.mock_object(gmgr1, 'gluster_call',
|
||||
mock.Mock(return_value=(snaplist, '')))
|
||||
|
@ -915,7 +823,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
}
|
||||
volume = ''.join(['manila-', share['id']])
|
||||
new_export_location = ':/'.join([glusterfs_server, volume])
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
old_gmgr = gmgr(glusterfs_target, self._execute, None, None)
|
||||
new_gmgr = gmgr(new_export_location, self._execute, None, None)
|
||||
self._driver.gluster_used_vols_dict = {glusterfs_target: old_gmgr}
|
||||
|
@ -966,7 +874,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
}
|
||||
volume = ''.join(['manila-', share['id']])
|
||||
new_export_location = ':/'.join([glusterfs_server, volume])
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
old_gmgr = gmgr(glusterfs_target, self._execute, None, None)
|
||||
new_gmgr = gmgr(new_export_location, self._execute, None, None)
|
||||
self._driver.gluster_used_vols_dict = {glusterfs_target: old_gmgr}
|
||||
|
@ -1011,7 +919,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
}
|
||||
volume = ''.join(['manila-', share['id']])
|
||||
new_export_location = ':/'.join([glusterfs_server, volume])
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
old_gmgr = gmgr(glusterfs_target, self._execute, None, None)
|
||||
new_gmgr = gmgr(new_export_location, self._execute, None, None)
|
||||
self._driver.gluster_used_vols_dict = {glusterfs_target: old_gmgr}
|
||||
|
@ -1065,7 +973,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
}
|
||||
volume = ''.join(['manila-', share['id']])
|
||||
new_export_location = ':/'.join([glusterfs_server, volume])
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
old_gmgr = gmgr(glusterfs_target, self._execute, None, None)
|
||||
new_gmgr = gmgr(new_export_location, self._execute, None, None)
|
||||
self._driver.gluster_used_vols_dict = {glusterfs_target: old_gmgr}
|
||||
|
@ -1102,7 +1010,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
def test_delete_snapshot(self):
|
||||
self._driver.gluster_nosnap_vols_dict = {}
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.share1['export_location'], self._execute, None, None)
|
||||
|
||||
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
|
||||
|
@ -1128,7 +1036,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
def test_delete_snapshot_error(self, badxmloutput):
|
||||
self._driver.gluster_nosnap_vols_dict = {}
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.share1['export_location'], self._execute, None, None)
|
||||
|
||||
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
|
||||
|
@ -1152,9 +1060,9 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
assert_called_once_with(gmgr1, snapshot))
|
||||
|
||||
def test_allow_access(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self.mock_object(gmgr1, 'get_gluster_vol_option',
|
||||
mock.Mock(return_value='some.common.name'))
|
||||
|
@ -1166,12 +1074,12 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._driver.allow_access(self._context, self.share1, access)
|
||||
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
|
||||
gmgr1.gluster_call.assert_called_once_with(*test_args)
|
||||
self._driver._restart_gluster_vol.assert_called_once_with(gmgr1)
|
||||
common._restart_gluster_vol.assert_called_once_with(gmgr1)
|
||||
|
||||
def test_allow_access_with_share_having_access(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self.mock_object(
|
||||
gmgr1, 'get_gluster_vol_option',
|
||||
|
@ -1182,17 +1090,17 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._driver.allow_access(self._context, self.share1, access)
|
||||
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
|
||||
self.assertFalse(gmgr1.gluster_call.called)
|
||||
self.assertFalse(self._driver._restart_gluster_vol.called)
|
||||
self.assertFalse(common._restart_gluster_vol.called)
|
||||
|
||||
def test_allow_access_invalid_access_type(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
access = {'access_type': 'invalid', 'access_to': 'client.example.com'}
|
||||
expected_exec = []
|
||||
|
||||
self.assertRaises(exception.InvalidShareAccess,
|
||||
self._driver.allow_access,
|
||||
self._context, self.share1, access)
|
||||
self.assertFalse(self._driver._restart_gluster_vol.called)
|
||||
self.assertFalse(common._restart_gluster_vol.called)
|
||||
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
|
||||
|
||||
def test_allow_access_excp(self):
|
||||
|
@ -1204,9 +1112,9 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
if (args == test_args):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self.mock_object(gmgr1, 'get_gluster_vol_option',
|
||||
mock.Mock(return_value='some.common.name'))
|
||||
|
@ -1220,12 +1128,12 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._context, self.share1, access)
|
||||
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
|
||||
gmgr1.gluster_call.assert_called_once_with(*test_args)
|
||||
self.assertFalse(self._driver._restart_gluster_vol.called)
|
||||
self.assertFalse(common._restart_gluster_vol.called)
|
||||
|
||||
def test_deny_access(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self.mock_object(
|
||||
gmgr1, 'get_gluster_vol_option',
|
||||
|
@ -1238,12 +1146,12 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._driver.deny_access(self._context, self.share1, access)
|
||||
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
|
||||
gmgr1.gluster_call.assert_called_once_with(*test_args)
|
||||
self._driver._restart_gluster_vol.assert_called_once_with(gmgr1)
|
||||
common._restart_gluster_vol.assert_called_once_with(gmgr1)
|
||||
|
||||
def test_deny_access_with_share_having_no_access(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self.mock_object(gmgr1, 'get_gluster_vol_option',
|
||||
mock.Mock(return_value='some.common.name'))
|
||||
|
@ -1253,16 +1161,16 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._driver.deny_access(self._context, self.share1, access)
|
||||
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
|
||||
self.assertFalse(gmgr1.gluster_call.called)
|
||||
self.assertFalse(self._driver._restart_gluster_vol.called)
|
||||
self.assertFalse(common._restart_gluster_vol.called)
|
||||
|
||||
def test_deny_access_invalid_access_type(self):
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
access = {'access_type': 'invalid', 'access_to': 'NotApplicable'}
|
||||
|
||||
self.assertRaises(exception.InvalidShareAccess,
|
||||
self._driver.deny_access,
|
||||
self._context, self.share1, access)
|
||||
self.assertFalse(self._driver._restart_gluster_vol.called)
|
||||
self.assertFalse(common._restart_gluster_vol.called)
|
||||
|
||||
def test_deny_access_excp(self):
|
||||
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
|
||||
|
@ -1273,9 +1181,9 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
if (args == test_args):
|
||||
raise exception.ProcessExecutionError()
|
||||
|
||||
self._driver._restart_gluster_vol = mock.Mock()
|
||||
common._restart_gluster_vol = mock.Mock()
|
||||
|
||||
gmgr = glusterfs.GlusterManager
|
||||
gmgr = common.GlusterManager
|
||||
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
|
||||
self.mock_object(
|
||||
gmgr1, 'get_gluster_vol_option',
|
||||
|
@ -1290,7 +1198,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
|
|||
self._context, self.share1, access)
|
||||
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
|
||||
gmgr1.gluster_call.assert_called_once_with(*test_args)
|
||||
self.assertFalse(self._driver._restart_gluster_vol.called)
|
||||
self.assertFalse(common._restart_gluster_vol.called)
|
||||
|
||||
def test_get_share_stats_refresh_false(self):
|
||||
self._driver._stats = mock.Mock()
|
||||
|
|
Loading…
Reference in New Issue