Exemple #1
0
    def test_get_qos_policy_group_name_from_spec_info(self):
        expected = 'openstack-%s' % fake.VOLUME_ID

        result = na_utils.get_qos_policy_group_name_from_info(
            fake.QOS_POLICY_GROUP_INFO)

        self.assertEqual(expected, result)
Exemple #2
0
    def test_get_qos_policy_group_name_from_legacy_info(self):
        expected = fake.QOS_POLICY_GROUP_NAME

        result = na_utils.get_qos_policy_group_name_from_info(
            fake.LEGACY_QOS_POLICY_GROUP_INFO)

        self.assertEqual(expected, result)
Exemple #3
0
    def manage_existing(self, volume, existing_ref):
        """Brings an existing storage object under Cinder management.

        existing_ref can contain source-id or source-name or both.
        source-id: lun uuid.
        source-name: complete lun path eg. /vol/vol0/lun.
        """
        lun = self._get_existing_vol_with_manage_ref(existing_ref)

        extra_specs = na_utils.get_volume_extra_specs(volume)

        self._check_volume_type_for_lun(volume, lun, existing_ref, extra_specs)

        qos_policy_group_info = self._setup_qos_for_volume(volume, extra_specs)
        qos_policy_group_name = na_utils.get_qos_policy_group_name_from_info(qos_policy_group_info)

        path = lun.get_metadata_property("Path")
        if lun.name == volume["name"]:
            new_path = path
            LOG.info(_LI("LUN with given ref %s need not be renamed " "during manage operation."), existing_ref)
        else:
            (rest, splitter, name) = path.rpartition("/")
            new_path = "%s/%s" % (rest, volume["name"])
            self.zapi_client.move_lun(path, new_path)
            lun = self._get_existing_vol_with_manage_ref({"source-name": new_path})
        if qos_policy_group_name is not None:
            self.zapi_client.set_lun_qos_policy_group(new_path, qos_policy_group_name)
        self._add_lun_to_table(lun)
        LOG.info(
            _LI("Manage operation completed for LUN with new path" " %(path)s and uuid %(uuid)s."),
            {"path": lun.get_metadata_property("Path"), "uuid": lun.get_metadata_property("UUID")},
        )
Exemple #4
0
    def test_get_qos_policy_group_name_from_none_qos_info(self):
        expected = None

        result = na_utils.get_qos_policy_group_name_from_info(
            fake.QOS_POLICY_GROUP_INFO_NONE)

        self.assertEqual(expected, result)
Exemple #5
0
 def _set_qos_policy_group_on_volume(self, volume, qos_policy_group_info):
     if qos_policy_group_info is None:
         return
     qos_policy_group_name = na_utils.get_qos_policy_group_name_from_info(qos_policy_group_info)
     if qos_policy_group_name is None:
         return
     target_path = "%s" % (volume["name"])
     share = volume_utils.extract_host(volume["host"], level="pool")
     export_path = share.split(":")[1]
     flex_vol_name = self.zapi_client.get_vol_by_junc_vserver(self.vserver, export_path)
     self.zapi_client.file_assign_qos(flex_vol_name, qos_policy_group_name, target_path)
Exemple #6
0
    def create_volume(self, volume):
        """Driver entry point for creating a new volume (Data ONTAP LUN)."""

        LOG.debug('create_volume on %s', volume['host'])

        # get Data ONTAP volume name as pool name
        pool_name = volume_utils.extract_host(volume['host'], level='pool')

        if pool_name is None:
            msg = _("Pool is not available in the volume host field.")
            raise exception.InvalidHost(reason=msg)

        extra_specs = na_utils.get_volume_extra_specs(volume)

        lun_name = volume['name']

        size = int(volume['size']) * units.Gi

        metadata = {'OsType': self.lun_ostype,
                    'SpaceReserved': self.lun_space_reservation,
                    'Path': '/vol/%s/%s' % (pool_name, lun_name)}

        qos_policy_group_info = self._setup_qos_for_volume(volume, extra_specs)
        qos_policy_group_name = (
            na_utils.get_qos_policy_group_name_from_info(
                qos_policy_group_info))

        try:
            self._create_lun(pool_name, lun_name, size, metadata,
                             qos_policy_group_name)
        except Exception:
            LOG.exception(_LE("Exception creating LUN %(name)s in pool "
                              "%(pool)s."),
                          {'name': lun_name, 'pool': pool_name})
            self._mark_qos_policy_group_for_deletion(qos_policy_group_info)
            msg = _("Volume %s could not be created.")
            raise exception.VolumeBackendAPIException(data=msg % (
                volume['name']))
        LOG.debug('Created LUN with name %(name)s and QoS info %(qos)s',
                  {'name': lun_name, 'qos': qos_policy_group_info})

        metadata['Path'] = '/vol/%s/%s' % (pool_name, lun_name)
        metadata['Volume'] = pool_name
        metadata['Qtree'] = None

        handle = self._create_lun_handle(metadata)
        self._add_lun_to_table(NetAppLun(handle, lun_name, size, metadata))

        model_update = self._get_volume_model_update(volume)

        return model_update
Exemple #7
0
 def _set_qos_policy_group_on_volume(self, volume, qos_policy_group_info):
     if qos_policy_group_info is None:
         return
     qos_policy_group_name = na_utils.get_qos_policy_group_name_from_info(
         qos_policy_group_info)
     if qos_policy_group_name is None:
         return
     target_path = '%s' % (volume['name'])
     share = volume_utils.extract_host(volume['host'], level='pool')
     __, export_path = na_utils.get_export_host_junction_path(share)
     flex_vol_name = self.zapi_client.get_vol_by_junc_vserver(self.vserver,
                                                              export_path)
     self.zapi_client.file_assign_qos(flex_vol_name,
                                      qos_policy_group_name,
                                      target_path)
    def create_volume(self, volume):
        """Driver entry point for creating a new volume (Data ONTAP LUN)."""

        LOG.debug('create_volume on %s', volume['host'])

        # get Data ONTAP volume name as pool name
        pool_name = volume_utils.extract_host(volume['host'], level='pool')

        if pool_name is None:
            msg = _("Pool is not available in the volume host field.")
            raise exception.InvalidHost(reason=msg)

        extra_specs = na_utils.get_volume_extra_specs(volume)

        lun_name = volume['name']

        size = int(volume['size']) * units.Gi

        metadata = {'OsType': self.lun_ostype,
                    'SpaceReserved': 'true',
                    'Path': '/vol/%s/%s' % (pool_name, lun_name)}

        qos_policy_group_info = self._setup_qos_for_volume(volume, extra_specs)
        qos_policy_group_name = (
            na_utils.get_qos_policy_group_name_from_info(
                qos_policy_group_info))

        try:
            self._create_lun(pool_name, lun_name, size, metadata,
                             qos_policy_group_name)
        except Exception:
            LOG.exception(_LE("Exception creating LUN %(name)s in pool "
                              "%(pool)s."),
                          {'name': lun_name, 'pool': pool_name})
            self._mark_qos_policy_group_for_deletion(qos_policy_group_info)
            msg = _("Volume %s could not be created.")
            raise exception.VolumeBackendAPIException(data=msg % (
                volume['name']))
        LOG.debug('Created LUN with name %(name)s and QoS info %(qos)s',
                  {'name': lun_name, 'qos': qos_policy_group_info})

        metadata['Path'] = '/vol/%s/%s' % (pool_name, lun_name)
        metadata['Volume'] = pool_name
        metadata['Qtree'] = None

        handle = self._create_lun_handle(metadata)
        self._add_lun_to_table(NetAppLun(handle, lun_name, size, metadata))
Exemple #9
0
    def create_volume(self, volume):
        """Driver entry point for creating a new volume (Data ONTAP LUN)."""

        LOG.debug("create_volume on %s", volume["host"])

        # get Data ONTAP volume name as pool name
        pool_name = volume_utils.extract_host(volume["host"], level="pool")

        if pool_name is None:
            msg = _("Pool is not available in the volume host field.")
            raise exception.InvalidHost(reason=msg)

        extra_specs = na_utils.get_volume_extra_specs(volume)

        lun_name = volume["name"]

        size = int(volume["size"]) * units.Gi

        metadata = {
            "OsType": self.lun_ostype,
            "SpaceReserved": self.lun_space_reservation,
            "Path": "/vol/%s/%s" % (pool_name, lun_name),
        }

        qos_policy_group_info = self._setup_qos_for_volume(volume, extra_specs)
        qos_policy_group_name = na_utils.get_qos_policy_group_name_from_info(qos_policy_group_info)

        try:
            self._create_lun(pool_name, lun_name, size, metadata, qos_policy_group_name)
        except Exception:
            LOG.exception(
                _LE("Exception creating LUN %(name)s in pool " "%(pool)s."), {"name": lun_name, "pool": pool_name}
            )
            self._mark_qos_policy_group_for_deletion(qos_policy_group_info)
            msg = _("Volume %s could not be created.")
            raise exception.VolumeBackendAPIException(data=msg % (volume["name"]))
        LOG.debug(
            "Created LUN with name %(name)s and QoS info %(qos)s", {"name": lun_name, "qos": qos_policy_group_info}
        )

        metadata["Path"] = "/vol/%s/%s" % (pool_name, lun_name)
        metadata["Volume"] = pool_name
        metadata["Qtree"] = None

        handle = self._create_lun_handle(metadata)
        self._add_lun_to_table(NetAppLun(handle, lun_name, size, metadata))
Exemple #10
0
    def _clone_source_to_destination(self, source, destination_volume):
        source_size = source['size']
        destination_size = destination_volume['size']

        source_name = source['name']
        destination_name = destination_volume['name']

        extra_specs = na_utils.get_volume_extra_specs(destination_volume)

        qos_policy_group_info = self._setup_qos_for_volume(
            destination_volume, extra_specs)
        qos_policy_group_name = (na_utils.get_qos_policy_group_name_from_info(
            qos_policy_group_info))

        try:
            self._clone_lun(source_name,
                            destination_name,
                            space_reserved=self.lun_space_reservation,
                            qos_policy_group_name=qos_policy_group_name)

            if destination_size != source_size:

                try:
                    self._extend_volume(destination_volume, destination_size,
                                        qos_policy_group_name)
                except Exception:
                    with excutils.save_and_reraise_exception():
                        LOG.error("Resizing %s failed. Cleaning volume.",
                                  destination_volume['id'])
                        self.delete_volume(destination_volume)

            return self._get_volume_model_update(destination_volume)

        except Exception:
            LOG.exception(
                "Exception cloning volume %(name)s from source "
                "volume %(source)s.", {
                    'name': destination_name,
                    'source': source_name
                })

            self._mark_qos_policy_group_for_deletion(qos_policy_group_info)

            msg = _("Volume %s could not be created from source volume.")
            raise exception.VolumeBackendAPIException(data=msg %
                                                      destination_name)
Exemple #11
0
    def _clone_source_to_destination(self, source, destination_volume):
        source_size = source['size']
        destination_size = destination_volume['size']

        source_name = source['name']
        destination_name = destination_volume['name']

        extra_specs = na_utils.get_volume_extra_specs(destination_volume)

        qos_policy_group_info = self._setup_qos_for_volume(
            destination_volume, extra_specs)
        qos_policy_group_name = (
            na_utils.get_qos_policy_group_name_from_info(
                qos_policy_group_info))

        try:
            self._clone_lun(source_name, destination_name,
                            space_reserved=self.lun_space_reservation,
                            qos_policy_group_name=qos_policy_group_name)

            if destination_size != source_size:

                try:
                    self._extend_volume(destination_volume,
                                        destination_size,
                                        qos_policy_group_name)
                except Exception:
                    with excutils.save_and_reraise_exception():
                        LOG.error(
                            _LE("Resizing %s failed. Cleaning volume."),
                            destination_volume['id'])
                        self.delete_volume(destination_volume)

            return self._get_volume_model_update(destination_volume)

        except Exception:
            LOG.exception(_LE("Exception cloning volume %(name)s from source "
                          "volume %(source)s."),
                          {'name': destination_name, 'source': source_name})

            self._mark_qos_policy_group_for_deletion(qos_policy_group_info)

            msg = _("Volume %s could not be created from source volume.")
            raise exception.VolumeBackendAPIException(
                data=msg % destination_name)
Exemple #12
0
    def manage_existing(self, volume, existing_ref):
        """Brings an existing storage object under Cinder management.

        existing_ref can contain source-id or source-name or both.
        source-id: lun uuid.
        source-name: complete lun path eg. /vol/vol0/lun.
        """
        lun = self._get_existing_vol_with_manage_ref(existing_ref)

        extra_specs = na_utils.get_volume_extra_specs(volume)

        self._check_volume_type_for_lun(volume, lun, existing_ref, extra_specs)

        qos_policy_group_info = self._setup_qos_for_volume(volume, extra_specs)
        qos_policy_group_name = (na_utils.get_qos_policy_group_name_from_info(
            qos_policy_group_info))
        is_adaptive = na_utils.is_qos_policy_group_spec_adaptive(
            qos_policy_group_info)

        path = lun.get_metadata_property('Path')
        if lun.name == volume['name']:
            new_path = path
            LOG.info(
                "LUN with given ref %s need not be renamed "
                "during manage operation.", existing_ref)
        else:
            (rest, splitter, name) = path.rpartition('/')
            new_path = '%s/%s' % (rest, volume['name'])
            self.zapi_client.move_lun(path, new_path)
            lun = self._get_existing_vol_with_manage_ref(
                {'source-name': new_path})

        if qos_policy_group_name is not None:
            self.zapi_client.set_lun_qos_policy_group(new_path,
                                                      qos_policy_group_name,
                                                      is_adaptive)
        self._add_lun_to_table(lun)
        LOG.info(
            "Manage operation completed for LUN with new path"
            " %(path)s and uuid %(uuid)s.", {
                'path': lun.get_metadata_property('Path'),
                'uuid': lun.get_metadata_property('UUID')
            })

        return self._get_volume_model_update(volume)
Exemple #13
0
    def extend_volume(self, volume, new_size):
        """Driver entry point to increase the size of a volume."""

        extra_specs = na_utils.get_volume_extra_specs(volume)

        # Create volume copy with new size for size-dependent QOS specs
        volume_copy = copy.copy(volume)
        volume_copy['size'] = new_size

        qos_policy_group_info = self._setup_qos_for_volume(
            volume_copy, extra_specs)
        qos_policy_group_name = (na_utils.get_qos_policy_group_name_from_info(
            qos_policy_group_info))

        try:
            self._extend_volume(volume, new_size, qos_policy_group_name)
        except Exception:
            with excutils.save_and_reraise_exception():
                # If anything went wrong, revert QoS settings
                self._setup_qos_for_volume(volume, extra_specs)
Exemple #14
0
    def extend_volume(self, volume, new_size):
        """Driver entry point to increase the size of a volume."""

        extra_specs = na_utils.get_volume_extra_specs(volume)

        # Create volume copy with new size for size-dependent QOS specs
        volume_copy = copy.copy(volume)
        volume_copy['size'] = new_size

        qos_policy_group_info = self._setup_qos_for_volume(volume_copy,
                                                           extra_specs)
        qos_policy_group_name = (
            na_utils.get_qos_policy_group_name_from_info(
                qos_policy_group_info))

        try:
            self._extend_volume(volume, new_size, qos_policy_group_name)
        except Exception:
            with excutils.save_and_reraise_exception():
                # If anything went wrong, revert QoS settings
                self._setup_qos_for_volume(volume, extra_specs)
Exemple #15
0
    def test_get_qos_policy_group_name_from_info_no_info(self):

        result = na_utils.get_qos_policy_group_name_from_info(None)

        self.assertIsNone(result)
Exemple #16
0
    def test_get_qos_policy_group_name_from_info_no_info(self):

        result = na_utils.get_qos_policy_group_name_from_info(None)

        self.assertIsNone(result)
Exemple #17
0
    def test_get_qos_policy_group_name_from_info(self):
        expected = 'openstack-%s' % fake.VOLUME_ID
        result = na_utils.get_qos_policy_group_name_from_info(
            fake.QOS_POLICY_GROUP_INFO)

        self.assertEqual(expected, result)