Ejemplo n.º 1
0
    def test_run_with_quotas(self):

        f = Mock()
        run_with_quotas(FAKE_TENANT1, {'instances': 1, 'volumes': 5}, f)

        self.assertTrue(QUOTAS.reserve.called)
        self.assertTrue(QUOTAS.commit.called)
        self.assertFalse(QUOTAS.rollback.called)
        self.assertTrue(f.called)
Ejemplo n.º 2
0
    def delete(self):
        def _delete_resources():
            if self.is_building:
                raise exception.UnprocessableEntity("Instance %s is not ready."
                                                    % self.id)
            LOG.debug("Deleting instance with compute id = %s.",
                      self.db_info.compute_instance_id)

            from trove.cluster.models import is_cluster_deleting
            if (self.db_info.cluster_id is not None and not
               is_cluster_deleting(self.context, self.db_info.cluster_id)):
                raise exception.ClusterInstanceOperationNotSupported()

            if self.slaves:
                msg = _("Detach replicas before deleting replica source.")
                LOG.warn(msg)
                raise exception.ReplicaSourceDeleteForbidden(msg)

            self.update_db(task_status=InstanceTasks.DELETING,
                           configuration_id=None)
            task_api.API(self.context).delete_instance(self.id)

        deltas = {'instances': -1}
        if self.volume_support:
            deltas['volumes'] = -self.volume_size
        return run_with_quotas(self.tenant_id,
                               deltas,
                               _delete_resources)
Ejemplo n.º 3
0
    def delete(cls, context, backup_id):
        """
        update Backup table on deleted flag for given Backup
        :param cls:
        :param context: context containing the tenant id and token
        :param backup_id: Backup uuid
        :return:
        """

        # Recursively delete all children and grandchildren of this backup.
        query = DBBackup.query()
        query = query.filter_by(parent_id=backup_id, deleted=False)
        for child in query.all():
            cls.delete(context, child.id)

        def _delete_resources():
            backup = cls.get_by_id(context, backup_id)
            if backup.is_running:
                msg = _("Backup %s cannot be deleted because it is running.")
                raise exception.UnprocessableEntity(msg % backup_id)
            cls.verify_swift_auth_token(context)
            api.API(context).delete_backup(backup_id)

        return run_with_quotas(context.tenant,
                               {'backups': -1},
                               _delete_resources)
Ejemplo n.º 4
0
    def create(cls, context, instance, name, description=None, parent_id=None):
        """
        create db record for Backup
        :param cls:
        :param context: tenant_id included
        :param instance:
        :param name:
        :param description:
        :return:
        """

        def _create_resources():
            # parse the ID from the Ref
            instance_id = utils.get_id_from_href(instance)

            # verify that the instance exists and can perform actions
            from trove.instance.models import Instance
            instance_model = Instance.load(context, instance_id)
            instance_model.validate_can_perform_action()
            cls.validate_can_perform_action(
                instance_model, 'backup_create')
            cls.verify_swift_auth_token(context)

            parent = None
            if parent_id:
                # Look up the parent info or fail early if not found or if
                # the user does not have access to the parent.
                _parent = cls.get_by_id(context, parent_id)
                parent = {
                    'location': _parent.location,
                    'checksum': _parent.checksum,
                }
            try:
                db_info = DBBackup.create(name=name,
                                          description=description,
                                          tenant_id=context.tenant,
                                          state=BackupState.NEW,
                                          instance_id=instance_id,
                                          parent_id=parent_id,
                                          deleted=False)
            except exception.InvalidModelError as ex:
                LOG.exception("Unable to create Backup record:")
                raise exception.BackupCreationError(str(ex))

            backup_info = {'id': db_info.id,
                           'name': name,
                           'description': description,
                           'instance_id': instance_id,
                           'backup_type': db_info.backup_type,
                           'checksum': db_info.checksum,
                           'parent': parent,
                           }
            api.API(context).create_backup(backup_info, instance_id)
            return db_info

        return run_with_quotas(context.tenant,
                               {'backups': 1},
                               _create_resources)
Ejemplo n.º 5
0
    def delete(self):
        def _delete_resources():
            if self.is_building:
                raise exception.UnprocessableEntity("Instance %s is not ready." % self.id)
            LOG.debug(_("  ... deleting compute id = %s") % self.db_info.compute_instance_id)
            LOG.debug(_(" ... setting status to DELETING."))
            self.update_db(task_status=InstanceTasks.DELETING)
            task_api.API(self.context).delete_instance(self.id)

        deltas = {"instances": -1}
        if CONF.trove_volume_support:
            deltas["volumes"] = -self.volume_size
        return run_with_quotas(self.tenant_id, deltas, _delete_resources)
Ejemplo n.º 6
0
    def delete(self):
        def _delete_resources():
            if self.is_building:
                raise exception.UnprocessableEntity("Instance %s is not ready."
                                                    % self.id)
            LOG.debug("Deleting instance with compute id = %s." %
                      self.db_info.compute_instance_id)
            self.update_db(task_status=InstanceTasks.DELETING,
                           configuration_id=None)
            task_api.API(self.context).delete_instance(self.id)

        deltas = {'instances': -1}
        if self.volume_support:
            deltas['volumes'] = -self.volume_size
        return run_with_quotas(self.tenant_id,
                               deltas,
                               _delete_resources)
Ejemplo n.º 7
0
    def resize_volume(self, new_size):
        def _resize_resources():
            self.validate_can_perform_action()
            LOG.info("Resizing volume of instance %s..." % self.id)
            if not self.volume_size:
                raise exception.BadRequest("Instance %s has no volume." % self.id)
            old_size = self.volume_size
            if int(new_size) <= old_size:
                msg = "The new volume 'size' must be larger than the current " "volume size of '%s'"
                raise exception.BadRequest(msg % old_size)
            # Set the task to Resizing before sending off to the taskmanager
            self.update_db(task_status=InstanceTasks.RESIZING)
            task_api.API(self.context).resize_volume(new_size, self.id)

        new_size_l = long(new_size)
        validate_volume_size(new_size_l)
        return run_with_quotas(self.tenant_id, {"volumes": new_size_l - self.volume_size}, _resize_resources)
Ejemplo n.º 8
0
    def delete(cls, context, backup_id):
        """
        update Backup table on deleted flag for given Backup
        :param cls:
        :param context: context containing the tenant id and token
        :param backup_id: Backup uuid
        :return:
        """

        def _delete_resources():
            backup = cls.get_by_id(context, backup_id)
            if backup.is_running:
                msg = "Backup %s cannot be delete because it is running." % backup_id
                raise exception.UnprocessableEntity(msg)
            cls.verify_swift_auth_token(context)
            api.API(context).delete_backup(backup_id)

        return run_with_quotas(context.tenant, {"backups": -1}, _delete_resources)
Ejemplo n.º 9
0
    def delete(self):
        def _delete_resources():
            if self.is_building:
                raise exception.UnprocessableEntity("Instance %s is not ready." % self.id)
            LOG.debug("Deleting instance with compute id = %s." % self.db_info.compute_instance_id)

            from trove.cluster.models import is_cluster_deleting

            if self.db_info.cluster_id is not None and not is_cluster_deleting(self.context, self.db_info.cluster_id):
                raise exception.ClusterInstanceOperationNotSupported()

            self.update_db(task_status=InstanceTasks.DELETING, configuration_id=None)
            task_api.API(self.context).delete_instance(self.id)

        deltas = {"instances": -1}
        if self.volume_support:
            deltas["volumes"] = -self.volume_size
        return run_with_quotas(self.tenant_id, deltas, _delete_resources)
Ejemplo n.º 10
0
    def resize_volume(self, new_size):
        def _resize_resources():
            self.validate_can_perform_action()
            LOG.info(_LI("Resizing volume of instance %s."), self.id)
            if self.db_info.cluster_id is not None:
                raise exception.ClusterInstanceOperationNotSupported()
            old_size = self.volume_size
            if int(new_size) <= old_size:
                raise exception.BadRequest(
                    _("The new volume 'size' must be " "larger than the current volume " "size of '%s'.") % old_size
                )
            # Set the task to Resizing before sending off to the taskmanager
            self.update_db(task_status=InstanceTasks.RESIZING)
            task_api.API(self.context).resize_volume(new_size, self.id)

        if not self.volume_size:
            raise exception.BadRequest(_("Instance %s has no volume.") % self.id)
        new_size_l = long(new_size)
        validate_volume_size(new_size_l)
        return run_with_quotas(self.tenant_id, {"volumes": new_size_l - self.volume_size}, _resize_resources)
Ejemplo n.º 11
0
    def create(cls, context, instance, name, description=None):
        """
        create db record for Backup
        :param cls:
        :param context: tenant_id included
        :param instance:
        :param name:
        :param description:
        :return:
        """

        def _create_resources():
            # parse the ID from the Ref
            instance_id = utils.get_id_from_href(instance)

            # verify that the instance exist and can perform actions
            from trove.instance.models import Instance

            instance_model = Instance.load(context, instance_id)
            instance_model.validate_can_perform_action()

            cls.verify_swift_auth_token(context)

            try:
                db_info = DBBackup.create(
                    name=name,
                    description=description,
                    tenant_id=context.tenant,
                    state=BackupState.NEW,
                    instance_id=instance_id,
                    deleted=False,
                )
            except exception.InvalidModelError as ex:
                LOG.exception("Unable to create Backup record:")
                raise exception.BackupCreationError(str(ex))

            api.API(context).create_backup(db_info.id, instance_id)
            return db_info

        return run_with_quotas(context.tenant, {"backups": 1}, _create_resources)
Ejemplo n.º 12
0
    def create(cls, context, instance, name, description=None):
        """
        create db record for Backup
        :param cls:
        :param context: tenant_id included
        :param instance:
        :param name:
        :param description:
        :return:
        """

        def _create_resources():
            # parse the ID from the Ref
            instance_id = utils.get_id_from_href(instance)

            # verify that the instance exist and can perform actions
            from trove.instance.models import Instance
            instance_model = Instance.load(context, instance_id)
            instance_model.validate_can_perform_action()

            cls.verify_swift_auth_token(context)

            try:
                db_info = DBBackup.create(name=name,
                                          description=description,
                                          tenant_id=context.tenant,
                                          state=BackupState.NEW,
                                          instance_id=instance_id,
                                          deleted=False)
            except exception.InvalidModelError as ex:
                LOG.exception("Unable to create Backup record:")
                raise exception.BackupCreationError(str(ex))

            api.API(context).create_backup(db_info.id, instance_id)
            return db_info

        return run_with_quotas(context.tenant,
                               {'backups': 1},
                               _create_resources)
Ejemplo n.º 13
0
    def resize_volume(self, new_size):
        def _resize_resources():
            self.validate_can_perform_action()
            LOG.info("Resizing volume of instance %s..." % self.id)
            if not self.volume_size:
                raise exception.BadRequest(
                    _("Instance %s has no volume.") % self.id)
            old_size = self.volume_size
            if int(new_size) <= old_size:
                raise exception.BadRequest(
                    _("The new volume 'size' must be "
                      "larger than the current volume "
                      "size of '%s'") % old_size)
            # Set the task to Resizing before sending off to the taskmanager
            self.update_db(task_status=InstanceTasks.RESIZING)
            task_api.API(self.context).resize_volume(new_size, self.id)

        new_size_l = long(new_size)
        validate_volume_size(new_size_l)
        return run_with_quotas(self.tenant_id,
                               {'volumes': new_size_l - self.volume_size},
                               _resize_resources)
Ejemplo n.º 14
0
    def delete(self):
        def _delete_resources():
            if self.is_building:
                raise exception.UnprocessableEntity("Instance %s is not ready."
                                                    % self.id)
            LOG.debug("Deleting instance with compute id = %s." %
                      self.db_info.compute_instance_id)

            from trove.cluster.models import is_cluster_deleting
            if (self.db_info.cluster_id is not None and not
               is_cluster_deleting(self.context, self.db_info.cluster_id)):
                raise exception.ClusterInstanceOperationNotSupported()

            self.update_db(task_status=InstanceTasks.DELETING,
                           configuration_id=None)
            task_api.API(self.context).delete_instance(self.id)

        deltas = {'instances': -1}
        if self.volume_support:
            deltas['volumes'] = -self.volume_size
        return run_with_quotas(self.tenant_id,
                               deltas,
                               _delete_resources)
Ejemplo n.º 15
0
    def create(cls, context, name, flavor_id, image_id, databases, users,
               datastore, datastore_version, volume_size, backup_id,
               availability_zone=None, nics=None, configuration_id=None):

        client = create_nova_client(context)
        try:
            flavor = client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)

        deltas = {'instances': 1}
        if CONF.trove_volume_support:
            validate_volume_size(volume_size)
            deltas['volumes'] = volume_size
        else:
            if volume_size is not None:
                raise exception.VolumeNotSupported()
            ephemeral_support = CONF.device_path
            if ephemeral_support and flavor.ephemeral == 0:
                raise exception.LocalStorageNotSpecified(flavor=flavor_id)

        if backup_id is not None:
            backup_info = Backup.get_by_id(context, backup_id)
            if backup_info.is_running:
                raise exception.BackupNotCompleteError(backup_id=backup_id)

            if not backup_info.check_swift_object_exist(
                    context,
                    verify_checksum=CONF.verify_swift_checksum_on_restore):
                raise exception.BackupFileNotFound(
                    location=backup_info.location)

            backup_db_info = DBInstance.find_by(
                context=context, id=backup_info.instance_id)
            if (backup_db_info.datastore_version_id
                    != datastore_version.id):
                ds_version = (datastore_models.DatastoreVersion.
                              load_by_uuid(backup_db_info.datastore_version_id)
                              )
                raise exception.BackupDatastoreVersionMismatchError(
                    version1=ds_version.name,
                    version2=datastore_version.name)

        if not nics and CONF.default_neutron_networks:
            nics = []
            for net_id in CONF.default_neutron_networks:
                nics.append({"net-id": net_id})

        def _create_resources():

            db_info = DBInstance.create(name=name, flavor_id=flavor_id,
                                        tenant_id=context.tenant,
                                        volume_size=volume_size,
                                        datastore_version_id=
                                        datastore_version.id,
                                        task_status=InstanceTasks.BUILDING,
                                        configuration_id=configuration_id)
            LOG.debug(_("Tenant %(tenant)s created new "
                        "Trove instance %(db)s...") %
                      {'tenant': context.tenant, 'db': db_info.id})

            # if a configuration group is associated with an instance,
            # generate an overrides dict to pass into the instance creation
            # method

            overrides = Configuration.get_configuration_overrides(
                context, configuration_id)
            datastore_status = InstanceServiceStatus.create(
                instance_id=db_info.id,
                status=tr_instance.ServiceStatuses.NEW)

            if CONF.trove_dns_support:
                dns_client = create_dns_client(context)
                hostname = dns_client.determine_hostname(db_info.id)
                db_info.hostname = hostname
                db_info.save()

            root_password = None
            if cls.get_root_on_create(
                    datastore_version.manager) and not backup_id:
                root_password = utils.generate_random_password()

            task_api.API(context).create_instance(db_info.id, name, flavor,
                                                  image_id, databases, users,
                                                  datastore_version.manager,
                                                  datastore_version.packages,
                                                  volume_size, backup_id,
                                                  availability_zone,
                                                  root_password,
                                                  nics,
                                                  overrides)

            return SimpleInstance(context, db_info, datastore_status,
                                  root_password)

        return run_with_quotas(context.tenant,
                               deltas,
                               _create_resources)
Ejemplo n.º 16
0
    def create(cls,
               context,
               instance,
               name,
               description=None,
               parent_id=None,
               incremental=False):
        """
        create db record for Backup
        :param cls:
        :param context: tenant_id included
        :param instance:
        :param name:
        :param description:
        :param parent_id:
        :param incremental: flag to indicate incremental backup
        based on previous backup
        :return:
        """
        def _create_resources():
            # parse the ID from the Ref
            instance_id = utils.get_id_from_href(instance)

            # verify that the instance exists and can perform actions
            from trove.instance.models import Instance
            instance_model = Instance.load(context, instance_id)
            instance_model.validate_can_perform_action()
            cls.validate_can_perform_action(instance_model, 'backup_create')
            cls.verify_swift_auth_token(context)
            if instance_model.cluster_id is not None:
                raise exception.ClusterInstanceOperationNotSupported()

            ds = instance_model.datastore
            ds_version = instance_model.datastore_version
            parent = None
            last_backup_id = None
            if parent_id:
                # Look up the parent info or fail early if not found or if
                # the user does not have access to the parent.
                _parent = cls.get_by_id(context, parent_id)
                parent = {
                    'location': _parent.location,
                    'checksum': _parent.checksum,
                }
            elif incremental:
                _parent = Backup.get_last_completed(context, instance_id)
                if _parent:
                    parent = {
                        'location': _parent.location,
                        'checksum': _parent.checksum
                    }
                    last_backup_id = _parent.id
            try:
                db_info = DBBackup.create(name=name,
                                          description=description,
                                          tenant_id=context.tenant,
                                          state=BackupState.NEW,
                                          instance_id=instance_id,
                                          parent_id=parent_id
                                          or last_backup_id,
                                          datastore_version_id=ds_version.id,
                                          deleted=False)
            except exception.InvalidModelError as ex:
                LOG.exception(
                    _("Unable to create backup record for "
                      "instance: %s"), instance_id)
                raise exception.BackupCreationError(str(ex))

            backup_info = {
                'id': db_info.id,
                'name': name,
                'description': description,
                'instance_id': instance_id,
                'backup_type': db_info.backup_type,
                'checksum': db_info.checksum,
                'parent': parent,
                'datastore': ds.name,
                'datastore_version': ds_version.name,
            }
            api.API(context).create_backup(backup_info, instance_id)
            return db_info

        return run_with_quotas(context.tenant, {'backups': 1},
                               _create_resources)
Ejemplo n.º 17
0
    def create(cls,
               context,
               instance,
               name,
               description=None,
               parent_id=None,
               incremental=False,
               swift_container=None,
               restore_from=None):
        """
        create db record for Backup
        :param cls:
        :param context: tenant_id included
        :param instance:
        :param name:
        :param description:
        :param parent_id:
        :param incremental: flag to indicate incremental backup
                            based on previous backup
        :param swift_container: Swift container name.
        :param restore_from: A dict that contains backup information of another
                             region.
        :return:
        """
        backup_state = BackupState.NEW
        checksum = None
        instance_id = None
        parent = None
        last_backup_id = None
        location = None
        backup_type = constants.BACKUP_TYPE_FULL
        size = None

        if restore_from:
            # Check location and datastore version.
            LOG.info(f"Restoring backup, restore_from: {restore_from}")
            backup_state = BackupState.RESTORED

            ds_version_id = restore_from.get('local_datastore_version_id')
            ds_version = datastore_models.DatastoreVersion.load_by_uuid(
                ds_version_id)

            location = restore_from.get('remote_location')
            swift_client = clients.create_swift_client(context)
            try:
                obj_meta = swift.get_metadata(swift_client,
                                              location,
                                              extra_attrs=['etag'])
            except Exception:
                msg = f'Failed to restore backup from {location}'
                LOG.exception(msg)
                raise exception.BackupCreationError(msg)

            checksum = obj_meta['etag']
            if 'parent_location' in obj_meta:
                backup_type = constants.BACKUP_TYPE_INC

            size = restore_from['size']
        else:
            instance_id = utils.get_id_from_href(instance)
            # Import here to avoid circular imports.
            from trove.instance import models as inst_model
            instance_model = inst_model.Instance.load(context, instance_id)
            instance_model.validate_can_perform_action()
            if instance_model.cluster_id is not None:
                raise exception.ClusterInstanceOperationNotSupported()

            cls.validate_can_perform_action(instance_model, 'backup_create')

            cls.verify_swift_auth_token(context)

            ds = instance_model.datastore
            ds_version = instance_model.datastore_version

            if parent_id:
                # Look up the parent info or fail early if not found or if
                # the user does not have access to the parent.
                _parent = cls.get_by_id(context, parent_id)
                parent = {
                    'location': _parent.location,
                    'checksum': _parent.checksum,
                }
            elif incremental:
                _parent = Backup.get_last_completed(context, instance_id)
                if _parent:
                    parent = {
                        'location': _parent.location,
                        'checksum': _parent.checksum
                    }
                    last_backup_id = _parent.id

            if parent:
                backup_type = constants.BACKUP_TYPE_INC

        def _create_resources():
            try:
                db_info = DBBackup.create(name=name,
                                          description=description,
                                          tenant_id=context.project_id,
                                          state=backup_state,
                                          instance_id=instance_id,
                                          parent_id=parent_id
                                          or last_backup_id,
                                          datastore_version_id=ds_version.id,
                                          deleted=False,
                                          location=location,
                                          checksum=checksum,
                                          backup_type=backup_type,
                                          size=size)
            except exception.InvalidModelError as ex:
                LOG.exception(
                    "Unable to create backup record for "
                    "instance: %s", instance_id)
                raise exception.BackupCreationError(str(ex))

            if not restore_from:
                backup_info = {
                    'id': db_info.id,
                    'name': name,
                    'description': description,
                    'instance_id': instance_id,
                    'backup_type': db_info.backup_type,
                    'checksum': db_info.checksum,
                    'parent': parent,
                    'datastore': ds.name,
                    'datastore_version': ds_version.name,
                    'swift_container': swift_container
                }
                api.API(context).create_backup(backup_info, instance_id)
            else:
                context.notification.payload.update({'backup_id': db_info.id})

            return db_info

        return run_with_quotas(context.project_id, {'backups': 1},
                               _create_resources)
Ejemplo n.º 18
0
    def create(
        cls,
        context,
        name,
        flavor_id,
        image_id,
        databases,
        users,
        service_type,
        volume_size,
        backup_id,
        availability_zone=None,
    ):

        client = create_nova_client(context)
        try:
            flavor = client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)

        deltas = {"instances": 1}
        if CONF.trove_volume_support:
            validate_volume_size(volume_size)
            deltas["volumes"] = volume_size
        else:
            if volume_size is not None:
                raise exception.VolumeNotSupported()
            ephemeral_support = CONF.device_path
            if ephemeral_support and flavor.ephemeral == 0:
                raise exception.LocalStorageNotSpecified(flavor=flavor_id)

        def _create_resources():
            security_groups = None

            if backup_id is not None:
                backup_info = Backup.get_by_id(context, backup_id)
                if backup_info.is_running:
                    raise exception.BackupNotCompleteError(backup_id=backup_id)

                location = backup_info.location
                LOG.info(_("Checking if backup exist in '%s'") % location)
                if not Backup.check_object_exist(context, location):
                    raise exception.BackupFileNotFound(location=location)

            db_info = DBInstance.create(
                name=name,
                flavor_id=flavor_id,
                tenant_id=context.tenant,
                volume_size=volume_size,
                service_type=service_type,
                task_status=InstanceTasks.BUILDING,
            )
            LOG.debug(
                _("Tenant %(tenant)s created new " "Trove instance %(db)s...")
                % {"tenant": context.tenant, "db": db_info.id}
            )

            service_status = InstanceServiceStatus.create(instance_id=db_info.id, status=ServiceStatuses.NEW)

            if CONF.trove_dns_support:
                dns_client = create_dns_client(context)
                hostname = dns_client.determine_hostname(db_info.id)
                db_info.hostname = hostname
                db_info.save()

            if CONF.trove_security_groups_support:
                security_group = SecurityGroup.create_for_instance(db_info.id, context)
                if CONF.trove_security_groups_rules_support:
                    SecurityGroupRule.create_sec_group_rule(
                        security_group,
                        CONF.trove_security_group_rule_protocol,
                        CONF.trove_security_group_rule_port,
                        CONF.trove_security_group_rule_port,
                        CONF.trove_security_group_rule_cidr,
                        context,
                    )
                security_groups = [security_group["name"]]

            task_api.API(context).create_instance(
                db_info.id,
                name,
                flavor,
                image_id,
                databases,
                users,
                service_type,
                volume_size,
                security_groups,
                backup_id,
                availability_zone,
            )

            return SimpleInstance(context, db_info, service_status)

        return run_with_quotas(context.tenant, deltas, _create_resources)
Ejemplo n.º 19
0
    def create(cls, context, instance, name, description=None,
               parent_id=None, incremental=False):
        """
        create db record for Backup
        :param cls:
        :param context: tenant_id included
        :param instance:
        :param name:
        :param description:
        :param parent_id:
        :param incremental: flag to indicate incremental backup
        based on previous backup
        :return:
        """

        def _create_resources():
            # parse the ID from the Ref
            instance_id = utils.get_id_from_href(instance)

            # verify that the instance exists and can perform actions
            from trove.instance.models import Instance
            instance_model = Instance.load(context, instance_id)
            instance_model.validate_can_perform_action()
            cls.validate_can_perform_action(
                instance_model, 'backup_create')
            cls.verify_swift_auth_token(context)

            ds = instance_model.datastore
            ds_version = instance_model.datastore_version

            manager = (datastore_models.DatastoreVersion.load_by_uuid(
                ds_version.id).manager)
            if (not CONF.get(manager).enable_cluster_instance_backup
                    and instance_model.cluster_id is not None):
                raise exception.ClusterInstanceOperationNotSupported()

            parent = None
            parent_backup = None
            parent_backup_id = None
            last_backup_id = None
            if parent_id:
                # Look up the parent info or fail early if not found or if
                # the user does not have access to the parent.
                if parent_id == 'last':
                    # Need to assign parent_id to a new variable
                    # parent_backup_id, otherwise an unbound variable error
                    # will be thrown
                    parent_backup = Backup.get_last_completed(context,
                                                              instance_id,
                                                              True)
                    if parent_backup is None:
                        raise exception.NotFound()
                    parent_backup_id = parent_backup.id
                else:
                    parent_backup_id = parent_id
                _parent = cls.get_by_id(context, parent_backup_id)
                parent = {
                    'id': parent_backup_id,
                    'location': _parent.location,
                    'checksum': _parent.checksum,
                }
            elif incremental:
                _parent = Backup.get_last_completed(context, instance_id)
                if _parent:
                    parent = {
                        'location': _parent.location,
                        'checksum': _parent.checksum
                    }
                    last_backup_id = _parent.id
            try:
                db_info = DBBackup.create(name=name,
                                          description=description,
                                          tenant_id=context.tenant,
                                          state=BackupState.NEW,
                                          instance_id=instance_id,
                                          parent_id=parent_backup_id or
                                          last_backup_id,
                                          datastore_version_id=ds_version.id,
                                          deleted=False)
            except exception.InvalidModelError as ex:
                LOG.exception(_("Unable to create backup record for "
                                "instance: %s"), instance_id)
                raise exception.BackupCreationError(str(ex))

            backup_info = {'id': db_info.id,
                           'name': name,
                           'description': description,
                           'instance_id': instance_id,
                           'backup_type': db_info.backup_type,
                           'checksum': db_info.checksum,
                           'parent': parent,
                           'datastore': ds.name,
                           'datastore_version': ds_version.name,
                           }
            api.API(context).create_backup(backup_info, instance_id)
            return db_info
        return run_with_quotas(context.tenant,
                               {'backups': 1},
                               _create_resources)
Ejemplo n.º 20
0
    def create(cls,
               context,
               name,
               flavor_id,
               image_id,
               databases,
               users,
               datastore,
               datastore_version,
               volume_size,
               backup_id,
               availability_zone=None,
               nics=None,
               configuration_id=None,
               slave_of_id=None,
               cluster_config=None):

        datastore_cfg = CONF.get(datastore_version.manager)
        client = create_nova_client(context)
        try:
            flavor = client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)

        deltas = {'instances': 1}
        volume_support = datastore_cfg.volume_support
        if volume_support:
            validate_volume_size(volume_size)
            deltas['volumes'] = volume_size
            # Instance volume should have enough space for the backup
            # Backup, and volume sizes are in GBs
            target_size = volume_size
        else:
            target_size = flavor.disk  # local_storage
            if volume_size is not None:
                raise exception.VolumeNotSupported()
            if datastore_cfg.device_path:
                if flavor.ephemeral == 0:
                    raise exception.LocalStorageNotSpecified(flavor=flavor_id)
                target_size = flavor.ephemeral  # ephemeral_Storage

        if backup_id is not None:
            backup_info = Backup.get_by_id(context, backup_id)
            if backup_info.is_running:
                raise exception.BackupNotCompleteError(backup_id=backup_id)

            if backup_info.size > target_size:
                raise exception.BackupTooLarge(backup_size=backup_info.size,
                                               disk_size=target_size)

            if not backup_info.check_swift_object_exist(
                    context,
                    verify_checksum=CONF.verify_swift_checksum_on_restore):
                raise exception.BackupFileNotFound(
                    location=backup_info.location)

            if (backup_info.datastore_version_id
                    and backup_info.datastore.name != datastore.name):
                raise exception.BackupDatastoreMismatchError(
                    datastore1=backup_info.datastore.name,
                    datastore2=datastore.name)

        if slave_of_id:
            replication_support = datastore_cfg.replication_strategy
            if not replication_support:
                raise exception.ReplicationNotSupported(
                    datastore=datastore.name)
            try:
                # looking for replica source
                replica_source = DBInstance.find_by(context,
                                                    id=slave_of_id,
                                                    deleted=False)
                if replica_source.slave_of_id:
                    raise exception.Forbidden(
                        _("Cannot create a replica of a replica %(id)s.") %
                        {'id': slave_of_id})
            except exception.ModelNotFoundError:
                LOG.exception(
                    _("Cannot create a replica of %(id)s "
                      "as that instance could not be found.") %
                    {'id': slave_of_id})
                raise exception.NotFound(uuid=slave_of_id)

        if not nics:
            nics = []
        if CONF.default_neutron_networks:
            nics = [{
                "net-id": net_id
            } for net_id in CONF.default_neutron_networks] + nics

        def _create_resources():

            if cluster_config:
                cluster_id = cluster_config.get("id", None)
                shard_id = cluster_config.get("shard_id", None)
                instance_type = cluster_config.get("instance_type", None)
            else:
                cluster_id = shard_id = instance_type = None

            db_info = DBInstance.create(
                name=name,
                flavor_id=flavor_id,
                tenant_id=context.tenant,
                volume_size=volume_size,
                datastore_version_id=datastore_version.id,
                task_status=InstanceTasks.BUILDING,
                configuration_id=configuration_id,
                slave_of_id=slave_of_id,
                cluster_id=cluster_id,
                shard_id=shard_id,
                type=instance_type)
            LOG.debug("Tenant %(tenant)s created new Trove instance %(db)s.", {
                'tenant': context.tenant,
                'db': db_info.id
            })

            # if a configuration group is associated with an instance,
            # generate an overrides dict to pass into the instance creation
            # method

            config = Configuration(context, configuration_id)
            overrides = config.get_configuration_overrides()
            service_status = InstanceServiceStatus.create(
                instance_id=db_info.id, status=tr_instance.ServiceStatuses.NEW)

            if CONF.trove_dns_support:
                dns_client = create_dns_client(context)
                hostname = dns_client.determine_hostname(db_info.id)
                db_info.hostname = hostname
                db_info.save()

            root_password = None
            if cls.get_root_on_create(
                    datastore_version.manager) and not backup_id:
                root_password = utils.generate_random_password()

            task_api.API(context).create_instance(
                db_info.id, name, flavor, image_id, databases, users,
                datastore_version.manager, datastore_version.packages,
                volume_size, backup_id, availability_zone, root_password, nics,
                overrides, slave_of_id, cluster_config)

            return SimpleInstance(context, db_info, service_status,
                                  root_password)

        return run_with_quotas(context.tenant, deltas, _create_resources)
Ejemplo n.º 21
0
    def create(cls, context, name, flavor_id, image_id,
               databases, users, service_type, volume_size, backup_id,
               availability_zone=None):

        client = create_nova_client(context)
        try:
            flavor = client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)

        deltas = {'instances': 1}
        if CONF.trove_volume_support:
            validate_volume_size(volume_size)
            deltas['volumes'] = volume_size
        else:
            if volume_size is not None:
                raise exception.VolumeNotSupported()
            ephemeral_support = CONF.device_path
            if ephemeral_support and flavor.ephemeral == 0:
                raise exception.LocalStorageNotSpecified(flavor=flavor_id)

        if backup_id is not None:
            backup_info = Backup.get_by_id(context, backup_id)
            if backup_info.is_running:
                raise exception.BackupNotCompleteError(backup_id=backup_id)

            if not backup_info.check_swift_object_exist(
                    context,
                    verify_checksum=CONF.verify_swift_checksum_on_restore):
                raise exception.BackupFileNotFound(
                    location=backup_info.location)

        def _create_resources():

            db_info = DBInstance.create(name=name, flavor_id=flavor_id,
                                        tenant_id=context.tenant,
                                        volume_size=volume_size,
                                        service_type=service_type,
                                        task_status=InstanceTasks.BUILDING)
            LOG.debug(_("Tenant %(tenant)s created new "
                        "Trove instance %(db)s...") %
                      {'tenant': context.tenant, 'db': db_info.id})

            service_status = InstanceServiceStatus.create(
                instance_id=db_info.id,
                status=rd_instance.ServiceStatuses.NEW)

            if CONF.trove_dns_support:
                dns_client = create_dns_client(context)
                hostname = dns_client.determine_hostname(db_info.id)
                db_info.hostname = hostname
                db_info.save()

            root_password = None
            if CONF.root_on_create and not backup_id:
                root_password = uuidutils.generate_uuid()

            task_api.API(context).create_instance(db_info.id, name, flavor,
                                                  image_id, databases, users,
                                                  service_type, volume_size,
                                                  backup_id,
                                                  availability_zone,
                                                  root_password)

            return SimpleInstance(context, db_info, service_status,
                                  root_password)

        return run_with_quotas(context.tenant,
                               deltas,
                               _create_resources)
Ejemplo n.º 22
0
    def create(cls, context, name, flavor_id, image_id, databases, users,
               datastore, datastore_version, volume_size, backup_id,
               availability_zone=None, nics=None, configuration_id=None,
               slave_of_id=None, cluster_config=None, replica_count=None):

        datastore_cfg = CONF.get(datastore_version.manager)
        client = create_nova_client(context)
        try:
            flavor = client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)

        deltas = {'instances': 1}
        volume_support = datastore_cfg.volume_support
        if volume_support:
            validate_volume_size(volume_size)
            deltas['volumes'] = volume_size
            # Instance volume should have enough space for the backup
            # Backup, and volume sizes are in GBs
            target_size = volume_size
        else:
            target_size = flavor.disk  # local_storage
            if volume_size is not None:
                raise exception.VolumeNotSupported()
            if datastore_cfg.device_path:
                if flavor.ephemeral == 0:
                    raise exception.LocalStorageNotSpecified(flavor=flavor_id)
                target_size = flavor.ephemeral  # ephemeral_Storage

        if backup_id:
            backup_info = Backup.get_by_id(context, backup_id)
            if not backup_info.is_done_successfuly:
                raise exception.BackupNotCompleteError(
                    backup_id=backup_id, state=backup_info.state)

            if backup_info.size > target_size:
                raise exception.BackupTooLarge(
                    backup_size=backup_info.size, disk_size=target_size)

            if not backup_info.check_swift_object_exist(
                    context,
                    verify_checksum=CONF.verify_swift_checksum_on_restore):
                raise exception.BackupFileNotFound(
                    location=backup_info.location)

            if (backup_info.datastore_version_id
                    and backup_info.datastore.name != datastore.name):
                raise exception.BackupDatastoreMismatchError(
                    datastore1=backup_info.datastore.name,
                    datastore2=datastore.name)

        if slave_of_id:
            replication_support = datastore_cfg.replication_strategy
            if not replication_support:
                raise exception.ReplicationNotSupported(
                    datastore=datastore.name)
            try:
                # looking for replica source
                replica_source = DBInstance.find_by(
                    context,
                    id=slave_of_id,
                    deleted=False)
                if replica_source.slave_of_id:
                    raise exception.Forbidden(
                        _("Cannot create a replica of a replica %(id)s.")
                        % {'id': slave_of_id})
                # load the replica source status to check if
                # source is available
                load_simple_instance_server_status(
                    context,
                    replica_source)
                replica_source_instance = Instance(
                    context, replica_source,
                    None,
                    InstanceServiceStatus.find_by(
                        context,
                        instance_id=slave_of_id))
                replica_source_instance.validate_can_perform_action()
            except exception.ModelNotFoundError:
                LOG.exception(
                    _("Cannot create a replica of %(id)s "
                      "as that instance could not be found.")
                    % {'id': slave_of_id})
                raise exception.NotFound(uuid=slave_of_id)
        elif replica_count and replica_count != 1:
            raise exception.Forbidden(_(
                "Replica count only valid when creating replicas. Cannot "
                "create %(count)d instances.") % {'count': replica_count})
        multi_replica = slave_of_id and replica_count and replica_count > 1
        instance_count = replica_count if multi_replica else 1

        if not nics:
            nics = []
        if CONF.default_neutron_networks:
            nics = [{"net-id": net_id}
                    for net_id in CONF.default_neutron_networks] + nics

        def _create_resources():

            if cluster_config:
                cluster_id = cluster_config.get("id", None)
                shard_id = cluster_config.get("shard_id", None)
                instance_type = cluster_config.get("instance_type", None)
            else:
                cluster_id = shard_id = instance_type = None

            ids = []
            names = []
            root_passwords = []
            root_password = None
            for instance_index in range(0, instance_count):
                db_info = DBInstance.create(
                    name=name, flavor_id=flavor_id, tenant_id=context.tenant,
                    volume_size=volume_size,
                    datastore_version_id=datastore_version.id,
                    task_status=InstanceTasks.BUILDING,
                    configuration_id=configuration_id,
                    slave_of_id=slave_of_id, cluster_id=cluster_id,
                    shard_id=shard_id, type=instance_type)
                LOG.debug("Tenant %(tenant)s created new Trove instance "
                          "%(db)s.",
                          {'tenant': context.tenant, 'db': db_info.id})

                instance_id = db_info.id
                instance_name = name
                ids.append(instance_id)
                names.append(instance_name)
                root_passwords.append(None)
                # change the name to be name + replica_number if more than one
                if multi_replica:
                    replica_number = instance_index + 1
                    names[instance_index] += '-' + str(replica_number)
                    setattr(db_info, 'name', names[instance_index])
                    db_info.save()

                # if a configuration group is associated with an instance,
                # generate an overrides dict to pass into the instance creation
                # method

                config = Configuration(context, configuration_id)
                overrides = config.get_configuration_overrides()
                service_status = InstanceServiceStatus.create(
                    instance_id=instance_id,
                    status=tr_instance.ServiceStatuses.NEW)

                if CONF.trove_dns_support:
                    dns_client = create_dns_client(context)
                    hostname = dns_client.determine_hostname(instance_id)
                    db_info.hostname = hostname
                    db_info.save()

                if cls.get_root_on_create(
                        datastore_version.manager) and not backup_id:
                    root_password = utils.generate_random_password()
                    root_passwords[instance_index] = root_password

            if instance_count > 1:
                instance_id = ids
                instance_name = names
                root_password = root_passwords
            task_api.API(context).create_instance(
                instance_id, instance_name, flavor, image_id, databases, users,
                datastore_version.manager, datastore_version.packages,
                volume_size, backup_id, availability_zone, root_password,
                nics, overrides, slave_of_id, cluster_config)

            return SimpleInstance(context, db_info, service_status,
                                  root_password)

        return run_with_quotas(context.tenant,
                               deltas,
                               _create_resources)
Ejemplo n.º 23
0
    def create(cls, context, name, flavor_id, image_id, databases, users,
               datastore, datastore_version, volume_size, backup_id,
               availability_zone=None, nics=None, configuration_id=None):

        client = create_nova_client(context)
        try:
            flavor = client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)

        deltas = {'instances': 1}
        if CONF.trove_volume_support:
            validate_volume_size(volume_size)
            deltas['volumes'] = volume_size
        else:
            if volume_size is not None:
                raise exception.VolumeNotSupported()
            ephemeral_support = CONF.device_path
            if ephemeral_support and flavor.ephemeral == 0:
                raise exception.LocalStorageNotSpecified(flavor=flavor_id)

        if backup_id is not None:
            backup_info = Backup.get_by_id(context, backup_id)
            if backup_info.is_running:
                raise exception.BackupNotCompleteError(backup_id=backup_id)

            if not backup_info.check_swift_object_exist(
                    context,
                    verify_checksum=CONF.verify_swift_checksum_on_restore):
                raise exception.BackupFileNotFound(
                    location=backup_info.location)

        if not nics and CONF.default_neutron_networks:
            nics = []
            for net_id in CONF.default_neutron_networks:
                nics.append({"net-id": net_id})

        def _create_resources():

            db_info = DBInstance.create(name=name, flavor_id=flavor_id,
                                        tenant_id=context.tenant,
                                        volume_size=volume_size,
                                        datastore_version_id=
                                        datastore_version.id,
                                        task_status=InstanceTasks.BUILDING,
                                        configuration_id=configuration_id)
            LOG.debug(_("Tenant %(tenant)s created new "
                        "Trove instance %(db)s...") %
                      {'tenant': context.tenant, 'db': db_info.id})

            # if a configuration group is associated with an instance,
            # generate an overrides dict to pass into the instance creation
            # method

            overrides = Configuration.get_configuration_overrides(
                context, configuration_id)
            service_status = InstanceServiceStatus.create(
                instance_id=db_info.id,
                status=tr_instance.ServiceStatuses.NEW)

            if CONF.trove_dns_support:
                dns_client = create_dns_client(context)
                hostname = dns_client.determine_hostname(db_info.id)
                db_info.hostname = hostname
                db_info.save()

            root_password = None
            if cls.get_root_on_create(
                    datastore_version.manager) and not backup_id:
                root_password = utils.generate_random_password()

            task_api.API(context).create_instance(db_info.id, name, flavor,
                                                  image_id, databases, users,
                                                  datastore_version.manager,
                                                  datastore_version.packages,
                                                  volume_size, backup_id,
                                                  availability_zone,
                                                  root_password,
                                                  nics,
                                                  overrides)

            return SimpleInstance(context, db_info, service_status,
                                  root_password)

        return run_with_quotas(context.tenant,
                               deltas,
                               _create_resources)
Ejemplo n.º 24
0
    def create(cls, context, instance_id, name, description=None, group_id=None, backup_type=None,
               expire_at=None, init=False, service_image_id=None, parent_id=None):
        if parent_id is not None:
            parent_id = str(parent_id)
            LOG.info("parent_id:%s, parent_id.len:%s", parent_id, len(parent_id.strip()))
            if len(parent_id.strip()) == 0:
                parent_id = None
        _parent_id = parent_id

        from trove.instance.models import Instance
        instance_id = utils.get_id_from_href(instance_id)
        instance_model = Instance.load(context, instance_id)
        if init:
            if instance_model.db_info.server_status != 'ACTIVE':
                msg = ("Instance is not currently available for an action to be "
                       "performed (server_status was %s).", instance_model.db_info.server_status)
                LOG.error(msg)
                raise exception.UnprocessableEntity(msg)
        else:
            instance_model.validate_can_perform_action()

        if instance_model.type == DBInstanceType.MASTER:
            try:
                standby_id = InstanceGroupItem.get_by_gid_type(context, instance_model.group_id, DBInstanceType.STANDBY).instance_id
                instance_model = Instance.load(context, standby_id)
                instance_model.validate_can_perform_action()
                instance_id = standby_id
            except Exception as e:
                LOG.error(e)
                raise e

        if group_id is None:
            raise exception.TroveError("group_id can't None")
        if backup_type is None or backup_type not in [Type.SNAPSHOT, Type.AUTOBACKUP]:
            raise exception.TroveError("instType can't None, only accept value: snapshot or autobackup ")

        if backup_type == Type.SNAPSHOT:
            expire_time = 0
            _parent_id = None  # force full
        elif backup_type == Type.AUTOBACKUP:
            expire_time = int(expire_at)
            if parent_id and parent_id == '0':
                _parent_id = None  # force full
            elif parent_id and parent_id != '0':
                try:
                    backup_parent = cls.get_by_id(context, parent_id)
                    LOG.debug("backup_parent:%s", backup_parent)
                except:
                    raise exception.NotFound("not found backup with parent_id: %s" % parent_id)
                if not backup_parent:
                    raise exception.NotFound("not found backup with parent_id: %s" % parent_id)
            elif parent_id is None:
                LOG.debug("parent_id is None:%s", parent_id)
                last_backup_chain = cls.get_last_backup_chain(group_id)
                backup_incremental_chain_size = CONF.backup_incremental_chain_size
                LOG.info("last_backup_chain: %s, backup_incremental_chain_size: %s",
                         last_backup_chain, backup_incremental_chain_size)
                if len(last_backup_chain) == 0 \
                        or len(last_backup_chain) >= int(backup_incremental_chain_size):
                    _parent_id = None  # create full
                else:
                    compare_instance = None
                    try:
                        compare_instance = InstanceGroupItem.get_by_gid_type(context, group_id, DBInstanceType.STANDBY)
                    except exception.NotFound:  # not has standby
                        try:
                            compare_instance = InstanceGroupItem.get_by_gid_type(context, group_id,
                                                                                 DBInstanceType.SINGLE)
                        except exception.NotFound:  # not has single
                            pass
                    if compare_instance:
                        compare_id = compare_instance.instance_id
                        switched = False
                        for b in last_backup_chain:  # has standby
                            if b["instance_id"] != compare_id:
                                switched = True  # create full
                                LOG.debug("last_backup_chain: %s, switched: %s, backup_instance_id: %s, b.instance_id: %s"
                                         , last_backup_chain, switched, compare_id, b["instance_id"])
                                break
                        if not switched:
                            parent = last_backup_chain.pop()  # create incremental
                            _parent_id = parent["id"]
                    else:  # not found standby and single
                        _parent_id = None  # create full
        LOG.debug("create backup use parent_id: %s", _parent_id)

        def _create_resources():
            try:
                db_info = models.DBBackup.create(name=name,
                                                 description=description,
                                                 tenant_id=context.tenant,
                                                 state=models.BackupState.NEW,
                                                 instance_id=instance_id,
                                                 deleted=False,
                                                 group_id=group_id,
                                                 type=backup_type,
                                                 expire_at=expire_time,
                                                 service_image_id=service_image_id,
                                                 parent_id=_parent_id)
            except exception.InvalidModelError as ex:
                LOG.exception("Unable to create Backup record:")
                msg = "Unable to create Backup record, group_id %s, instance_id %s, parent_id %s " % (group_id, _instance_id, _parent_id)
                AlarmRpc(context).alarm(context.tenant, level=AlarmRpc.LEVEL_ERROR,
                                        _type=AlarmRpc.TYPE_TASKMANAGER, message=msg+str(ex))             
                raise exception.BackupCreationError(str(ex))

            api.API(context).create_backup(db_info.id, instance_id)
            return db_info

        return run_with_quotas(context.tenant,
                               {'backups': 1},
                               _create_resources)
Ejemplo n.º 25
0
    def create(cls, context, name, flavor_id, image_id, databases, users,
               datastore, datastore_version, volume_size, backup_id,
               availability_zone=None, nics=None, configuration_id=None,
               slave_of_id=None, cluster_config=None):

        datastore_cfg = CONF.get(datastore_version.manager)
        client = create_nova_client(context)
        try:
            flavor = client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)

        deltas = {'instances': 1}
        volume_support = datastore_cfg.volume_support
        if volume_support:
            validate_volume_size(volume_size)
            deltas['volumes'] = volume_size
        else:
            if volume_size is not None:
                raise exception.VolumeNotSupported()
            ephemeral_support = datastore_cfg.device_path
            if ephemeral_support:
                if flavor.ephemeral == 0:
                    raise exception.LocalStorageNotSpecified(flavor=flavor_id)

        if backup_id is not None:
            backup_info = Backup.get_by_id(context, backup_id)
            if backup_info.is_running:
                raise exception.BackupNotCompleteError(backup_id=backup_id)

            if not backup_info.check_swift_object_exist(
                    context,
                    verify_checksum=CONF.verify_swift_checksum_on_restore):
                raise exception.BackupFileNotFound(
                    location=backup_info.location)

            if (backup_info.datastore_version_id
                    and backup_info.datastore.name != datastore.name):
                raise exception.BackupDatastoreMismatchError(
                    datastore1=backup_info.datastore.name,
                    datastore2=datastore.name)

        if slave_of_id:
            replication_support = datastore_cfg.replication_strategy
            if not replication_support:
                raise exception.ReplicationNotSupported(
                    datastore=datastore.name)

        if not nics:
            nics = []
        if CONF.default_neutron_networks:
            nics = [{"net-id": net_id}
                    for net_id in CONF.default_neutron_networks] + nics

        def _create_resources():

            if cluster_config:
                cluster_id = cluster_config.get("id", None)
                shard_id = cluster_config.get("shard_id", None)
                instance_type = cluster_config.get("instance_type", None)
            else:
                cluster_id = shard_id = instance_type = None

            db_info = DBInstance.create(name=name, flavor_id=flavor_id,
                                        tenant_id=context.tenant,
                                        volume_size=volume_size,
                                        datastore_version_id=
                                        datastore_version.id,
                                        task_status=InstanceTasks.BUILDING,
                                        configuration_id=configuration_id,
                                        slave_of_id=slave_of_id,
                                        cluster_id=cluster_id,
                                        shard_id=shard_id,
                                        type=instance_type)
            LOG.debug("Tenant %(tenant)s created new Trove instance %(db)s."
                      % {'tenant': context.tenant, 'db': db_info.id})

            # if a configuration group is associated with an instance,
            # generate an overrides dict to pass into the instance creation
            # method

            config = Configuration(context, configuration_id)
            overrides = config.get_configuration_overrides()
            service_status = InstanceServiceStatus.create(
                instance_id=db_info.id,
                status=tr_instance.ServiceStatuses.NEW)

            if CONF.trove_dns_support:
                dns_client = create_dns_client(context)
                hostname = dns_client.determine_hostname(db_info.id)
                db_info.hostname = hostname
                db_info.save()

            root_password = None
            if cls.get_root_on_create(
                    datastore_version.manager) and not backup_id:
                root_password = utils.generate_random_password()

            task_api.API(context).create_instance(db_info.id, name, flavor,
                                                  image_id, databases, users,
                                                  datastore_version.manager,
                                                  datastore_version.packages,
                                                  volume_size, backup_id,
                                                  availability_zone,
                                                  root_password, nics,
                                                  overrides, slave_of_id,
                                                  cluster_config)

            return SimpleInstance(context, db_info, service_status,
                                  root_password)

        return run_with_quotas(context.tenant,
                               deltas,
                               _create_resources)
Ejemplo n.º 26
0
    def create(cls, context, name, flavor_id, image_id, databases, users,
               service_type, volume_size, backup_id):

        client = create_nova_client(context)
        try:
            flavor = client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)

        deltas = {'instances': 1}
        if CONF.trove_volume_support:
            validate_volume_size(volume_size)
            deltas['volumes'] = volume_size
        else:
            if volume_size is not None:
                raise exception.VolumeNotSupported()
            ephemeral_support = CONF.device_path
            if ephemeral_support and flavor.ephemeral == 0:
                raise exception.LocalStorageNotSpecified(flavor=flavor_id)

        def _create_resources():
            security_groups = None

            if backup_id is not None:
                backup_info = Backup.get_by_id(context, backup_id)
                if backup_info.is_running:
                    raise exception.BackupNotCompleteError(backup_id=backup_id)

                location = backup_info.location
                LOG.info(_("Checking if backup exist in '%s'") % location)
                if not Backup.check_object_exist(context, location):
                    raise exception.BackupFileNotFound(location=location)

            db_info = DBInstance.create(name=name,
                                        flavor_id=flavor_id,
                                        tenant_id=context.tenant,
                                        volume_size=volume_size,
                                        service_type=service_type,
                                        task_status=InstanceTasks.BUILDING)
            LOG.debug(
                _("Tenant %s created new Trove instance %s...") %
                (context.tenant, db_info.id))

            service_status = InstanceServiceStatus.create(
                instance_id=db_info.id, status=ServiceStatuses.NEW)

            if CONF.trove_dns_support:
                dns_client = create_dns_client(context)
                hostname = dns_client.determine_hostname(db_info.id)
                db_info.hostname = hostname
                db_info.save()

            if CONF.trove_security_groups_support:
                security_group = SecurityGroup.create_for_instance(
                    db_info.id, context)
                security_groups = [security_group["name"]]

            task_api.API(context).create_instance(db_info.id, name, flavor,
                                                  image_id, databases, users,
                                                  service_type, volume_size,
                                                  security_groups, backup_id)

            return SimpleInstance(context, db_info, service_status)

        return run_with_quotas(context.tenant, deltas, _create_resources)