Example #1
0
    def instance_claim(self, context, instance_ref, limits=None):
        """Indicate that some resources are needed for an upcoming compute
        instance build operation.

        This should be called before the compute node is about to perform
        an instance build operation that will consume additional resources.

        :param context: security context
        :param instance_ref: instance to reserve resources for
        :param limits: Dict of oversubscription limits for memory, disk,
                       and CPUs.
        :returns: A Claim ticket representing the reserved resources.  It can
                  be used to revert the resource usage if an error occurs
                  during the instance build.
        """
        if self.disabled:
            # compute_driver doesn't support resource tracking, just
            # set the 'host' and node fields and continue the build:
            self._set_instance_host_and_node(context, instance_ref)
            return claims.NopClaim()

        # sanity checks:
        if instance_ref['host']:
            LOG.warning(_("Host field should not be set on the instance until "
                          "resources have been claimed."),
                        instance=instance_ref)

        if instance_ref['node']:
            LOG.warning(_("Node field should not be set on the instance "
                          "until resources have been claimed."),
                        instance=instance_ref)

        # get memory overhead required to build this instance:
        overhead = self.driver.estimate_instance_overhead(instance_ref)
        LOG.debug(
            "Memory overhead for %(flavor)d MB instance; %(overhead)d "
            "MB", {
                'flavor': instance_ref['memory_mb'],
                'overhead': overhead['memory_mb']
            })

        claim = claims.Claim(context,
                             instance_ref,
                             self,
                             self.compute_node,
                             overhead=overhead,
                             limits=limits)

        self._set_instance_host_and_node(context, instance_ref)
        instance_ref['numa_topology'] = claim.claimed_numa_topology

        # Mark resources in-use and update stats
        self._update_usage_from_instance(context, self.compute_node,
                                         instance_ref)

        elevated = context.elevated()
        # persist changes to the compute node:
        self._update(elevated, self.compute_node)

        return claim
Example #2
0
    def _move_claim(self, context, instance, new_instance_type, move_type=None,
                    image_meta=None, limits=None, migration=None):
        """Indicate that resources are needed for a move to this host.

        Move can be either a migrate/resize, live-migrate or an
        evacuate/rebuild operation.

        :param context: security context
        :param instance: instance object to reserve resources for
        :param new_instance_type: new instance_type being resized to
        :param image_meta: instance image metadata
        :param move_type: move type - can be one of 'migration', 'resize',
                         'live-migration', 'evacuate'
        :param limits: Dict of oversubscription limits for memory, disk,
        and CPUs
        :param migration: A migration object if one was already created
                          elsewhere for this operation
        :returns: A Claim ticket representing the reserved resources.  This
        should be turned into finalize  a resource claim or free
        resources after the compute operation is finished.
        """
        image_meta = image_meta or {}
        if migration:
            self._claim_existing_migration(migration)
        else:
            migration = self._create_migration(context, instance,
                                               new_instance_type, move_type)

        if self.disabled:
            # compute_driver doesn't support resource tracking, just
            # generate the migration record and continue the resize:
            return claims.NopClaim(migration=migration)

        # get memory overhead required to build this instance:
        overhead = self.driver.estimate_instance_overhead(new_instance_type)
        LOG.debug("Memory overhead for %(flavor)d MB instance; %(overhead)d "
                  "MB", {'flavor': new_instance_type.memory_mb,
                          'overhead': overhead['memory_mb']})

        pci_requests = objects.InstancePCIRequests.\
                       get_by_instance_uuid_and_newness(
                           context, instance.uuid, True)
        claim = claims.MoveClaim(context, instance, new_instance_type,
                                 image_meta, self, self.compute_node,
                                 pci_requests, overhead=overhead,
                                 limits=limits,flavor=instance.flavor)
        claim.migration = migration
        instance.migration_context = claim.create_migration_context()
        instance.save()

        # Mark the resources in-use for the resize landing on this
        # compute host:
        self._update_usage_from_migration(context, instance, image_meta,
                                          migration)
        elevated = context.elevated()
        self._update(elevated)

        return claim
Example #3
0
    def resize_claim(self,
                     context,
                     instance,
                     instance_type,
                     image_meta=None,
                     limits=None):
        """Indicate that resources are needed for a resize operation to this
        compute host.
        :param context: security context
        :param instance: instance object to reserve resources for
        :param instance_type: new instance_type being resized to
        :param limits: Dict of oversubscription limits for memory, disk,
        and CPUs
        :returns: A Claim ticket representing the reserved resources.  This
        should be turned into finalize  a resource claim or free
        resources after the compute operation is finished.
        """
        image_meta = image_meta or {}

        if self.disabled:
            # compute_driver doesn't support resource tracking, just
            # generate the migration record and continue the resize:
            migration = self._create_migration(context, instance,
                                               instance_type)
            return claims.NopClaim(migration=migration)

        # get memory overhead required to build this instance:
        overhead = self.driver.estimate_instance_overhead(instance_type)
        LOG.debug(
            "Memory overhead for %(flavor)d MB instance; %(overhead)d "
            "MB", {
                'flavor': instance_type['memory_mb'],
                'overhead': overhead['memory_mb']
            })

        instance_ref = obj_base.obj_to_primitive(instance)
        claim = claims.ResizeClaim(context,
                                   instance_ref,
                                   instance_type,
                                   image_meta,
                                   self,
                                   self.compute_node,
                                   overhead=overhead,
                                   limits=limits)

        migration = self._create_migration(context, instance_ref,
                                           instance_type)
        claim.migration = migration

        # Mark the resources in-use for the resize landing on this
        # compute host:
        self._update_usage_from_migration(context, instance_ref, image_meta,
                                          self.compute_node, migration)
        elevated = context.elevated()
        self._update(elevated, self.compute_node)

        return claim
Example #4
0
    def instance_claim(self, context, instance_ref, limits=None):
        """Indicate that some resources are needed for an upcoming compute
        instance build operation.

        This should be called before the compute node is about to perform
        an instance build operation that will consume additional resources.

        :param context: security context
        :param instance_ref: instance to reserve resources for.
        :type instance_ref: nova.objects.instance.Instance object
        :param limits: Dict of oversubscription limits for memory, disk,
                       and CPUs.
        :returns: A Claim ticket representing the reserved resources.  It can
                  be used to revert the resource usage if an error occurs
                  during the instance build.
        """
        if self.disabled:
            # compute_driver doesn't support resource tracking, just
            # set the 'host' and node fields and continue the build:
            self._set_instance_host_and_node(context, instance_ref)
            return claims.NopClaim()

        # sanity checks:
        if instance_ref.host:
            LOG.warning(_LW("Host field should not be set on the instance "
                            "until resources have been claimed."),
                        instance=instance_ref)

        if instance_ref.node:
            LOG.warning(_LW("Node field should not be set on the instance "
                            "until resources have been claimed."),
                        instance=instance_ref)

        # get memory overhead required to build this instance:
        overhead = self.driver.estimate_instance_overhead(instance_ref)
        LOG.debug("Memory overhead for %(flavor)d MB instance; %(overhead)d "
                  "MB", {'flavor': instance_ref.memory_mb,
                          'overhead': overhead['memory_mb']})

        claim = claims.Claim(context, instance_ref, self, self.compute_node,
                             overhead=overhead, limits=limits)

        # self._set_instance_host_and_node() will save instance_ref to the DB
        # so set instance_ref['numa_topology'] first.  We need to make sure
        # that numa_topology is saved while under COMPUTE_RESOURCE_SEMAPHORE
        # so that the resource audit knows about any cpus we've pinned.
        instance_ref.numa_topology = claim.claimed_numa_topology
        self._set_instance_host_and_node(context, instance_ref)

        # Mark resources in-use and update stats
        self._update_usage_from_instance(context, instance_ref)

        elevated = context.elevated()
        # persist changes to the compute node:
        self._update(elevated)

        return claim
    def instance_claim(self, context, instance_ref, limits=None):
        """Indicate that some resources are needed for an upcoming compute
        instance build operation.

        This should be called before the compute node is about to perform
        an instance build operation that will consume additional resources.

        :param context: security context
        :param instance_ref: instance to reserve resources for
        :param limits: Dict of oversubscription limits for memory, disk,
                       and CPUs.
        :returns: A Claim ticket representing the reserved resources.  It can
                  be used to revert the resource usage if an error occurs
                  during the instance build.
        """
        if self.disabled:
            # compute_driver doesn't support resource tracking, just
            # set the 'host' and node fields and continue the build:
            self._set_instance_host_and_node(context, instance_ref)
            return claims.NopClaim()

        # sanity checks:
        if instance_ref['host']:
            LOG.warning(_("Host field should not be set on the instance until "
                          "resources have been claimed."),
                        instance=instance_ref)

        if instance_ref['node']:
            LOG.warning(_("Node field should be not be set on the instance "
                          "until resources have been claimed."),
                        instance=instance_ref)

        claim = claims.Claim(instance_ref, self)

        if claim.test(self.compute_node, limits):

            self._set_instance_host_and_node(context, instance_ref)

            # Mark resources in-use and update stats
            self._update_usage_from_instance(self.compute_node, instance_ref)

            # persist changes to the compute node:
            self._update(context, self.compute_node)

            return claim

        else:
            raise exception.ComputeResourcesUnavailable()
    def resize_claim(self, context, instance_ref, instance_type, limits=None):
        """Indicate that resources are needed for a resize operation to this
        compute host.
        :param context: security context
        :param instance_ref: instance to reserve resources for
        :param instance_type: new instance_type being resized to
        :param limits: Dict of oversubscription limits for memory, disk,
                       and CPUs.
        :returns: A Claim ticket representing the reserved resources.  This
                  should be turned into finalize  a resource claim or free
                  resources after the compute operation is finished.
        """
        if self.disabled:
            # compute_driver doesn't support resource tracking, just
            # generate the migration record and continue the resize:
            migration_ref = self._create_migration(context, instance_ref,
                                                   instance_type)
            return claims.NopClaim(migration=migration_ref)

        claim = claims.ResizeClaim(instance_ref, instance_type, self)

        if claim.test(self.compute_node, limits):

            migration_ref = self._create_migration(context, instance_ref,
                                                   instance_type)
            claim.migration = migration_ref

            # Mark the resources in-use for the resize landing on this
            # compute host:
            self._update_usage_from_migration(context, instance_ref,
                                              self.compute_node, migration_ref)
            elevated = context.elevated()
            self._update(elevated, self.compute_node)

            return claim

        else:
            raise exception.ComputeResourcesUnavailable()
Example #7
0
    def _move_claim(self,
                    context,
                    instance,
                    new_instance_type,
                    nodename,
                    move_type=None,
                    image_meta=None,
                    limits=None,
                    migration=None):
        """Indicate that resources are needed for a move to this host.

        Move can be either a migrate/resize, live-migrate or an
        evacuate/rebuild operation.

        :param context: security context
        :param instance: instance object to reserve resources for
        :param new_instance_type: new instance_type being resized to
        :param nodename: The Ironic nodename selected by the scheduler
        :param image_meta: instance image metadata
        :param move_type: move type - can be one of 'migration', 'resize',
                         'live-migration', 'evacuate'
        :param limits: Dict of oversubscription limits for memory, disk,
        and CPUs
        :param migration: A migration object if one was already created
                          elsewhere for this operation
        :returns: A Claim ticket representing the reserved resources.  This
        should be turned into finalize  a resource claim or free
        resources after the compute operation is finished.
        """
        image_meta = image_meta or {}
        if migration:
            self._claim_existing_migration(migration, nodename)
        else:
            migration = self._create_migration(context, instance,
                                               new_instance_type, nodename,
                                               move_type)

        if self.disabled(nodename):
            # compute_driver doesn't support resource tracking, just
            # generate the migration record and continue the resize:
            return claims.NopClaim(migration=migration)

        # get memory overhead required to build this instance:
        overhead = self.driver.estimate_instance_overhead(new_instance_type)
        LOG.debug(
            "Memory overhead for %(flavor)d MB instance; %(overhead)d "
            "MB", {
                'flavor': new_instance_type.memory_mb,
                'overhead': overhead['memory_mb']
            })
        LOG.debug(
            "Disk overhead for %(flavor)d GB instance; %(overhead)d "
            "GB", {
                'flavor': instance.flavor.root_gb,
                'overhead': overhead.get('disk_gb', 0)
            })
        LOG.debug(
            "CPU overhead for %(flavor)d vCPUs instance; %(overhead)d "
            "vCPU(s)", {
                'flavor': instance.flavor.vcpus,
                'overhead': overhead.get('vcpus', 0)
            })

        cn = self.compute_nodes[nodename]

        # TODO(moshele): we are recreating the pci requests even if
        # there was no change on resize. This will cause allocating
        # the old/new pci device in the resize phase. In the future
        # we would like to optimise this.
        new_pci_requests = pci_request.get_pci_requests_from_flavor(
            new_instance_type)
        new_pci_requests.instance_uuid = instance.uuid
        # PCI requests come from two sources: instance flavor and
        # SR-IOV ports. SR-IOV ports pci_request don't have an alias_name.
        # On resize merge the SR-IOV ports pci_requests with the new
        # instance flavor pci_requests.
        if instance.pci_requests:
            for request in instance.pci_requests.requests:
                if request.alias_name is None:
                    new_pci_requests.requests.append(request)
        claim = claims.MoveClaim(context,
                                 instance,
                                 nodename,
                                 new_instance_type,
                                 image_meta,
                                 self,
                                 cn,
                                 new_pci_requests,
                                 overhead=overhead,
                                 limits=limits)

        claim.migration = migration
        claimed_pci_devices_objs = []
        if self.pci_tracker:
            # NOTE(jaypipes): ComputeNode.pci_device_pools is set below
            # in _update_usage_from_instance().
            claimed_pci_devices_objs = self.pci_tracker.claim_instance(
                context, new_pci_requests, claim.claimed_numa_topology)
        claimed_pci_devices = objects.PciDeviceList(
            objects=claimed_pci_devices_objs)

        # TODO(jaypipes): Move claimed_numa_topology out of the Claim's
        # constructor flow so the Claim constructor only tests whether
        # resources can be claimed, not consume the resources directly.
        mig_context = objects.MigrationContext(
            context=context,
            instance_uuid=instance.uuid,
            migration_id=migration.id,
            old_numa_topology=instance.numa_topology,
            new_numa_topology=claim.claimed_numa_topology,
            old_pci_devices=instance.pci_devices,
            new_pci_devices=claimed_pci_devices,
            old_pci_requests=instance.pci_requests,
            new_pci_requests=new_pci_requests)
        instance.migration_context = mig_context
        instance.save()

        # Mark the resources in-use for the resize landing on this
        # compute host:
        self._update_usage_from_migration(context, instance, migration,
                                          nodename)
        elevated = context.elevated()
        self._update(elevated, cn)

        return claim
Example #8
0
    def instance_claim(self, context, instance, nodename, limits=None):
        """Indicate that some resources are needed for an upcoming compute
        instance build operation.

        This should be called before the compute node is about to perform
        an instance build operation that will consume additional resources.

        :param context: security context
        :param instance: instance to reserve resources for.
        :type instance: nova.objects.instance.Instance object
        :param nodename: The Ironic nodename selected by the scheduler
        :param limits: Dict of oversubscription limits for memory, disk,
                       and CPUs.
        :returns: A Claim ticket representing the reserved resources.  It can
                  be used to revert the resource usage if an error occurs
                  during the instance build.
        """
        if self.disabled(nodename):
            # instance_claim() was called before update_available_resource()
            # (which ensures that a compute node exists for nodename). We
            # shouldn't get here but in case we do, just set the instance's
            # host and nodename attribute (probably incorrect) and return a
            # NoopClaim.
            # TODO(jaypipes): Remove all the disabled junk from the resource
            # tracker. Servicegroup API-level active-checking belongs in the
            # nova-compute manager.
            self._set_instance_host_and_node(instance, nodename)
            return claims.NopClaim()

        # sanity checks:
        if instance.host:
            LOG.warning(_LW("Host field should not be set on the instance "
                            "until resources have been claimed."),
                        instance=instance)

        if instance.node:
            LOG.warning(_LW("Node field should not be set on the instance "
                            "until resources have been claimed."),
                        instance=instance)

        # get the overhead required to build this instance:
        overhead = self.driver.estimate_instance_overhead(instance)
        LOG.debug(
            "Memory overhead for %(flavor)d MB instance; %(overhead)d "
            "MB", {
                'flavor': instance.flavor.memory_mb,
                'overhead': overhead['memory_mb']
            })
        LOG.debug(
            "Disk overhead for %(flavor)d GB instance; %(overhead)d "
            "GB", {
                'flavor': instance.flavor.root_gb,
                'overhead': overhead.get('disk_gb', 0)
            })
        LOG.debug(
            "CPU overhead for %(flavor)d vCPUs instance; %(overhead)d "
            "vCPU(s)", {
                'flavor': instance.flavor.vcpus,
                'overhead': overhead.get('vcpus', 0)
            })

        cn = self.compute_nodes[nodename]
        pci_requests = objects.InstancePCIRequests.get_by_instance_uuid(
            context, instance.uuid)
        claim = claims.Claim(context,
                             instance,
                             nodename,
                             self,
                             cn,
                             pci_requests,
                             overhead=overhead,
                             limits=limits)

        # self._set_instance_host_and_node() will save instance to the DB
        # so set instance.numa_topology first.  We need to make sure
        # that numa_topology is saved while under COMPUTE_RESOURCE_SEMAPHORE
        # so that the resource audit knows about any cpus we've pinned.
        instance_numa_topology = claim.claimed_numa_topology
        instance.numa_topology = instance_numa_topology
        self._set_instance_host_and_node(instance, nodename)

        if self.pci_tracker:
            # NOTE(jaypipes): ComputeNode.pci_device_pools is set below
            # in _update_usage_from_instance().
            self.pci_tracker.claim_instance(context, pci_requests,
                                            instance_numa_topology)

        # Mark resources in-use and update stats
        self._update_usage_from_instance(context, instance, nodename)

        elevated = context.elevated()
        # persist changes to the compute node:
        self._update(elevated, cn)

        return claim
Example #9
0
    def instance_claim(self,
                       context,
                       instance,
                       limits=None,
                       filter_properties=None):
        """Indicate that some resources are needed for an upcoming compute
        instance build operation.

        This should be called before the compute node is about to perform
        an instance build operation that will consume additional resources.

        :param context: security context
        :param instance: instance to reserve resources for.
        :type instance: nova.objects.instance.Instance object
        :param limits: Dict of oversubscription limits for memory, disk,
                       and CPUs.
        :param filter_properties: Dict of the scheduler hints for the instance.
        :returns: A Claim ticket representing the reserved resources.  It can
                  be used to revert the resource usage if an error occurs
                  during the instance build.
        """
        if self.disabled:
            # compute_driver doesn't support resource tracking, just
            # set the 'host' and node fields and continue the build:
            self._set_instance_host_and_node(instance)
            return claims.NopClaim()

        # sanity checks:
        if instance.host:
            LOG.warning(_LW("Host field should not be set on the instance "
                            "until resources have been claimed."),
                        instance=instance)

        if instance.node:
            LOG.warning(_LW("Node field should not be set on the instance "
                            "until resources have been claimed."),
                        instance=instance)

        # get the overhead required to build this instance:
        overhead = self.driver.estimate_instance_overhead(instance)
        LOG.debug(
            "Memory overhead for %(flavor)d MB instance; %(overhead)d "
            "MB", {
                'flavor': instance.flavor.memory_mb,
                'overhead': overhead['memory_mb']
            })
        LOG.debug(
            "Disk overhead for %(flavor)d GB instance; %(overhead)d "
            "GB", {
                'flavor': instance.flavor.root_gb,
                'overhead': overhead.get('disk_gb', 0)
            })

        pci_requests = objects.InstancePCIRequests.get_by_instance_uuid(
            context, instance.uuid)
        claim = claims.Claim(context,
                             instance,
                             self,
                             self.compute_node,
                             pci_requests,
                             overhead=overhead,
                             limits=limits,
                             filter_properties=filter_properties)

        # self._set_instance_host_and_node() will save instance to the DB
        # so set instance.numa_topology first.  We need to make sure
        # that numa_topology is saved while under COMPUTE_RESOURCE_SEMAPHORE
        # so that the resource audit knows about any cpus we've pinned.
        instance_numa_topology = claim.claimed_numa_topology
        instance.numa_topology = instance_numa_topology
        self._set_instance_host_and_node(instance)

        if self.pci_tracker:
            # NOTE(jaypipes): ComputeNode.pci_device_pools is set below
            # in _update_usage_from_instance().
            self.pci_tracker.claim_instance(context, pci_requests,
                                            instance_numa_topology)

        # Mark resources in-use and update stats
        self._update_usage_from_instance(context, instance)

        elevated = context.elevated()
        # persist changes to the compute node:
        self._update(elevated)

        return claim
Example #10
0
    def resize_claim(self, context, instance, instance_type,
                     image_meta=None, limits=None):
        """Indicate that resources are needed for a resize operation to this
        compute host.
        :param context: security context
        :param instance: instance object to reserve resources for
        :param instance_type: new instance_type being resized to
        :param limits: Dict of oversubscription limits for memory, disk,
        and CPUs
        :returns: A Claim ticket representing the reserved resources.  This
        should be turned into finalize  a resource claim or free
        resources after the compute operation is finished.
        """
        image_meta = image_meta or {}

        if self.disabled:
            # compute_driver doesn't support resource tracking, just
            # generate the migration record and continue the resize:
            migration = self._create_migration(context, instance,
                                               instance_type)
            return claims.NopClaim(migration=migration)

        # get memory overhead required to build this instance:
        overhead = self.driver.estimate_instance_overhead(instance_type)
        LOG.debug("Memory overhead for %(flavor)d MB instance; %(overhead)d "
                  "MB", {'flavor': instance_type['memory_mb'],
                          'overhead': overhead['memory_mb']})

        instance_ref = obj_base.obj_to_primitive(instance)
        try:
            claim = h_claims.HuaweiResizeClaim(context, instance_ref,
                                               instance_type, image_meta,
                                               self, self.compute_node,
                                               overhead=overhead,
                                               limits=limits)
        except Exception as e:
            # Update partial stats locally and populate them to Scheduler
            self._update(context.elevated(), self.compute_node, force=True)
            LOG.exception("Failed to claim when resize %s." % instance['uuid'])
            raise exception.InstanceFaultRollback(inner_exception=e)
        migration = self._create_migration(context, instance_ref,
                                           instance_type)
        # save pci_requests
        if claim.pci_requests:
            claim.pci_requests.save(context)
        claim.migration = migration
        system_metadata = instance.system_metadata
        if claim.claimed_numa_topology:
            system_metadata['new_numa_topo'] = jsonutils.dumps(
                claim.claimed_numa_topology)
        if claim.bind_info:
            system_metadata['new_bind_info'] = jsonutils.dumps(claim.bind_info)
        instance.system_metadata = system_metadata
        instance.save()
        # Mark the resources in-use for the resize landing on this
        # compute host:
        self._update_usage_from_migration(context, instance_ref, image_meta,
                                          self.compute_node, migration)
        elevated = context.elevated()
        self._update(elevated, self.compute_node)

        return claim