def _create_from_existing_volume(self, docker_volume_name, cinder_volume_id, volume_opts): try: cinder_volume = self.cinderclient.volumes.get(cinder_volume_id) except cinder_exception.ClientException as e: msg = _LE("Failed to get volume %(vol_id)s from Cinder. " "Error: %(err)s") LOG.error(msg, {'vol_id': cinder_volume_id, 'err': e}) raise status = cinder_volume.status if status not in ('available', 'in-use'): LOG.error( _LE("Current volume %(vol)s status %(status)s not in " "desired states"), { 'vol': cinder_volume, 'status': status }) raise exceptions.NotMatchedState('Cinder volume is unavailable') elif status == 'in-use' and not cinder_volume.multiattach: if not self._check_attached_to_this(cinder_volume): msg = _LE("Current volume %(vol)s status %(status)s not " "in desired states") LOG.error(msg, {'vol': cinder_volume, 'status': status}) raise exceptions.NotMatchedState( 'Cinder volume is unavailable') if cinder_volume.name != docker_volume_name: LOG.error( _LE("Provided volume name %(d_name)s does not match " "with existing Cinder volume name %(c_name)s"), { 'd_name': docker_volume_name, 'c_name': cinder_volume.name }) raise exceptions.InvalidInput('Volume name does not match') fstype = volume_opts.pop('fstype', cinder_conf.fstype) vol_fstype = cinder_volume.metadata.get('fstype', cinder_conf.fstype) if fstype != vol_fstype: LOG.error( _LE("Volume already exists with fstype %(c_fstype)s, " "but currently provided fstype is %(fstype)s, not " "match"), { 'c_fstype': vol_fstype, 'fstype': fstype }) raise exceptions.InvalidInput('FSType does not match') try: metadata = {consts.VOLUME_FROM: CONF.volume_from, 'fstype': fstype} self.cinderclient.volumes.set_metadata(cinder_volume, metadata) except cinder_exception.ClientException as e: LOG.error( _LE("Failed to update volume %(vol)s information. " "Error: %(err)s"), { 'vol': cinder_volume_id, 'err': e }) raise return cinder_volume
def _create_from_existing_share(self, docker_volume_name, share_id, share_opts): try: share = self.manilaclient.shares.get(share_id) except manila_exception.NotFound: LOG.error("Could not find share %s", share_id) raise if share.status != 'available': raise exceptions.UnexpectedStateException( "Manila share is unavailable") if share.name != docker_volume_name: LOG.error( "Provided volume name %(d_name)s does not match " "with existing share name %(s_name)s", { 'd_name': docker_volume_name, 's_name': share.name }) raise exceptions.InvalidInput('Volume name does not match') metadata = {consts.VOLUME_FROM: CONF.volume_from} self.manilaclient.shares.update_all_metadata(share, metadata) return share
def volumedriver_create(): json_data = flask.request.get_json(force=True) LOG.info("Received JSON data %s for /VolumeDriver.Create", json_data) docker_volume_name = json_data.get('Name', None) volume_opts = json_data.get('Opts', None) or {} if not docker_volume_name: msg = _("Request /VolumeDriver.Create need parameter 'Name'") LOG.error(msg) raise exceptions.InvalidInput(msg) if not isinstance(volume_opts, dict): msg = _("Request parameter 'Opts' must be dict type") LOG.error(msg) raise exceptions.InvalidInput(msg) volume_provider_type = volume_opts.get('volume_provider', None) if not volume_provider_type: volume_provider_type = list(app.volume_providers.keys())[0] if volume_provider_type not in app.volume_providers: msg_fmt = _("Could not find a handler for %(volume_provider_type)s " "volume") % { 'volume_provider_type': volume_provider_type } LOG.error(msg_fmt) return flask.jsonify(Err=msg_fmt) # If the volume with the same name already exists in other volume # provider backend, then raise an error for vpt, provider in app.volume_providers.items(): if volume_provider_type != vpt \ and provider.check_exist(docker_volume_name): msg_fmt = _("The volume with the same name already exists in " "other volume provider backend") LOG.error(msg_fmt) return flask.jsonify(Err=msg_fmt) # Create if volume does not exist, or attach to this server if needed # volume exists in related volume provider. app.volume_providers[volume_provider_type].create(docker_volume_name, volume_opts) return flask.jsonify(Err=u'')
def __init__(self): super(Manila, self).__init__() self.manilaclient = utils.get_manilaclient() conn_conf = manila_conf.volume_connector if not conn_conf or conn_conf not in volume_connector_conf: msg = _("Must provide a valid volume connector") LOG.error(msg) raise exceptions.InvalidInput(msg) self.connector = importutils.import_object( volume_connector_conf[conn_conf], manilaclient=self.manilaclient)
def get_cinder_volume_kwargs(docker_volume_name, docker_volume_opt): """Retrieve parameters for creating Cinder volume. Retrieve required parameters and remove unsupported arguments from client input. These parameters are used to create a Cinder volume. :param docker_volume_name: Name for Cinder volume :type docker_volume_name: str :param docker_volume_opt: Optional parameters for Cinder volume :type docker_volume_opt: dict :rtype: dict """ options = [ 'size', 'consistencygroup_id', 'snapshot_id', 'source_volid', 'description', 'volume_type', 'user_id', 'project_id', 'availability_zone', 'scheduler_hints', 'source_replica', 'multiattach' ] kwargs = {} if 'size' in docker_volume_opt: try: size = int(docker_volume_opt.pop('size')) except ValueError: msg = _LE("Volume size must be able to convert to int type") LOG.error(msg) raise exceptions.InvalidInput(msg) else: size = CONF.default_volume_size LOG.info( _LI("Volume size doesn't provide from command, so use" " default size %sG"), size) kwargs['size'] = size for key, value in docker_volume_opt.items(): if key in options: kwargs[key] = value if not kwargs.get('availability_zone', None): kwargs['availability_zone'] = cinder_conf.availability_zone if not kwargs.get('volume_type', None): kwargs['volume_type'] = cinder_conf.volume_type kwargs['name'] = docker_volume_name kwargs['metadata'] = { consts.VOLUME_FROM: CONF.volume_from, 'fstype': kwargs.pop('fstype', cinder_conf.fstype) } req_multiattach = kwargs.pop('multiattach', cinder_conf.multiattach) kwargs['multiattach'] = strutils.bool_from_string(req_multiattach, strict=True) return kwargs
def volumedriver_remove(): json_data = flask.request.get_json(force=True) LOG.info("Received JSON data %s for /VolumeDriver.Remove", json_data) docker_volume_name = json_data.get('Name', None) if not docker_volume_name: msg = _("Request /VolumeDriver.Remove need parameter 'Name'") LOG.error(msg) raise exceptions.InvalidInput(msg) for provider in app.volume_providers.values(): if provider.delete(docker_volume_name): return flask.jsonify(Err=u'') return flask.jsonify(Err=u'')
def volumedriver_mount(): json_data = flask.request.get_json(force=True) LOG.info("Receive JSON data %s for /VolumeDriver.Mount", json_data) docker_volume_name = json_data.get('Name', None) if not docker_volume_name: msg = _("Request /VolumeDriver.Mount need parameter 'Name'") LOG.error(msg) raise exceptions.InvalidInput(msg) for provider in app.volume_providers.values(): if provider.check_exist(docker_volume_name): mountpoint = provider.mount(docker_volume_name) return flask.jsonify(Mountpoint=mountpoint, Err=u'') return flask.jsonify(Err=u'Mount Failed')
def volumedriver_get(): json_data = flask.request.get_json(force=True) LOG.info("Receive JSON data %s for /VolumeDriver.Get", json_data) docker_volume_name = json_data.get('Name', None) if not docker_volume_name: msg = _("Request /VolumeDriver.Get need parameter 'Name'") LOG.error(msg) raise exceptions.InvalidInput(msg) volume = get_docker_volume(docker_volume_name) if volume is not None: LOG.info("Get docker volume: %s", volume) return flask.jsonify(Volume=volume, Err=u'') LOG.warning("Can't find volume %s from every provider", docker_volume_name) return flask.jsonify(Err=u'Volume Not Found')
def extract_share_kwargs(docker_volume_name, docker_volume_opts): """Extract parameters for creating manila share. Retrieve required parameters and remove unsupported arguments from client input. These parameters are used to create a Cinder volume. :param docker_volume_name: Name for Manila share. :param docker_volume_opts: Optional parameters for Manila share. :rtype: dict """ options = [ 'share_proto', 'size', 'snapshot_id', 'description', 'share_network', 'share_type', 'is_public', 'availability_zone', 'consistency_group_id' ] kwargs = {} if 'size' in docker_volume_opts: try: size = int(docker_volume_opts.pop('size')) except ValueError: msg = _("Volume size must able to convert to int type") LOG.error(msg) raise exceptions.InvalidInput(msg) else: size = CONF.default_volume_size LOG.info( "Volume size doesn't provide from command, so use " "default size %sG", size) kwargs['size'] = size share_proto = docker_volume_opts.pop('share_proto', None) \ or manila_conf.share_proto kwargs['share_proto'] = share_proto for key, value in docker_volume_opts.items(): if key in options: kwargs[key] = value kwargs['name'] = docker_volume_name kwargs['metadata'] = {consts.VOLUME_FROM: CONF.volume_from} return kwargs
def volumedriver_get(): json_data = flask.request.get_json(force=True) app.logger.info(_LI("Receive JSON data {0} for " "/VolumeDriver.Get").format(json_data)) docker_volume_name = json_data.get('Name', None) if not docker_volume_name: msg = _("Request /VolumeDriver.Get need parameter 'Name'") app.logger.error(msg) raise exceptions.InvalidInput(msg) volume = get_docker_volume(docker_volume_name) if volume is not None: msg_fmt = _LI("Get docker volume: {0}").format(volume) app.logger.info(msg_fmt) return flask.jsonify(Volume=volume, Err=u'') app.logger.warn(_LW("Can't find volume {0} from every " "provider").format(docker_volume_name)) return flask.jsonify(Err=u'Volume Not Found')
def volumedriver_path(): json_data = flask.request.get_json(force=True) app.logger.info(_LI("Receive JSON data {0} for " "/VolumeDriver.Path").format(json_data)) docker_volume_name = json_data.get('Name', None) if not docker_volume_name: msg = _("Request /VolumeDriver.Path need parameter 'Name'") app.logger.error(msg) raise exceptions.InvalidInput(msg) volume = get_docker_volume(docker_volume_name) if volume is not None: mountpoint = volume.get('Mountpoint', '') app.logger.info("Get mountpoint %(mp)s for docker volume %(name)s" % {'mp': mountpoint, 'name': docker_volume_name}) return flask.jsonify(Mountpoint=mountpoint, Err=u'') app.logger.warn(_LW("Can't find mountpoint for docker volume " "%(name)s") % {'name': docker_volume_name}) return flask.jsonify(Err=u'Mountpoint Not Found')
def volumedriver_path(): json_data = flask.request.get_json(force=True) LOG.info("Receive JSON data %s for /VolumeDriver.Path", json_data) docker_volume_name = json_data.get('Name', None) if not docker_volume_name: msg = _("Request /VolumeDriver.Path need parameter 'Name'") LOG.error(msg) raise exceptions.InvalidInput(msg) volume = get_docker_volume(docker_volume_name) if volume is not None: mountpoint = volume.get('Mountpoint', '') LOG.info("Get mountpoint %(mp)s for docker volume %(name)s", { 'mp': mountpoint, 'name': docker_volume_name }) return flask.jsonify(Mountpoint=mountpoint, Err=u'') LOG.warning("Can't find mountpoint for docker volume %(name)s", {'name': docker_volume_name}) return flask.jsonify(Err=u'Mountpoint Not Found')