def attach_volume(self, blockdevice_id, attach_to): """ Attach ``blockdevice_id`` to ``host``. :param unicode blockdevice_id: The unique identifier for the block device being attached. :param unicode attach_to: An identifier like the one returned by the ``compute_instance_id`` method indicating the node to which to attach the volume. :raises UnknownVolume: If the supplied ``blockdevice_id`` does not exist. :raises AlreadyAttachedVolume: If the supplied ``blockdevice_id`` is already attached. :returns: A ``BlockDeviceVolume`` with a ``host`` attribute set to ``host``. """ # Raises UnknownVolume volume = self._get(blockdevice_id) # raises AlreadyAttachedVolume if volume.attached_to is not None: Message.new(Error="Could Not Destroy Volume " + str(blockdevice_id) + "is already attached").write(_logger) raise AlreadyAttachedVolume(blockdevice_id) # Get the SDC Object by the GUID of the host. sdc = self._client.get_sdc_by_guid( self._instance_id.upper()) # Try mapping volumes # TODO errors are currently hard to get from sclaeio-py # https://github.com/swevm/scaleio-py/issues/6 # ultimately we should be able to get more specific # errors about why the failure happened such as # ``{"message":"Only a single SDC may be mapped to this # volume at a time","httpStatusCode":500,"errorCode":306}`` try: self._client.map_volume_to_sdc( self._client.get_volume_by_id( str(blockdevice_id)), sdcObj=sdc, allowMultipleMappings=False) except Exception as e: # TODO real errors need to be returned by scaleio-py Message.new(Error=str(blockdevice_id) + " " + str(e)).write(_logger) raise AlreadyAttachedVolume(blockdevice_id) attached_volume = volume.set( attached_to=self._instance_id) return attached_volume
def attach_volume(self, blockdevice_id, attach_to): """ Attach ``blockdevice_id`` to the node indicated by ``attach_to``. :param unicode blockdevice_id: The unique identifier for the block device being attached. :param unicode attach_to: An identifier like the one returned by the ``compute_instance_id`` method indicating the node to which to attach the volume. :raises UnknownVolume: If the supplied ``blockdevice_id`` does not exist. :raises AlreadyAttachedVolume: If the supplied ``blockdevice_id`` is already attached. :returns: A ``BlockDeviceVolume`` with a ``attached_to`` attribute set to ``attach_to``. """ # This also checks if it exists if self._is_already_mapped(blockdevice_id): raise AlreadyAttachedVolume(blockdevice_id) if attach_to != self.compute_instance_id(): # TODO log this. return self._check_output([b"rbd", b"-p", self._pool, b"map", blockdevice_id]) rbd_image = rbd.Image(self._ioctx, _rbd_blockdevice_id(blockdevice_id)) size = int(rbd_image.stat()["size"]) return BlockDeviceVolume(blockdevice_id=blockdevice_id, size=size, attached_to=self.compute_instance_id(), dataset_id=_dataset_id(blockdevice_id))
def attach_volume(self, blockdevice_id, attach_to): """ See ``IBlockDeviceAPI.attach_volume``. :returns: """ volume = self._get_volume(blockdevice_id) if volume['attach_to'] is not None: LOG.error("attach_volume: AlreadyAttachedVolume, " + unicode(blockdevice_id)) raise AlreadyAttachedVolume(blockdevice_id) connector = self._find_vmax_host(attach_to) if connector is None: LOG.error("attach_volume: VolumeException, " + unicode(blockdevice_id)) raise VolumeException(blockdevice_id) LOG.info("attach_volume " + unicode(volume) + " to " + unicode(connector)) volume['attach_to'] = unicode(attach_to) self.dbconn.update_volume_by_id(blockdevice_id, volume) self.vmax_common.initialize_connection(volume, connector) return _blockdevicevolume_from_vmax_volume(blockdevice_id, volume)
def attach_volume(self, blockdevice_id, attach_to): """ Attach ``blockdevice_id`` to the node indicated by ``attach_to``. :param unicode blockdevice_id: The unique identifier for the block device being attached. :param unicode attach_to: An identifier like the one returned by the ``compute_instance_id`` method indicating the node to which to attach the volume. :raises UnknownVolume: If the supplied ``blockdevice_id`` does not exist. :raises AlreadyAttachedVolume: If the supplied ``blockdevice_id`` is already attached. :returns: A ``BlockDeviceVolume`` with a ``attached_to`` attribute set to ``attach_to``. """ current_vol = self.eqlx_con.volume_info(blockdevice_id) if current_vol.attached_to != None: raise AlreadyAttachedVolume('attached to %s' % current_vol.attached_to) self.eqlx_con.allow_volume(blockdevice_id, attach_to) self.eqlx_con.iscsi_login(blockdevice_id) return current_vol.set(attached_to=attach_to)
def attach_volume(self, blockdevice_id, attach_to): """ Attach ``blockdevice_id`` to the node indicated by ``attach_to``. :param unicode blockdevice_id: The unique identifier for the block device being attached. :param unicode attach_to: An identifier like the one returned by the ``compute_instance_id`` method indicating the node to which to attach the volume. :raises UnknownVolume: If the supplied ``blockdevice_id`` does not exist. :raises AlreadyAttachedVolume: If the supplied ``blockdevice_id`` is already attached. :returns: A ``BlockDeviceVolume`` with a ``attached_to`` attribute set to ``attach_to``. """ ascii_blockdevice_id = blockdevice_id.encode() self._check_exists(ascii_blockdevice_id) if self._is_already_mapped(blockdevice_id): raise AlreadyAttachedVolume(blockdevice_id) if attach_to != self.compute_instance_id(): return Blktap.Tapdisk.create(blockdevice_id) object_id = self.client.get_object_id(str("/%s.raw" % blockdevice_id)) size = self.client.info_volume(object_id).volume_size return BlockDeviceVolume(blockdevice_id=blockdevice_id, size=size, attached_to=self.compute_instance_id(), dataset_id=_dataset_id(blockdevice_id))
def resize_volume(self, blockdevice_id, size): """ Resize an unattached ``blockdevice_id``. This changes the amount of storage available. It does not change the data on the volume (including the filesystem). :param unicode blockdevice_id: The unique identifier for the block device being detached. :param int size: The required size, in bytes, of the volume. :raises UnknownVolume: If the supplied ``blockdevice_id`` does not exist. :returns: ``None`` """ # raises UnknownVolume volume = self._get(blockdevice_id) # raises AlreadyAttachedVolume, do we want this? # is says only an unattached volume, if it is attached # do we detach and then resize thenr reattach? Or should we # just assume that all things that call this function know # that the volume is detached already? if volume.attached_to is not None: Message.new(Error="Cannot Resize Volume " + str(blockdevice_id) + "is attached").write(_logger) raise AlreadyAttachedVolume(blockdevice_id) sio_volume = self._client.get_volume_by_id(str(blockdevice_id)) size_in_gb = int(Byte(size).to_GiB().value) self._client.resize_volume(sio_volume, size_in_gb)
def attach_volume(self, blockdevice_id, attach_to): """ Attach an CIO volume to given compute instance. :param unicode blockdevice_id: CIO UUID for volume to be attached. :param unicode attach_to: Instance id of CIO Compute instance to attached the blockdevice to. :raises UnknownVolume: If there does not exist a BlockDeviceVolume corresponding to the input blockdevice_id. :raises AlreadyAttachedVolume: If the input volume is already attached to a device. :raises AttachedUnexpectedDevice: If the attach operation fails to associate the volume with the expected OS device file. This indicates use on an unsupported OS, a misunderstanding of the CIO device assignment rules, or some other bug in this implementation. """ command = [ b"/usr/bin/cio", b"vdinfo", b"-u", unicode(blockdevice_id), b"-v" ] output = check_output(command).split(b'\n')[0] cio_volume = output.split()[0] if cio_volume == "Fail:": raise UnknownVolume(blockdevice_id) command = [ b"/usr/bin/cio", b"vdinfo", b"-v", bytes(cio_volume), b"--attachstatus" ] current_attachment = check_output(command).split(b'\n')[0] if current_attachment != "None": #if current_attachment == attach_to: raise AlreadyAttachedVolume(blockdevice_id) #else : # compute_instance_id = self.compute_instance_id() # if attach_to != compute_instance_id : # move_volume_command = [b"/usr/bin/cio", b"vdmv", b"-v", bytes(cio_volume), b"-N", attach_to] # command_output = check_output(move_volume_command).split(b'\n') else: if attach_to != None: add_attach_metadata_command = [ b"/usr/bin/cio", b"vdmod", b"-v", bytes(cio_volume), b"--attachstatus", attach_to ] command_output = check_output( add_attach_metadata_command).split(b'\n') command = [ b"/usr/bin/cio", b"vdinfo", b"-v", bytes(cio_volume), b"--datasetid" ] output = check_output(command).split(b'\n')[0] dataset_id = output.split()[0].decode("ascii") return _blockdevicevolume_from_cio_volume(bytes(cio_volume), datasetid=UUID(dataset_id), computeinstanceid=attach_to)
def attach_volume(self, blockdevice_id, attach_to): """ Attach ``blockdevice_id`` to ``host``. :param unicode blockdevice_id: The unique identifier for the block device being attached. :param unicode attach_to: An identifier like the one returned by the ``compute_instance_id`` method indicating the node to which to attach the volume. :raises UnknownVolume: If the supplied ``blockdevice_id`` does not exist. :raises AlreadyAttachedVolume: If the supplied ``blockdevice_id`` is already attached. :returns: A ``BlockDeviceVolume`` with a ``host`` attribute set to ``host``. """ vol = self._get_solidfire_volume(blockdevice_id) if not vol: raise UnknownVolume(blockdevice_id) tgt_iqn = vol['iqn'] if utils.path_exists('/dev/disk/by-path/ip-%s-iscsi-%s-lun-0' % (self.svip, tgt_iqn), 1): raise AlreadyAttachedVolume(blockdevice_id) # It's not attached here, make sure it's not attached somewhere else # In the future we can add multi-attach support maybe, but for now # avoid the trouble of file-systems etc current_sessions = self._current_iscsi_sessions(blockdevice_id) if current_sessions: raise AlreadyAttachedVolume(blockdevice_id) targets = utils.iscsi_discovery(self.svip) if len(targets) < 1 and tgt_iqn not in targets: raise Exception("No targes found during discovery.") if utils.iscsi_login(self.svip, tgt_iqn): return BlockDeviceVolume( blockdevice_id=unicode(blockdevice_id), size=vol['totalSize'], attached_to=attach_to, dataset_id=uuid.UUID(str(vol['name']))) raise Exception("Failed iSCSI login to device: %s" % blockdevice_id)
def attach_volume(self, blockdevice_id, attach_to): """ Attach ``blockdevice_id`` to ``host``. :param unicode blockdevice_id: The unique identifier for the block device being attached. :param unicode attach_to: An identifier like the one returned by the ``compute_instance_id`` method indicating the node to which to attach the volume. :raises UnknownVolume: If the supplied ``blockdevice_id`` does not exist. :raises AlreadyAttachedVolume: If the supplied ``blockdevice_id`` is already attached. :returns: A ``BlockDeviceVolume`` with a ``host`` attribute set to ``host``. """ log_info('Attempting to attach ' + str(blockdevice_id) + ' to ' + str(attach_to)) _vmstate_lock.acquire() try: # Make sure disk is present. Also, need the disk size is needed. disks = self._manager.list_disks() target_disk = None for disk in disks: if disk.name == blockdevice_id: target_disk = disk break if target_disk is None: raise UnknownVolume(blockdevice_id) (disk, vmname, lun) = self._get_disk_vmname_lun(blockdevice_id) if vmname is not None: if unicode(vmname) != self.compute_instance_id(): raise AlreadyAttachedVolume(blockdevice_id) else: return self._blockdevicevolume_from_azure_volume( blockdevice_id, target_disk.properties.content_length, attach_to) self._manager.attach_disk( str(attach_to), target_disk.name, int(GiB(bytes=target_disk.properties.content_length))) finally: _vmstate_lock.release() log_info('disk attached') return self._blockdevicevolume_from_azure_volume( blockdevice_id, target_disk.properties.content_length, attach_to)
def attach_volume(self, blockdevice_id, attach_to): """ Attach ``blockdevice_id`` to the node indicated by ``attach_to``. :param unicode blockdevice_id: The unique identifier for the block device being attached. :param unicode attach_to: An identifier like the one returned by the ``compute_instance_id`` method indicating the node to which to attach the volume. :raises UnknownVolume: If the supplied ``blockdevice_id`` does not exist. :raises AlreadyAttachedVolume: If the supplied ``blockdevice_id`` is already attached. :raises UnknownVm: If the supplied ``attach_to`` vm does not exist. :raises VolumeAttachFailure: If the attach volume failed with some error. exist. :returns: A ``BlockDeviceVolume`` with a ``attached_to`` attribute set to ``attach_to``. """ logging.debug("Attaching {} to {}".format(blockdevice_id, attach_to)) vm = self._si.content.searchIndex.FindByUuid(datacenter=None, uuid=attach_to, vmSearch=True, instanceUuid=True) try: if vm is None: raise UnknownVm("VM not found {}".format(attach_to)) vsphere_volume = self._get_vsphere_blockdevice_volume( blockdevice_id) if vsphere_volume.blockDeviceVolume.attached_to is not None: logging.error("Volume is attached to a vm so cannot attach.") raise AlreadyAttachedVolume(blockdevice_id) try: attached_volume = self._attach_vmdk(vm, vsphere_volume) except Exception as e: logging.error("Cannot attach volume {} to {} ({}) " "because of exception: {}".format( blockdevice_id, attach_to, vm.name, e)) raise VolumeAttachFailure(e) logging.debug("Volume attached to {}".format( attached_volume.attached_to)) logging.debug("Block Device {} will be attached to {} {}".format( blockdevice_id, attach_to, attached_volume)) logging.debug("Rescanning scsi bus for attached disk") self._rescan_scsi() return attached_volume except Exception, ex: logging.error( 'An error occurred attaching volume {} to {}: {}'.format( blockdevice_id, attach_to, ex)) raise VolumeAttachFailure(ex)
def attach_volume(self, blockdevice_id, attach_to): """ Attach ``blockdevice_id`` to ``host``. :param unicode blockdevice_id: The unique identifier for the block device being attached. :param unicode attach_to: An identifier like the one returned by the ``compute_instance_id`` method indicating the node to which to attach the volume. :raises UnknownVolume: If the supplied ``blockdevice_id`` does not exist. :raises AlreadyAttachedVolume: If the supplied ``blockdevice_id`` is already attached. :returns: A ``BlockDeviceVolume`` with a ``host`` attribute set to ``host``. """ volName = str(blockdevice_id) vdiskInfo = findVDisk(volName) if (vdiskInfo == None): raise UnknownVolume(blockdevice_id) computeHost = socket.getfqdn(attach_to) try: tgtHost = hedvigLookupTgt('wood', self.logger_) lunnum = hedvigGetLun(tgtHost, volName, self.logger_) except: raise Exception("Failed to get Lun number") if lunnum == -1: self.logger_.error("failed to add vDiskName:%s:tgtHost:%s", volName, tgtHost) raise Exception("Failed to add Lun") if (self._is_attached(tgtHost, lunnum) != None): raise AlreadyAttachedVolume(blockdevice_id) try: hedvigAddAccess(tgtHost, lunnum, socket.gethostbyname(socket.getfqdn(computeHost)), self.logger_) hedvigAddAccess(tgtHost, lunnum, socket.gethostbyname(socket.getfqdn()), self.logger_) targetName, portal = hedvigDoIscsiDiscovery( tgtHost, lunnum, self.logger_) except Exception as e: self.logger_.exception( "volume assignment to connector failed :volume:%s:connector:%s", volName, attach_to) return None return BlockDeviceVolume(blockdevice_id=unicode(blockdevice_id), size=vdiskInfo.size, attached_to=attach_to, dataset_id=UUID(blockdevice_id))
def attach_volume(self, blockdevice_id, attach_to): with start_action(action_type=six.text_type( "flocker:node:agents:do:attach_volume"), blockdevice_id=blockdevice_id, droplet_id=attach_to): try: vol = self._get_volume(blockdevice_id) if vol.droplet_ids: raise AlreadyAttachedVolume(blockdevice_id) r = vol.attach(attach_to, vol.region["slug"]) if self._await_action_id(r['action']['id']): vol.droplet_ids = [attach_to] return self._to_block_device_volume(vol) except NotFoundError as _: raise UnknownVolume(blockdevice_id)
def attach_volume(self, blockdevice_id, attach_to): """ Attach volume associates a volume with to a initiator group. The resultant of this is a LUN - Logical Unit Number. This association can be made to any number of initiator groups. Post of this attachment, the device shall appear in /dev/sd<1>. See ``IBlockDeviceAPI.attach_volume`` for parameter and return type documentation. """ volume = self._get_vol_details(blockdevice_id) if volume.attached_to is None: self.data.create_lun_map(str(blockdevice_id), str(attach_to)) else: raise AlreadyAttachedVolume(blockdevice_id) attached_volume = volume.set(attached_to=unicode(attach_to)) self.volume_list[str(blockdevice_id)] = attached_volume Message.new(attached_to=attached_volume.attached_to).write(_logger) self.data.rescan_scsi() return attached_volume
def attachOsnexusVolume(self, blockdevice_id, attach_to): vol = self.validateVolume(blockdevice_id) volUuid = self.getDataSetId(vol._name) if volUuid is None: raise UnknownVolume(blockdevice_id) if self.isVolumeAttached(blockdevice_id) is True: raise AlreadyAttachedVolume(blockdevice_id) self.createHost() self._qsclient.volume_attach(blockdevice_id, self._osnexusHostId) try: self.doIscsiLogin(vol._name) except Exception as e: self._logger.error("failed to login") raise UnattachedVolume(blockdevice_id) return BlockDeviceVolume(blockdevice_id=blockdevice_id, size=int(vol._size), attached_to=attach_to, dataset_id=volUuid)
def attach_volume(self, blockdevice_id, attach_to): """ Attach ``blockdevice_id`` to ``host``. :param unicode blockdevice_id: The unique identifier for the block device being attached. :param unicode attach_to: An identifier like the one returned by the ``compute_instance_id`` method indicating the node to which to attach the volume. :raises UnknownVolume: If the supplied ``blockdevice_id`` does not exist. :raises AlreadyAttachedVolume: If the supplied ``blockdevice_id`` is already attached. :returns: A ``BlockDeviceVolume`` with a ``host`` attribute set to ``host``. """ # Raises UnknownVolume volume = self._get_volume(blockdevice_id) # raises AlreadyAttachedVolume if volume.attached_to is not None: LOG.error("Could Not attach Volume {} is already attached". format(str(blockdevice_id))) raise AlreadyAttachedVolume(blockdevice_id) # Try to map the volume self._client.map_volume(wwn=blockdevice_id, host=attach_to) attached_volume = volume.set(attached_to=attach_to) LOG.info(messages.DRIVER_OPERATION_VOL_ATTACH.format( blockdevice_id=blockdevice_id, attach_to=attach_to)) # Rescan the OS to discover the attached volume LOG.info(messages.DRIVER_OPERATION_VOL_RESCAN_START_ATTACH.format( blockdevice_id=blockdevice_id)) self._host_ops.rescan_scsi() return attached_volume
def attach_volume(self, blockdevice_id, attach_to): """ 1) Add initiator to storage instance 2) Login """ if self._is_attached(blockdevice_id): raise AlreadyAttachedVolume(blockdevice_id) if not self._known(blockdevice_id): raise UnknownVolume(blockdevice_id) ai_name = self._vols[blockdevice_id]['ai_name'] si = get_datera_storageinst(self._api, ai_name) ii = self._initiator_exists(attach_to) if not ii: ii = self._initiator_create(attach_to) if not ii: raise DeviceExceptionAPIError(attach_to) Message.new( Info=' adding initiator : ', attached_to=attach_to).write(_logger) ensure_acl_exists(si, ii) login_to_target(si) # Need to let multipath do its thing before moving on time.sleep (ISCSI_LOGIN_TIME_DELAY) self._vols[blockdevice_id]['attached_to'] = attach_to volume = BlockDeviceVolume( size=self._vols[blockdevice_id]['size'], attached_to=attach_to, dataset_id=self._vols[blockdevice_id]['dataset_id'], blockdevice_id=blockdevice_id) self._vols[blockdevice_id]['volume'] = volume Message.new( Info=' attach_volume', vol=blockdevice_id, attached_to=attach_to).write(_logger) return volume
def attach_volume(self, blockdevice_id, attach_to): """ Attach ``blockdevice_id`` to ``host``. :param unicode blockdevice_id: The unique identifier for the block device being attached. :param unicode attach_to: An identifier like the one returned by the ``compute_instance_id`` method indicating the node to which to attach the volume. :raises UnknownVolume: If the supplied ``blockdevice_id`` does not exist. :raises AlreadyAttachedVolume: If the supplied ``blockdevice_id`` is already attached. :returns: A ``BlockDeviceVolume`` with a ``host`` attribute set to ``host``. """ (target_disk, role_name, lun) = \ self._get_disk_vmname_lun(blockdevice_id) if target_disk is None: raise UnknownVolume(blockdevice_id) if lun is not None: raise AlreadyAttachedVolume(blockdevice_id) log_info('Attempting to attach ' + str(blockdevice_id) + ' to ' + str(attach_to)) disk_size = self._attach_disk(blockdevice_id, target_disk, attach_to) self._wait_for_attach(blockdevice_id) log_info('disk attached') return self._blockdevicevolume_from_azure_volume( blockdevice_id, disk_size, attach_to)
def attach_volume(self, blockdevice_id, attach_to): """ Attach an existing volume to an initiator. If host is not created, it will create the host :param blockdevice_id: WWID of the reduxio Volume :param attach_to: is the value generated by the compute_instance_id ... here IQN of the current node :return: BlockDeviceVolume with attachd_to """ logger.info("Attaching Volume with blockdevice id {} with iscsi target {}".format(blockdevice_id, attach_to)) try: new_host_created = False volume_info = self.find_volume_by_blockdevice_id(blockdevice_id) dataset_id = uuid.UUID(volume_info[u'description']) volume_name = volume_info[u'name'] logger.debug('Found the Volume, Volume name is {}, dataset id is {} .'.format(volume_name, dataset_id)) except Exception as e: logger.error( 'An error occured finding the volume with blockdevice id {} .'.format(blockdevice_id)) logger.error('Exception: ' + str(e)) raise UnknownVolume(e) try: logger.info("Checking if the volume {} is attached to any node/s".format(volume_name)) assignmentlist = self._rdxapi.list_assignments(vol=volume_name) if len(assignmentlist) > 0: logger.error("Volume {} is already attached to a node.".format(volume_name)) raise AlreadyAttachedVolume(blockdevice_id) hostname = None logger.debug('Listing all the hosts.') host_list = self._rdxapi.list_hosts() logger.debug("Checking if the host with iscsi name {} already exist.".format(attach_to)) for host in host_list: if attach_to == host[u'iscsi_name']: hostname = host[u'name'] logger.debug('Host with iscsi name {} exists, Host name is {}'.format(attach_to, hostname)) break if hostname is None: logger.debug('Host not found, must be created.') hostname = self._rdxhelper._host_name() logger.debug( "Trying to create host {} with iscsi name {} since it does not exist.".format(hostname, attach_to)) self._rdxapi.create_host(name=hostname, iscsi_name=attach_to, user_chap=self._chap_user, pwd_chap=self._chap_password) new_host_created = True logger.debug("Created host {} with iscsi name {} successfuly".format(hostname, attach_to)) logger.debug("Trying to assign host {} to volume {} .".format(hostname, volume_name)) self._rdxapi.assign(vol_name=volume_name, host_name=hostname) volume_size = volume_info[u'size'] attached_volume = self.build_block_device(blockdevice_id=blockdevice_id, dataset_id=dataset_id, volume_size=volume_size, attach_to=attach_to) logger.info('Assigning host {} to volume {} is successful.'.format(hostname, volume_name)) # Fetching the DataIPs and add to iscsi session except Exception as ex: logger.error('An error occurred attaching volume {} to {}'.format(blockdevice_id, attach_to)) logger.error('Exception: ' + str(ex)) raise VolumeAttachFailure(ex) try: logger.debug("Getting all data IPs.") data_ips = [] settings_info = self._rdxapi.get_settings() data_ips.append(settings_info[u'iscsi_network1'][u'controller_1_port_1']) data_ips.append(settings_info[u'iscsi_network1'][u'controller_2_port_1']) data_ips.append(settings_info[u'iscsi_network2'][u'controller_1_port_2']) data_ips.append(settings_info[u'iscsi_network2'][u'controller_2_port_2']) logger.debug("Listing all data IPs:") logger.debug(data_ips[0]) logger.debug(data_ips[1]) logger.debug(data_ips[2]) logger.debug(data_ips[3]) scsi_tcp_port = settings_info[u'network_configuration'][u'iscsi_target_tcp_port'] logger.debug("Scsi TCP port is {} .".format(scsi_tcp_port)) iter_count = 0 for data_ip in data_ips: try: iter_count += 1 _manage_session(ip_addr=data_ip, port=scsi_tcp_port, chap_user=self._chap_user, chap_password=self._chap_password) break except Exception: logger.debug( 'Failed to discover targets with data ip {}, will continue with next data ip.'.format(data_ip)) if iter_count == data_ips.__len__(): logger.error('No more data ips, Target discovery failed.') raise Exception() continue rescan_iscsi_session() except Exception as exc: logger.error('An error occurred while discovering the attached volume.') logger.error("Exception: {}".format(str(exc))) try: logger.debug("Error occurred while discovering attached volume." "unassigning the volume {} from host {}.".format(volume_name, hostname)) self._rdxapi.unassign(vol_name=volume_name, host_name=hostname) logger.debug('unassigned the volume {} from host {} successfully.'.format(volume_name, hostname)) except Exception as ex: logger.error('Error occurred while unassigning the volume {} from host {},' ' Exception: {}'.format(volume_name, hostname, str(ex))) try: if new_host_created: logger.debug("Error occured while discovering attached volume.") self._rdxapi.delete_host(name=hostname) logger.debug("Deleted host {} successfully.".format(hostname)) except Exception as ex: logger.error("Error occurred while deleting host {}," " Exception: {}".format(hostname, str(ex))) return attached_volume
def attach_volume(self, blockdevice_id, attach_to): """ Attach ``blockdevice_id`` to the node indicated by ``attach_to``. :param unicode blockdevice_id: The unique identifier for the block device being attached. :param unicode attach_to: An identifier like the one returned by the ``compute_instance_id`` method indicating the node to which to attach the volume. :returns: A ``BlockDeviceVolume`` with a ``attached_to`` attribute set to ``attach_to``. """ LOG.debug("Call attach_volume blockdevice_id=%s, attach_to=%s" % (blockdevice_id, attach_to)) if not self.rest.is_lun(self.Pool, blockdevice_id): raise UnknownVolume(blockdevice_id) vol_info = self.rest.get_lun(self.Pool, blockdevice_id) target_name = '{}{}.{}'.format(self.jovian_target_prefix, blockdevice_id, attach_to) targets = [targ['name'] for targ in self.rest.get_targets(self.Pool)] for target in targets: if blockdevice_id in target and target_name != target and \ self.rest.is_target_lun(self.Pool, target, blockdevice_id): raise AlreadyAttachedVolume(blockdevice_id) elif target_name == target and jcom.check_target_by_path( target_name): raise AlreadyAttachedVolume(blockdevice_id) if not self.rest.is_target(self.Pool, target_name): self.rest.create_target(self.Pool, target_name) if not self.rest.is_target_lun(self.Pool, target_name, blockdevice_id): try: self.rest.attach_target_vol(self.Pool, target_name, blockdevice_id) if not self.rest.is_target_lun(self.Pool, target_name, blockdevice_id): self.rest.delete_target(self.Pool, target_name) raise VolumeException(blockdevice_id) except jexc.JDSSRESTException as error_message: LOG.debug(error_message) raise VolumeException(error_message) if not jcom.check_target_by_path(target_name): jcom.iscsiadm_discovery_target(target_name, self.host) jcom.iscsiadm_login_target(target_name, self.host, self.target_port) else: raise AlreadyAttachedVolume(blockdevice_id) jcom.check_local_disck_by_path() attached_volume = BlockDeviceVolume( size=int(vol_info['volsize']), attached_to=attach_to, dataset_id=UUID('{}'.format(blockdevice_id.split('.')[-1])), blockdevice_id=blockdevice_id) return attached_volume