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
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
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
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()
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
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
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
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