Beispiel #1
0
 def _get_referenced_lun(self, existing_ref):
     if 'source-id' in existing_ref:
         lun = self.client.get_lun(lun_id=existing_ref['source-id'])
     elif 'source-name' in existing_ref:
         lun = self.client.get_lun(name=existing_ref['source-name'])
     else:
         reason = _('Reference must contain source-id or source-name key.')
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref, reason=reason)
     if lun is None or not lun.existed:
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref, reason=_("LUN doesn't exist."))
     return lun
 def _get_existing_vol_with_manage_ref(self, volume, existing_ref):
     try:
         return self._get_volume_with_label_wwn(
             existing_ref.get('source-name'), existing_ref.get('source-id'))
     except exception.InvalidInput:
         reason = _('Reference must contain either source-name'
                    ' or source-id element.')
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref, reason=reason)
     except KeyError:
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref,
             reason=_('Volume not found on configured storage pools.'))
Beispiel #3
0
 def _get_existing_name(existing_ref):
     if not isinstance(existing_ref, dict):
         existing_ref = {"source-name": existing_ref}
     if 'source-name' not in existing_ref:
         reason = _('Reference must contain source-name element.')
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref, reason=reason)
     src_name = utils.convert_str(existing_ref['source-name'])
     if not src_name:
         reason = _('Reference must contain source-name element.')
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref, reason=reason)
     return src_name
Beispiel #4
0
    def _get_share_mount_and_vol_from_vol_ref(self, vol_ref):
        """Get the NFS share, the NFS mount, and the volume from reference

        Determine the NFS share point, the NFS mount point, and the volume
        (with possible path) from the given volume reference. Raise exception
        if unsuccessful.

        :param vol_ref: Driver-specific information used to identify a volume
        :return:        NFS Share, NFS mount, volume path or raise error
        """
        # Check that the reference is valid.
        if 'source-name' not in vol_ref:
            reason = _('Reference must contain source-name element.')
            raise exception.ManageExistingInvalidReference(
                existing_ref=vol_ref, reason=reason)
        vol_ref_name = vol_ref['source-name']

        self._ensure_shares_mounted()

        # If a share was declared as '1.2.3.4:/a/b/c' in the nfs_shares_config
        # file, but the admin tries to manage the file located at
        # 'my.hostname.com:/a/b/c/d.vol', this might cause a lookup miss below
        # when searching self._mounted_shares to see if we have an existing
        # mount that would work to access the volume-to-be-managed (a string
        # comparison is done instead of IP comparison).
        vol_ref_share = self._convert_vol_ref_share_name_to_share_ip(
            vol_ref_name)
        for nfs_share in self._mounted_shares:
            cfg_share = self._convert_vol_ref_share_name_to_share_ip(nfs_share)
            (orig_share, work_share, file_path) = \
                vol_ref_share.partition(cfg_share)
            if work_share == cfg_share:
                file_path = file_path[1:]  # strip off leading path divider
                LOG.debug("Found possible share %s; checking mount.",
                          work_share)
                nfs_mount = self._get_mount_point_for_share(nfs_share)
                vol_full_path = os.path.join(nfs_mount, file_path)
                if os.path.isfile(vol_full_path):
                    LOG.debug("Found share %(share)s and vol %(path)s on "
                              "mount %(mnt)s",
                              {'share': nfs_share, 'path': file_path,
                               'mnt': nfs_mount})
                    return nfs_share, nfs_mount, file_path
            else:
                LOG.debug("vol_ref %(ref)s not on share %(share)s.",
                          {'ref': vol_ref_share, 'share': nfs_share})

        raise exception.ManageExistingInvalidReference(
            existing_ref=vol_ref,
            reason=_('Volume not found on configured storage backend.'))
    def manage_existing_object_get_size(self, existing_object, existing_ref,
                                        object_type):
        """Return size of an existing ZVOL for manage existing volume/snapshot.

        existing_ref is a dictionary of the form:
        {'source-name': <name of ZVOL>}
        """

        # Check that the reference is valid
        if 'source-name' not in existing_ref:
            reason = _('Reference must contain source-name element.')
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref, reason=reason)

        root_helper = utils.get_root_helper()
        zvol_name = existing_ref['source-name']
        zvol = self._zfs_volume({'name': zvol_name})

        try:
            out, err = self._execute('zfs',
                                     'get',
                                     'volsize',
                                     '-H',
                                     '-p',
                                     '-oname,value',
                                     zvol,
                                     root_helper=root_helper,
                                     run_as_root=True)
            name, size = out.strip().split('\t')
        except processutils.ProcessExecutionError:
            kwargs = {
                'existing_ref': zvol_name,
                'reason': 'Specified logical volume does not exist.'
            }
            raise exception.ManageExistingInvalidReference(**kwargs)

        # Round up the size
        try:
            zvol_size = int(math.ceil(float(size) / units.Gi))
        except ValueError:
            exception_message = (_("Failed to manage existing %(type)s "
                                   "%(name)s, because reported size %(size)s "
                                   "was not a floating-point number.") % {
                                       'type': object_type,
                                       'name': zvol_name,
                                       'size': zvol_size
                                   })
            raise exception.VolumeBackendAPIException(data=exception_message)
        return zvol_size
    def manage_existing_get_size(self, volume, existing_ref):
        """Return size of volume to be managed by manage_existing.

        existing_ref is a dictionary of the form:
        {'source-name': <name of the virtual volume>}
        """
        # Check API version.
        self._check_api_version()

        target_vol_name = self._get_existing_volume_ref_name(existing_ref)

        # Make sure the reference is not in use.
        if re.match('volume-*|snapshot-*', target_vol_name):
            reason = _("Reference must be the volume name of an unmanaged "
                       "virtual volume.")
            raise exception.ManageExistingInvalidReference(
                existing_ref=target_vol_name, reason=reason)

        # Check for the existence of the virtual volume.
        client = self._login()
        try:
            volume_info = client.getVolumeByName(target_vol_name)
        except hpexceptions.HTTPNotFound:
            err = (_("Virtual volume '%s' doesn't exist on array.") %
                   target_vol_name)
            LOG.error(err)
            raise exception.InvalidInput(reason=err)
        finally:
            self._logout(client)

        return int(math.ceil(float(volume_info['size']) / units.Gi))
Beispiel #7
0
 def _validate_existing_ref(self, existing_ref):
     """Validates existing ref"""
     if not existing_ref.get('name'):
         raise cinder_exception.ManageExistingInvalidReference(
             existing_ref=existing_ref,
             reason=_("manage_existing requires a 'name'"
                      " key to identify an existing volume."))
Beispiel #8
0
    def manage_existing(self, volume, existing_ref):
        """Brings an existing backend storage object under Cinder management.

        We expect a volume name in the existing_ref that matches one in Purity.
        """

        self._validate_manage_existing_ref(existing_ref)

        ref_vol_name = existing_ref['name']

        connected_hosts = \
            self._array.list_volume_private_connections(ref_vol_name)
        if len(connected_hosts) > 0:
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref,
                reason=_("%(driver)s manage_existing cannot manage a volume "
                         "connected to hosts. Please disconnect this volume "
                         "from existing hosts before importing") %
                {'driver': self.__class__.__name__})
        new_vol_name = self._get_vol_name(volume)
        LOG.info(_LI("Renaming existing volume %(ref_name)s to %(new_name)s"),
                 {
                     "ref_name": ref_vol_name,
                     "new_name": new_vol_name
                 })
        self._rename_volume_object(ref_vol_name,
                                   new_vol_name,
                                   raise_not_exist=True)
        return None
    def _get_file_handler(self, volume_path, _evs_id, fs_label,
                          raise_except):

        try:
            out, err = self._run_cmd("console-context", "--evs", _evs_id,
                                     'file-clone-stat', '-f', fs_label,
                                     volume_path)
        except putils.ProcessExecutionError as e:
            if 'File is not a clone' in e.stderr and raise_except:
                msg = (_("%s is not a clone!") % volume_path)
                raise exception.ManageExistingInvalidReference(
                    existing_ref=volume_path, reason=msg)
            else:
                return

        lines = out.split('\n')
        filehandle_list = []

        for line in lines:
            if "SnapshotFile:" in line and "FileHandle" in line:
                item = line.split(':')
                handler = item[1][:-1].replace(' FileHandle[', "")
                filehandle_list.append(handler)
                LOG.debug("Volume handler found: %(fh)s. Adding to list...",
                          {'fh': handler})

        return filehandle_list
Beispiel #10
0
    def manage_existing(self, volume, existing_ref):
        """Brings an existing backend storage object under Cinder management.

        We expect a volume name in the existing_ref that matches one in Purity.
        """
        LOG.debug("Enter PureISCSIDriver.manage_existing.")

        self._validate_manage_existing_ref(existing_ref)

        ref_vol_name = existing_ref['name']

        connected_hosts = \
            self._array.list_volume_private_connections(ref_vol_name)
        if len(connected_hosts) > 0:
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref,
                reason=_("PureISCSIDriver manage_existing cannot manage a "
                         "volume connected to hosts. Please disconnect the "
                         "volume from existing hosts before importing."))

        new_vol_name = _get_vol_name(volume)
        LOG.info(_LI("Renaming existing volume %(ref_name)s to %(new_name)s"),
                 {
                     "ref_name": ref_vol_name,
                     "new_name": new_vol_name
                 })
        self._array.rename_volume(ref_vol_name, new_vol_name)
        LOG.debug("Leave PureISCSIDriver.manage_existing.")
        return None
Beispiel #11
0
    def manage_existing_get_size(self, volume, existing_ref):
        """Get the size of an unmanaged volume on the Datera backend

        The existing_ref must be either the current name or Datera UUID of
        an app_instance on the Datera backend in a colon separated list with
        the storage instance name and volume name.  This means only
        single storage instances and single volumes are supported for
        managing by cinder.

        Eg.

        existing_ref == app_inst_name:storage_inst_name:vol_name

        :param volume:       Cinder volume to manage
        :param existing_ref: Driver-specific information used to identify a
                             volume on the Datera backend
        """
        existing_ref = existing_ref['source-name']
        if existing_ref.count(":") != 2:
            raise exception.ManageExistingInvalidReference(
                _("existing_ref argument must be of this format:"
                  "app_inst_name:storage_inst_name:vol_name"))
        app_inst_name, si_name, vol_name = existing_ref.split(":")
        app_inst = self._issue_api_request(
            URL_TEMPLATES['ai_inst']().format(app_inst_name))
        return self._get_size(volume, app_inst, si_name, vol_name)
Beispiel #12
0
    def manage_existing(self, volume, existing_ref):
        """Manage an existing volume on the Datera backend

        The existing_ref must be either the current name or Datera UUID of
        an app_instance on the Datera backend in a colon separated list with
        the storage instance name and volume name.  This means only
        single storage instances and single volumes are supported for
        managing by cinder.

        Eg.

        existing_ref['source-name'] == app_inst_name:storage_inst_name:vol_name

        :param volume:       Cinder volume to manage
        :param existing_ref: Driver-specific information used to identify a
                             volume
        """
        existing_ref = existing_ref['source-name']
        if existing_ref.count(":") != 2:
            raise exception.ManageExistingInvalidReference(
                _("existing_ref argument must be of this format:"
                  "app_inst_name:storage_inst_name:vol_name"))
        app_inst_name = existing_ref.split(":")[0]
        LOG.debug("Managing existing Datera volume %(volume)s.  "
                  "Changing name to %(existing)s",
                  existing=existing_ref, volume=_get_name(volume['id']))
        data = {'name': _get_name(volume['id'])}
        self._issue_api_request(URL_TEMPLATES['ai_inst']().format(
            app_inst_name), method='put', body=data)
 def _manage_existing_2_1(self, volume, existing_ref):
     # Only volumes created under the requesting tenant can be managed in
     # the v2.1 API.  Eg.  If tenant A is the tenant for the volume to be
     # managed, it must also be tenant A that makes this request.
     # This will be fixed in a later API update
     tenant = self._create_tenant(volume)
     existing_ref = existing_ref['source-name']
     if existing_ref.count(":") not in (2, 3):
         raise exception.ManageExistingInvalidReference(
             _("existing_ref argument must be of this format: "
               "tenant:app_inst_name:storage_inst_name:vol_name or "
               "app_inst_name:storage_inst_name:vol_name"))
     app_inst_name = existing_ref.split(":")[0]
     try:
         (tenant, app_inst_name, storage_inst_name,
             vol_name) = existing_ref.split(":")
     except TypeError:
         app_inst_name, storage_inst_name, vol_name = existing_ref.split(
             ":")
         tenant = None
     LOG.debug("Managing existing Datera volume %s  "
               "Changing name to %s",
               datc._get_name(volume['id']), existing_ref)
     data = {'name': datc._get_name(volume['id'])}
     self._issue_api_request(datc.URL_TEMPLATES['ai_inst']().format(
         app_inst_name), method='put', body=data, api_version='2.1',
         tenant=tenant)
Beispiel #14
0
 def manage_existing_get_size(self, volume, existing_ref):
     try:
         return self._manage_existing_get_size(volume, existing_ref)
     except exception.HBSDError as ex:
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref,
             reason=six.text_type(ex))
Beispiel #15
0
 def _get_existing_vol_name(self, existing_ref):
     if 'source-name' not in existing_ref:
         msg = _("Reference to volume to be managed must contain "
                 "source-name.")
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref, reason=msg)
     return existing_ref['source-name']
Beispiel #16
0
    def manage_existing_get_size(self, volume, existing_ref):
        """Return size of an existing image for manage_existing.

        :param volume:
            volume ref info to be set
        :param existing_ref:
            existing_ref is a dictionary of the form:
            {'source-name': <name of rbd image>}
        """

        # Check that the reference is valid
        if 'source-name' not in existing_ref:
            reason = _('Reference must contain source-name element.')
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref, reason=reason)

        rbd_name = utils.convert_str(existing_ref['source-name'])

        with RADOSClient(self) as client:
            # Raise an exception if we didn't find a suitable rbd image.
            try:
                rbd_image = self.rbd.Image(client.ioctx, rbd_name)
                image_size = rbd_image.size()
            except self.rbd.ImageNotFound:
                kwargs = {
                    'existing_ref': rbd_name,
                    'reason': 'Specified rbd image does not exist.'
                }
                raise exception.ManageExistingInvalidReference(**kwargs)
            finally:
                rbd_image.close()

            # RBD image size is returned in bytes.  Attempt to parse
            # size as a float and round up to the next integer.
            try:
                convert_size = int(math.ceil(int(image_size))) / units.Gi
                return convert_size
            except ValueError:
                exception_message = (_("Failed to manage existing volume "
                                       "%(name)s, because reported size "
                                       "%(size)s was not a floating-point"
                                       " number.") % {
                                           'name': rbd_name,
                                           'size': image_size
                                       })
                raise exception.VolumeBackendAPIException(
                    data=exception_message)
Beispiel #17
0
def _check_ldev_manageability(ldev_info, ldev, existing_ref):
    """Check if the LDEV meets the criteria for being managed."""
    if ldev_info['status'] != NORMAL_STS:
        msg = utils.output_log(MSG.INVALID_LDEV_FOR_MANAGE)
        raise exception.ManageExistingInvalidReference(
            existing_ref=existing_ref, reason=msg)
    attributes = set(ldev_info['attributes'])
    if (not ldev_info['emulationType'].startswith('OPEN-V') or
            len(attributes) < 2 or not attributes.issubset(_PERMITTED_TYPES)):
        msg = utils.output_log(MSG.INVALID_LDEV_ATTR_FOR_MANAGE, ldev=ldev,
                               ldevtype=utils.NVOL_LDEV_TYPE)
        raise exception.ManageExistingInvalidReference(
            existing_ref=existing_ref, reason=msg)
    if ldev_info['numOfPorts']:
        msg = utils.output_log(MSG.INVALID_LDEV_PORT_FOR_MANAGE, ldev=ldev)
        raise exception.ManageExistingInvalidReference(
            existing_ref=existing_ref, reason=msg)
    def manage_existing_get_size(self, volume, existing_vol_ref):
        """Gets the size to manage_existing.

        Returns the size of volume to be managed by manage_existing.

        :param volume:           cinder volume to manage
        :param existing_vol_ref: existing volume to take under management
        """
        # Check that the reference is valid.
        if 'source-name' not in existing_vol_ref:
            reason = _('Reference must contain source-name element.')
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_vol_ref, reason=reason)

        ref_name = existing_vol_ref['source-name']
        fs_label, vol_name = self._get_info_from_vol_ref(ref_name)

        LOG.debug("File System: %(fs_label)s "
                  "Volume name: %(vol_name)s.", {
                      'fs_label': fs_label,
                      'vol_name': vol_name
                  })

        vol_name = "'{}'".format(vol_name)

        lu_info = self.bend.get_existing_lu_info(self.config['hnas_cmd'],
                                                 self.config['mgmt_ip0'],
                                                 self.config['username'],
                                                 self.config['password'],
                                                 fs_label, vol_name)

        if fs_label in lu_info:
            aux = lu_info.split('\n')[3]
            size = aux.split(':')[1]
            size_unit = size.split(' ')[2]

            if size_unit == 'TB':
                return int(size.split(' ')[1]) * units.k
            else:
                return int(size.split(' ')[1])
        else:
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_vol_ref,
                reason=_('Volume not found on configured storage backend. '
                         'If your volume name contains "/", please rename it '
                         'and try to manage again.'))
 def manage_existing_get_size(self, volume, existing_ref):
     """Return size of volume to be managed by manage_existing."""
     vdisk = self._manage_input_check(existing_ref)
     if self._get_vdiskhost_mappings(vdisk['name']):
         reason = _('The specified vdisk is mapped to a host.')
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref, reason=reason)
     return int(vdisk['capacity']) / units.Gi
Beispiel #20
0
    def _get_snapshot_info(self, volume, existing_ref):
        snapshot_name = existing_ref.get('source-name')
        if not snapshot_name:
            msg = _("Can't find volume on the array, please check the "
                    "source-name.")
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref, reason=msg)

        pool_id = self._get_pool_id(volume)
        snapshot_info = self.client.query_snapshot_by_name(
            pool_id, snapshot_name=snapshot_name)
        if not snapshot_info:
            msg = _("Can't find snapshot on the array.")
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref, reason=msg)

        return snapshot_info
Beispiel #21
0
    def _get_volume_info(self, pool_id, existing_ref):
        vol_name = existing_ref.get('source-name')
        vol_id = existing_ref.get('source-id')

        if not (vol_name or vol_id):
            msg = _('Must specify source-name or source-id.')
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref, reason=msg)

        vol_info = self._get_vol_info(pool_id, vol_name, vol_id)

        if not vol_info:
            msg = _("Can't find volume on the array, please check the "
                    "source-name or source-id.")
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref, reason=msg)
        return vol_info
Beispiel #22
0
    def manage_existing_get_size(self, dummy_volume, existing_ref):
        ldev = existing_ref.get('source-id')
        if not EXISTING_POOL_REF.get(ldev):
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref, reason='No valid value is '
                'specified for "source-id". A valid value '
                'must be specified for "source-id" to manage the volume.')

        size = EXISTING_POOL_REF[ldev]['size']
        return size
Beispiel #23
0
    def _get_existing_volume_ref_name(self, existing_ref):
        """Return the volume name of an existing ref."""
        if 'source-name' in existing_ref:
            vol_name = existing_ref['source-name']
        else:
            reason = _("Reference must contain source-name.")
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref, reason=reason)

        return vol_name
Beispiel #24
0
 def manage_existing_get_size(self, existing_ref):
     """Return the size[GB] of the specified volume."""
     ldev = _str2int(existing_ref.get('source-id'))
     # When 'ldev' is 0, it should be true.
     # Therefore, it cannot remove 'is None'.
     if ldev is None:
         msg = utils.output_log(MSG.INVALID_LDEV_FOR_MANAGE)
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref, reason=msg)
     return self.get_ldev_size_in_gigabyte(ldev, existing_ref)
    def manage_existing_snapshot(self, snapshot, existing_ref):
        # Attempt to find NFS share, NFS mount, and volume path from ref.
        (nfs_share, nfs_mount, src_snapshot_name
         ) = self._get_share_mount_and_vol_from_vol_ref(existing_ref)

        LOG.info(
            _LI("Asked to manage NFS snapshot %(snap)s for volume "
                "%(vol)s, with vol ref %(ref)s."), {
                    'snap': snapshot.id,
                    'vol': snapshot.volume_id,
                    'ref': existing_ref['source-name']
                })

        volume = snapshot.volume

        # Check if the snapshot belongs to the volume
        real_parent = self._check_snapshot_parent(volume, src_snapshot_name,
                                                  nfs_share)

        if not real_parent:
            msg = (_("This snapshot %(snap)s doesn't belong "
                     "to the volume parent %(vol)s.") % {
                         'snap': snapshot.id,
                         'vol': volume.id
                     })
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref, reason=msg)

        if src_snapshot_name == snapshot.name:
            LOG.debug(
                "New Cinder snapshot %(snap)s name matches reference "
                "name. No need to rename.", {'snap': snapshot.name})
        else:
            src_snap = os.path.join(nfs_mount, src_snapshot_name)
            dst_snap = os.path.join(nfs_mount, snapshot.name)
            try:
                self._try_execute("mv",
                                  src_snap,
                                  dst_snap,
                                  run_as_root=False,
                                  check_exit_code=True)
                LOG.info(
                    _LI("Setting newly managed Cinder snapshot name "
                        "to %(snap)s."), {'snap': snapshot.name})
                self._set_rw_permissions_for_all(dst_snap)
            except (OSError, processutils.ProcessExecutionError) as err:
                msg = (_("Failed to manage existing snapshot "
                         "%(name)s, because rename operation "
                         "failed: Error msg: %(msg)s.") % {
                             'name': existing_ref['source-name'],
                             'msg': six.text_type(err)
                         })
                LOG.error(msg)
                raise exception.VolumeBackendAPIException(data=msg)
        return {'provider_location': nfs_share}
 def _manage_input_check(self, existing_ref):
     """Verify the input of manage function."""
     # Check that the reference is valid
     if 'source-name' in existing_ref:
         manage_source = existing_ref['source-name']
         vdisk = self._get_vdisk_attributes(manage_source)
     elif 'source-id' in existing_ref:
         manage_source = existing_ref['source-id']
         vdisk = self._get_vdisk_attributes(manage_source)
     else:
         reason = _('Reference must contain source-id or '
                    'source-name element.')
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref, reason=reason)
     if vdisk is None:
         reason = (_('No vdisk with the ID specified by ref %s.') %
                   manage_source)
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref, reason=reason)
     return vdisk
Beispiel #27
0
 def manage_existing_get_size(self, volume, existing_ref):
     vol_name = existing_ref['source-name']
     v_rs = self.client.search("volumes", name=vol_name)
     if hasattr(v_rs, 'hits') and v_rs.total != 0:
         vol = v_rs.hits[0]
         size = vol.size / units.Mi
         return math.ceil(size)
     else:
         raise exception.ManageExistingInvalidReference(
             existing_ref=existing_ref,
             reason=_('Unable to get size of manage volume.'))
    def manage_existing_get_size(self, volume, existing_ref):
        """Return size of an existing LV for manage_existing."""
        # Check that the reference is valid
        if 'source-name' not in existing_ref:
            reason = _('Reference must contain source-name element.')
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref, reason=reason)
        lv_name = existing_ref['source-name']
        # Attempt to locate the volume.
        try:
            vol_obj = self.client.req('volumes', name=lv_name)['content']
        except exception.NotFound:
            kwargs = {'existing_ref': lv_name,
                      'reason': 'Specified logical volume does not exist.'}
            raise exception.ManageExistingInvalidReference(**kwargs)
        # LV size is returned in gigabytes.  Attempt to parse size as a float
        # and round up to the next integer.
        lv_size = int(math.ceil(int(vol_obj['vol-size']) / units.Mi))

        return lv_size
Beispiel #29
0
 def _manage_existing_get_size_2(self, volume, existing_ref):
     existing_ref = existing_ref['source-name']
     if existing_ref.count(":") != 2:
         raise exception.ManageExistingInvalidReference(
             _("existing_ref argument must be of this format:"
               "app_inst_name:storage_inst_name:vol_name"))
     app_inst_name, si_name, vol_name = existing_ref.split(":")
     app_inst = self._issue_api_request(
         datc.URL_TEMPLATES['ai_inst']().format(app_inst_name),
         api_version='2')
     return self._get_size_2(volume, app_inst, si_name, vol_name)
Beispiel #30
0
    def _validate_manage_existing_ref(self, existing_ref, is_snap=False):
        """Ensure that an existing_ref is valid and return volume info

        If the ref is not valid throw a ManageExistingInvalidReference
        exception with an appropriate error.

        Will return volume or snapshot information from the array for
        the object specified by existing_ref.
        """
        if "name" not in existing_ref or not existing_ref["name"]:
            raise exception.ManageExistingInvalidReference(
                existing_ref=existing_ref,
                reason=_("manage_existing requires a 'name'"
                         " key to identify an existing volume."))

        if is_snap:
            # Purity snapshot names are prefixed with the source volume name
            ref_vol_name, ref_snap_suffix = existing_ref['name'].split('.')
        else:
            ref_vol_name = existing_ref['name']

        try:
            volume_info = self._array.get_volume(ref_vol_name, snap=is_snap)
            if volume_info:
                if is_snap:
                    for snap in volume_info:
                        if snap['name'] == existing_ref['name']:
                            return snap
                else:
                    return volume_info
        except purestorage.PureHTTPError as err:
            with excutils.save_and_reraise_exception() as ctxt:
                if (err.code == 400 and
                        ERR_MSG_NOT_EXIST in err.text):
                    ctxt.reraise = False

        # If volume information was unable to be retrieved we need
        # to throw a Invalid Reference exception
        raise exception.ManageExistingInvalidReference(
            existing_ref=existing_ref,
            reason=_("Unable to find Purity ref with name=%s") % ref_vol_name)