示例#1
0
 def test_get_share_type_extra_specs(self):
     share_type = self.fake_type_w_extra["test_with_extra"]
     self.mock_object(db, "share_type_get", mock.Mock(return_value=share_type))
     id = share_type["id"]
     extra_spec = share_types.get_share_type_extra_specs(id, key="gold")
     self.assertEqual(share_type["extra_specs"]["gold"], extra_spec)
     extra_spec = share_types.get_share_type_extra_specs(id)
     self.assertEqual(share_type["extra_specs"], extra_spec)
示例#2
0
 def test_get_share_type_extra_specs(self):
     share_type = self.fake_type_w_extra['test_with_extra']
     self.mock_object(db, 'share_type_get',
                      mock.Mock(return_value=share_type))
     id = share_type['id']
     extra_spec = share_types.get_share_type_extra_specs(id, key='gold')
     self.assertEqual(share_type['extra_specs']['gold'], extra_spec)
     extra_spec = share_types.get_share_type_extra_specs(id)
     self.assertEqual(share_type['extra_specs'], extra_spec)
示例#3
0
 def test_get_share_type_extra_specs(self):
     share_type = self.fake_type_w_extra['test_with_extra']
     self.mock_object(db,
                      'share_type_get',
                      mock.Mock(return_value=share_type))
     id = share_type['id']
     extra_spec = share_types.get_share_type_extra_specs(id, key='gold')
     self.assertEqual(share_type['extra_specs']['gold'], extra_spec)
     extra_spec = share_types.get_share_type_extra_specs(id)
     self.assertEqual(share_type['extra_specs'], extra_spec)
示例#4
0
def get_share_extra_specs_params(type_id):
    """Return the parameters for creating the share."""
    opts = None
    if type_id is not None:
        specs = share_types.get_share_type_extra_specs(type_id)

        opts = _get_opts_from_specs(specs)
        LOG.debug('Get share type extra specs: %s', opts)

    return opts
示例#5
0
def get_share_extra_specs_params(type_id):
    """Return the parameters for creating the share."""
    opts = None
    if type_id is not None:
        specs = share_types.get_share_type_extra_specs(type_id)

        opts = _get_opts_from_specs(specs)
        LOG.debug('Get share type extra specs: %s', opts)

    return opts
示例#6
0
    def manage_existing(self, share, driver_options):
        """Manage existing share."""
        driver_mode = share_types.get_share_type_extra_specs(
            share['share_type_id'],
            common_constants.ExtraSpecs.DRIVER_HANDLES_SHARE_SERVERS)

        if strutils.bool_from_string(driver_mode):
            msg = _("%(mode)s != False") % {
                'mode':
                common_constants.ExtraSpecs.DRIVER_HANDLES_SHARE_SERVERS
            }
            raise exception.ManageExistingShareTypeMismatch(reason=msg)

        share_proto = share['share_proto']
        share_name = share['name']
        old_export_location = share['export_locations'][0]['path']
        pool_name = share_utils.extract_host(share['host'], level='pool')
        share_url_type = self.helper._get_share_url_type(share_proto)

        old_share_name = self.helper._get_share_name_by_export_location(
            old_export_location, share_proto)

        share = self.helper._get_share_by_name(old_share_name,
                                               share_url_type)
        if not share:
            err_msg = (_("Can not get share ID by share %s.")
                       % old_export_location)
            LOG.error(err_msg)
            raise exception.InvalidShare(reason=err_msg)

        fs_id = share['FSID']
        fs = self.helper._get_fs_info_by_id(fs_id)
        if not self.check_fs_status(fs['HEALTHSTATUS'],
                                    fs['RUNNINGSTATUS']):
            raise exception.InvalidShare(
                reason=(_('Invalid status of filesystem: %(health)s '
                          '%(running)s.')
                        % {'health': fs['HEALTHSTATUS'],
                           'running': fs['RUNNINGSTATUS']}))

        if pool_name and pool_name != fs['POOLNAME']:
            raise exception.InvalidHost(
                reason=(_('The current pool(%(fs_pool)s) of filesystem '
                          'does not match the input pool(%(host_pool)s).')
                        % {'fs_pool': fs['POOLNAME'],
                           'host_pool': pool_name}))

        self.helper._change_fs_name(fs_id, share_name)
        share_size = int(fs['CAPACITY']) / units.Mi / 2

        location = self._get_location_path(share_name, share_proto)
        return (share_size, [location])
示例#7
0
def get_share_extra_specs_params(type_id):
    specs = {}
    if type_id:
        specs = share_types.get_share_type_extra_specs(type_id)

    opts = _get_opts_from_specs(specs)
    _get_smartprovisioning_opts(opts)
    _check_smartcache_opts(opts)
    _check_smartpartition_opts(opts)
    _get_qos_opts(opts)

    LOG.info('Get share type extra specs: %s', opts)
    return opts
示例#8
0
def get_share_privilege(type_id):
    specs = {}
    if type_id:
        specs = share_types.get_share_type_extra_specs(type_id)

    share_privilege = {
        'huawei_share_privilege:sync': _get_string_param,
        'huawei_share_privilege:allsquash': _get_string_param,
        'huawei_share_privilege:rootsquash': _get_string_param,
        'huawei_share_privilege:secure': _get_string_param,
    }

    opts = {}
    for spec_key in specs:
        key = spec_key.lower()
        if share_privilege.get(key):
            opt_key = _get_opt_key(key)
            opts[opt_key.upper()] = share_privilege[key](key, specs[spec_key])

    return opts
示例#9
0
    def manage_existing(self, share, driver_options):
        """Manage existing share to manila.

        Generic driver accepts only one driver_option 'volume_id'.
        If an administrator provides this option, then appropriate Cinder
        volume will be managed by Manila as well.

        :param share: share data
        :param driver_options: Empty dict or dict with 'volume_id' option.
        :return: dict with share size, example: {'size': 1}
        """
        if self.driver_handles_share_servers:
            msg = _('Operation "manage" for shares is supported only when '
                    'driver does not handle share servers.')
            raise exception.InvalidDriverMode(msg)

        helper = self._get_helper(share)
        driver_mode = share_types.get_share_type_extra_specs(
            share['share_type_id'],
            const.ExtraSpecs.DRIVER_HANDLES_SHARE_SERVERS)

        if strutils.bool_from_string(driver_mode):
            msg = _("%(mode)s != False") % {
                'mode': const.ExtraSpecs.DRIVER_HANDLES_SHARE_SERVERS
            }
            raise exception.ManageExistingShareTypeMismatch(reason=msg)

        share_server = self.service_instance_manager.get_common_server()
        server_details = share_server['backend_details']

        old_export_location = share['export_locations'][0]['path']
        mount_path = helper.get_share_path_by_export_location(
            share_server['backend_details'], old_export_location)
        LOG.debug("Manage: mount path = %s", mount_path)

        mounted = self._is_device_mounted(mount_path, server_details)
        LOG.debug("Manage: is share mounted = %s", mounted)

        if not mounted:
            msg = _("Provided share %s is not mounted.") % share['id']
            raise exception.ManageInvalidShare(reason=msg)

        def get_volume():
            if 'volume_id' in driver_options:
                try:
                    return self.volume_api.get(
                        self.admin_context, driver_options['volume_id'])
                except exception.VolumeNotFound as e:
                    raise exception.ManageInvalidShare(reason=six.text_type(e))

            # NOTE(vponomaryov): Manila can only combine volume name by itself,
            # nowhere to get volume ID from. Return None since Cinder volume
            # names are not unique or fixed, hence, they can not be used for
            # sure.
            return None

        share_volume = get_volume()

        if share_volume:
            instance_volumes = self.compute_api.instance_volumes_list(
                self.admin_context, server_details['instance_id'])

            attached_volumes = [vol.id for vol in instance_volumes]
            LOG.debug('Manage: attached volumes = %s',
                      six.text_type(attached_volumes))

            if share_volume['id'] not in attached_volumes:
                msg = _("Provided volume %s is not attached "
                        "to service instance.") % share_volume['id']
                raise exception.ManageInvalidShare(reason=msg)

            linked_volume_name = self._get_volume_name(share['id'])
            if share_volume['name'] != linked_volume_name:
                LOG.debug('Manage: volume_id = %s' % share_volume['id'])
                self.volume_api.update(self.admin_context, share_volume['id'],
                                       {'name': linked_volume_name})

            self.private_storage.update(
                share['id'], {'volume_id': share_volume['id']})

            share_size = share_volume['size']
        else:
            share_size = self._get_mounted_share_size(
                mount_path, share_server['backend_details'])

        export_locations = helper.get_exports_for_share(
            server_details, old_export_location)
        return {'size': share_size, 'export_locations': export_locations}
示例#10
0
    def manage_existing(self, share, driver_options):
        """Manage existing share."""

        share_proto = share['share_proto']
        share_name = share['name']
        old_export_location = share['export_locations'][0]['path']
        pool_name = share_utils.extract_host(share['host'], level='pool')
        share_url_type = self.helper._get_share_url_type(share_proto)
        old_share_name = self.helper._get_share_name_by_export_location(
            old_export_location, share_proto)

        share_storage = self.helper._get_share_by_name(old_share_name,
                                                       share_url_type)
        if not share_storage:
            err_msg = (_("Can not get share ID by share %s.")
                       % old_export_location)
            LOG.error(err_msg)
            raise exception.InvalidShare(reason=err_msg)

        fs_id = share_storage['FSID']
        fs = self.helper._get_fs_info_by_id(fs_id)
        if not self.check_fs_status(fs['HEALTHSTATUS'],
                                    fs['RUNNINGSTATUS']):
            raise exception.InvalidShare(
                reason=(_('Invalid status of filesystem: %(health)s '
                          '%(running)s.')
                        % {'health': fs['HEALTHSTATUS'],
                           'running': fs['RUNNINGSTATUS']}))

        if pool_name and pool_name != fs['POOLNAME']:
            raise exception.InvalidHost(
                reason=(_('The current pool(%(fs_pool)s) of filesystem '
                          'does not match the input pool(%(host_pool)s).')
                        % {'fs_pool': fs['POOLNAME'],
                           'host_pool': pool_name}))

        result = self.helper._find_all_pool_info()
        poolinfo = self.helper._find_pool_info(pool_name, result)

        opts = huawei_utils.get_share_extra_specs_params(
            share['share_type_id'])
        specs = share_types.get_share_type_extra_specs(share['share_type_id'])
        if ('capabilities:thin_provisioning' not in specs.keys()
                and 'thin_provisioning' not in specs.keys()):
            if fs['ALLOCTYPE'] == constants.ALLOC_TYPE_THIN_FLAG:
                opts['thin_provisioning'] = constants.THIN_PROVISIONING
            else:
                opts['thin_provisioning'] = constants.THICK_PROVISIONING

        change_opts = self.check_retype_change_opts(opts, poolinfo, fs)
        LOG.info(_LI('Retyping share (%(share)s), changed options are : '
                     '(%(change_opts)s).'),
                 {'share': old_share_name, 'change_opts': change_opts})
        try:
            self.retype_share(change_opts, fs_id)
        except Exception as err:
            message = (_("Retype share error. Share: %(share)s. "
                         "Reason: %(reason)s.")
                       % {'share': old_share_name,
                          'reason': err})
            raise exception.InvalidShare(reason=message)

        share_size = int(fs['CAPACITY']) / units.Mi / 2
        self.helper._change_fs_name(fs_id, share_name)
        location = self._get_location_path(share_name, share_proto)
        return (share_size, [location])
示例#11
0
    def manage_existing(self, share, driver_options):
        """Manage existing share to manila.

        Generic driver accepts only one driver_option 'volume_id'.
        If an administrator provides this option, then appropriate Cinder
        volume will be managed by Manila as well.

        :param share: share data
        :param driver_options: Empty dict or dict with 'volume_id' option.
        :return: dict with share size, example: {'size': 1}
        """
        if self.driver_handles_share_servers:
            msg = _('Operation "manage" for shares is supported only when '
                    'driver does not handle share servers.')
            raise exception.InvalidDriverMode(msg)

        helper = self._get_helper(share)
        driver_mode = share_types.get_share_type_extra_specs(
            share['share_type_id'],
            const.ExtraSpecs.DRIVER_HANDLES_SHARE_SERVERS)

        if strutils.bool_from_string(driver_mode):
            msg = _("%(mode)s != False") % {
                'mode': const.ExtraSpecs.DRIVER_HANDLES_SHARE_SERVERS
            }
            raise exception.ManageExistingShareTypeMismatch(reason=msg)

        share_server = self.service_instance_manager.get_common_server()
        server_details = share_server['backend_details']

        old_export_location = share['export_locations'][0]['path']
        mount_path = helper.get_share_path_by_export_location(
            share_server['backend_details'], old_export_location)
        LOG.debug("Manage: mount path = %s", mount_path)

        mounted = self._is_device_mounted(mount_path, server_details)
        LOG.debug("Manage: is share mounted = %s", mounted)

        if not mounted:
            msg = _("Provided share %s is not mounted.") % share['id']
            raise exception.ManageInvalidShare(reason=msg)

        def get_volume():
            if 'volume_id' in driver_options:
                try:
                    return self.volume_api.get(self.admin_context,
                                               driver_options['volume_id'])
                except exception.VolumeNotFound as e:
                    raise exception.ManageInvalidShare(reason=six.text_type(e))

            # NOTE(vponomaryov): Manila can only combine volume name by itself,
            # nowhere to get volume ID from. Return None since Cinder volume
            # names are not unique or fixed, hence, they can not be used for
            # sure.
            return None

        share_volume = get_volume()

        if share_volume:
            instance_volumes = self.compute_api.instance_volumes_list(
                self.admin_context, server_details['instance_id'])

            attached_volumes = [vol.id for vol in instance_volumes]
            LOG.debug('Manage: attached volumes = %s',
                      six.text_type(attached_volumes))

            if share_volume['id'] not in attached_volumes:
                msg = _("Provided volume %s is not attached "
                        "to service instance.") % share_volume['id']
                raise exception.ManageInvalidShare(reason=msg)

            linked_volume_name = self._get_volume_name(share['id'])
            if share_volume['name'] != linked_volume_name:
                LOG.debug('Manage: volume_id = %s' % share_volume['id'])
                self.volume_api.update(self.admin_context, share_volume['id'],
                                       {'name': linked_volume_name})

            share_size = share_volume['size']
        else:
            share_size = self._get_mounted_share_size(
                mount_path, share_server['backend_details'])

        export_locations = helper.get_exports_for_share(
            server_details, old_export_location)
        return {'size': share_size, 'export_locations': export_locations}