def test_volume_type_get_by_id_and_name(self):
        """Ensure volume types get returns same entry"""
        volume_types.create(self.ctxt, self.vol_type1_name, self.vol_type1_specs)
        new = volume_types.get_volume_type_by_name(self.ctxt, self.vol_type1_name)

        new2 = volume_types.get_volume_type(self.ctxt, new["id"])
        self.assertEqual(new, new2)
Beispiel #2
0
 def _get_ss_type(self, volume):
     """Get the storage service type for a volume."""
     id = volume['volume_type_id']
     if not id:
         return None
     volume_type = volume_types.get_volume_type(None, id)
     if not volume_type:
         return None
     return volume_type['name']
Beispiel #3
0
    def delete(self, req, id):
        """ Deletes an existing volume type """
        context = req.environ['nova.context']

        try:
            vol_type = volume_types.get_volume_type(context, id)
            volume_types.destroy(context, vol_type['name'])
        except exception.NotFound:
            raise exc.HTTPNotFound()
Beispiel #4
0
    def test_volume_type_get_by_id_and_name(self):
        """Ensure volume types get returns same entry"""
        volume_types.create(self.ctxt, self.vol_type1_name,
                            self.vol_type1_specs)
        new = volume_types.get_volume_type_by_name(self.ctxt,
                                                   self.vol_type1_name)

        new2 = volume_types.get_volume_type(self.ctxt, new['id'])
        self.assertEqual(new, new2)
Beispiel #5
0
 def _get_ss_type(self, volume):
     """Get the storage service type for a volume."""
     id = volume['volume_type_id']
     if not id:
         return None
     volume_type = volume_types.get_volume_type(None, id)
     if not volume_type:
         return None
     return volume_type['name']
Beispiel #6
0
    def delete(self, req, id):
        """ Deletes an existing volume type """
        context = req.environ['nova.context']

        try:
            vol_type = volume_types.get_volume_type(context, id)
            volume_types.destroy(context, vol_type['name'])
        except exception.NotFound:
            raise exc.HTTPNotFound()
Beispiel #7
0
    def schedule_create_volume(self, context, volume_id, *_args, **_kwargs):
        """Picks the best host based on requested drive type capability."""
        volume_ref = db.volume_get(context, volume_id)

        host = self._check_host_enforcement(context,
                                            volume_ref['availability_zone'])
        if host:
            driver.cast_to_volume_host(context,
                                       host,
                                       'create_volume',
                                       volume_id=volume_id,
                                       **_kwargs)
            return None

        volume_type_id = volume_ref['volume_type_id']
        if volume_type_id:
            volume_type = volume_types.get_volume_type(context, volume_type_id)

        if volume_type_id is None or\
           volume_types.is_vsa_volume(volume_type_id, volume_type):

            LOG.debug(_("Non-VSA volume %d"), volume_ref['id'])
            return super(VsaScheduler,
                         self).schedule_create_volume(context, volume_id,
                                                      *_args, **_kwargs)

        self._print_capabilities_info()

        drive_type = {
            'name': volume_type['extra_specs'].get('drive_name'),
            'type': volume_type['extra_specs'].get('drive_type'),
            'size': int(volume_type['extra_specs'].get('drive_size')),
            'rpm': volume_type['extra_specs'].get('drive_rpm'),
        }

        LOG.debug(_("Spawning volume %(volume_id)s with drive type "\
                    "%(drive_type)s"), locals())

        request_spec = {'size': volume_ref['size'], 'drive_type': drive_type}
        hosts = self._filter_hosts("volume", request_spec)

        try:
            (host, qos_cap) = self._select_hosts(request_spec, all_hosts=hosts)
        except Exception:
            LOG.exception(_("Error creating volume"))
            if volume_ref['to_vsa_id']:
                db.vsa_update(context, volume_ref['to_vsa_id'],
                              dict(status=VsaState.FAILED))
            raise

        if host:
            driver.cast_to_volume_host(context,
                                       host,
                                       'create_volume',
                                       volume_id=volume_id,
                                       **_kwargs)
Beispiel #8
0
    def show(self, req, id):
        """ Return a single volume type item """
        context = req.environ["nova.context"]

        try:
            vol_type = volume_types.get_volume_type(context, id)
        except exception.NotFound:
            raise exc.HTTPNotFound()

        return {"volume_type": vol_type}
Beispiel #9
0
    def show(self, req, id):
        """ Return a single volume type item """
        context = req.environ['nova.context']

        try:
            vol_type = volume_types.get_volume_type(context, id)
        except exception.NotFound or exception.ApiError:
            raise exc.HTTPNotFound()

        return {'volume_type': vol_type}
Beispiel #10
0
    def show(self, req, id):
        """ Return a single volume type item """
        context = req.environ['nova.context']

        try:
            vol_type = volume_types.get_volume_type(context, id)
        except exception.NotFound or exception.ApiError:
            raise exc.HTTPNotFound()

        return {'volume_type': vol_type}
Beispiel #11
0
    def schedule_create_volume(self, context, volume_id, *_args, **_kwargs):
        """Picks the best host based on requested drive type capability."""
        volume_ref = db.volume_get(context, volume_id)

        host = self._check_host_enforcement(context,
                                            volume_ref['availability_zone'])
        if host:
            now = utils.utcnow()
            db.volume_update(context, volume_id, {'host': host,
                                                  'scheduled_at': now})
            return host

        volume_type_id = volume_ref['volume_type_id']
        if volume_type_id:
            volume_type = volume_types.get_volume_type(context, volume_type_id)

        if volume_type_id is None or\
           volume_types.is_vsa_volume(volume_type_id, volume_type):

            LOG.debug(_("Non-VSA volume %d"), volume_ref['id'])
            return super(VsaScheduler, self).schedule_create_volume(context,
                        volume_id, *_args, **_kwargs)

        self._print_capabilities_info()

        drive_type = {
            'name': volume_type['extra_specs'].get('drive_name'),
            'type': volume_type['extra_specs'].get('drive_type'),
            'size': int(volume_type['extra_specs'].get('drive_size')),
            'rpm': volume_type['extra_specs'].get('drive_rpm'),
            }

        LOG.debug(_("Spawning volume %(volume_id)s with drive type "\
                    "%(drive_type)s"), locals())

        request_spec = {'size': volume_ref['size'],
                        'drive_type': drive_type}
        hosts = self._filter_hosts("volume", request_spec)

        try:
            (host, qos_cap) = self._select_hosts(request_spec, all_hosts=hosts)
        except:
            if volume_ref['to_vsa_id']:
                db.vsa_update(context, volume_ref['to_vsa_id'],
                                dict(status=VsaState.FAILED))
            raise

        if host:
            now = utils.utcnow()
            db.volume_update(context, volume_id, {'host': host,
                                                  'scheduled_at': now})
            self._consume_resource(qos_cap, volume_ref['size'], -1)
            return host
Beispiel #12
0
    def _delete(self, req, id):
        """ Deletes an existing volume type """
        context = req.environ['nova.context']
        authorize(context)

        try:
            vol_type = volume_types.get_volume_type(context, id)
            volume_types.destroy(context, vol_type['name'])
        except exception.NotFound:
            raise webob.exc.HTTPNotFound()

        return webob.Response(status_int=202)
Beispiel #13
0
    def _delete(self, req, id):
        """ Deletes an existing volume type """
        context = req.environ['nova.context']
        authorize(context)

        try:
            vol_type = volume_types.get_volume_type(context, id)
            volume_types.destroy(context, vol_type['name'])
        except exception.NotFound:
            raise webob.exc.HTTPNotFound()

        return webob.Response(status_int=202)
Beispiel #14
0
    def show(self, req, id):
        """ Return a single volume type item """
        context = req.environ['nova.context']

        try:
            vol_type = volume_types.get_volume_type(context, id)
        except exception.NotFound:
            raise exc.HTTPNotFound()

        # TODO(bcwaldon): remove str cast once we use uuids
        vol_type['id'] = str(vol_type['id'])
        return {'volume_type': vol_type}
Beispiel #15
0
    def schedule_create_volume(self, context, volume_id, *_args, **_kwargs):
        """Picks the best host based on requested drive type capability."""
        volume_ref = db.volume_get(context, volume_id)

        host = self._check_host_enforcement(context,
                                            volume_ref['availability_zone'])
        if host:
            driver.cast_to_volume_host(context, host, 'create_volume',
                    volume_id=volume_id, **_kwargs)
            return None

        volume_type_id = volume_ref['volume_type_id']
        if volume_type_id:
            volume_type = volume_types.get_volume_type(context, volume_type_id)

        if (volume_type_id is None or
            volume_types.is_vsa_volume(volume_type_id, volume_type)):

            LOG.debug(_("Non-VSA volume %d"), volume_ref['id'])
            return super(VsaScheduler, self).schedule_create_volume(context,
                        volume_id, *_args, **_kwargs)

        self._print_capabilities_info()

        drive_type = {
            'name': volume_type['extra_specs'].get('drive_name'),
            'type': volume_type['extra_specs'].get('drive_type'),
            'size': int(volume_type['extra_specs'].get('drive_size')),
            'rpm': volume_type['extra_specs'].get('drive_rpm'),
            }

        LOG.debug(_("Spawning volume %(volume_id)s with drive type "
                    "%(drive_type)s"), locals())

        request_spec = {'size': volume_ref['size'],
                        'drive_type': drive_type}
        hosts = self._filter_hosts("volume", request_spec)

        try:
            (host, qos_cap) = self._select_hosts(request_spec, all_hosts=hosts)
        except Exception:
            LOG.exception(_("Error creating volume"))
            if volume_ref['to_vsa_id']:
                db.vsa_update(context, volume_ref['to_vsa_id'],
                                dict(status=vsa_api.VsaState.FAILED))
            raise

        if host:
            driver.cast_to_volume_host(context, host, 'create_volume',
                    volume_id=volume_id, **_kwargs)
Beispiel #16
0
    def create_volume(self, volume):
        """Creates BE volume."""
        if self._not_vsa_volume_or_drive(volume):
            return super(ZadaraBEDriver, self).create_volume(volume)

        if self._is_vsa_volume(volume):
            LOG.debug(_("\tFE VSA Volume %s creation - do nothing"),
                      volume['name'])
            return

        if int(volume['size']) == 0:
            sizestr = '0'  # indicates full-partition
        else:
            sizestr = '%s' % (int(volume['size']) << 30)  # size in bytes

        # Set the qos-str to default type sas
        qosstr = 'SAS_1000'
        volume_type = volume_types.get_volume_type(None,
                                                   volume['volume_type_id'])
        if volume_type is not None:
            qosstr = '_'.join([
                volume_type['extra_specs']['drive_type'],
                volume_type['extra_specs']['drive_size']
            ])

        vsa_id = None
        for i in volume.get('volume_metadata'):
            if i['key'] == 'to_vsa_id':
                vsa_id = i['value']
                break

        try:
            self._execute('/var/lib/zadara/bin/zadara_sncfg',
                          'create_qospart',
                          '--qos',
                          qosstr,
                          '--pname',
                          volume['name'],
                          '--psize',
                          sizestr,
                          '--vsaid',
                          vsa_id,
                          run_as_root=True,
                          check_exit_code=0)
        except exception.ProcessExecutionError:
            LOG.debug(_("VSA BE create_volume for %s failed"), volume['name'])
            raise

        LOG.debug(_("VSA BE create_volume for %s succeeded"), volume['name'])
Beispiel #17
0
    def create_volume(self, volume):
        """Creates BE volume."""
        if self._not_vsa_volume_or_drive(volume):
            return super(ZadaraBEDriver, self).create_volume(volume)

        if self._is_vsa_volume(volume):
            LOG.debug(_("\tFE VSA Volume %s creation - do nothing"), volume["name"])
            return

        if int(volume["size"]) == 0:
            sizestr = "0"  # indicates full-partition
        else:
            sizestr = "%s" % (int(volume["size"]) << 30)  # size in bytes

        # Set the qos-str to default type sas
        qosstr = "SAS_1000"
        volume_type = volume_types.get_volume_type(None, volume["volume_type_id"])
        if volume_type is not None:
            qosstr = volume_type["extra_specs"]["drive_type"] + ("_%s" % volume_type["extra_specs"]["drive_size"])

        vsa_id = None
        for i in volume.get("volume_metadata"):
            if i["key"] == "to_vsa_id":
                vsa_id = i["value"]
                break

        try:
            self._execute(
                "/var/lib/zadara/bin/zadara_sncfg",
                "create_qospart",
                "--qos",
                qosstr,
                "--pname",
                volume["name"],
                "--psize",
                sizestr,
                "--vsaid",
                vsa_id,
                run_as_root=True,
                check_exit_code=0,
            )
        except exception.ProcessExecutionError:
            LOG.debug(_("VSA BE create_volume for %s failed"), volume["name"])
            raise

        LOG.debug(_("VSA BE create_volume for %s succeeded"), volume["name"])
Beispiel #18
0
    def _assign_hosts_to_volumes(self, context, volume_params, forced_host):

        prev_volume_type_id = None
        request_spec = {}
        selected_hosts = []

        LOG.debug(_("volume_params %(volume_params)s") % locals())

        i = 1
        for vol in volume_params:
            name = vol['name']
            LOG.debug(_("%(i)d: Volume %(name)s"), locals())
            i += 1

            if forced_host:
                vol['host'] = forced_host
                vol['capabilities'] = None
                continue

            volume_type_id = vol['volume_type_id']
            request_spec['size'] = vol['size']

            if prev_volume_type_id is None or\
               prev_volume_type_id != volume_type_id:
                # generate list of hosts for this drive type

                volume_type = volume_types.get_volume_type(context,
                                                volume_type_id)
                drive_type = {
                    'name': volume_type['extra_specs'].get('drive_name'),
                    'type': volume_type['extra_specs'].get('drive_type'),
                    'size': int(volume_type['extra_specs'].get('drive_size')),
                    'rpm': volume_type['extra_specs'].get('drive_rpm'),
                    }
                request_spec['drive_type'] = drive_type

                all_hosts = self._filter_hosts("volume", request_spec)
                prev_volume_type_id = volume_type_id

            (host, qos_cap) = self._select_hosts(request_spec,
                                    all_hosts, selected_hosts)
            vol['host'] = host
            vol['capabilities'] = qos_cap
            self._consume_resource(qos_cap, vol['size'], -1)
Beispiel #19
0
    def _assign_hosts_to_volumes(self, context, volume_params, forced_host):

        prev_volume_type_id = None
        request_spec = {}
        selected_hosts = []

        LOG.debug(_("volume_params %(volume_params)s") % locals())

        i = 1
        for vol in volume_params:
            name = vol['name']
            LOG.debug(_("%(i)d: Volume %(name)s"), locals())
            i += 1

            if forced_host:
                vol['host'] = forced_host
                vol['capabilities'] = None
                continue

            volume_type_id = vol['volume_type_id']
            request_spec['size'] = vol['size']

            if prev_volume_type_id is None or\
               prev_volume_type_id != volume_type_id:
                # generate list of hosts for this drive type

                volume_type = volume_types.get_volume_type(
                    context, volume_type_id)
                drive_type = {
                    'name': volume_type['extra_specs'].get('drive_name'),
                    'type': volume_type['extra_specs'].get('drive_type'),
                    'size': int(volume_type['extra_specs'].get('drive_size')),
                    'rpm': volume_type['extra_specs'].get('drive_rpm'),
                }
                request_spec['drive_type'] = drive_type

                all_hosts = self._filter_hosts("volume", request_spec)
                prev_volume_type_id = volume_type_id

            (host, qos_cap) = self._select_hosts(request_spec, all_hosts,
                                                 selected_hosts)
            vol['host'] = host
            vol['capabilities'] = qos_cap
            self._consume_resource(qos_cap, vol['size'], -1)
Beispiel #20
0
    def create_volume(self, volume):
        """Creates BE volume."""
        if self._not_vsa_volume_or_drive(volume):
            return super(ZadaraBEDriver, self).create_volume(volume)

        if self._is_vsa_volume(volume):
            LOG.debug(_("\tFE VSA Volume %s creation - do nothing"),
                        volume['name'])
            return

        if int(volume['size']) == 0:
            sizestr = '0'   # indicates full-partition
        else:
            sizestr = '%s' % (int(volume['size']) << 30)    # size in bytes

        # Set the qos-str to default type sas
        qosstr = 'SAS_1000'
        volume_type = volume_types.get_volume_type(None,
                                            volume['volume_type_id'])
        if volume_type is not None:
            qosstr = volume_type['extra_specs']['drive_type'] + \
                     ("_%s" % volume_type['extra_specs']['drive_size'])

        vsa_id = None
        for i in volume.get('volume_metadata'):
            if i['key'] == 'to_vsa_id':
                vsa_id = i['value']
                break

        try:
            self._execute('/var/lib/zadara/bin/zadara_sncfg',
                          'create_qospart',
                          '--qos', qosstr,
                          '--pname', volume['name'],
                          '--psize', sizestr,
                          '--vsaid', vsa_id,
                          run_as_root=True,
                          check_exit_code=0)
        except exception.ProcessExecutionError:
            LOG.debug(_("VSA BE create_volume for %s failed"), volume['name'])
            raise

        LOG.debug(_("VSA BE create_volume for %s succeeded"), volume['name'])
Beispiel #21
0
    def _assign_hosts_to_volumes(self, context, volume_params, forced_host):

        prev_volume_type_id = None
        request_spec = {}
        selected_hosts = []

        LOG.debug(_("volume_params %(volume_params)s") % locals())

        i = 1
        for vol in volume_params:
            name = vol["name"]
            LOG.debug(_("%(i)d: Volume %(name)s"), locals())
            i += 1

            if forced_host:
                vol["host"] = forced_host
                vol["capabilities"] = None
                continue

            volume_type_id = vol["volume_type_id"]
            request_spec["size"] = vol["size"]

            if prev_volume_type_id is None or prev_volume_type_id != volume_type_id:
                # generate list of hosts for this drive type

                volume_type = volume_types.get_volume_type(context, volume_type_id)
                drive_type = {
                    "name": volume_type["extra_specs"].get("drive_name"),
                    "type": volume_type["extra_specs"].get("drive_type"),
                    "size": int(volume_type["extra_specs"].get("drive_size")),
                    "rpm": volume_type["extra_specs"].get("drive_rpm"),
                }
                request_spec["drive_type"] = drive_type

                all_hosts = self._filter_hosts("volume", request_spec)
                prev_volume_type_id = volume_type_id

            (host, qos_cap) = self._select_hosts(request_spec, all_hosts, selected_hosts)
            vol["host"] = host
            vol["capabilities"] = qos_cap
            self._consume_resource(qos_cap, vol["size"], -1)
Beispiel #22
0
    def create(self, context, display_name='', display_description='',
                vc_count=1, instance_type=None, image_name=None,
                availability_zone=None, storage=[], shared=None):
        """Provision VSA instance with compute instances and volumes

        :param storage: List of dictionaries with following keys:
                        disk_name, num_disks, size
        :param shared: Specifies if storage is dedicated or shared.
                       For shared storage disks split into partitions
        """

        LOG.info(_("*** Experimental VSA code ***"))

        if vc_count > FLAGS.max_vcs_in_vsa:
            LOG.warning(_("Requested number of VCs (%d) is too high."
                          " Setting to default"), vc_count)
            vc_count = FLAGS.max_vcs_in_vsa

        if instance_type is None:
            instance_type = self._get_default_vsa_instance_type()

        if availability_zone is None:
            availability_zone = FLAGS.storage_availability_zone

        if storage is None:
            storage = []

        if not shared or shared == 'False':
            shared = False
        else:
            shared = True

        # check if image is ready before starting any work
        if image_name is None:
            image_name = FLAGS.vc_image_name

        image_service = self.compute_api.image_service
        vc_image = image_service.show_by_name(context, image_name)
        vc_image_href = vc_image['id']

        options = {
            'display_name': display_name,
            'display_description': display_description,
            'project_id': context.project_id,
            'availability_zone': availability_zone,
            'instance_type_id': instance_type['id'],
            'image_ref': vc_image_href,
            'vc_count': vc_count,
            'status': VsaState.CREATING,
        }
        LOG.info(_("Creating VSA: %s") % options)

        # create DB entry for VSA instance
        vsa_ref = self.db.vsa_create(context, options)

        vsa_id = vsa_ref['id']
        vsa_name = vsa_ref['name']

        # check storage parameters
        try:
            volume_params = self._check_storage_parameters(context, vsa_name,
                                                           storage, shared)
        except exception.InvalidVolumeType:
            self.db.vsa_destroy(context, vsa_id)
            raise

        # after creating DB entry, re-check and set some defaults
        updates = {}
        if (not hasattr(vsa_ref, 'display_name') or
                vsa_ref.display_name is None or
                vsa_ref.display_name == ''):
            updates['display_name'] = display_name = vsa_name
        updates['vol_count'] = len(volume_params)
        vsa_ref = self.update(context, vsa_id, **updates)

        # create volumes
        if FLAGS.vsa_multi_vol_creation:
            if len(volume_params) > 0:
                request_spec = {
                    'num_volumes': len(volume_params),
                    'vsa_id': str(vsa_id),
                    'volumes': volume_params,
                }

                rpc.cast(context,
                         FLAGS.scheduler_topic,
                         {"method": "create_volumes",
                          "args": {"topic": FLAGS.volume_topic,
                                   "request_spec": request_spec,
                                   "availability_zone": availability_zone}})
        else:
            # create BE volumes one-by-one
            for vol in volume_params:
                try:
                    vol_name = vol['name']
                    vol_size = vol['size']
                    vol_type_id = vol['volume_type_id']
                    LOG.debug(_("VSA ID %(vsa_id)d %(vsa_name)s: Create "
                                "volume %(vol_name)s, %(vol_size)d GB, "
                                "type %(vol_type_id)s"), locals())

                    vol_type = volume_types.get_volume_type(context,
                                                vol['volume_type_id'])

                    vol_ref = self.volume_api.create(context,
                                    vol_size,
                                    vol_name,
                                    vol['description'],
                                    None,
                                    volume_type=vol_type,
                                    metadata=dict(to_vsa_id=str(vsa_id)),
                                    availability_zone=availability_zone)
                except Exception:
                    self.update_vsa_status(context, vsa_id,
                                           status=VsaState.PARTIAL)
                    raise

        if len(volume_params) == 0:
            # No BE volumes - ask VSA manager to start VCs
            rpc.cast(context,
                     FLAGS.vsa_topic,
                     {"method": "create_vsa",
                      "args": {"vsa_id": str(vsa_id)}})

        return vsa_ref
Beispiel #23
0
    def create(self,
               context,
               display_name='',
               display_description='',
               vc_count=1,
               instance_type=None,
               image_name=None,
               availability_zone=None,
               storage=[],
               shared=None):
        """
        Provision VSA instance with corresponding compute instances
        and associated volumes
        :param storage: List of dictionaries with following keys:
                        disk_name, num_disks, size
        :param shared: Specifies if storage is dedicated or shared.
                       For shared storage disks split into partitions
        """

        LOG.info(_("*** Experimental VSA code ***"))

        if vc_count > FLAGS.max_vcs_in_vsa:
            LOG.warning(_("Requested number of VCs (%d) is too high."\
                          " Setting to default"), vc_count)
            vc_count = FLAGS.max_vcs_in_vsa

        if instance_type is None:
            instance_type = self._get_default_vsa_instance_type()

        if availability_zone is None:
            availability_zone = FLAGS.storage_availability_zone

        if storage is None:
            storage = []

        if not shared or shared == 'False':
            shared = False
        else:
            shared = True

        # check if image is ready before starting any work
        if image_name is None:
            image_name = FLAGS.vc_image_name
        try:
            image_service = self.compute_api.image_service
            vc_image = image_service.show_by_name(context, image_name)
            vc_image_href = vc_image['id']
        except exception.ImageNotFound:
            raise exception.ApiError(
                _("Failed to find configured image %s") % image_name)

        options = {
            'display_name': display_name,
            'display_description': display_description,
            'project_id': context.project_id,
            'availability_zone': availability_zone,
            'instance_type_id': instance_type['id'],
            'image_ref': vc_image_href,
            'vc_count': vc_count,
            'status': VsaState.CREATING,
        }
        LOG.info(_("Creating VSA: %s") % options)

        # create DB entry for VSA instance
        try:
            vsa_ref = self.db.vsa_create(context, options)
        except exception.Error:
            raise exception.ApiError(_(sys.exc_info()[1]))
        vsa_id = vsa_ref['id']
        vsa_name = vsa_ref['name']

        # check storage parameters
        try:
            volume_params = self._check_storage_parameters(
                context, vsa_name, storage, shared)
        except exception.ApiError:
            self.db.vsa_destroy(context, vsa_id)
            raise exception.ApiError(
                _("Error in storage parameters: %s") % storage)

        # after creating DB entry, re-check and set some defaults
        updates = {}
        if (not hasattr(vsa_ref, 'display_name')
                or vsa_ref.display_name is None or vsa_ref.display_name == ''):
            updates['display_name'] = display_name = vsa_name
        updates['vol_count'] = len(volume_params)
        vsa_ref = self.update(context, vsa_id, **updates)

        # create volumes
        if FLAGS.vsa_multi_vol_creation:
            if len(volume_params) > 0:
                request_spec = {
                    'num_volumes': len(volume_params),
                    'vsa_id': str(vsa_id),
                    'volumes': volume_params,
                }

                rpc.cast(
                    context, FLAGS.scheduler_topic, {
                        "method": "create_volumes",
                        "args": {
                            "topic": FLAGS.volume_topic,
                            "request_spec": request_spec,
                            "availability_zone": availability_zone
                        }
                    })
        else:
            # create BE volumes one-by-one
            for vol in volume_params:
                try:
                    vol_name = vol['name']
                    vol_size = vol['size']
                    vol_type_id = vol['volume_type_id']
                    LOG.debug(_("VSA ID %(vsa_id)d %(vsa_name)s: Create "\
                                "volume %(vol_name)s, %(vol_size)d GB, "\
                                "type %(vol_type_id)s"), locals())

                    vol_type = volume_types.get_volume_type(
                        context, vol['volume_type_id'])

                    vol_ref = self.volume_api.create(
                        context,
                        vol_size,
                        vol_name,
                        vol['description'],
                        None,
                        volume_type=vol_type,
                        metadata=dict(to_vsa_id=str(vsa_id)),
                        availability_zone=availability_zone)
                except Exception:
                    self.update_vsa_status(context,
                                           vsa_id,
                                           status=VsaState.PARTIAL)
                    raise

        if len(volume_params) == 0:
            # No BE volumes - ask VSA manager to start VCs
            rpc.cast(context, FLAGS.vsa_topic, {
                "method": "create_vsa",
                "args": {
                    "vsa_id": str(vsa_id)
                }
            })

        return vsa_ref
Beispiel #24
0
    def create(
        self,
        context,
        display_name="",
        display_description="",
        vc_count=1,
        instance_type=None,
        image_name=None,
        availability_zone=None,
        storage=[],
        shared=None,
    ):
        """
        Provision VSA instance with corresponding compute instances
        and associated volumes
        :param storage: List of dictionaries with following keys:
                        disk_name, num_disks, size
        :param shared: Specifies if storage is dedicated or shared.
                       For shared storage disks split into partitions
        """

        LOG.info(_("*** Experimental VSA code ***"))

        if vc_count > FLAGS.max_vcs_in_vsa:
            LOG.warning(_("Requested number of VCs (%d) is too high." " Setting to default"), vc_count)
            vc_count = FLAGS.max_vcs_in_vsa

        if instance_type is None:
            instance_type = self._get_default_vsa_instance_type()

        if availability_zone is None:
            availability_zone = FLAGS.storage_availability_zone

        if storage is None:
            storage = []

        if shared is None or shared == "False" or shared == False:
            shared = False
        else:
            shared = True

        # check if image is ready before starting any work
        if image_name is None:
            image_name = FLAGS.vc_image_name
        try:
            image_service = self.compute_api.image_service
            vc_image = image_service.show_by_name(context, image_name)
            vc_image_href = vc_image["id"]
        except exception.ImageNotFound:
            raise exception.ApiError(_("Failed to find configured image %s") % image_name)

        options = {
            "display_name": display_name,
            "display_description": display_description,
            "project_id": context.project_id,
            "availability_zone": availability_zone,
            "instance_type_id": instance_type["id"],
            "image_ref": vc_image_href,
            "vc_count": vc_count,
            "status": VsaState.CREATING,
        }
        LOG.info(_("Creating VSA: %s") % options)

        # create DB entry for VSA instance
        try:
            vsa_ref = self.db.vsa_create(context, options)
        except exception.Error:
            raise exception.ApiError(_(sys.exc_info()[1]))
        vsa_id = vsa_ref["id"]
        vsa_name = vsa_ref["name"]

        # check storage parameters
        try:
            volume_params = self._check_storage_parameters(context, vsa_name, storage, shared)
        except exception.ApiError:
            self.db.vsa_destroy(context, vsa_id)
            raise exception.ApiError(_("Error in storage parameters: %s") % storage)

        # after creating DB entry, re-check and set some defaults
        updates = {}
        if not hasattr(vsa_ref, "display_name") or vsa_ref.display_name is None or vsa_ref.display_name == "":
            updates["display_name"] = display_name = vsa_name
        updates["vol_count"] = len(volume_params)
        vsa_ref = self.update(context, vsa_id, **updates)

        # create volumes
        if FLAGS.vsa_multi_vol_creation:
            if len(volume_params) > 0:
                request_spec = {"num_volumes": len(volume_params), "vsa_id": str(vsa_id), "volumes": volume_params}

                rpc.cast(
                    context,
                    FLAGS.scheduler_topic,
                    {
                        "method": "create_volumes",
                        "args": {
                            "topic": FLAGS.volume_topic,
                            "request_spec": request_spec,
                            "availability_zone": availability_zone,
                        },
                    },
                )
        else:
            # create BE volumes one-by-one
            for vol in volume_params:
                try:
                    vol_name = vol["name"]
                    vol_size = vol["size"]
                    vol_type_id = vol["volume_type_id"]
                    LOG.debug(
                        _(
                            "VSA ID %(vsa_id)d %(vsa_name)s: Create "
                            "volume %(vol_name)s, %(vol_size)d GB, "
                            "type %(vol_type_id)s"
                        ),
                        locals(),
                    )

                    vol_type = volume_types.get_volume_type(context, vol["volume_type_id"])

                    vol_ref = self.volume_api.create(
                        context,
                        vol_size,
                        None,
                        vol_name,
                        vol["description"],
                        volume_type=vol_type,
                        metadata=dict(to_vsa_id=str(vsa_id)),
                        availability_zone=availability_zone,
                    )
                except Exception:
                    self.update_vsa_status(context, vsa_id, status=VsaState.PARTIAL)
                    raise

        if len(volume_params) == 0:
            # No BE volumes - ask VSA manager to start VCs
            rpc.cast(context, FLAGS.vsa_topic, {"method": "create_vsa", "args": {"vsa_id": str(vsa_id)}})

        return vsa_ref
Beispiel #25
0
 def _check_type(self, context, type_id):
     try:
         volume_types.get_volume_type(context, type_id)
     except exception.NotFound as ex:
         raise webob.exc.HTTPNotFound(explanation=unicode(ex))
Beispiel #26
0
 def _check_type(self, context, type_id):
     try:
         volume_types.get_volume_type(context, type_id)
     except exception.NotFound as ex:
         raise webob.exc.HTTPNotFound(explanation=unicode(ex))