diff --git a/contrib/ci/post_test_hook.sh b/contrib/ci/post_test_hook.sh index 3526c0e56c..484a6ab4f0 100755 --- a/contrib/ci/post_test_hook.sh +++ b/contrib/ci/post_test_hook.sh @@ -25,21 +25,6 @@ source $BASE/new/devstack/functions export TEMPEST_CONFIG=$BASE/new/tempest/etc/tempest.conf -# provide_user_rules - Sets up Samba for drivers which rely on LVM. -function provide_user_rules { - if ! grep $USERNAME_FOR_USER_RULES "/etc/passwd"; then - sudo useradd $USERNAME_FOR_USER_RULES - fi - (echo $PASSWORD_FOR_SAMBA_USER; echo $PASSWORD_FOR_SAMBA_USER) | sudo smbpasswd -s -a $USERNAME_FOR_USER_RULES - sudo smbpasswd -e $USERNAME_FOR_USER_RULES - samba_daemon_name=smbd - if is_fedora; then - samba_daemon_name=smb - fi - sudo service $samba_daemon_name restart -} - - # === Handle script arguments === # First argument is expected to contain value equal either to 'singlebackend' @@ -167,7 +152,16 @@ if [[ "$DRIVER" == "lvm" ]]; then iniset $TEMPEST_CONFIG share run_shrink_tests False iniset $TEMPEST_CONFIG share enable_ip_rules_for_protocols 'nfs' iniset $TEMPEST_CONFIG share enable_user_rules_for_protocols 'cifs' - provide_user_rules + if ! grep $USERNAME_FOR_USER_RULES "/etc/passwd"; then + sudo useradd $USERNAME_FOR_USER_RULES + fi + (echo $PASSWORD_FOR_SAMBA_USER; echo $PASSWORD_FOR_SAMBA_USER) | sudo smbpasswd -s -a $USERNAME_FOR_USER_RULES + sudo smbpasswd -e $USERNAME_FOR_USER_RULES + samba_daemon_name=smbd + if is_fedora; then + samba_daemon_name=smb + fi + sudo service $samba_daemon_name restart elif [[ "$DRIVER" == "zfsonlinux" ]]; then MANILA_TEMPEST_CONCURRENCY=8 RUN_MANILA_CG_TESTS=False @@ -188,17 +182,6 @@ elif [[ "$DRIVER" == "zfsonlinux" ]]; then iniset $TEMPEST_CONFIG share multitenancy_enabled False iniset $TEMPEST_CONFIG share multi_backend True iniset $TEMPEST_CONFIG share backend_replication_type 'readable' -elif [[ "$DRIVER" == "lxd" ]]; then - MANILA_TEMPEST_CONCURRENCY=1 - RUN_MANILA_CG_TESTS=False - RUN_MANILA_MANAGE_TESTS=False - iniset $TEMPEST_CONFIG share run_shrink_tests False - iniset $TEMPEST_CONFIG share run_consistency_group_tests False - iniset $TEMPEST_CONFIG share run_snapshot_tests False - iniset $TEMPEST_CONFIG share run_migration_tests False - iniset $TEMPEST_CONFIG share enable_ip_rules_for_protocols 'nfs' - iniset $TEMPEST_CONFIG share enable_user_rules_for_protocols 'cifs' - provide_user_rules fi # Enable consistency group tests diff --git a/contrib/ci/pre_test_hook.sh b/contrib/ci/pre_test_hook.sh index 77a2610cb9..58aa52b72b 100755 --- a/contrib/ci/pre_test_hook.sh +++ b/contrib/ci/pre_test_hook.sh @@ -75,9 +75,6 @@ elif [[ "$DRIVER" == "zfsonlinux" ]]; then echo "SHARE_DRIVER=manila.share.drivers.zfsonlinux.driver.ZFSonLinuxShareDriver" >> $localrc_path echo "RUN_MANILA_REPLICATION_TESTS=True" >> $localrc_path echo "MANILA_ZFSONLINUX_USE_SSH=True" >> $localrc_path -elif [[ "$DRIVER" == "lxd" ]]; then - echo "SHARE_DRIVER=manila.share.drivers.lxd.LXDDriver" >> $localrc_path - echo "SHARE_BACKING_FILE_SIZE=32000M" >> $localrc_path fi echo "MANILA_SERVICE_IMAGE_ENABLED=$MANILA_SERVICE_IMAGE_ENABLED" >> $localrc_path diff --git a/devstack/plugin.sh b/devstack/plugin.sh index eaa9b3dee8..5cfe41af4f 100755 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -57,12 +57,6 @@ function cleanup_manila { _clean_share_group $SHARE_GROUP $SHARE_NAME_PREFIX _clean_manila_lvm_backing_file $SHARE_GROUP _clean_zfsonlinux_data - - if is_driver_enabled $MANILA_LXD_DRIVER; then - # Remove all containers created by manila - lxc delete `lxc list | grep -E 'manila-.*' | awk '{print $2}'` - remove_lxd_service_image - fi } # configure_default_backends - configures default Manila backends with generic driver. @@ -265,18 +259,6 @@ function create_manila_service_keypair { nova keypair-add $MANILA_SERVICE_KEYPAIR_NAME --pub-key $MANILA_PATH_TO_PUBLIC_KEY } -function is_driver_enabled { - driver_name=$1 - - for BE in ${MANILA_ENABLED_BACKENDS//,/ }; do - share_driver=$(iniget $MANILA_CONF $BE share_driver) - - if [ "$share_driver" == "$driver_name" ]; then - return 0 - fi - done - return 1 -} # create_service_share_servers - creates service Nova VMs, one per generic # driver, and only if it is configured to mode without handling of share servers. @@ -352,11 +334,6 @@ function create_manila_service_image { if is_service_enabled g-reg; then upload_image $MANILA_SERVICE_IMAGE_URL $TOKEN fi - - # Download LXD image - if is_driver_enabled $MANILA_LXD_DRIVER; then - import_lxd_service_image - fi } # create_manila_service_secgroup - creates security group that is used by @@ -433,40 +410,13 @@ function create_default_share_type { enabled_backends=(${MANILA_ENABLED_BACKENDS//,/ }) driver_handles_share_servers=$(iniget $MANILA_CONF ${enabled_backends[0]} driver_handles_share_servers) - local command_args="$MANILA_DEFAULT_SHARE_TYPE $driver_handles_share_servers" - - if is_driver_enabled $MANILA_LXD_DRIVER; then - # TODO(u_glide): Remove this condition when LXD driver supports - # snapshots - command_args="$command_args --snapshot_support false" - fi - - manila type-create $command_args + manila type-create $MANILA_DEFAULT_SHARE_TYPE $driver_handles_share_servers if [[ $MANILA_DEFAULT_SHARE_TYPE_EXTRA_SPECS ]]; then manila type-key $MANILA_DEFAULT_SHARE_TYPE set $MANILA_DEFAULT_SHARE_TYPE_EXTRA_SPECS fi } -# configure_backing_file - Set up backing file for LVM -function configure_backing_file { - if ! sudo vgs $SHARE_GROUP; then - if [ "$CONFIGURE_BACKING_FILE" = "True" ]; then - SHARE_BACKING_FILE=${SHARE_BACKING_FILE:-$DATA_DIR/${SHARE_GROUP}-backing-file} - # Only create if the file doesn't already exists - [[ -f $SHARE_BACKING_FILE ]] || truncate -s $SHARE_BACKING_FILE_SIZE $SHARE_BACKING_FILE - DEV=`sudo losetup -f --show $SHARE_BACKING_FILE` - else - DEV=$SHARE_BACKING_FILE - fi - # Only create if the loopback device doesn't contain $SHARE_GROUP - if ! sudo vgs $SHARE_GROUP; then sudo vgcreate $SHARE_GROUP $DEV; fi - fi - - mkdir -p $MANILA_STATE_PATH/shares -} - - # init_manila - Initializes database and creates manila dir if absent function init_manila { @@ -496,14 +446,20 @@ function init_manila { # # By default, the backing file is 8G in size, and is stored in ``/opt/stack/data``. - configure_backing_file - fi - fi + if ! sudo vgs $SHARE_GROUP; then + if [ "$CONFIGURE_BACKING_FILE" = "True" ]; then + SHARE_BACKING_FILE=${SHARE_BACKING_FILE:-$DATA_DIR/${SHARE_GROUP}-backing-file} + # Only create if the file doesn't already exists + [[ -f $SHARE_BACKING_FILE ]] || truncate -s $SHARE_BACKING_FILE_SIZE $SHARE_BACKING_FILE + DEV=`sudo losetup -f --show $SHARE_BACKING_FILE` + else + DEV=$SHARE_BACKING_FILE + fi + # Only create if the loopback device doesn't contain $SHARE_GROUP + if ! sudo vgs $SHARE_GROUP; then sudo vgcreate $SHARE_GROUP $DEV; fi + fi - if [ "$SHARE_DRIVER" == "manila.share.drivers.lxd.LXDDriver" ]; then - if is_service_enabled m-shr; then - SHARE_GROUP="manila_lxd_volumes" - configure_backing_file + mkdir -p $MANILA_STATE_PATH/shares fi elif [ "$SHARE_DRIVER" == "manila.share.drivers.zfsonlinux.driver.ZFSonLinuxShareDriver" ]; then if is_service_enabled m-shr; then @@ -671,60 +627,6 @@ function update_tempest { fi } -function install_lxd { - sudo apt-get -y install software-properties-common - sudo apt-add-repository -y ppa:ubuntu-lxc/lxd-stable - sudo apt-get update - install_package lxd - install_package lxd-client - - # Wait for LXD service - sleep 15 - - sudo chmod a+rw /var/lib/lxd/unix.socket -} - -function download_image { - local image_url=$1 - - local image image_fname - - image_fname=`basename "$image_url"` - if [[ $image_url != file* ]]; then - # Downloads the image (uec ami+akistyle), then extracts it. - if [[ ! -f $FILES/$image_fname || "$(stat -c "%s" $FILES/$image_fname)" = "0" ]]; then - wget --progress=dot:giga -c $image_url -O $FILES/$image_fname - if [[ $? -ne 0 ]]; then - echo "Not found: $image_url" - return - fi - fi - image="$FILES/${image_fname}" - else - # File based URL (RFC 1738): ``file://host/path`` - # Remote files are not considered here. - # unix: ``file:///home/user/path/file`` - # windows: ``file:///C:/Documents%20and%20Settings/user/path/file`` - image=$(echo $image_url | sed "s/^file:\/\///g") - if [[ ! -f $image || "$(stat -c "%s" $image)" == "0" ]]; then - echo "Not found: $image_url" - return - fi - fi -} - -function import_lxd_service_image { - download_image $MANILA_LXD_META_URL - download_image $MANILA_LXD_ROOTFS_URL - - # Import image in LXD - lxc image import $FILES/`basename "$MANILA_LXD_META_URL"` $FILES/`basename "$MANILA_LXD_ROOTFS_URL"` --alias manila-lxd-image -} - -function remove_lxd_service_image { - lxc image delete $MANILA_LXD_IMAGE_ALIAS || echo "LXD image $MANILA_LXD_IMAGE_ALIAS not found" -} - function install_libraries { if [ $(trueorfalse False MANILA_MULTI_BACKEND) == True ]; then if [ $(trueorfalse True RUN_MANILA_MIGRATION_TESTS) == True ]; then @@ -735,10 +637,6 @@ function install_libraries { fi fi fi - - if is_driver_enabled $MANILA_LXD_DRIVER; then - install_lxd - fi } # Main dispatcher diff --git a/devstack/settings b/devstack/settings index 04e7074cd6..0e4ea5bf4d 100644 --- a/devstack/settings +++ b/devstack/settings @@ -155,16 +155,6 @@ MANILA_ZFSONLINUX_SSH_USERNAME=${MANILA_ZFSONLINUX_SSH_USERNAME:-$STACK_USER} # Manila will consider replication feature as disabled for ZFSonLinux share driver. MANILA_ZFSONLINUX_REPLICATION_DOMAIN=${MANILA_ZFSONLINUX_REPLICATION_DOMAIN:-"ZFSonLinux"} -# LXD Driver -MANILA_LXD_DRIVER=${MANILA_LXD_DRIVER:-"manila.share.drivers.lxd.LXDDriver"} -MANILA_LXD_IMAGE_ALIAS=${MANILA_LXD_IMAGE_ALIAS:-"manila-lxd-image"} -# (aovchinnikov): This location is temporary and will be changed to a -# permanent one as soon as possible. -MANILA_LXD_META_URL=${MANILA_LXD_META_URL:-"https://github.com/a-ovchinnikov/manila-image-elements-lxd-images/releases/download/0.1.0/manila-lxd-meta.tar"} -# (aovchinnikov): This location is temporary and will be changed to a -# permanent one as soon as possible. -MANILA_LXD_ROOTFS_URL=${MANILA_LXD_ROOTFS_URL:-"https://github.com/a-ovchinnikov/manila-image-elements-lxd-images/releases/download/0.1.0/manila-service-image.tar.xz"} - # Enable manila services # ---------------------- # We have to add Manila to enabled services for screen_it to work diff --git a/doc/source/devref/share_back_ends_feature_support_mapping.rst b/doc/source/devref/share_back_ends_feature_support_mapping.rst index ed7ef62496..ca73a6db09 100644 --- a/doc/source/devref/share_back_ends_feature_support_mapping.rst +++ b/doc/source/devref/share_back_ends_feature_support_mapping.rst @@ -59,8 +59,6 @@ Mapping of share drivers and share features support +----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+--------------------------+ | LVM | DHSS = False (M) | \- | M | \- | M | M | \- | +----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+--------------------------+ -| LXD | DHSS = True (M) | \- | M | \- | \- | \- | \- | -+----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+--------------------------+ | Quobyte | DHSS = False (K) | \- | M | M | \- | \- | \- | +----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+--------------------------+ | Windows SMB | DHSS = True (L) & False (L) | L | L | L | L | L | \- | @@ -108,8 +106,6 @@ Mapping of share drivers and share access rules support +----------------------------------------+--------------+----------------+------------+--------------+--------------+----------------+------------+------------+ | LVM | NFS (M) | CIFS (M) | \- | \- | NFS (M) | CIFS (M) | \- | \- | +----------------------------------------+--------------+----------------+------------+--------------+--------------+----------------+------------+------------+ -| LXD | NFS,CIFS (M) | CIFS (M) | \- | \- | NFS (M) | CIFS (M) | \- | \- | -+----------------------------------------+--------------+----------------+------------+--------------+--------------+----------------+------------+------------+ | Quobyte | NFS (K) | \- | \- | \- | NFS (K) | \- | \- | \- | +----------------------------------------+--------------+----------------+------------+--------------+--------------+----------------+------------+------------+ | Windows SMB | \- | CIFS (L) | \- | \- | \- | CIFS (L) | \- | \- | @@ -153,8 +149,6 @@ Mapping of share drivers and security services support +----------------------------------------+------------------+-----------------+------------------+ | LVM | \- | \- | \- | +----------------------------------------+------------------+-----------------+------------------+ -| LXD | \- | \- | \- | -+----------------------------------------+------------------+-----------------+------------------+ | Quobyte | \- | \- | \- | +----------------------------------------+------------------+-----------------+------------------+ | Windows SMB | L | \- | \- | diff --git a/etc/manila/rootwrap.d/share.filters b/etc/manila/rootwrap.d/share.filters index 7dd79e6e51..87e213b953 100644 --- a/etc/manila/rootwrap.d/share.filters +++ b/etc/manila/rootwrap.d/share.filters @@ -146,12 +146,6 @@ zpool: CommandFilter, zpool, root # manila/share/drivers/zfsonlinux/utils.py zfs: CommandFilter, zfs, root -# LXD driver commands -# manila/share/drivers/lxd.py -lxc: CommandFilter, lxc, root -# manila/share/drivers/lxd.py -brctl: CommandFilter, brctl, root - # manila/data/utils.py: 'ls', '-pA1', '--group-directories-first', '%s' ls: CommandFilter, ls, root diff --git a/manila/network/neutron/neutron_network_plugin.py b/manila/network/neutron/neutron_network_plugin.py index 0439bc99a8..e7bc011160 100644 --- a/manila/network/neutron/neutron_network_plugin.py +++ b/manila/network/neutron/neutron_network_plugin.py @@ -39,14 +39,6 @@ neutron_single_network_plugin_opts = [ deprecated_group='DEFAULT'), ] -neutron_network_plugin_opts = [ - cfg.StrOpt( - "neutron_host_id", - help="Host id to be used when creating neutron port. Hostname of " - "a controller running Neutron should be used in a general case.", - deprecated_group='DEFAULT'), -] - CONF = cfg.CONF @@ -59,9 +51,6 @@ class NeutronNetworkPlugin(network.NetworkBaseAPI): self._neutron_api_args = args self._neutron_api_kwargs = kwargs self._label = kwargs.pop('label', 'user') - CONF.register_opts( - neutron_network_plugin_opts, - group=self.neutron_api.config_group_name) @property def label(self): @@ -125,12 +114,11 @@ class NeutronNetworkPlugin(network.NetworkBaseAPI): self._delete_port(context, port) def _create_port(self, context, share_server, share_network, device_owner): - host_id = self.neutron_api.configuration.neutron_host_id port = self.neutron_api.create_port( share_network['project_id'], network_id=share_network['neutron_net_id'], subnet_id=share_network['neutron_subnet_id'], - device_owner='manila:' + device_owner, host_id=host_id) + device_owner='manila:' + device_owner) port_dict = { 'id': port['id'], 'share_server_id': share_server['id'], diff --git a/manila/opts.py b/manila/opts.py index 5b76019ade..5d63c53eb9 100644 --- a/manila/opts.py +++ b/manila/opts.py @@ -64,7 +64,6 @@ import manila.share.drivers.hitachi.hds_hnas import manila.share.drivers.hpe.hpe_3par_driver import manila.share.drivers.huawei.huawei_nas import manila.share.drivers.ibm.gpfs -import manila.share.drivers.lxd import manila.share.drivers.netapp.options import manila.share.drivers.quobyte.quobyte import manila.share.drivers.service_instance @@ -130,8 +129,6 @@ _global_opt_lists = [ manila.share.drivers.hpe.hpe_3par_driver.HPE3PAR_OPTS, manila.share.drivers.huawei.huawei_nas.huawei_opts, manila.share.drivers.ibm.gpfs.gpfs_share_opts, - manila.share.drivers.lxd.lxd_opts, - manila.share.drivers.lxd.lv_opts, manila.share.drivers.netapp.options.netapp_proxy_opts, manila.share.drivers.netapp.options.netapp_connection_opts, manila.share.drivers.netapp.options.netapp_transport_opts, diff --git a/manila/share/drivers/lxd.py b/manila/share/drivers/lxd.py deleted file mode 100644 index fc784fa3ac..0000000000 --- a/manila/share/drivers/lxd.py +++ /dev/null @@ -1,774 +0,0 @@ -# Copyright (c) 2015 Mirantis, 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. - -"""LXC/LXD Driver for shares. - -This driver allows to use a LXD container as a share server. -Current implementation suggests that a container when started by LXD will be -plugged into a Linux bridge. Also it is suggested that all interfaces willing -to talk to each other reside in an OVS bridge.""" - -import os -import re - -from oslo_config import cfg -from oslo_log import log -# NOTE(tbarron): pylxd module is unavailable in some distribtutions so -# handle this circumstance gracefully. Also handle failure to import -# pylxd_exc directly in versions >= pylxd 2. -try: - from pylxd import api as lxd_api - try: - from pylxd import exceptions as pylxd_exc - NO_LXD = False - except ImportError: - try: - # pylint: disable=E0611 - from pylxd.deprecated import exceptions as pylxd_exc - NO_LXD = False - except ImportError: - NO_LXD = True -except ImportError: - NO_LXD = True -import six - -from manila.common import constants as const -from manila import context -from manila import exception -from manila.i18n import _ -from manila.i18n import _LI -from manila.i18n import _LW -from manila.share import driver -from manila import utils - -CONF = cfg.CONF -LOG = log.getLogger(__name__) - -lxd_opts = [ - # (aovchinnikov): this has to stay till we can produce images which - # can set up OVS correctly. - cfg.StrOpt("lxd_linux_bridge_name", - default="lxcbr0", - required=True, - help="Linux bridge used by LXD to plug host-side veth to. " - "It will be unplugged from here by the driver."), - cfg.StrOpt("lxd_ovs_bridge_name", - default="br-int", - required=True, - help="OVS bridge to use to plug a container to."), - cfg.StrOpt("lxd_nfs_server", - default="unfs3", - help="User space NFS server to be used. Currently the only " - "implementation supported is unfs3. In future ganesha " - "is planned to be supported as well. Please note, that " - "unfs3 is mostly an experimental driver which should " - "be used in production with care and at the user's own " - "risk."), - cfg.IntOpt("lxd_build_timeout", - default=120, - help="Time to wait till container is considered being unable " - "to start."), - cfg.IntOpt("lxd_check_timeout", - default=1, - help="Inter-check delay for container operations."), - cfg.StrOpt("lxd_cifs_guest_ok", - default="yes", - help="Determines whether to allow guest access to CIFS share " - "or not."), - cfg.StrOpt("lxd_image_name", - default="manila-lxd-image", - help="LXD image to be used for a server."), -] - -lv_opts = [ - cfg.StrOpt("lxd_volume_group", - default="manila_lxd_volumes", - help="LVM volume group to use for volumes."), - cfg.StrOpt("lxd_lv_size", - default="10M", - help="Logical volume size."), -] - -CONF.register_opts(lxd_opts) -CONF.register_opts(lv_opts) - - -class LXDHelper(object): - - def __init__(self, lxd_api, config): - if NO_LXD: - LOG.info(_LI('pylxd modules are not present on this system: LXD ' - 'driver will not function.')) - return - super(LXDHelper, self).__init__() - self.api = lxd_api - self.conf = config - - def create_container(self, name): - container_config = { - "name": name, - "source": { - "type": "image", - "alias": self.conf.lxd_image_name - } - } - - state, data = self.api.container_init(container_config) - - LOG.debug("Container init result: %s, %s.", state, data) - LOG.debug("Containers list %s.", self.api.container_list()) - - def container_initialized(): - try: - LOG.debug("Operation 'initialize': %s.", data["operation"]) - state, info = self.api.operation_info(data["operation"]) - - LOG.debug("Operation 'initialize' info: %s, %s.", state, info) - - return info["status"].lower() == "success" - - except Exception as e: - LOG.debug("Check error '%s'.", e) - return False - - self._wait( - container_initialized, - exception.ManilaException(_("Container creation error.")) - ) - - @utils.retry(exception.ManilaException, retries=5) - def start_container(self, name): - LOG.debug("Starting container %s.", name) - - throwaway, data = self.api.container_start(name, -1) - - def container_running(): - LOG.debug("Operation 'start': %s.", data["operation"]) - - try: - state, info = self.api.operation_info(data["operation"]) - except Exception as e: - raise exception.ManilaException( - _("Cannot get operation info: %s.") % e - ) - - LOG.debug("Operation 'start' info: %s, %s.", state, info) - - if "status" in info["metadata"]: - meta = info["metadata"] - operation_failed = ( - six.text_type(meta["status"]).lower() == "failure" and - six.text_type(meta["err"]).lower() != - "the container is already running" - ) - else: - operation_failed = False - - if operation_failed: - err_info = info["metadata"]["metadata"] - - raise exception.ManilaException( - _("Cannot start container: %s.") % err_info - ) - - result = self.api.container_running(name) - LOG.debug("Check is container running: %s.", result) - return result - - self._wait( - container_running, - exception.ManilaException("Container startup error.") - ) - - def stop_container(self, name): - LOG.debug("Stopping container %s.", name) - state, data = self.api.container_stop(name, 60) - - def container_stopped(): - return not self.api.container_running(name) - - self._wait( - container_stopped, - exception.ManilaException(_("Container stopping error.")) - ) - self.api.container_destroy(name) - - def _wait(self, predicate, timeout_exception): - utils.wait_until_true( - predicate, - timeout=self.conf.lxd_build_timeout, - sleep=self.conf.lxd_check_timeout, - exception=timeout_exception - ) - - def _wait_operation(self, operation): - def wait(): - LOG.debug("Wait operation %s...", operation) - try: - state, info = self.api.operation_info(operation) - LOG.debug("Operation details: %s.", info) - except pylxd_exc.APIError as e: - LOG.exception(e) - return True - except Exception as e: - LOG.exception(e) - raise exception.ManilaException( - _("Cannot get operation info: %s.") % e - ) - - return ( - six.text_type(info["metadata"]["status"]).lower() != "running" - ) - self._wait( - wait, - exception.ManilaException(_("Operation %s still running.") % - operation) - ) - - def execute_sync(self, container_name, args): - status, result = self.api.container_run_command( - container_name, args, interactive=True, web_sockets=True) - - LOG.debug("CMD: %s", args) - LOG.debug("Execution result: %s", result) - - try: - socket_pass = result["metadata"]["metadata"]["fds"]["0"] - except KeyError: - raise exception.ManilaException( - _("Socket secret not found in operation details.") - ) - - stream = self.api.operation_stream(result["operation"], socket_pass) - cmd_result = "" - - while True: - message = stream.receive() - - if not message: - break - cmd_result += message.data.decode("utf-8") - - LOG.debug("CMD output: %s", cmd_result) - - # NOTE(u_glide): Since LXD >= 0.24 socket should be closed by client - # Fix in PyLXD: https://github.com/lxc/pylxd/pull/51 - stream.close() - - status, info = self.api.operation_info(result["operation"]) - - LOG.debug("Operation details: %(info)s, %(status)s.", - {"info": info, "status": status}) - return cmd_result - - -class LXDUnfs3Helper(object): - # NOTE(aovchinnikov): This is a temporary replacement for nfs-ganesha - # designed for testing purposes. It is not intended to be used in - # production. - def __init__(self, lxd_helper, *args, **kwargs): - super(LXDUnfs3Helper, self).__init__() - self.share = None or kwargs.get("share") - self.lxd = lxd_helper - self.access_rules_ro = "(ro,no_root_squash,async,no_subtree_check)" - self.access_rules_rw = "(rw,no_root_squash,async,no_subtree_check)" - - def _restart_unfsd(self, server_id): - LOG.debug("Restarting unfsd....") - self.lxd.execute_sync( - server_id, - ["pkill", "unfsd"] - ) - self.lxd.execute_sync( - server_id, - ["service", "unfs3", "start"] - ) - LOG.debug("Restarting unfsd - done!") - - def create_share(self, server_id): - # (aovchinnikov): the moment a folder appears in /etc/exports it could - # have accessed with ro from anywhere. Thus create_share does - # essentially nothing. - self.lxd.execute_sync( - server_id, - ["touch", "/etc/exports"] - ) - result = self.lxd.execute_sync( - server_id, - ["ip", "addr", "show", "eth0"] - ).split()[18].split('/')[0] - location = result + ':' + "/shares/%s" % self.share.share_id - return location - - def delete_share(self, server_id): - share_name = self.share.share_id - share_folder = "/shares/%s" % share_name - delete_pattern = "\$" + share_folder + ".*$d" - self.lxd.execute_sync( - server_id, - ["sed", "-i", delete_pattern, "/etc/exports"] - ) - self._restart_unfsd(server_id) - - def _deny_access(self, server_id, host_to_deny): - share_name = self.share.share_id - share_folder = "/shares/%s" % share_name - deny_pattern = ("\$" + share_folder + '.*' + - host_to_deny.replace('.', '\.') + '.*$d') - self.lxd.execute_sync( - server_id, - ["sed", "-i", deny_pattern, "/etc/exports"] - ) - self._restart_unfsd(server_id) - - def _allow_access(self, share_name, server_id, host_to_allow, - access_level): - if access_level == const.ACCESS_LEVEL_RO: - access_rules = self.access_rules_ro - elif access_level == const.ACCESS_LEVEL_RW: - access_rules = self.access_rules_rw - else: - raise exception.InvalidShareAccessLevel(level=access_level) - share_name = self.share.share_id - share_folder = "/shares/%s" % share_name - search_pattern = (share_folder + '.*' + - host_to_allow.replace('.', '\.') + '.*') - result = self.lxd.execute_sync( - server_id, - ["grep", search_pattern, "/etc/exports"] - ) - - if result == '': - new_share = share_folder + ' ' + host_to_allow + access_rules - result = self.lxd.execute_sync( - server_id, - ["sed", "-i", "$ a\\" + new_share, "/etc/exports"] - ) - - self._restart_unfsd(server_id) - - def update_access(self, share_name, server_id, access_rules, add_rules, - delete_rules): - if not (add_rules or delete_rules): - share_folder = "/shares/%s" % share_name - delete_pattern = "\$" + share_folder + ".*$d" - self.lxd.execute_sync( - server_id, - ["sed", "-i", delete_pattern, "/etc/exports"] - ) - for rule in (access_rules or []): - host_to_allow = rule['access_to'] - access_level = rule['access_level'] - access_type = rule['access_type'] - if access_type == 'ip': - self._allow_access(share_name, server_id, host_to_allow, - access_level) - else: - msg = _("Access type '%s' is not supported by the " - "driver.") % access_type - raise exception.InvalidShareAccess(reason=msg) - return - for rule in add_rules: - host_to_allow = rule['access_to'] - access_level = rule['access_level'] - access_type = rule['access_type'] - if access_type == 'ip': - self._allow_access(share_name, server_id, host_to_allow, - access_level) - else: - msg = _("Access type '%s' is not supported by the " - "driver.") % access_type - raise exception.InvalidShareAccess(reason=msg) - for rule in delete_rules: - host_to_deny = rule['access_to'] - access_type = rule['access_type'] - if access_type == 'ip': - self._deny_access(server_id, host_to_deny) - else: - LOG.warning(_LW("Attempt to use access type %s has been " - "blocked.") % access_type) - - -class LXDCIFSHelper(object): - def __init__(self, lxd_helper, *args, **kwargs): - super(LXDCIFSHelper, self).__init__() - self.share = None or kwargs.get("share") - self.conf = kwargs.get("config") - self.lxd = lxd_helper - - def create_share(self, server_id): - share_name = self.share.share_id - cmd = ["net", "conf", "addshare", share_name, - "/shares/%s" % share_name, "writeable=y"] - if self.conf.lxd_cifs_guest_ok == "yes": - cmd.append("guest_ok=y") - else: - cmd.append("guest_ok=n") - self.lxd.execute_sync(server_id, cmd) - parameters = { - "browseable": "yes", - "create mask": "0755", - "hosts deny": "0.0.0.0/0", - "hosts allow": "127.0.0.1", - "read only": "no", - } - for param, value in parameters.items(): - self.lxd.execute_sync( - server_id, - ["net", "conf", "setparm", share_name, param, value] - ) - result = self.lxd.execute_sync( - server_id, - ["ip", "addr", "show", "eth0"] - ).split()[18].split('/')[0] - location = '\\\\' + result + '\\' + "/shares/%s" % share_name - return location - - def delete_share(self, server_id): - self.lxd.execute_sync( - server_id, - ["net", "conf", "delshare", self.share.share_id] - ) - - def _deny_access(self, server_id, host_to_deny): - share_name = self.share.share_id - allowed_hosts = self.lxd.execute_sync( - server_id, - ["net", "conf", "getparm", share_name, "hosts allow"] - ) - if allowed_hosts.count(host_to_deny) == 0: - LOG.debug("Access for host %s is already denied.", host_to_deny) - return - pruned_hosts = filter(lambda x: not x.startswith(host_to_deny), - allowed_hosts.split()) - allowed_hosts = " ".join(pruned_hosts) - self.lxd.execute_sync( - server_id, - ["net", "conf", "setparm", share_name, "hosts allow", - allowed_hosts] - ) - - def _allow_access(self, share_name, server_id, host_to_allow, - access_level): - if access_level == const.ACCESS_LEVEL_RO: - if self.conf.lxd_cifs_guest_ok != "yes": - raise exception.ManilaException(_("Can't provide 'ro' access" - "for guest.")) - LOG.debug("Host is accessible for reading data.") - return - elif access_level == const.ACCESS_LEVEL_RW: - allowed_hosts = self.lxd.execute_sync( - server_id, - ["net", "conf", "getparm", share_name, "hosts allow"] - ) - if allowed_hosts.count(host_to_allow) != 0: - LOG.debug("Access for host %s is already allowed.", - host_to_allow) - return - - allowed_hosts = ", ".join([host_to_allow, allowed_hosts]) - self.lxd.execute_sync( - server_id, - ["net", "conf", "setparm", share_name, "hosts allow", - allowed_hosts] - ) - else: - raise exception.InvalidShareAccessLevel(level=access_level) - - def _allow_user_access(self, share_name, server_id, user_to_allow, - access_level): - if access_level == const.ACCESS_LEVEL_RO: - access = 'read list' - elif access_level == const.ACCESS_LEVEL_RW: - access = 'valid users' - else: - raise exception.InvalidShareAccessLevel(level=access_level) - self.lxd.execute_sync( - server_id, - ["net", "conf", "setparm", share_name, access, - user_to_allow] - ) - - def update_access(self, share_name, server_id, access_rules, - add_rules, delete_rules): - if not (add_rules or delete_rules): - # clean all hosts from allowed hosts list first. - self.lxd.execute_sync( - server_id, - ["net", "conf", "setparm", share_name, "hosts allow", ""] - ) - for rule in access_rules: - host_to_allow = rule['access_to'] - access_level = rule['access_level'] - access_type = rule['access_type'] - if access_type == 'ip': - self._allow_access(share_name, server_id, host_to_allow, - access_level) - elif access_type == 'user': - self._allow_user_access(share_name, server_id, - rule['access_to'], access_level) - else: - msg = _("Access type '%s' is not supported by the " - "driver.") % access_type - raise exception.InvalidShareAccess(reason=msg) - return - for rule in add_rules: - host_to_allow = rule['access_to'] - access_level = rule['access_level'] - access_type = rule['access_type'] - if access_type == 'ip': - self._allow_access(share_name, server_id, host_to_allow, - access_level) - elif access_type == 'user': - self._allow_user_access(share_name, server_id, - rule['access_to'], access_level) - else: - msg = _("Access type '%s' is not supported by the " - "driver.") % access_type - raise exception.InvalidShareAccess(reason=msg) - for rule in delete_rules: - host_to_deny = rule['access_to'] - access_type = rule['access_type'] - if access_type == 'ip': - self._deny_access(server_id, host_to_deny) - else: - LOG.warning(_LW("Attempt to use access type %s has been " - "blocked.") % access_type) - - -class LXDDriver(driver.GaneshaMixin, driver.ShareDriver, driver.ExecuteMixin): - """Executes commands relating to Shares.""" - - def __init__(self, *args, **kwargs): - """Do initialization.""" - super(LXDDriver, self).__init__([True], *args, **kwargs) - - self.admin_context = context.get_admin_context() - self.configuration.append_config_values(lxd_opts) - self.configuration.append_config_values(lv_opts) - self._helpers = {} - self.backend_name = self.configuration.safe_get( - "share_backend_name") or "LXD" - self.private_storage = kwargs.get("private_storage") - # TODO(uglide): add config options for LXD host and port - # TODO(uglide): raise specific exception on timeout - self.lxd = LXDHelper(lxd_api.API(), self.configuration) - self.ssh_connections = {} - self.nfshelper = self._get_nfs_helper() - - def _update_share_stats(self): - """Retrieve stats info from share volume group.""" - data = { - 'share_backend_name': self.backend_name, - 'storage_protocol': 'NFS_CIFS', - 'reserved_percentage': - self.configuration.reserved_share_percentage, - 'consistency_group_support': None, - 'snapshot_support': False, - 'driver_name': 'LXDDriver', - 'pools': self.get_share_server_pools() - } - super(LXDDriver, self)._update_share_stats(data) - - def get_share_server_pools(self, share_server=None): - out, err = self._execute('vgs', - self.configuration.lxd_volume_group, - '--rows', run_as_root=True) - total_size = re.findall("VSize\s[0-9.]+g", out)[0][6:-1] - free_size = re.findall("VFree\s[0-9.]+g", out)[0][6:-1] - return [{ - 'pool_name': self.configuration.lxd_volume_group, - 'total_capacity_gb': float(total_size), - 'free_capacity_gb': float(free_size), - 'reserved_percentage': 0, - }, ] - - def _get_nfs_helper(self): - if self.configuration.lxd_nfs_server == 'ganesha': - raise exception.ManilaException(_("NFSGanesha is currently not " - "supported by this driver.")) - elif self.configuration.lxd_nfs_server == 'unfs3': - return LXDUnfs3Helper - else: - raise exception.ManilaException(_("Unsupported NFS userspace " - "server: %s.") % - self.configuration.lxd_nfs_server) - - def _get_helper(self, share): - if share["share_proto"].upper() == "NFS": - helper = self._helpers.get("NFS") - if helper is not None: - helper.share = share - return helper - self._helpers["NFS"] = self.nfshelper(self.lxd, share=share) - return self._helpers["NFS"] - elif share["share_proto"].upper() == "CIFS": - helper = self._helpers.get("CIFS") - if helper is not None: - helper.share = share - return helper - self._helpers["CIFS"] = LXDCIFSHelper(self.lxd, share=share, - config=self.configuration) - return self._helpers["CIFS"] - else: - raise exception.InvalidShare( - reason=_("Wrong, unsupported or disabled protocol.")) - - def _get_lv_device(self, share): - return os.path.join("/dev", self.configuration.lxd_volume_group, - share.share_id) - - def _get_lv_folder(self, share): - # Provides folder name in hosts /tmp to which logical volume is - # mounted prior to providing access to it from a container. - return os.path.join("/tmp", share.share_id) - - def create_share(self, context, share, share_server=None): - LOG.debug("Create share on server '%s'." % share_server["id"]) - server_id = self._get_container_name(share_server["id"]) - share_name = share.share_id - self.lxd.execute_sync( - server_id, - ["mkdir", "-m", "777", "/shares/%s" % share_name] - ) - self._execute("lvcreate", "-p", "rw", "-L", - self.configuration.lxd_lv_size, "-n", share_name, - self.configuration.lxd_volume_group, run_as_root=True) - self._execute("mkfs.ext4", self._get_lv_device(share), - run_as_root=True) - self._execute("mkdir", "-m", "777", self._get_lv_folder(share)) - self._execute("mount", self._get_lv_device(share), - self._get_lv_folder(share), run_as_root=True) - self._execute("chmod", "-R", "777", self._get_lv_folder(share), - run_as_root=True) - self._execute("lxc", "config", "device", "add", - server_id, share_name, "disk", - "source=" + self._get_lv_folder(share), - "path=/shares/" + share_name, run_as_root=True) - - location = self._get_helper(share).create_share(server_id) - return location - - def extend_share(self, share, new_size, share_server=None): - lv_device = self._get_lv_device(share) - cmd = ('lvextend', '-L', '%sG' % new_size, '-n', lv_device) - self._execute(*cmd, run_as_root=True) - self._execute('resize2fs', lv_device, run_as_root=True) - - def _connect_to_network(self, server_id, network_info): - LOG.debug("Attempting to connect container to neutron network.") - network_allocation = network_info['network_allocations'][0] - port_address = network_allocation.ip_address - port_mac = network_allocation.mac_address - port_id = network_allocation.id - self.lxd.execute_sync( - server_id, - ["ifconfig", "eth0", port_address, "up"] - ) - host_veth = self._get_host_veth(server_id) - msg_helper = { - 'id': server_id, 'veth': host_veth, - 'lb': self.configuration.lxd_linux_bridge_name, - 'ovsb': self.configuration.lxd_ovs_bridge_name, - 'ip': port_address, - 'subnet': network_info['neutron_subnet_id'] - } - LOG.debug("Container %(id)s veth is %(veth)s.", msg_helper) - LOG.debug("Removing %(veth)s from %(lb)s.", msg_helper) - self._execute("brctl", "delif", - self.configuration.lxd_linux_bridge_name, host_veth, - run_as_root=True) - - LOG.debug("Plugging %(veth)s into %(ovsb)s.", msg_helper) - set_if = ['--', 'set', 'interface', host_veth] - e_mac = set_if + ['external-ids:attached-mac="%s"' % port_mac] - e_id = set_if + ['external-ids:iface-id="%s"' % port_id] - e_status = set_if + ['external-ids:iface-status=active'] - self._execute("ovs-vsctl", "--", "add-port", - self.configuration.lxd_ovs_bridge_name, host_veth, - *(e_mac + e_id + e_status), run_as_root=True) - LOG.debug("Now container %(id)s should be accessible from network " - "%(subnet)s by address %(ip)s." % msg_helper) - - def delete_share(self, context, share, share_server=None): - LOG.debug("Deleting share %(share)s on server '%(server)s'." % - {"server": share_server["id"], - "share": share.share_id}) - server_id = self._get_container_name(share_server["id"]) - self._get_helper(share).delete_share(server_id) - - self._execute("umount", self._get_lv_device(share), run_as_root=True) - self._execute("lxc", "config", "device", "remove", - server_id, share.share_id, run_as_root=True) - self._execute("lvremove", "-f", "--autobackup", "n", - self._get_lv_device(share), run_as_root=True) - self.lxd.execute_sync( - server_id, - ["rm", "-fR", "/shares/%s" % share.share_id] - ) - LOG.debug("Deletion of share %s is complete!", share.share_id) - - def _get_host_veth(self, server_id): - data = self.lxd.api.container_info(server_id) - host_veth = data['network']['eth0']['host_name'] - return host_veth - - def _teardown_server(self, *args, **kwargs): - server_id = self._get_container_name(kwargs["server_details"]["id"]) - host_veth = self._get_host_veth(server_id) - self.lxd.stop_container(server_id) - self._execute("ovs-vsctl", "--", "del-port", - self.configuration.lxd_ovs_bridge_name, host_veth, - run_as_root=True) - - def ensure_share(self, context, share, share_server=None): - pass - - def update_access(self, context, share, access_rules, add_rules, - delete_rules, share_server=None): - server_id = self._get_container_name(share_server["id"]) - share_name = share.share_id - LOG.debug("Updating access to share %(share)s at " - "share server %(share_server)s.", - {"share_server": share_server["id"], - "share": share.share_id}) - self._get_helper(share).update_access(share_name, server_id, - access_rules, add_rules, - delete_rules) - - def get_network_allocations_number(self): - return 1 - - def _get_container_name(self, server_id): - return "manila-%s" % server_id - - def _setup_server(self, network_info, metadata=None): - msg = "Creating share server '%s'." - server_id = self._get_container_name(network_info["server_id"]) - LOG.debug(msg % server_id) - - try: - self.lxd.create_container(server_id) - except Exception as e: - raise exception.ManilaException(_("Cannot create container: %s") % - e) - - self.lxd.start_container(server_id) - self.lxd.api.container_run_command(server_id, - ["mkdir", "-m", "777", "/shares"]) - self._connect_to_network(server_id, network_info) - # TODO(aovchinnikov): expand metadata above the bare minimum - LOG.debug("Container %s was created!", server_id) - return {"id": network_info["server_id"]} diff --git a/manila/tests/network/neutron/test_neutron_plugin.py b/manila/tests/network/neutron/test_neutron_plugin.py index f94fc4aa21..55b38d31e2 100644 --- a/manila/tests/network/neutron/test_neutron_plugin.py +++ b/manila/tests/network/neutron/test_neutron_plugin.py @@ -128,7 +128,7 @@ class NeutronNetworkPluginTest(test.TestCase): fake_share_network['project_id'], network_id=fake_share_network['neutron_net_id'], subnet_id=fake_share_network['neutron_subnet_id'], - device_owner='manila:share', host_id=None) + device_owner='manila:share') db_api.network_allocation_create.assert_called_once_with( self.fake_context, fake_network_allocation) @@ -137,54 +137,6 @@ class NeutronNetworkPluginTest(test.TestCase): save_nw_data.stop() save_subnet_data.stop() - @mock.patch.object(db_api, 'network_allocation_create', - mock.Mock(return_values=fake_network_allocation)) - @mock.patch.object(db_api, 'share_network_get', - mock.Mock(return_value=fake_share_network)) - @mock.patch.object(db_api, 'share_server_get', - mock.Mock(return_value=fake_share_server)) - def test_allocate_network_one_allocation_host_id(self): - has_provider_nw_ext = mock.patch.object( - self.plugin, '_has_provider_network_extension').start() - has_provider_nw_ext.return_value = True - save_nw_data = mock.patch.object(self.plugin, - '_save_neutron_network_data').start() - save_subnet_data = mock.patch.object( - self.plugin, - '_save_neutron_subnet_data').start() - config_data = { - 'DEFAULT': { - 'neutron_host_id': "fakehost", - } - } - - with test_utils.create_temp_config_with_opts(config_data): - with mock.patch.object(self.plugin.neutron_api, 'create_port', - mock.Mock(return_value=fake_neutron_port)): - self.plugin.allocate_network( - self.fake_context, - fake_share_server, - fake_share_network, - allocation_info={'count': 1}) - - has_provider_nw_ext.assert_any_call() - save_nw_data.assert_called_once_with(self.fake_context, - fake_share_network) - save_subnet_data.assert_called_once_with(self.fake_context, - fake_share_network) - self.plugin.neutron_api.create_port.assert_called_once_with( - fake_share_network['project_id'], - network_id=fake_share_network['neutron_net_id'], - subnet_id=fake_share_network['neutron_subnet_id'], - device_owner='manila:share', host_id="fakehost") - db_api.network_allocation_create.assert_called_once_with( - self.fake_context, - fake_network_allocation) - - has_provider_nw_ext.stop() - save_nw_data.stop() - save_subnet_data.stop() - @mock.patch.object(db_api, 'network_allocation_create', mock.Mock(return_values=fake_network_allocation)) @mock.patch.object(db_api, 'share_network_get', @@ -213,11 +165,11 @@ class NeutronNetworkPluginTest(test.TestCase): mock.call(fake_share_network['project_id'], network_id=fake_share_network['neutron_net_id'], subnet_id=fake_share_network['neutron_subnet_id'], - device_owner='manila:share', host_id=None), + device_owner='manila:share'), mock.call(fake_share_network['project_id'], network_id=fake_share_network['neutron_net_id'], subnet_id=fake_share_network['neutron_subnet_id'], - device_owner='manila:share', host_id=None), + device_owner='manila:share'), ] db_api_calls = [ mock.call(self.fake_context, fake_network_allocation), diff --git a/manila/tests/share/drivers/test_lxd.py b/manila/tests/share/drivers/test_lxd.py deleted file mode 100644 index 4fd4ada0bf..0000000000 --- a/manila/tests/share/drivers/test_lxd.py +++ /dev/null @@ -1,877 +0,0 @@ -# Copyright (c) 2016 Mirantis, 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. -"""Unit tests for the LXD driver module.""" - -import functools -import mock -from oslo_config import cfg -import testtools - -from manila.common import constants as const -from manila import context -from manila import exception -from manila.share import configuration -from manila.share.drivers import lxd -from manila import test -from manila.tests.db import fakes as db_fakes -from manila.tests import fake_utils -from manila import utils - -CONF = cfg.CONF - - -def fake_share(**kwargs): - share = { - 'id': 'fakeid', - 'share_id': 'fakeshareid', - 'name': 'fakename', - 'size': 1, - 'share_proto': 'NFS', - 'export_location': '127.0.0.1:/mnt/nfs/volume-00002', - } - share.update(kwargs) - return db_fakes.FakeModel(share) - - -def fake_access(**kwargs): - access = { - 'id': 'fakeaccid', - 'access_type': 'ip', - 'access_to': '10.0.0.2', - 'access_level': 'rw', - 'state': 'active', - } - access.update(kwargs) - return db_fakes.FakeModel(access) - - -def fake_network(**kwargs): - allocations = db_fakes.FakeModel({'id': 'fake_allocation_id', - 'ip_address': '127.0.0.0.1', - 'mac_address': 'fe:16:3e:61:e0:58'}) - network = { - 'id': 'fake_network_id', - 'server_id': 'fake_server_id', - 'network_allocations': [allocations], - 'neutron_subnet_id': 'fake_subnet', - } - network.update(kwargs) - return db_fakes.FakeModel(network) - - -@testtools.skipIf(lxd.NO_LXD, "pylxd is unavailable") -class LXDHelperTestCase(test.TestCase): - """Tests LXDUnfs3Helper""" - - def setUp(self): - super(LXDHelperTestCase, self).setUp() - lxd_api = mock.Mock() - config = None - self.LXDHelper = lxd.LXDHelper(lxd_api, config) - - def tearDown(self): - super(LXDHelperTestCase, self).tearDown() - - def test_create_container_initialized_ok(self): - self.LXDHelper.conf = mock.Mock() - self.LXDHelper.conf.lxd_image_name = "fake-image" - fake_data = {"operation": "2"} - - def fake_inner_wait(): - return True - - def fake__wait(wait, whatever): - try: - fake_inner_wait() - except Exception: - raise exception.ManilaException() - self.mock_object(self.LXDHelper, "_wait", fake__wait) - self.mock_object(self.LXDHelper.api, "container_init", - mock.Mock(return_value=(0, fake_data))) - self.mock_object(self.LXDHelper, "_wait", fake__wait) - self.LXDHelper.create_container("fake_container") - - def test_create_container_initialized_not_ok(self): - self.LXDHelper.conf = mock.Mock() - self.LXDHelper.conf.lxd_image_name = "fake-image" - fake_data = {"operation": "2"} - fake_operation = {"operation": "2", "status": "failure"} - - def fake_inner_wait(): - return True - - def fake__wait(wait, whatever): - fake_inner_wait() - self.mock_object(self.LXDHelper, "_wait", fake__wait) - self.mock_object(self.LXDHelper.api, "container_init", - mock.Mock(return_value=(0, fake_data))) - self.mock_object(self.LXDHelper.api, "operation_info", - mock.Mock(return_value=(0, fake_operation))) - self.mock_object(self.LXDHelper, "_wait", fake__wait) - self.LXDHelper.create_container("fake_container") - - def test_start_container_running_ok_status_fails(self): - fake_data = {"operation": "2"} - - def fake_inner_wait(): - return False - - def fake__wait(wait, whatever): - try: - fake_inner_wait() - except Exception: - raise exception.ManilaException() - self.mock_object(self.LXDHelper, "_wait", fake__wait) - self.mock_object(self.LXDHelper.api, "container_start", - mock.Mock(return_value=(0, fake_data))) - self.mock_object(self.LXDHelper, "_wait", fake__wait) - self.LXDHelper.start_container("fake_container") - - def test_start_container_running_ok_status_ok(self): - fake_data = {"operation": "1"} - - def fake_inner_wait(): - return True - - def fake__wait(wait, whatever): - try: - fake_inner_wait() - except Exception: - raise exception.ManilaException() - self.mock_object(self.LXDHelper, "_wait", fake__wait) - self.mock_object(self.LXDHelper.api, "container_start", - mock.Mock(return_value=(0, fake_data))) - self.mock_object(self.LXDHelper, "_wait", fake__wait) - self.LXDHelper.start_container("fake_container") - - def test_stop_container(self): - self.mock_object(self.LXDHelper.api, "container_stop", - mock.Mock(return_value=(0, 0))) - self.mock_object(self.LXDHelper.api, "container_destroy") - self.mock_object(self.LXDHelper, "_wait") - self.LXDHelper.stop_container("fake") - self.LXDHelper.api.container_stop.assert_called_once_with("fake", 60) - - def test__wait(self): - self.mock_object(utils, "wait_until_true") - self.LXDHelper.conf = mock.Mock() - self.LXDHelper.conf.lxd_build_timeout = 0 - self.LXDHelper.conf.lxd_check_timeout = 0 - self.LXDHelper._wait("spam", KeyError) - utils.wait_until_true.assert_called_with('spam', exception=KeyError, - sleep=0, timeout=0) - - def test__wait_operation_ok(self): - def fake_inner_wait(): - return True - - def fake__wait(wait, whatever): - try: - fake_inner_wait() - except Exception: - raise exception.ManilaException() - self.mock_object(self.LXDHelper, "_wait", fake__wait) - self.LXDHelper._wait_operation("whatever") - - def test__wait_operation_unkown_error(self): - def fake_inner_wait(): - raise exception.ManilaException("Cannot get operation info") - - def fake__wait(wait, whatever): - try: - wait() - except Exception: - raise exception.ManilaException() - self.mock_object(self.LXDHelper, "_wait", fake__wait) - self.assertRaises(exception.ManilaException, - self.LXDHelper._wait_operation, - fake_inner_wait) - - def test_execute_sync_soket_error(self): - self.mock_object(self.LXDHelper.api, 'container_run_command', - mock.Mock(return_value=(0, {}))) - self.assertRaises(exception.ManilaException, - self.LXDHelper.execute_sync, 'fake', "fakes") - - def test_execute_sync(self): - ret_val = {"metadata": {"metadata": {"fds": {"0": ""}}}, - "operation": "None"} - fake_stream = mock.Mock() - self.mock_object(fake_stream, "receive", mock.Mock(return_value=None)) - self.mock_object(self.LXDHelper.api, 'container_run_command', - mock.Mock(return_value=(0, ret_val))) - self.mock_object(self.LXDHelper.api, 'operation_stream', - mock.Mock(return_value=fake_stream)) - self.mock_object(self.LXDHelper.api, 'operation_info', - mock.Mock(return_value=("", ""))) - self.LXDHelper.execute_sync("fake", "fake") - fake_stream.close.assert_called_once_with() - - -@testtools.skipIf(lxd.NO_LXD, "pylxd is unavailable") -class LXDUnfs3HelperTestCase(test.TestCase): - """Tests LXDUnfs3Helper""" - - def setUp(self): - super(LXDUnfs3HelperTestCase, self).setUp() - self.lxd_helper = mock.Mock() - self.UNFS3Helper = lxd.LXDUnfs3Helper(self.lxd_helper, - share=fake_share()) - - def tearDown(self): - super(LXDUnfs3HelperTestCase, self).tearDown() - - def fake_exec_sync(self, *args, **kwargs): - kwargs['execute_arguments'].append(args) - try: - ret_val = kwargs['ret_val'] - except KeyError: - ret_val = None - return ret_val - - def test__restart_unfsd(self): - actual_arguments = [] - expected_arguments = [ - ('fakeserver', ['pkill', 'unfsd']), - ('fakeserver', ['service', 'unfs3', 'start'])] - self.lxd_helper.execute_sync = functools.partial( - self.fake_exec_sync, execute_arguments=actual_arguments, - ret_val='') - self.UNFS3Helper._restart_unfsd('fakeserver') - self.assertEqual(expected_arguments, actual_arguments) - - def test_create_share(self): - self.mock_object(self.lxd_helper, 'execute_sync', - mock.Mock(return_value="0/0 " * 20)) - self.UNFS3Helper.create_share('fakeserver') - self.UNFS3Helper.lxd.execute_sync.assert_called_with( - 'fakeserver', ['ip', 'addr', 'show', 'eth0']) - - def test_delete_share(self): - self.mock_object(self.UNFS3Helper, '_restart_unfsd') - self.mock_object(self.lxd_helper, 'execute_sync') - self.UNFS3Helper.delete_share('fakeserver') - self.UNFS3Helper.lxd.execute_sync.assert_called_once_with( - 'fakeserver', - ['sed', '-i', '\\$/shares/fakeshareid.*$d', '/etc/exports']) - self.UNFS3Helper._restart_unfsd.assert_called_once_with('fakeserver') - - def test__deny_access(self): - self.mock_object(self.UNFS3Helper, '_restart_unfsd') - self.mock_object(self.lxd_helper, 'execute_sync') - self.UNFS3Helper._deny_access('fakeserver', '127.0.0.1') - self.UNFS3Helper.lxd.execute_sync.assert_called_once_with( - 'fakeserver', - ['sed', '-i', '\\$/shares/fakeshareid.*127\\.0\\.0' - '\\.1.*$d', '/etc/exports']) - self.UNFS3Helper._restart_unfsd.assert_called_once_with('fakeserver') - - def test__allow_access_wrong_level(self): - self.assertRaises(exception.InvalidShareAccessLevel, - self.UNFS3Helper._allow_access, 'fakeshare', - 'fakeserver', '127.0.0.1', 'rwx') - - def test__allow_access_host_present_ro(self): - actual_arguments = [] - expected_arguments = [ - ('fakeserver', - ['grep', '/shares/fakeshareid.*127\\.0\\.0\\.1.*', - '/etc/exports'])] - self.lxd_helper.execute_sync = functools.partial( - self.fake_exec_sync, execute_arguments=actual_arguments, - ret_val='127.0.0.1') - self.UNFS3Helper._allow_access('fakeshare', 'fakeserver', '127.0.0.1', - 'rw') - self.assertEqual(expected_arguments, actual_arguments) - - def test__allow_access_host_present_rw(self): - actual_arguments = [] - expected_arguments = [ - ('fakeserver', - ['grep', '/shares/fakeshareid.*127\\.0\\.0\\.1.*', - '/etc/exports'])] - self.lxd_helper.execute_sync = functools.partial( - self.fake_exec_sync, execute_arguments=actual_arguments, - ret_val='127.0.0.1') - self.UNFS3Helper._allow_access('fakeshare', 'fakeserver', '127.0.0.1', - 'rw') - self.assertEqual(expected_arguments, actual_arguments) - - def test__allow_access_host_present_other(self): - actual_arguments = [] - expected_arguments = [ - ('fakeserver', - ['grep', '/shares/fakeshareid.*127\\.0\\.0\\.1.*', - '/etc/exports'])] - self.lxd_helper.execute_sync = functools.partial( - self.fake_exec_sync, execute_arguments=actual_arguments, - ret_val='127.0.0.1') - self.UNFS3Helper._allow_access('fakeshare', 'fakeserver', '127.0.0.1', - 'rw') - self.assertEqual(expected_arguments, actual_arguments) - - def test__allow_access_no_host_ro(self): - actual_arguments = [] - expected_arguments = [ - ('fakeserver', - ['grep', '/shares/fakeshareid.*127\\.0\\.0\\.1.*', - '/etc/exports']), - ('fakeserver', - ['sed', '-i', - '$ a\\/shares/fakeshareid 127.0.0.1(rw,no_root_squash,async,' - 'no_subtree_check)', '/etc/exports'])] - self.lxd_helper.execute_sync = functools.partial( - self.fake_exec_sync, execute_arguments=actual_arguments, - ret_val='') - self.mock_object(self.UNFS3Helper, '_restart_unfsd') - self.UNFS3Helper._allow_access('fakeshare', 'fakeserver', '127.0.0.1', - 'rw') - self.UNFS3Helper._restart_unfsd.assert_called_once_with('fakeserver') - self.assertEqual(expected_arguments, actual_arguments) - - def test__allow_access_no_host_rw(self): - actual_arguments = [] - expected_arguments = [ - ('fakeserver', - ['grep', '/shares/fakeshareid.*127\\.0\\.0\\.1.*', - '/etc/exports']), - ('fakeserver', - ['sed', '-i', - '$ a\\/shares/fakeshareid 127.0.0.1(rw,no_root_squash,async,' - 'no_subtree_check)', '/etc/exports'])] - self.lxd_helper.execute_sync = functools.partial( - self.fake_exec_sync, execute_arguments=actual_arguments, - ret_val='') - self.mock_object(self.UNFS3Helper, '_restart_unfsd') - self.UNFS3Helper._allow_access('fakeshare', 'fakeserver', '127.0.0.1', - 'rw') - self.UNFS3Helper._restart_unfsd.assert_called_once_with('fakeserver') - self.assertEqual(expected_arguments, actual_arguments) - - def test_update_access_access_rules_ok(self): - allow_rules = [{ - 'access_to': '127.0.0.1', - 'access_level': 'ro', - 'access_type': 'ip' - }] - self.mock_object(self.UNFS3Helper, "_allow_access") - self.UNFS3Helper.update_access("fakeshareid", "fakeserver", - allow_rules, [], []) - self.UNFS3Helper._allow_access.assert_called_once_with("fakeshareid", - "fakeserver", - "127.0.0.1", - "ro") - - def test_update_access_access_rules_wrong_type(self): - access_rules = [{ - 'access_to': '127.0.0.1', - 'access_level': 'ro', - 'access_type': 'user' - }] - self.mock_object(self.UNFS3Helper, "_allow_access") - self.assertRaises(exception.InvalidShareAccess, - self.UNFS3Helper.update_access, "fakeshareid", - "fakeserver", access_rules, [], []) - - def test_update_access_add_rules_ok(self): - add_rules = [{ - 'access_to': '127.0.0.1', - 'access_level': 'ro', - 'access_type': 'ip' - }] - self.mock_object(self.UNFS3Helper, "_allow_access") - self.UNFS3Helper.update_access("fakeshareid", "fakeserver", [], - add_rules, []) - self.UNFS3Helper._allow_access.assert_called_once_with("fakeshareid", - "fakeserver", - "127.0.0.1", - "ro") - - def test_update_access_add_rules_wrong_type(self): - add_rules = [{ - 'access_to': '127.0.0.1', - 'access_level': 'ro', - 'access_type': 'user' - }] - self.mock_object(self.UNFS3Helper, "_allow_access") - self.assertRaises(exception.InvalidShareAccess, - self.UNFS3Helper.update_access, "fakeshareid", - "fakeserver", [], add_rules, []) - - def test_update_access_delete_rules_ok(self): - delete_rules = [{ - 'access_to': '127.0.0.1', - 'access_level': 'ro', - 'access_type': 'ip' - }] - self.mock_object(self.UNFS3Helper, "_deny_access") - self.UNFS3Helper.update_access("fakeshareid", "fakeserver", [], [], - delete_rules) - self.UNFS3Helper._deny_access.assert_called_once_with("fakeserver", - "127.0.0.1") - - def test_update_access_delete_rules_not_ok(self): - delete_rules = [{ - 'access_to': '127.0.0.1', - 'access_level': 'ro', - 'access_type': 'user' - }] - self.mock_object(self.UNFS3Helper, "_deny_access") - self.UNFS3Helper.update_access("fakeshareid", "fakeserver", [], [], - delete_rules) - self.assertFalse(self.UNFS3Helper._deny_access.called) - - -@testtools.skipIf(lxd.NO_LXD, "pylxd is unavailable") -class LXDCIFSHelperTestCase(test.TestCase): - """Tests LXDCIFSHelper""" - - def setUp(self): - super(LXDCIFSHelperTestCase, self).setUp() - self.lxd_helper = mock.Mock() - self.fake_conf = mock.Mock() - self.fake_conf.lxd_cifs_guest_ok = "yes" - self.CIFSHelper = lxd.LXDCIFSHelper(self.lxd_helper, - share=fake_share(), - config=self.fake_conf) - - def tearDown(self): - super(LXDCIFSHelperTestCase, self).tearDown() - - def fake_exec_sync(self, *args, **kwargs): - kwargs['execute_arguments'].append(args) - try: - ret_val = kwargs['ret_val'] - except KeyError: - ret_val = None - return ret_val - - def test_create_share_guest_ok(self): - expected_arguments = [ - ('fakeserver', ['net', 'conf', 'addshare', 'fakeshareid', - '/shares/fakeshareid', 'writeable=y', 'guest_ok=y']), - ('fakeserver', ['net', 'conf', 'setparm', 'fakeshareid', - 'browseable', 'yes']), - ('fakeserver', ['net', 'conf', 'setparm', 'fakeshareid', - 'hosts allow', '127.0.0.1']), - ('fakeserver', ['net', 'conf', 'setparm', 'fakeshareid', - 'read only', 'no']), - ('fakeserver', ['net', 'conf', 'setparm', 'fakeshareid', - 'hosts deny', '0.0.0.0/0']), - ('fakeserver', ['net', 'conf', 'setparm', 'fakeshareid', - 'create mask', '0755'])] - actual_arguments = [] - self.lxd_helper.execute_sync = functools.partial( - self.fake_exec_sync, execute_arguments=actual_arguments, - ret_val="0/0 " * 20) - self.CIFSHelper.share = fake_share() - self.CIFSHelper.create_share("fakeserver") - self.assertEqual(expected_arguments.sort(), actual_arguments.sort()) - - def test_create_share_guest_not_ok(self): - self.CIFSHelper.conf = mock.Mock() - self.CIFSHelper.conf.lxd_cifs_guest_ok = "no" - expected_arguments = [ - ('fakeserver', ['net', 'conf', 'addshare', 'fakeshareid', - '/shares/fakeshareid', 'writeable=y', 'guest_ok=n']), - ('fakeserver', ['net', 'conf', 'setparm', 'fakeshareid', - 'browseable', 'yes']), - ('fakeserver', ['net', 'conf', 'setparm', 'fakeshareid', - 'hosts allow', '127.0.0.1']), - ('fakeserver', ['net', 'conf', 'setparm', 'fakeshareid', - 'read only', 'no']), - ('fakeserver', ['net', 'conf', 'setparm', 'fakeshareid', - 'hosts deny', '0.0.0.0/0']), - ('fakeserver', ['net', 'conf', 'setparm', 'fakeshareid', - 'create mask', '0755'])] - actual_arguments = [] - self.lxd_helper.execute_sync = functools.partial( - self.fake_exec_sync, execute_arguments=actual_arguments, - ret_val="0/0 " * 20) - self.CIFSHelper.share = fake_share() - self.CIFSHelper.create_share("fakeserver") - self.assertEqual(expected_arguments.sort(), actual_arguments.sort()) - - def test_delete_share(self): - self.CIFSHelper.share = fake_share() - self.CIFSHelper.delete_share("fakeserver") - self.CIFSHelper.lxd.execute_sync.assert_called_with( - 'fakeserver', - ['net', 'conf', 'delshare', 'fakeshareid']) - - def test__deny_access_host_present(self): - self.lxd_helper.execute_sync.side_effect = ['127.0.0.1', ""] - self.CIFSHelper.share = fake_share() - self.CIFSHelper._deny_access("fakeserver", "127.0.0.1") - self.CIFSHelper.lxd.execute_sync.assert_called_with( - 'fakeserver', - ['net', 'conf', 'setparm', 'fakeshareid', 'hosts allow', '']) - - def test__deny_access_no_host(self): - self.lxd_helper.execute_sync.side_effect = ['', ""] - self.CIFSHelper.share = fake_share() - self.CIFSHelper._deny_access("fakeserver", "127.0.0.1") - self.CIFSHelper.lxd.execute_sync.assert_called_with( - 'fakeserver', - ['net', 'conf', 'getparm', 'fakeshareid', 'hosts allow']) - - def test__allow_access_host_present(self): - self.lxd_helper.execute_sync.side_effect = ['127.0.0.1', ""] - self.CIFSHelper._allow_access("fakeshareid", "fakeserver", "127.0.0.1", - "rw") - self.CIFSHelper.lxd.execute_sync.assert_called_with( - 'fakeserver', - ['net', 'conf', 'getparm', 'fakeshareid', 'hosts allow']) - - def test__allow_access_no_host(self): - self.lxd_helper.execute_sync.side_effect = ['', ""] - self.CIFSHelper._allow_access("fakeshareid", "fakeserver", "127.0.0.1", - "rw") - self.CIFSHelper.lxd.execute_sync.assert_called_with( - 'fakeserver', - ['net', 'conf', 'setparm', 'fakeshareid', 'hosts allow', - '127.0.0.1, ']) - - def test_allow_access_ro_guest_ok(self): - self.CIFSHelper.conf = mock.Mock() - self.CIFSHelper.conf.lxd_cifs_guest_ok = "yes" - self.CIFSHelper._allow_access("fakeshareid", "fakeserver", "127.0.0.1", - "ro") - self.assertFalse(self.lxd_helper.execute_sync.called) - - def test_allow_access_ro_guest_not_ok(self): - self.CIFSHelper.conf = mock.Mock() - self.CIFSHelper.conf.lxd_cifs_guest_ok = "no" - self.assertRaises(exception.ManilaException, - self.CIFSHelper._allow_access, "fakeshareid", - "fakeserver", "127.0.0.1", "ro") - - def test_allow_user_access_ok(self): - self.CIFSHelper._allow_user_access("fakeshareid", "fakeserver", - "fakeuser", "ro") - self.CIFSHelper.lxd.execute_sync.assert_called_with( - 'fakeserver', - ['net', 'conf', 'setparm', 'fakeshareid', 'read list', 'fakeuser']) - - def test_allow_user_access_not_ok(self): - self.assertRaises(exception.InvalidShareAccessLevel, - self.CIFSHelper._allow_user_access, - "fakeshareid", "fakeserver", "fakeuser", "rx") - - def test_update_access_access_rules_ok(self): - allow_rules = [{ - 'access_to': '127.0.0.1', - 'access_level': 'ro', - 'access_type': 'ip' - }] - self.mock_object(self.CIFSHelper, "_allow_access") - self.CIFSHelper.update_access("fakeshareid", "fakeserver", allow_rules, - [], []) - self.CIFSHelper._allow_access.assert_called_once_with("fakeshareid", - "fakeserver", - "127.0.0.1", - "ro") - - def test_update_access_access_rules_ok_user(self): - allow_rules = [{ - 'access_to': 'fakeuser', - 'access_level': 'ro', - 'access_type': 'user' - }] - self.mock_object(self.CIFSHelper, "_allow_user_access") - self.CIFSHelper.update_access("fakeshareid", "fakeserver", allow_rules, - [], []) - self.CIFSHelper._allow_user_access.assert_called_once_with( - "fakeshareid", - "fakeserver", - "fakeuser", - "ro") - - def test_update_access_access_rules_wrong_type(self): - allow_rules = [{ - 'access_to': '127.0.0.1', - 'access_level': 'ro', - 'access_type': 'fake' - }] - self.mock_object(self.CIFSHelper, "_allow_access") - self.assertRaises(exception.InvalidShareAccess, - self.CIFSHelper.update_access, "fakeshareid", - "fakeserver", allow_rules, [], []) - - def test_update_access_add_rules_ok(self): - add_rules = [{ - 'access_to': '127.0.0.1', - 'access_level': 'ro', - 'access_type': 'ip' - }] - self.mock_object(self.CIFSHelper, "_allow_access") - self.CIFSHelper.update_access("fakeshareid", "fakeserver", [], - add_rules, []) - self. CIFSHelper._allow_access.assert_called_once_with("fakeshareid", - "fakeserver", - "127.0.0.1", - "ro") - - def test_update_access_add_rules_ok_user(self): - add_rules = [{ - 'access_to': 'fakeuser', - 'access_level': 'ro', - 'access_type': 'user' - }] - self.mock_object(self.CIFSHelper, "_allow_user_access") - self.CIFSHelper.update_access("fakeshareid", "fakeserver", [], - add_rules, []) - self. CIFSHelper._allow_user_access.assert_called_once_with( - "fakeshareid", - "fakeserver", - "fakeuser", - "ro") - - def test_update_access_add_rules_wrong_type(self): - add_rules = [{ - 'access_to': '127.0.0.1', - 'access_level': 'ro', - 'access_type': 'fake' - }] - self.mock_object(self.CIFSHelper, "_allow_access") - self.assertRaises(exception.InvalidShareAccess, - self.CIFSHelper.update_access, "fakeshareid", - "fakeserver", [], add_rules, []) - - def test_update_access_delete_rules_ok(self): - delete_rules = [{ - 'access_to': '127.0.0.1', - 'access_level': 'ro', - 'access_type': 'ip' - }] - self.mock_object(self.CIFSHelper, "_deny_access") - self.CIFSHelper.update_access("fakeshareid", "fakeserver", [], [], - delete_rules) - self.CIFSHelper._deny_access.assert_called_once_with("fakeserver", - "127.0.0.1") - - def test_update_access_delete_rules_not_ok(self): - delete_rules = [{ - 'access_to': '127.0.0.1', - 'access_level': 'ro', - 'access_type': 'user' - }] - self.mock_object(self.CIFSHelper, "_deny_access") - self.CIFSHelper.update_access("fakeshareid", "fakeserver", [], [], - delete_rules) - self.assertFalse(self.CIFSHelper._deny_access.called) - - -@testtools.skipIf(lxd.NO_LXD, "pylxd is unavailable") -class LXDDriverTestCase(test.TestCase): - """Tests LXDDriver.""" - - def setUp(self): - super(LXDDriverTestCase, self).setUp() - fake_utils.stub_out_utils_execute(self) - self._context = context.get_admin_context() - self._db = mock.Mock() - self.fake_conf = configuration.Configuration(None) - - CONF.set_default('driver_handles_share_servers', True) - - self._driver = lxd.LXDDriver(self._db, configuration=self.fake_conf) - - self.share = fake_share() - self.access = fake_access() - self.server = { - 'public_address': self.fake_conf.lvm_share_export_ip, - 'instance_id': 'LVM', - } - - # Used only to test compatibility with share manager - self.share_server = "fake_share_server" - - def tearDown(self): - super(LXDDriverTestCase, self).tearDown() - - def test_create_share(self): - helper = mock.Mock() - self.mock_object(helper, 'create_share', - mock.Mock(return_value='export_location')) - self.mock_object(self._driver, "_get_helper", - mock.Mock(return_value=helper)) - self.mock_object(self._driver, '_execute') - self.mock_object(self._driver.lxd, 'execute_sync') - self.assertEqual('export_location', - self._driver.create_share(self._context, self.share, - {'id': 'fake'})) - - def test_update_share_stats(self): - self.mock_object(self._driver, 'get_share_server_pools', - mock.Mock(return_value='test-pool')) - - self._driver._update_share_stats() - self.assertEqual('LXD', self._driver._stats['share_backend_name']) - self.assertEqual('NFS_CIFS', self._driver._stats['storage_protocol']) - self.assertEqual(0, self._driver._stats['reserved_percentage']) - self.assertEqual(None, - self._driver._stats['consistency_group_support']) - self.assertEqual(False, self._driver._stats['snapshot_support']) - self.assertEqual('LXDDriver', self._driver._stats['driver_name']) - self.assertEqual('test-pool', self._driver._stats['pools']) - - def test_get_share_server_pools(self): - ret_vgs = "VSize 100g size\nVFree 100g whatever" - expected_result = [{'reserved_percentage': 0, - 'pool_name': 'manila_lxd_volumes', - 'total_capacity_gb': 100.0, - 'free_capacity_gb': 100.0}] - self.mock_object(self._driver, "_execute", - mock.Mock(return_value=(ret_vgs, 0))) - result = self._driver.get_share_server_pools() - self.assertEqual(expected_result, result) - - def test__get_nfs_helper_ganesha(self): - self._driver.configuration.lxd_nfs_server = "ganesha" - self.assertRaises(exception.ManilaException, - self._driver._get_nfs_helper) - - def test__get_nfs_helper_unfs3(self): - self.assertEqual(lxd.LXDUnfs3Helper, self._driver._get_nfs_helper()) - - def test__get_nfs_helper_other(self): - self._driver.configuration.lxd_nfs_server = "MightyNFS" - self.assertRaises(exception.ManilaException, - self._driver._get_nfs_helper) - - def test__get_helper_nfs_new(self): - share = {'share_proto': 'NFS'} - self.mock_object(self._driver, "nfshelper") - self._driver._get_helper(share) - self._driver.nfshelper.assert_called_once_with(self._driver.lxd, - share=share) - - def test__get_helper_nfs_existing(self): - share = {'share_proto': 'NFS'} - self._driver._helpers['NFS'] = mock.Mock() - result = self._driver._get_helper(share) - self.assertEqual(share, result.share) - - def test__get_helper_cifs_new(self): - share = {'share_proto': 'CIFS'} - result = self._driver._get_helper(share) - self.assertEqual(lxd.LXDCIFSHelper, type(result)) - - def test__get_helper_cifs_existing(self): - share = {'share_proto': 'CIFS'} - self._driver._helpers['CIFS'] = mock.Mock() - result = self._driver._get_helper(share) - self.assertEqual(share, result.share) - - def test__get_helper_other(self): - share = {'share_proto': 'SuperProtocol'} - self.assertRaises(exception.InvalidShare, self._driver._get_helper, - share) - - def test__get_lv_device(self): - self.assertEqual("/dev/manila_lxd_volumes/fakeshareid", - self._driver._get_lv_device(self.share)) - - def test__get_lv_folder(self): - self.assertEqual("/tmp/fakeshareid", - self._driver._get_lv_folder(self.share)) - - def test_extend_share(self): - self.mock_object(self._driver, '_execute') - self.mock_object(self._driver, '_get_lv_device', - mock.Mock(return_value="path")) - self._driver.extend_share(self.share, 'share', 3) - local_path = 'path' - self._driver._execute.assert_called_with('resize2fs', local_path, - run_as_root=True) - - def test__connect_to_network(self): - network_info = fake_network() - helper = mock.Mock() - self.mock_object(self._driver, "_execute", - mock.Mock(return_value=helper)) - self.mock_object(self._driver.lxd, "execute_sync") - self.mock_object(self._driver, "_get_host_veth", - mock.Mock(return_value="vethBEEF42")) - self._driver._connect_to_network("fake-server", network_info) - - def test_delete_share(self): - helper = mock.Mock() - self.mock_object(self._driver, "_get_helper", - mock.Mock(return_value=helper)) - self.mock_object(self._driver, '_execute') - self.mock_object(self._driver.lxd, 'execute_sync') - self._driver.delete_share(self._context, self.share, {'id': 'fake'}) - self._driver._execute.assert_called_with( - 'lvremove', '-f', '--autobackup', 'n', - '/dev/manila_lxd_volumes/fakeshareid', - run_as_root=True) - - def test__get_host_veth(self): - fake_data = { - "network": {"eth0": {"host_name": "vethBEEF42"}} - } - self.mock_object(self._driver.lxd.api, "container_info", - mock.Mock(return_value=fake_data)) - self.assertEqual("vethBEEF42", - self._driver._get_host_veth("fakeserver")) - - def test__teardown_server(self): - self.mock_object(self._driver, '_get_host_veth', - mock.Mock(return_value='veth42BEEF')) - self.mock_object(self._driver.lxd, 'stop_container') - self.mock_object(self._driver, '_execute') - self._driver._teardown_server(server_details={'id': 'fake'}) - self._driver.lxd.stop_container.assert_called_with('manila-fake') - self._driver._execute.assert_called_with("ovs-vsctl", "--", "del-port", - 'br-int', 'veth42BEEF', - run_as_root=True) - - def test_update_access_access_rules_ok(self): - helper = mock.Mock() - self.mock_object(self._driver, "_get_helper", - mock.Mock(return_value=helper)) - self._driver.update_access(self._context, self.share, - [{'access_level': const.ACCESS_LEVEL_RW}], - [], [], {"id": "fake"}) - helper.update_access.assert_called_with('fakeshareid', 'manila-fake', - [{'access_level': 'rw'}], - [], []) - - def test__get_container_name(self): - self.assertEqual("manila-fake-server", - self._driver._get_container_name("fake-server")) - - def test__setup_server_container_fails(self): - network_info = fake_network() - self.mock_object(self._driver.lxd, 'create_container') - self._driver.lxd.create_container.side_effect = KeyError() - self.assertRaises(exception.ManilaException, - self._driver._setup_server, network_info) - - def test__setup_server_ok(self): - network_info = fake_network() - server_id = self._driver._get_container_name(network_info["server_id"]) - self.mock_object(self._driver.lxd, 'create_container') - self.mock_object(self._driver.lxd, 'start_container') - self.mock_object(self._driver.lxd.api, 'container_run_command') - self.mock_object(self._driver, '_connect_to_network') - self.assertEqual(network_info['server_id'], - self._driver._setup_server(network_info)['id']) - self._driver.lxd.create_container.assert_called_once_with(server_id) - self._driver.lxd.start_container.assert_called_once_with(server_id) - self._driver._connect_to_network.assert_called_once_with(server_id, - network_info) diff --git a/manila/tests/test_utils.py b/manila/tests/test_utils.py index 7c61fa5025..1c885314b9 100644 --- a/manila/tests/test_utils.py +++ b/manila/tests/test_utils.py @@ -875,21 +875,6 @@ class RequireDriverInitializedTestCase(test.TestCase): self.assertRaises(expected_exception, FakeManager().call_me) -class WaitUntilTrueTestCase(test.TestCase): - - def test_wait_until_true_ok(self): - fake_predicate = mock.Mock(return_value=True) - exc = exception.ManilaException - utils.wait_until_true(fake_predicate, 1, 1, exc) - self.assertTrue(fake_predicate.called) - - def test_wait_until_true_not_ok(self): - fake_predicate = mock.Mock(return_value=False) - exc = exception.ManilaException - self.assertRaises(exception.ManilaException, utils.wait_until_true, - fake_predicate, 0, 0, exc) - - @ddt.ddt class ShareMigrationHelperTestCase(test.TestCase): """Tests DataMigrationHelper.""" diff --git a/manila/utils.py b/manila/utils.py index c147e73f1d..cab18a9c69 100644 --- a/manila/utils.py +++ b/manila/utils.py @@ -31,7 +31,6 @@ import sys import tempfile import time -import eventlet from eventlet import pools import netaddr from oslo_concurrency import lockutils @@ -660,21 +659,6 @@ def translate_string_size_to_float(string, multiplier='G'): return value * multiplier -def wait_until_true(predicate, timeout=60, sleep=1, exception=None): - """Wait until callable predicate is evaluated as True - - :param predicate: Callable deciding whether waiting should continue. - Best practice is to instantiate predicate with functools.partial() - :param timeout: Timeout in seconds how long should function wait. - :param sleep: Polling interval for results in seconds. - :param exception: Exception class for eventlet.Timeout. - (see doc for eventlet.Timeout for more information) - """ - with eventlet.timeout.Timeout(timeout, exception): - while not predicate(): - eventlet.sleep(sleep) - - def wait_for_access_update(context, db, share_instance, migration_wait_access_rules_timeout): starttime = time.time() diff --git a/requirements.txt b/requirements.txt index be9356c78e..2fb4d12e9e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,7 +27,6 @@ oslo.concurrency>=3.5.0 # Apache-2.0 paramiko>=1.16.0 # LGPL Paste # MIT PasteDeploy>=1.5.0 # MIT -pylxd>=0.19.0 # Apache-2.0 python-neutronclient!=4.1.0,>=2.6.0 # Apache-2.0 keystonemiddleware!=4.1.0,>=4.0.0 # Apache-2.0 requests!=2.9.0,>=2.8.1 # Apache-2.0