예제 #1
0
    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
예제 #2
0
    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
예제 #5
0
    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
예제 #6
0
    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))
예제 #7
0
 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
예제 #8
0
    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)
예제 #9
0
 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
         }
     }
예제 #10
0
 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]
예제 #13
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)
예제 #14
0
 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
예제 #15
0
    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)
예제 #16
0
 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)
예제 #17
0
 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)
예제 #18
0
 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
예제 #19
0
 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))
예제 #21
0
    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)
예제 #22
0
 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
         }
     }
예제 #23
0
 def delete(self):
     raise exception.KaminarioCinderDriverException("test")
예제 #24
0
    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
            }
        }