def get_target_info(self, volume): LOG.debug("Searching first iscsi port ip without wan in K2.") iscsi_ip_rs = self.client.search("system/net_ips") iscsi_portals = target_iqns = None if hasattr(iscsi_ip_rs, 'hits') and iscsi_ip_rs.total != 0: iscsi_portals = [ '%s:%s' % (ip.ip_address, ISCSI_TCP_PORT) for ip in iscsi_ip_rs.hits if not ip.wan_port ] if not iscsi_portals: msg = _("Unable to get ISCSI IP address from K2.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) LOG.debug("Searching system state for target iqn in K2.") sys_state_rs = self.client.search("system/state") if hasattr(sys_state_rs, 'hits') and sys_state_rs.total != 0: iqn = sys_state_rs.hits[0].iscsi_qualified_target_name target_iqns = [iqn] * len(iscsi_portals) if not target_iqns: msg = _("Unable to get target iqn from K2.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) return iscsi_portals, target_iqns
def check_for_setup_error(self): if krest is None: msg = _("Unable to import 'krest' python module.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) else: conf = self.configuration self.client = KrestWrap(conf.san_ip, conf.san_login, conf.san_password, ssl_validate=False) if self.replica: self.target = KrestWrap(self.replica.backend_id, self.replica.login, self.replica.password, ssl_validate=False) v_rs = self.client.search("system/state") if hasattr(v_rs, 'hits') and v_rs.total != 0: ver = v_rs.hits[0].rest_api_version ver_exist = versionutils.convert_version_to_int(ver) ver_min = versionutils.convert_version_to_int(K2_MIN_VERSION) if ver_exist < ver_min: msg = _("K2 REST API version should be " ">= %s.") % K2_MIN_VERSION LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) else: msg = _("K2 REST API version search failed.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg)
def create_volume_from_snapshot(self, volume, snapshot): """Create volume from snapshot. - search for snapshot and retention_policy - create a view from snapshot and attach view - create a volume and attach volume - copy data from attached view to attached volume - detach volume and view and finally delete view """ snap_name = self.get_snap_name(snapshot.id) view_name = self.get_view_name(volume.id) vol_name = self.get_volume_name(volume.id) cview = src_attach_info = dest_attach_info = None rpolicy = self.get_policy() properties = utils.brick_get_connector_properties() LOG.debug("Searching for snapshot: %s in K2.", snap_name) snap_rs = self.client.search("snapshots", short_name=snap_name) if hasattr(snap_rs, 'hits') and snap_rs.total != 0: snap = snap_rs.hits[0] LOG.debug("Creating a view: %(view)s from snapshot: %(snap)s", {'view': view_name, 'snap': snap_name}) try: cview = self.client.new("snapshots", short_name=view_name, source=snap, retention_policy=rpolicy, is_exposable=True).save() except Exception as ex: LOG.exception(_LE("Creating a view: %(view)s from snapshot: " "%(snap)s failed"), {"view": view_name, "snap": snap_name}) raise exception.KaminarioCinderDriverException( reason=six.text_type(ex.message)) else: msg = _("Snapshot: %s search failed in K2.") % snap_name LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) try: conn = self.initialize_connection(cview, properties) src_attach_info = self._connect_device(conn) self.create_volume(volume) conn = self.initialize_connection(volume, properties) dest_attach_info = self._connect_device(conn) vol_utils.copy_volume(src_attach_info['device']['path'], dest_attach_info['device']['path'], snapshot.volume.size * units.Ki, self.configuration.volume_dd_blocksize, sparse=True) self.terminate_connection(volume, properties) self.terminate_connection(cview, properties) except Exception as ex: self.terminate_connection(cview, properties) self.terminate_connection(volume, properties) cview.delete() self.delete_volume(volume) LOG.exception(_LE("Copy to volume: %(vol)s from view: %(view)s " "failed"), {"vol": vol_name, "view": view_name}) raise exception.KaminarioCinderDriverException( reason=six.text_type(ex.message))
def get_target_info(self, volume): LOG.debug("Searching first iscsi port ip without wan in K2.") iscsi_ip_rs = self.client.search("system/net_ips") iscsi_ip = target_iqn = None if hasattr(iscsi_ip_rs, 'hits') and iscsi_ip_rs.total != 0: for ip in iscsi_ip_rs.hits: if not ip.wan_port: iscsi_ip = ip.ip_address break if not iscsi_ip: msg = _("Unable to get ISCSI IP address from K2.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) iscsi_portal = "{0}:{1}".format(iscsi_ip, ISCSI_TCP_PORT) LOG.debug("Searching system state for target iqn in K2.") sys_state_rs = self.client.search("system/state") if hasattr(sys_state_rs, 'hits') and sys_state_rs.total != 0: target_iqn = sys_state_rs.hits[0].iscsi_qualified_target_name if not target_iqn: msg = _("Unable to get target iqn from K2.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) return iscsi_portal, target_iqn
def get_target_info(self, volume): rep_status = fields.ReplicationStatus.FAILED_OVER if (hasattr(volume, 'replication_status') and volume.replication_status == rep_status): self.client = self.target LOG.debug("Searching first iscsi port ip without wan in K2.") iscsi_ip_rs = self.client.search("system/net_ips", wan_port="") iscsi_ip = target_iqn = None if hasattr(iscsi_ip_rs, 'hits') and iscsi_ip_rs.total != 0: iscsi_ip = iscsi_ip_rs.hits[0].ip_address if not iscsi_ip: msg = _("Unable to get ISCSI IP address from K2.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) iscsi_portal = "{0}:{1}".format(iscsi_ip, ISCSI_TCP_PORT) LOG.debug("Searching system state for target iqn in K2.") sys_state_rs = self.client.search("system/state") if hasattr(sys_state_rs, 'hits') and sys_state_rs.total != 0: target_iqn = sys_state_rs.hits[0].iscsi_qualified_target_name if not target_iqn: msg = _("Unable to get target iqn from K2.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) return iscsi_portal, target_iqn
def _create_volume_replica(self, volume, vg, vol, rpo): """Volume replica creation in K2 needs session and remote volume. - create a session - create a volume in the volume group """ session_name = self.get_session_name(volume.id) rsession_name = self.get_rep_name(session_name) rvg_name = self.get_rep_name(vg.name) rvol_name = self.get_rep_name(vol.name) k2peer_rs = self.client.search("replication/peer_k2arrays", mgmt_host=self.replica.backend_id) if hasattr(k2peer_rs, 'hits') and k2peer_rs.total != 0: k2peer = k2peer_rs.hits[0] else: msg = _("Unable to find K2peer in source K2:") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) try: LOG.debug( "Creating source session with name: %(sname)s and " " target session name: %(tname)s", { 'sname': session_name, 'tname': rsession_name }) src_ssn = self.client.new("replication/sessions") src_ssn.replication_peer_k2array = k2peer src_ssn.auto_configure_peer_volumes = "False" src_ssn.local_volume_group = vg src_ssn.replication_peer_volume_group_name = rvg_name src_ssn.remote_replication_session_name = rsession_name src_ssn.name = session_name src_ssn.rpo = rpo src_ssn.save() LOG.debug("Creating remote volume with name: %s", rvol_name) self.client.new("replication/peer_volumes", local_volume=vol, name=rvol_name, replication_session=src_ssn).save() src_ssn.state = "in_sync" src_ssn.save() except Exception as ex: LOG.exception(_LE("Replication for the volume %s has " "failed."), vol.name) self._delete_by_ref(self.client, "replication/sessions", session_name, 'session') self._delete_by_ref(self.target, "replication/sessions", rsession_name, 'remote session') self._delete_by_ref(self.target, "volumes", rvol_name, 'remote volume') self._delete_by_ref(self.client, "volumes", vol.name, "volume") self._delete_by_ref(self.target, "volume_groups", rvg_name, "remote vg") self._delete_by_ref(self.client, "volume_groups", vg.name, "vg") raise exception.KaminarioCinderDriverException( reason=six.text_type(ex.message))
def k2_initialize_connection(self, volume, connector): # Get volume object. if type(volume).__name__ != 'RestObject': vol = self._get_volume_object(volume) else: vol = volume # Get host object. host, host_rs, host_name = self._get_host_object(connector) try: # Map volume object to host object. LOG.debug("Mapping volume: %(vol)s to host: %(host)s", {'host': host_name, 'vol': vol.name}) mapping = self.client.new("mappings", volume=vol, host=host).save() except Exception as ex: if host_rs.total == 0: self._delete_host_by_name(host_name) LOG.exception("Unable to map volume: %(vol)s to host: " "%(host)s", {'host': host_name, 'vol': vol.name}) raise exception.KaminarioCinderDriverException(reason=ex) # Get lun number. if type(volume).__name__ == 'RestObject': return self._get_lun_number(vol, host) else: return mapping.lun
def create_volume(self, volume): """Volume creation in K2 needs a volume group. - create a volume group - create a volume in the volume group """ vg_name = self.get_volume_group_name(volume.id) vol_name = self.get_volume_name(volume.id) prov_type = self._get_is_dedup(volume.get('volume_type')) try: LOG.debug("Creating volume group with name: %(name)s, " "quota: unlimited and dedup_support: %(dedup)s", {'name': vg_name, 'dedup': prov_type}) vg = self.client.new("volume_groups", name=vg_name, quota=0, is_dedup=prov_type).save() LOG.debug("Creating volume with name: %(name)s, size: %(size)s " "GB, volume_group: %(vg)s", {'name': vol_name, 'size': volume.size, 'vg': vg_name}) vol = self.client.new("volumes", name=vol_name, size=volume.size * units.Mi, volume_group=vg).save() except Exception as ex: vg_rs = self.client.search("volume_groups", name=vg_name) if vg_rs.total != 0: LOG.debug("Deleting vg: %s for failed volume in K2.", vg_name) vg_rs.hits[0].delete() LOG.exception("Creation of volume %s failed.", vol_name) raise exception.KaminarioCinderDriverException(reason=ex) if self._get_is_replica(volume.volume_type) and self.replica: self._create_volume_replica(volume, vg, vol, self.replica.rpo)
def initialize_connection(self, volume, connector): """Attach K2 volume to host.""" # Check wwpns in host connector. if not connector.get('wwpns'): msg = _("No wwpns found in host connector.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) # To support replication failback temp_client = None if (hasattr(volume, 'replication_status') and volume.replication_status == K2_REP_FAILED_OVER): temp_client = self.client self.client = self.target # Get target wwpns. target_wwpns = self.get_target_info(volume) # Map volume. lun = self.k2_initialize_connection(volume, connector) # Create initiator-target mapping. target_wwpns, init_target_map = self._build_initiator_target_map( connector, target_wwpns) # To support replication failback if temp_client: self.client = temp_client # Return target volume information. return { 'driver_volume_type': 'fibre_channel', 'data': { "target_discovered": True, "target_lun": lun, "target_wwn": target_wwpns, "initiator_target_map": init_target_map } }
def _get_host_object(self, connector): host_name = self.get_initiator_host_name(connector) LOG.debug("Searching initiator hostname: %s in K2.", host_name) host_rs = self.client.search("hosts", name=host_name) """Create a host if not exists.""" if host_rs.total == 0: try: LOG.debug("Creating initiator hostname: %s in K2.", host_name) host = self.client.new("hosts", name=host_name, type="Linux").save() LOG.debug("Adding iqn: %(iqn)s to host: %(host)s in K2.", { 'iqn': connector['initiator'], 'host': host_name }) iqn = self.client.new("host_iqns", iqn=connector['initiator'], host=host) iqn.save() except Exception as ex: self._delete_host_by_name(host_name) LOG.exception(_LE("Unable to create host: %s in K2."), host_name) raise exception.KaminarioCinderDriverException( reason=six.text_type(ex.message)) else: LOG.debug("Use existing initiator hostname: %s in K2.", host_name) host = host_rs.hits[0] return host, host_rs, host_name
def create_volume(self, volume): """Volume creation in K2 needs a volume group. - create a volume group - create a volume in the volume group """ vg_name = self.get_volume_group_name(volume.id) vol_name = self.get_volume_name(volume.id) if CONF.kaminario_nodedup_substring in volume.volume_type.name: prov_type = False else: prov_type = True try: LOG.debug("Creating volume group with name: %(name)s, " "quota: unlimited and dedup_support: %(dedup)s", {'name': vg_name, 'dedup': prov_type}) vg = self.client.new("volume_groups", name=vg_name, quota=0, is_dedup=prov_type).save() LOG.debug("Creating volume with name: %(name)s, size: %(size)s " "GB, volume_group: %(vg)s", {'name': vol_name, 'size': volume.size, 'vg': vg_name}) self.client.new("volumes", name=vol_name, size=volume.size * units.Mi, volume_group=vg).save() except Exception as ex: vg_rs = self.client.search("volume_groups", name=vg_name) if vg_rs.total != 0: LOG.debug("Deleting vg: %s for failed volume in K2.", vg_name) vg_rs.hits[0].delete() LOG.exception(_LE("Creation of volume %s failed."), vol_name) raise exception.KaminarioCinderDriverException( reason=six.text_type(ex.message))
def _get_volume_object(self, volume): vol_name = self.get_volume_name(volume.id) LOG.debug("Searching volume : %s in K2.", vol_name) vol_rs = self.client.search("volumes", name=vol_name) if not hasattr(vol_rs, 'hits') or vol_rs.total == 0: msg = _("Unable to find volume: %s from K2.") % vol_name LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) return vol_rs.hits[0]
def get_policy(self): """Return the retention policy.""" try: LOG.debug("Searching for retention_policy in K2.") return self.client.search("retention_policies", name="Best_Effort_Retention").hits[0] except Exception as ex: LOG.exception("Retention policy search failed in K2.") raise exception.KaminarioCinderDriverException(reason=ex)
def _get_host_object(self, connector): host_name = self.get_initiator_host_name(connector) LOG.debug("Searching initiator hostname: %s in K2.", host_name) host_rs = self.client.search("hosts", name=host_name) host_wwpns = connector['wwpns'] if host_rs.total == 0: try: LOG.debug("Creating initiator hostname: %s in K2.", host_name) host = self.client.new("hosts", name=host_name, type="Linux").save() except Exception as ex: LOG.exception(_LE("Unable to create host : %s in K2."), host_name) raise exception.KaminarioCinderDriverException( reason=six.text_type(ex.message)) else: # Use existing host. LOG.debug("Use existing initiator hostname: %s in K2.", host_name) host = host_rs.hits[0] # Adding host wwpn. for wwpn in host_wwpns: wwpn = ":".join([wwpn[i:i + 2] for i in range(0, len(wwpn), 2)]) if self.client.search("host_fc_ports", pwwn=wwpn, host=host).total == 0: LOG.debug("Adding wwpn: %(wwpn)s to host: " "%(host)s in K2.", { 'wwpn': wwpn, 'host': host_name }) try: self.client.new("host_fc_ports", pwwn=wwpn, host=host).save() except Exception as ex: if host_rs.total == 0: self._delete_host_by_name(host_name) LOG.exception( _LE("Unable to add wwpn : %(wwpn)s to " "host: %(host)s in K2."), { 'wwpn': wwpn, 'host': host_name }) raise exception.KaminarioCinderDriverException( reason=six.text_type(ex.message)) return host, host_rs, host_name
def create_cloned_volume(self, volume, src_vref): """Create a clone from source volume. - attach source volume - create and attach new volume - copy data from attached source volume to attached new volume - detach both volumes """ clone_name = self.get_volume_name(volume.id) src_name = self.get_volume_name(src_vref.id) src_vol = self.client.search("volumes", name=src_name) src_map = self.client.search("mappings", volume=src_vol) src_attach_info = dest_attach_info = None if src_map.total != 0: msg = _("K2 driver does not support clone of a attached volume. " "To get this done, create a snapshot from the attached " "volume and then create a volume from the snapshot.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) try: properties = utils.brick_get_connector_properties() conn = self.initialize_connection(src_vref, properties) src_attach_info = self._connect_device(conn) self.create_volume(volume) conn = self.initialize_connection(volume, properties) dest_attach_info = self._connect_device(conn) vol_utils.copy_volume(src_attach_info['device']['path'], dest_attach_info['device']['path'], src_vref.size * units.Ki, self.configuration.volume_dd_blocksize, sparse=True) self._kaminario_disconnect_volume(src_attach_info, dest_attach_info) self.terminate_connection(volume, properties) self.terminate_connection(src_vref, properties) except Exception as ex: self._kaminario_disconnect_volume(src_attach_info, dest_attach_info) self.terminate_connection(src_vref, properties) self.terminate_connection(volume, properties) self.delete_volume(volume) LOG.exception("Create a clone: %s failed.", clone_name) raise exception.KaminarioCinderDriverException(reason=ex)
def delete_snapshot(self, snapshot): """Delete a snapshot.""" snap_name = self.get_snap_name(snapshot.id) try: LOG.debug("Searching and deleting snapshot: %s in K2.", snap_name) snap_rs = self.client.search("snapshots", short_name=snap_name) if snap_rs.total != 0: snap_rs.hits[0].delete() except Exception as ex: LOG.exception("Deletion of snapshot: %s failed.", snap_name) raise exception.KaminarioCinderDriverException(reason=ex)
def extend_volume(self, volume, new_size): """Extend volume.""" vol_name = self.get_volume_name(volume.id) try: LOG.debug("Searching volume: %s in K2.", vol_name) vol = self.client.search("volumes", name=vol_name).hits[0] vol.size = new_size * units.Mi LOG.debug("Extending volume: %s in K2.", vol_name) vol.save() except Exception as ex: LOG.exception("Extending volume: %s failed.", vol_name) raise exception.KaminarioCinderDriverException(reason=ex)
def get_target_info(self, volume): LOG.debug("Searching target wwpns in K2.") fc_ports_rs = self.client.search("system/fc_ports") target_wwpns = [] if hasattr(fc_ports_rs, 'hits') and fc_ports_rs.total != 0: for port in fc_ports_rs.hits: if port.pwwn: target_wwpns.append((port.pwwn).replace(':', '')) if not target_wwpns: msg = _("Unable to get FC target wwpns from K2.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) return target_wwpns
def create_snapshot(self, snapshot): """Create a snapshot from a volume_group.""" vg_name = self.get_volume_group_name(snapshot.volume_id) snap_name = self.get_snap_name(snapshot.id) rpolicy = self.get_policy() try: LOG.debug("Searching volume_group: %s in K2.", vg_name) vg = self.client.search("volume_groups", name=vg_name).hits[0] LOG.debug("Creating a snapshot: %(snap)s from vg: %(vg)s", {'snap': snap_name, 'vg': vg_name}) self.client.new("snapshots", short_name=snap_name, source=vg, retention_policy=rpolicy, is_auto_deleteable=False).save() except Exception as ex: LOG.exception("Creation of snapshot: %s failed.", snap_name) raise exception.KaminarioCinderDriverException(reason=ex)
def delete_volume(self, volume): """Volume in K2 exists in a volume group. - delete the volume - delete the corresponding volume group """ vg_name = self.get_volume_group_name(volume.id) vol_name = self.get_volume_name(volume.id) try: LOG.debug("Searching and deleting volume: %s in K2.", vol_name) vol_rs = self.client.search("volumes", name=vol_name) if vol_rs.total != 0: vol_rs.hits[0].delete() LOG.debug("Searching and deleting vg: %s in K2.", vg_name) vg_rs = self.client.search("volume_groups", name=vg_name) if vg_rs.total != 0: vg_rs.hits[0].delete() except Exception as ex: LOG.exception(_LE("Deletion of volume %s failed."), vol_name) raise exception.KaminarioCinderDriverException( reason=six.text_type(ex.message))
def delete_volume(self, volume): """Volume in K2 exists in a volume group. - delete the volume - delete the corresponding volume group """ vg_name = self.get_volume_group_name(volume.id) vol_name = self.get_volume_name(volume.id) try: if self._get_is_replica(volume.volume_type) and self.replica: self._delete_volume_replica(volume, vg_name, vol_name) LOG.debug("Searching and deleting volume: %s in K2.", vol_name) vol_rs = self.client.search("volumes", name=vol_name) if vol_rs.total != 0: vol_rs.hits[0].delete() LOG.debug("Searching and deleting vg: %s in K2.", vg_name) vg_rs = self.client.search("volume_groups", name=vg_name) if vg_rs.total != 0: vg_rs.hits[0].delete() except Exception as ex: LOG.exception("Deletion of volume %s failed.", vol_name) raise exception.KaminarioCinderDriverException(reason=ex)
def initialize_connection(self, volume, connector): """Attach K2 volume to host.""" # Check wwpns in host connector. if not connector.get('wwpns'): msg = _("No wwpns found in host connector.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) # Get target wwpns. target_wwpns = self.get_target_info(volume) # Map volume. lun = self.k2_initialize_connection(volume, connector) # Create initiator-target mapping. target_wwpns, init_target_map = self._build_initiator_target_map( connector, target_wwpns) # Return target volume information. return { 'driver_volume_type': 'fibre_channel', 'data': { "target_discovered": True, "target_lun": lun, "target_wwn": target_wwpns, "initiator_target_map": init_target_map } }
def delete(self): raise exception.KaminarioCinderDriverException("test")
def initialize_connection(self, volume, connector): """Get volume object and map to initiator host.""" if type(volume).__name__ != 'RestObject': vol_name = self.get_volume_name(volume.id) LOG.debug("Searching volume : %s in K2.", vol_name) vol_rs = self.client.search("volumes", name=vol_name) if not hasattr(vol_rs, 'hits') or vol_rs.total == 0: msg = _("Unable to find volume: %s from K2.") % vol_name LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) vol = vol_rs.hits[0] else: vol = volume """Get target_portal""" LOG.debug("Searching first iscsi port ip without wan in K2.") iscsi_ip_rs = self.client.search("system/net_ips", wan_port="") iscsi_ip = target_iqn = None if hasattr(iscsi_ip_rs, 'hits') and iscsi_ip_rs.total != 0: iscsi_ip = iscsi_ip_rs.hits[0].ip_address if not iscsi_ip: msg = _("Unable to get ISCSI IP addres from K2.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) iscsi_portal = "{0}:{1}".format(iscsi_ip, ISCSI_TCP_PORT) LOG.debug("Searching system state for target iqn in K2.") sys_state_rs = self.client.search("system/state") if hasattr(sys_state_rs, 'hits') and sys_state_rs.total != 0: target_iqn = sys_state_rs.hits[0].iscsi_qualified_target_name if not target_iqn: msg = _("Unable to get target iqn from K2.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) host_name = self.get_initiator_host_name(connector) LOG.debug("Searching initiator hostname: %s in K2.", host_name) host_rs = self.client.search("hosts", name=host_name) """Create a host if not exists.""" if host_rs.total == 0: try: LOG.debug("Creating initiator hostname: %s in K2.", host_name) host = self.client.new("hosts", name=host_name, type="Linux").save() LOG.debug("Adding iqn: %(iqn)s to host: %(host)s in K2.", { 'iqn': connector['initiator'], 'host': host_name }) iqn = self.client.new("host_iqns", iqn=connector['initiator'], host=host) iqn.save() except Exception as ex: LOG.debug("Unable to create host : %s in K2.", host_name) self.delete_host_by_name(host_name) raise exception.KaminarioCinderDriverException( reason=six.text_type(ex.message)) else: LOG.debug("Use existing initiator hostname: %s in K2.", host_name) host = host_rs.hits[0] try: LOG.debug("Mapping volume: %(vol)s to host: %(host)s", { 'host': host_name, 'vol': vol.name }) mapping = self.client.new("mappings", volume=vol, host=host).save() except Exception as ex: if host_rs.total == 0: LOG.debug("Unable to mapping volume:%(vol)s to host: %(host)s", { 'host': host_name, 'vol': vol.name }) self.delete_host_by_name(host_name) raise exception.KaminarioCinderDriverException( reason=six.text_type(ex.message)) if type(volume).__name__ == 'RestObject': volsnap = None LOG.debug("Searching volsnaps in K2.") volsnaps = self.client.search("volsnaps") for v in volsnaps.hits: if v.snapshot.id == vol.id: volsnap = v break LOG.debug("Searching mapping of volsnap in K2.") rv = self.client.search("mappings", volume=volsnap) lun = rv.hits[0].lun else: lun = mapping.lun return { "driver_volume_type": "iscsi", "data": { "target_iqn": target_iqn, "target_portal": iscsi_portal, "target_lun": lun, "target_discovered": True } }