示例#1
0
    def __init__(self, config, driver_type):
        if not config.safe_get('iscsi_ip_address'):
            raise exception.InvalidConfigurationValue(
                option='iscsi_ip_address', value='')
        if not config.safe_get('synology_pool_name'):
            raise exception.InvalidConfigurationValue(
                option='synology_pool_name', value='')

        self.config = config
        self.vendor_name = 'Synology'
        self.driver_type = driver_type
        self.volume_backend_name = self._get_backend_name()
        self.iscsi_port = self.config.safe_get('iscsi_port')

        api = APIRequest(
            self.config.iscsi_ip_address,
            self.config.synology_admin_port,
            self.config.synology_username,
            self.config.synology_password,
            self.config.safe_get('driver_use_ssl'),
            self.config.safe_get('synology_ssl_verify'),
            self.config.safe_get('synology_one_time_pass'),
            self.config.safe_get('synology_device_id'),
        )
        self.synoexec = api.request
        self.host_uuid = self._get_node_uuid()
示例#2
0
    def validate_ports(self, ports_whitelist):
        all_ports = self.get_all_ports()
        # After normalize_config, `ports_whitelist` could be only None or valid
        # list in which the items are stripped.
        if ports_whitelist is None:
            return all_ports.id

        # For iSCSI port, the format is 'spa_eth0', and 'spa_iom_0_fc0' for FC.
        # Unix style glob like 'spa_*' is supported.
        whitelist = set(ports_whitelist)

        matched, _ignored, unmatched_whitelist = utils.match_any(
            all_ports.id, whitelist)
        if not matched:
            LOG.error('No matched ports filtered by all patterns: %s',
                      whitelist)
            raise exception.InvalidConfigurationValue(
                option='%s.unity_io_ports' % self.config.config_group,
                value=self.config.unity_io_ports)

        if unmatched_whitelist:
            LOG.error('No matched ports filtered by below patterns: %s',
                      unmatched_whitelist)
            raise exception.InvalidConfigurationValue(
                option='%s.unity_io_ports' % self.config.config_group,
                value=self.config.unity_io_ports)

        LOG.info(
            'These ports %(matched)s will be used based on '
            'the option unity_io_ports: %(config)s', {
                'matched': matched,
                'config': self.config.unity_io_ports
            })
        return matched
示例#3
0
    def __init__(self, conf_dict, driver):
        """Constructs a replication device from driver configuration.

        :param conf_dict: the conf of one replication device entry. It's a
            dict with content like
            `{backend_id: vendor-id-1, key-1: val-1, ...}`
        :param driver: the backend driver.
        """
        driver_conf = driver.configuration

        self.backend_id = conf_dict.get('backend_id')
        self.san_ip = conf_dict.get('san_ip', None)
        if (self.backend_id is None or not self.backend_id.strip()
                or self.san_ip is None or not self.san_ip.strip()):
            LOG.error(
                'No backend_id or san_ip in %(conf)s of '
                '%(group)s.replication_device',
                conf=conf_dict,
                group=driver_conf.config_group)
            raise exception.InvalidConfigurationValue(
                option='%s.replication_device' % driver_conf.config_group,
                value=driver_conf.replication_device)

        # Use the driver settings if not configured in replication_device.
        self.san_login = conf_dict.get('san_login', driver_conf.san_login)
        self.san_password = conf_dict.get('san_password',
                                          driver_conf.san_password)

        # Max time (in minute) out of sync is a setting for replication.
        # It means maximum time to wait before syncing the source and
        # destination. `0` means it is a sync replication. Default is `60`.
        try:
            self.max_time_out_of_sync = int(
                conf_dict.get('max_time_out_of_sync', 60))
        except ValueError:
            LOG.error(
                'max_time_out_of_sync is not a number, %(conf)s of '
                '%(group)s.replication_device',
                conf=conf_dict,
                group=driver_conf.config_group)
            raise exception.InvalidConfigurationValue(
                option='%s.replication_device' % driver_conf.config_group,
                value=driver_conf.replication_device)
        if self.max_time_out_of_sync < 0:
            LOG.error(
                'max_time_out_of_sync should be greater than 0, '
                '%(conf)s of %(group)s.replication_device',
                conf=conf_dict,
                group=driver_conf.config_group)
            raise exception.InvalidConfigurationValue(
                option='%s.replication_device' % driver_conf.config_group,
                value=driver_conf.replication_device)

        self.driver = driver
        self._adapter = init_adapter(driver.get_version(), driver.protocol)
        self._dst_pool = None
        self._serial_number = None
示例#4
0
    def get_qos_parameters(self, specs, reset):
        qos_params = {}
        if 'upperlimit' in specs and specs['upperlimit'] is not None:
            if self.validates_number(specs['upperlimit']) is True:
                upper_limit = int(specs['upperlimit'], 10)
                if ((upper_limit != 0)
                        and ((upper_limit < 10) or (upper_limit > 1000000))):
                    raise exception.InvalidConfigurationValue(
                        value=upper_limit, option='upperlimit')
                qos_params['upperlimit'] = upper_limit
            else:
                raise exception.InvalidConfigurationValue(
                    value=specs['upperlimit'], option='upperlimit')
        else:
            # 0: Set to no limit.(default)
            #    On the QoS function in NEC Storage, 0 means there is no
            #    limit.
            # None: Keep current value.
            qos_params['upperlimit'] = 0 if reset else None

        if 'lowerlimit' in specs and specs['lowerlimit'] is not None:
            if self.validates_number(specs['lowerlimit']) is True:
                lower_limit = int(specs['lowerlimit'], 10)
                if (lower_limit != 0
                        and (lower_limit < 10 or lower_limit > 1000000)):
                    raise exception.InvalidConfigurationValue(
                        value=lower_limit, option='lowerlimit')
                qos_params['lowerlimit'] = lower_limit
            else:
                raise exception.InvalidConfigurationValue(
                    value=specs['lowerlimit'], option='lowerlimit')
        else:
            # 0: Set to no limit.(default)
            #    On the QoS function in NEC Storage, 0 means there is no
            #    limit.
            # None: Keep current value.
            qos_params['lowerlimit'] = 0 if reset else None

        if 'upperreport' in specs:
            if specs['upperreport'] not in ['on', 'off']:
                LOG.debug(
                    'Illegal arguments. '
                    'upperreport is not on or off.'
                    'upperreport=%s', specs['upperreport'])
                qos_params['upperreport'] = 'off' if reset else None
            else:
                qos_params['upperreport'] = specs['upperreport']
        else:
            # off: Set to no report.(default)
            # None: Keep current value.
            qos_params['upperreport'] = 'off' if reset else None
        return qos_params
示例#5
0
    def do_setup(self, driver):
        self.default_conf = driver.configuration

        self.replication_devices = self.parse_rep_device(driver)
        if DEFAULT_ADAPTER_NAME in self.replication_devices:
            LOG.error('backend_id cannot be `default`')
            raise exception.InvalidConfigurationValue(
                option=('%s.replication_device' %
                        self.default_conf.config_group),
                value=self.default_conf.replication_device)

        # Only support one replication device currently.
        if len(self.replication_devices) > 1:
            LOG.error('At most one replication_device is supported')
            raise exception.InvalidConfigurationValue(
                option=('%s.replication_device' %
                        self.default_conf.config_group),
                value=self.default_conf.replication_device)

        self.is_replication_configured = len(self.replication_devices) >= 1

        self.active_backend_id = driver.active_backend_id
        if self.active_backend_id:
            if self.active_backend_id not in self.replication_devices:
                LOG.error(
                    'Service starts under failed-over status, '
                    'active_backend_id: %s is not empty, but not in '
                    'replication_device.', self.active_backend_id)
                raise exception.InvalidConfigurationValue(
                    option=('%s.replication_device' %
                            self.default_conf.config_group),
                    value=self.default_conf.replication_device)
        else:
            self.active_backend_id = DEFAULT_ADAPTER_NAME

        default_device_conf = {
            'backend_id': DEFAULT_ADAPTER_NAME,
            'san_ip': driver.configuration.san_ip
        }
        self.default_device = ReplicationDevice(default_device_conf, driver)
        if not self.is_service_failed_over:
            # If service doesn't fail over, setup the adapter.
            # Otherwise, the primary backend could be down, adapter setup could
            # fail.
            self.default_device.setup_adapter()

        if self.is_replication_configured:
            # If replication_device is configured, consider the replication is
            # enabled and check the same configuration is valid for secondary
            # backend or not.
            self.setup_rep_adapters()
示例#6
0
文件: tsm.py 项目: lubidl0/cinder-1
 def check_for_setup_error(self):
     required_flags = ['backup_share']
     for flag in required_flags:
         val = getattr(CONF, flag, None)
         if not val:
             raise exception.InvalidConfigurationValue(option=flag,
                                                       value=val)
示例#7
0
def get_pool_name_filter_regex(configuration):
    """Build the regex for filtering pools by name

    :param configuration: The volume driver configuration
    :raise InvalidConfigurationValue: if configured regex pattern is invalid
    :returns: A compiled regex for filtering pool names
    """

    # If the configuration parameter is specified as an empty string
    # (interpreted as matching all pools), we replace it here with
    # (.+) to be explicit with CSV compatibility support implemented below.
    pool_patterns = configuration.netapp_pool_name_search_pattern or r'(.+)'

    # Strip whitespace from start/end and then 'or' all regex patterns
    pool_patterns = '|'.join([
        '^' + pool_pattern.strip('^$ \t') + '$'
        for pool_pattern in pool_patterns.split(',')
    ])

    try:
        return re.compile(pool_patterns)
    except re.error:
        raise exception.InvalidConfigurationValue(
            option='netapp_pool_name_search_pattern',
            value=configuration.netapp_pool_name_search_pattern)
    def check_for_setup_error(self):
        if self.proxy.session_id is None:
            msg = _('FSS cinder volume driver not ready: Unable to determine '
                    'session id.')
            raise exception.VolumeBackendAPIException(data=msg)

        if self.configuration.fss_pool:
            self.configuration.fss_pools = {
                'A': six.text_type(self.configuration.fss_pool)
            }
            # The fss_pool is deprecated.
            LOG.warning("'fss_pool=<pool-id>' is deprecated. Using the "
                        "fss_pools=A:<pool-id> for single pool or "
                        "fss_pools=P:<pool-id>,O:<other-pool-id> instead "
                        "as old format will be removed once Queens development"
                        " opens up.")

        if not self.configuration.fss_pools:
            msg = _('Pool is not available in the cinder configuration '
                    'fields.')
            raise exception.InvalidHost(reason=msg)
        self._pool_checking(self.configuration.fss_pools)

        if self.configuration.san_thin_provision:
            if not self.configuration.max_over_subscription_ratio:
                msg = _('The max_over_subscription_ratio have to set '
                        'when thin provisioning enabled.')
                raise exception.InvalidConfigurationValue(reason=msg)
示例#9
0
文件: utils.py 项目: neilqing/cinder
def clear_volume(volume_size, volume_path, volume_clear=None,
                 volume_clear_size=None, volume_clear_ionice=None,
                 throttle=None):
    """Unprovision old volumes to prevent data leaking between users."""
    if volume_clear is None:
        volume_clear = CONF.volume_clear

    if volume_clear_size is None:
        volume_clear_size = CONF.volume_clear_size

    if volume_clear_size == 0:
        volume_clear_size = volume_size

    if volume_clear_ionice is None:
        volume_clear_ionice = CONF.volume_clear_ionice

    LOG.info("Performing secure delete on volume: %s", volume_path)

    # We pass sparse=False explicitly here so that zero blocks are not
    # skipped in order to clear the volume.
    if volume_clear == 'zero':
        return copy_volume('/dev/zero', volume_path, volume_clear_size,
                           CONF.volume_dd_blocksize,
                           sync=True, execute=utils.execute,
                           ionice=volume_clear_ionice,
                           throttle=throttle, sparse=False)
    else:
        raise exception.InvalidConfigurationValue(
            option='volume_clear',
            value=volume_clear)
示例#10
0
def clear_volume(volume_size, volume_path, volume_clear=None,
                 volume_clear_size=None, volume_clear_ionice=None,
                 throttle=None):
    """Unprovision old volumes to prevent data leaking between users."""
    if volume_clear is None:
        volume_clear = CONF.volume_clear

    if volume_clear_size is None:
        volume_clear_size = CONF.volume_clear_size

    if volume_clear_size == 0:
        volume_clear_size = volume_size

    if volume_clear_ionice is None:
        volume_clear_ionice = CONF.volume_clear_ionice

    LOG.info(_LI("Performing secure delete on volume: %s"), volume_path)

    if volume_clear == 'shred':
        LOG.warning(_LW("volume_clear=shred has been deprecated and will "
                        "be removed in the next release. Clearing with dd."))
        volume_clear = 'zero'

    # We pass sparse=False explicitly here so that zero blocks are not
    # skipped in order to clear the volume.
    if volume_clear == 'zero':
        return copy_volume('/dev/zero', volume_path, volume_clear_size,
                           CONF.volume_dd_blocksize,
                           sync=True, execute=utils.execute,
                           ionice=volume_clear_ionice,
                           throttle=throttle, sparse=False)
    else:
        raise exception.InvalidConfigurationValue(
            option='volume_clear',
            value=volume_clear)
示例#11
0
文件: tintri.py 项目: zhu1fei/cinder
 def _check_ops(self, required_ops, configuration):
     """Ensures that the options we care about are set."""
     for op in required_ops:
         if not getattr(configuration, op):
             LOG.error('Configuration value %s is not set.', op)
             raise exception.InvalidConfigurationValue(option=op,
                                                       value=None)
示例#12
0
    def __init__(self, config):
        """:param config: list of config values."""

        self.proto = 'http'
        if config.get('driver_use_ssl', True):
            self.proto = 'https'

        self.hosts = config.get('san_hosts', [])
        self.port = str(config.get('san_api_port', 82))

        for host in self.hosts:
            if o_netutils.is_valid_ip(host) is False:
                err_msg = ('Invalid value of jovian_host property: '
                           '%(addr)s, IP address expected.' % {
                               'addr': host
                           })

                LOG.debug(err_msg)
                raise exception.InvalidConfigurationValue(err_msg)

        self.active_host = 0

        self.delay = config.get('jovian_recovery_delay', 40)

        self.pool = config.get('jovian_pool', 'Pool-0')

        self.user = config.get('san_login', 'admin')
        self.password = config.get('san_password', 'admin')
        self.verify = config.get('driver_ssl_cert_verify', True)
        self.cert = config.get('driver_ssl_cert_path')

        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

        self.session = self._get_session()
示例#13
0
    def __init__(self,
                 context,
                 chunk_size_bytes,
                 sha_block_size_bytes,
                 backup_default_container,
                 enable_progress_timer,
                 db=None):
        super(ChunkedBackupDriver, self).__init__(context, db)
        self.chunk_size_bytes = chunk_size_bytes
        self.sha_block_size_bytes = sha_block_size_bytes
        self.backup_default_container = backup_default_container
        self.enable_progress_timer = enable_progress_timer

        self.backup_timer_interval = CONF.backup_timer_interval
        self.data_block_num = CONF.backup_object_number_per_notification
        self.az = CONF.storage_availability_zone
        self.backup_compression_algorithm = CONF.backup_compression_algorithm
        self.compressor = \
            self._get_compressor(CONF.backup_compression_algorithm)
        self.support_force_delete = True

        if sys.platform == 'win32' and self.chunk_size_bytes % 4096:
            # The chunk size must be a multiple of the sector size. In order
            # to fail out early and avoid attaching the disks, we'll just
            # enforce the chunk size to be a multiple of 4096.
            err = _("Invalid chunk size. It must be a multiple of 4096.")
            raise exception.InvalidConfigurationValue(message=err)
示例#14
0
    def __init__(self, name, loader=None):
        """Initialize, but do not start the WSGI server.

        :param name: The name of the WSGI server given to the loader.
        :param loader: Loads the WSGI application using the given name.
        :returns: None

        """
        self.name = name
        self.manager = self._get_manager()
        self.loader = loader or wsgi.Loader(CONF)
        self.app = self.loader.load_app(name)
        self.host = getattr(CONF, '%s_listen' % name, "0.0.0.0")
        self.port = getattr(CONF, '%s_listen_port' % name, 0)
        self.use_ssl = getattr(CONF, '%s_use_ssl' % name, False)
        self.workers = (getattr(CONF, '%s_workers' % name, None)
                        or processutils.get_worker_count())
        if self.workers and self.workers < 1:
            worker_name = '%s_workers' % name
            msg = (_("%(worker_name)s value of %(workers)d is invalid, "
                     "must be greater than 0.") % {
                         'worker_name': worker_name,
                         'workers': self.workers
                     })
            raise exception.InvalidConfigurationValue(msg)
        setup_profiler(name, self.host)

        self.server = wsgi.Server(CONF,
                                  name,
                                  self.app,
                                  host=self.host,
                                  port=self.port,
                                  use_ssl=self.use_ssl)
示例#15
0
    def _get_pool_lun_provisioned_size(self):
        pool_name = self.config.synology_pool_name
        if not pool_name:
            raise exception.InvalidConfigurationValue(option='pool_name',
                                                      value=pool_name)
        try:
            out = self.exec_webapi('SYNO.Core.ISCSI.LUN',
                                   'list',
                                   1,
                                   location='/' + pool_name)

            self.check_response(out)
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.exception('Failed to _get_pool_lun_provisioned_size.')

        if not self.check_value_valid(out, ['data', 'luns'], list):
            raise exception.MalformedResponse(
                cmd='_get_pool_lun_provisioned_size',
                reason=_('no data found'))

        size = 0
        for lun in out['data']['luns']:
            size += lun['size']

        return int(math.ceil(float(size) / units.Gi))
示例#16
0
def remove_empty(option, value_list):
    if value_list is not None:
        value_list = list(filter(None, map(str.strip, value_list)))
        if not value_list:
            raise exception.InvalidConfigurationValue(option=option,
                                                      value=value_list)
    return value_list
示例#17
0
 def check_for_setup_error(self):
     required_options = ('backup_gcs_bucket', 'backup_gcs_credential_file',
                         'backup_gcs_project_id')
     for opt in required_options:
         val = getattr(CONF, opt, None)
         if not val:
             raise exception.InvalidConfigurationValue(option=opt,
                                                       value=val)
示例#18
0
    def do_setup(self, context):
        """Any initialization the volume driver does while starting."""
        super(NfsDriver, self).do_setup(context)

        config = self.configuration.nfs_shares_config
        if not config:
            msg = (_("There's no NFS config file configured (%s)") %
                   'nfs_shares_config')
            LOG.warning(msg)
            raise exception.NfsException(msg)
        if not os.path.exists(config):
            msg = (_("NFS config file at %(config)s doesn't exist") %
                   {'config': config})
            LOG.warning(msg)
            raise exception.NfsException(msg)
        if not self.configuration.nfs_oversub_ratio > 0:
            msg = _("NFS config 'nfs_oversub_ratio' invalid.  Must be > 0: "
                    "%s") % self.configuration.nfs_oversub_ratio

            LOG.error(msg)
            raise exception.InvalidConfigurationValue(msg)
        if not ((self.configuration.nfs_used_ratio > 0) and
                (self.configuration.nfs_used_ratio <= 1)):
            msg = _("NFS config 'nfs_used_ratio' invalid.  Must be > 0 "
                    "and <= 1.0: %s") % self.configuration.nfs_used_ratio
            LOG.error(msg)
            raise exception.InvalidConfigurationValue(msg)

        self.shares = {}  # address : options

        # Check if mount.nfs is installed on this system; note that we don't
        # need to be root to see if the package is installed.
        package = 'mount.nfs'
        try:
            self._execute(package, check_exit_code=False,
                          run_as_root=False)
        except OSError as exc:
            if exc.errno == errno.ENOENT:
                msg = _('%s is not installed') % package
                raise exception.NfsException(msg)
            else:
                raise

        # Now that all configuration data has been loaded (shares),
        # we can "set" our final NAS file security options.
        self.set_nas_security_options(self._is_voldb_empty_at_startup)
示例#19
0
 def check_for_setup_error(self):
     """Raises error if any required configuration flag is missing."""
     required_flags = ['glusterfs_backup_share']
     for flag in required_flags:
         val = getattr(CONF, flag, None)
         if not val:
             raise exception.InvalidConfigurationValue(option=flag,
                                                       value=val)
示例#20
0
def setup_api_trace_pattern(api_trace_pattern):
    global API_TRACE_PATTERN
    try:
        re.compile(api_trace_pattern)
    except (re.error, TypeError):
        msg = _('Cannot parse the API trace pattern. %s is not a '
                'valid python regular expression.') % api_trace_pattern
        raise exception.InvalidConfigurationValue(msg)
    API_TRACE_PATTERN = api_trace_pattern
示例#21
0
    def _get_iscsi_properties(self, volume, connector):
        """Return dict according to cinder/driver.py implementation.

        :param volume:
        :return:
        """
        vname = volume["id"]

        zvol_info = self.ra.get_zvol_info(self.pool, vname)
        if zvol_info is None:
            LOG.debug('JovianDSS: Unable to get zvol lun for'
                      ' volume %s.', vname)

            raise exception.VolumeBackendAPIException(
                'JovianDSS: Unable to get'
                ' zvolume lun for volume %s.', vname)

        iface_info = []
        multipath = connector.get('multipath', False)
        if multipath is True:
            iface_info = self._get_active_ifaces()
            if not iface_info:
                raise exception.InvalidConfigurationValue(
                    'JovianDSS: No available interfaces '
                    'or config excludes them')

        iscsi_properties = dict()

        if multipath:
            iscsi_properties['target_iqns'] = []
            iscsi_properties['target_portals'] = []
            iscsi_properties['target_luns'] = []
            LOG.debug('JovianDSS: tpaths %s.', str(iface_info))
            for iface in iface_info:
                iscsi_properties['target_iqns'].append(
                    self.jovian_target_prefix + vname)
                iscsi_properties['target_portals'].append(
                    iface + ":" + self.jovian_iscsi_target_portal_port)
                iscsi_properties['target_luns'].append(int(zvol_info["lun"]))
        else:
            iscsi_properties['target_iqn'] = self.jovian_target_prefix + vname
            iscsi_properties['target_portal'] = \
                self.jovian_host + ":" + self.jovian_iscsi_target_portal_port

        iscsi_properties['target_discovered'] = False

        auth = volume['provider_auth']
        if auth:
            (auth_method, auth_username, auth_secret) = auth.split()

            iscsi_properties['auth_method'] = auth_method
            iscsi_properties['auth_username'] = auth_username
            iscsi_properties['auth_password'] = auth_secret

        iscsi_properties['target_lun'] = int(zvol_info["lun"])
        return iscsi_properties
示例#22
0
    def check_io_parameter(self, specs):
        if ('upperlimit' not in specs and 'lowerlimit' not in specs
                and 'upperreport' not in specs):
            specs['upperlimit'] = None
            specs['lowerlimit'] = None
            specs['upperreport'] = None
            LOG.debug('qos parameter not found.')
        else:
            if 'upperlimit' in specs and specs['upperlimit'] is not None:
                if self.validates_number(specs['upperlimit']) is True:
                    upper_limit = int(specs['upperlimit'], 10)
                    if ((upper_limit != 0) and ((upper_limit < 10) or
                                                (upper_limit > 1000000))):
                        raise exception.InvalidConfigurationValue(
                            value=upper_limit, option='upperlimit')
                else:
                    raise exception.InvalidConfigurationValue(
                        value=specs['upperlimit'], option='upperlimit')
            else:
                specs['upperlimit'] = None

            if 'lowerlimit' in specs and specs['lowerlimit'] is not None:
                if self.validates_number(specs['lowerlimit']) is True:
                    lower_limit = int(specs['lowerlimit'], 10)
                    if (lower_limit != 0
                            and (lower_limit < 10 or lower_limit > 1000000)):
                        raise exception.InvalidConfigurationValue(
                            value=lower_limit, option='lowerlimit')
                else:
                    raise exception.InvalidConfigurationValue(
                        value=specs['lowerlimit'], option='lowerlimit')
            else:
                specs['lowerlimit'] = None

            if 'upperreport' in specs:
                if specs['upperreport'] not in ['on', 'off']:
                    LOG.debug(
                        'Illegal arguments. '
                        'upperreport is not on or off.'
                        'upperreport=%s', specs['upperreport'])
                    specs['upperreport'] = None
            else:
                specs['upperreport'] = None
示例#23
0
    def correct_qos_parameter(self, specs, reset):
        if 'upperlimit' in specs and specs['upperlimit'] is not None:
            if self.validates_number(specs['upperlimit']) is True:
                upper_limit = int(specs['upperlimit'], 10)
                if ((upper_limit != 0)
                        and ((upper_limit < 10) or (upper_limit > 1000000))):
                    raise exception.InvalidConfigurationValue(
                        value=upper_limit, option='upperlimit')
            else:
                raise exception.InvalidConfigurationValue(
                    value=specs['upperlimit'], option='upperlimit')
        else:
            # 0: Set to no limit.(default)
            # None: Keep current value.
            specs['upperlimit'] = '0' if reset else None

        if 'lowerlimit' in specs and specs['lowerlimit'] is not None:
            if self.validates_number(specs['lowerlimit']) is True:
                lower_limit = int(specs['lowerlimit'], 10)
                if (lower_limit != 0
                        and (lower_limit < 10 or lower_limit > 1000000)):
                    raise exception.InvalidConfigurationValue(
                        value=lower_limit, option='lowerlimit')
            else:
                raise exception.InvalidConfigurationValue(
                    value=specs['lowerlimit'], option='lowerlimit')
        else:
            # 0: Set to no limit.(default)
            # None: Keep current value.
            specs['lowerlimit'] = '0' if reset else None

        if 'upperreport' in specs:
            if specs['upperreport'] not in ['on', 'off']:
                LOG.debug(
                    'Illegal arguments. '
                    'upperreport is not on or off.'
                    'upperreport=%s', specs['upperreport'])
                specs['upperreport'] = 'off' if reset else None
        else:
            # off: Set to no report.(default)
            # None: Keep current value.
            specs['upperreport'] = 'off' if reset else None
示例#24
0
文件: tsm.py 项目: xin3liang/cinder
 def check_for_setup_error(self):
     versionutils.report_deprecated_feature(
         LOG, "Cinder TSM Backup Driver is deprecated and will be removed "
         "in Wallaby release. Please, migrate you backups to a supported "
         "backend.")
     required_flags = ['backup_share']
     for flag in required_flags:
         val = getattr(CONF, flag, None)
         if not val:
             raise exception.InvalidConfigurationValue(option=flag,
                                                       value=val)
示例#25
0
    def clear_volume(self, volume, is_snapshot=False):
        """unprovision old volumes to prevent data leaking between users."""

        # NOTE(jdg): Don't write the blocks of thin provisioned
        # volumes
        if self.configuration.volume_clear == 'none' or \
                self.configuration.lvm_type == 'thin':
            return

        if is_snapshot:
            # if the volume to be cleared is a snapshot of another volume
            # we need to clear out the volume using the -cow instead of the
            # directly volume path.  We need to skip this if we are using
            # thin provisioned LVs.
            # bug# lp1191812
            dev_path = self.local_path(volume) + "-cow"
        else:
            dev_path = self.local_path(volume)

        if not os.path.exists(dev_path):
            msg = (_('Volume device file path %s does not exist.') % dev_path)
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        size_in_g = volume.get('size', volume.get('volume_size', None))
        if size_in_g is None:
            msg = (_("Size for volume: %s not found, "
                     "cannot secure delete.") % volume['id'])
            LOG.error(msg)
            raise exception.InvalidParameterValue(msg)
        size_in_m = self.configuration.volume_clear_size

        LOG.info(_("Performing secure delete on volume: %s") % volume['id'])

        if self.configuration.volume_clear == 'zero':
            if size_in_m == 0:
                return volutils.copy_volume('/dev/zero',
                                            dev_path,
                                            size_in_g * 1024,
                                            sync=True,
                                            execute=self._execute)
            else:
                clear_cmd = ['shred', '-n0', '-z', '-s%dMiB' % size_in_m]
        elif self.configuration.volume_clear == 'shred':
            clear_cmd = ['shred', '-n3']
            if size_in_m:
                clear_cmd.append('-s%dMiB' % size_in_m)
        else:
            raise exception.InvalidConfigurationValue(
                option='volume_clear', value=self.configuration.volume_clear)

        clear_cmd.append(dev_path)
        self._execute(*clear_cmd, run_as_root=True)
示例#26
0
    def _get_iscsi_properties(self, volume, connector):
        """Return dict according to cinder/driver.py implementation.

        :param volume:
        :return:
        """
        tname = self.jovian_target_prefix + volume.id
        iface_info = []
        multipath = connector.get('multipath', False)
        if multipath:
            iface_info = self._get_active_ifaces()
            if not iface_info:
                raise exception.InvalidConfigurationValue(
                    _('No available interfaces '
                      'or config excludes them'))

        iscsi_properties = dict()

        if multipath:
            iscsi_properties['target_iqns'] = []
            iscsi_properties['target_portals'] = []
            iscsi_properties['target_luns'] = []
            LOG.debug('tpaths %s.', iface_info)
            for iface in iface_info:
                iscsi_properties['target_iqns'].append(
                    self.jovian_target_prefix +
                    volume.id)
                iscsi_properties['target_portals'].append(
                    iface +
                    ":" +
                    str(self.jovian_iscsi_target_portal_port))
                iscsi_properties['target_luns'].append(0)
        else:
            iscsi_properties['target_iqn'] = tname
            iscsi_properties['target_portal'] = (
                self.ra.get_active_host() +
                ":" +
                str(self.jovian_iscsi_target_portal_port))

        iscsi_properties['target_discovered'] = False

        auth = volume.provider_auth
        if auth:
            (auth_method, auth_username, auth_secret) = auth.split()

            iscsi_properties['auth_method'] = auth_method
            iscsi_properties['auth_username'] = auth_username
            iscsi_properties['auth_password'] = auth_secret

        iscsi_properties['target_lun'] = 0
        return iscsi_properties
示例#27
0
def clear_volume(volume_size,
                 volume_path,
                 volume_clear=None,
                 volume_clear_size=None,
                 volume_clear_ionice=None,
                 throttle=None):
    """Unprovision old volumes to prevent data leaking between users."""
    if volume_clear is None:
        volume_clear = CONF.volume_clear

    if volume_clear_size is None:
        volume_clear_size = CONF.volume_clear_size

    if volume_clear_size == 0:
        volume_clear_size = volume_size

    if volume_clear_ionice is None:
        volume_clear_ionice = CONF.volume_clear_ionice

    LOG.info(_LI("Performing secure delete on volume: %s"), volume_path)

    # We pass sparse=False explicitly here so that zero blocks are not
    # skipped in order to clear the volume.
    if volume_clear == 'zero':
        return copy_volume('/dev/zero',
                           volume_path,
                           volume_clear_size,
                           CONF.volume_dd_blocksize,
                           sync=True,
                           execute=utils.execute,
                           ionice=volume_clear_ionice,
                           throttle=throttle,
                           sparse=False)
    elif volume_clear == 'shred':
        clear_cmd = ['shred', '-n3']
        if volume_clear_size:
            clear_cmd.append('-s%dMiB' % volume_clear_size)
    else:
        raise exception.InvalidConfigurationValue(option='volume_clear',
                                                  value=volume_clear)

    clear_cmd.append(volume_path)
    start_time = timeutils.utcnow()
    utils.execute(*clear_cmd, run_as_root=True)
    duration = timeutils.delta_seconds(start_time, timeutils.utcnow())

    # NOTE(jdg): use a default of 1, mostly for unit test, but in
    # some incredible event this is 0 (cirros image?) don't barf
    if duration < 1:
        duration = 1
    LOG.info(_LI('Elapsed time for clear volume: %.2f sec'), duration)
示例#28
0
    def test_init_host_retry(self, mock_sleep):
        kwargs = {'service_id': 2}
        self.volume = importutils.import_object(CONF.volume_manager)
        self.volume.driver.do_setup = mock.MagicMock()
        self.volume.driver.do_setup.side_effect = [
            exception.CinderException("Test driver error."),
            exception.InvalidConfigurationValue('Test config error.'),
            ImportError
        ]

        self.volume.init_host(added_to_cluster=False, **kwargs)

        self.assertEqual(4, self.volume.driver.do_setup.call_count)
        self.assertFalse(self.volume.is_working())
示例#29
0
    def check_for_setup_error(self):
        """Return an error if prerequisites aren't met."""
        super(RBDISCSIDriver, self).check_for_setup_error()

        required_options = [
            'rbd_iscsi_api_user', 'rbd_iscsi_api_password',
            'rbd_iscsi_api_url', 'rbd_iscsi_target_iqn'
        ]

        for attr in required_options:
            val = getattr(self.configuration, attr)
            if not val:
                raise exception.InvalidConfigurationValue(option=attr,
                                                          value=val)
示例#30
0
文件: iscsi.py 项目: openstack/cinder
    def check_for_setup_error(self):
        """Check for setup error."""
        if len(self.jovian_hosts) == 0:
            msg = _("No hosts provided in configuration")
            raise exception.VolumeDriverException(msg)

        if not self.ra.is_pool_exists():
            msg = (_("Unable to identify pool %s") % self._pool)
            raise exception.VolumeDriverException(msg)

        valid_bsize = ['16K', '32K', '64K', '128K', '256K', '512K', '1M']
        if self.block_size not in valid_bsize:
            raise exception.InvalidConfigurationValue(
                value=self.block_size, option='jovian_block_size')