<s> """<STR_LIT>""" <EOL> import copy <EOL> from oslo_log import log as logging <EOL> from oslo_serialization import jsonutils <EOL> from oslo_utils import importutils <EOL> from nova . compute import claims <EOL> from nova . compute import monitors <EOL> from nova . compute import task_states <EOL> from nova . compute import vm_states <EOL> import nova . conf <EOL> from nova import exception <EOL> from nova . i18n import _ , _LE , _LI , _LW <EOL> from nova import objects <EOL> from nova . objects import base as obj_base <EOL> from nova . objects import migration as migration_obj <EOL> from nova . pci import manager as pci_manager <EOL> from nova import rpc <EOL> from nova . scheduler import client as scheduler_client <EOL> from nova import utils <EOL> from nova . virt import hardware <EOL> CONF = nova . conf . CONF <EOL> LOG = logging . getLogger ( __name__ ) <EOL> COMPUTE_RESOURCE_SEMAPHORE = "<STR_LIT>" <EOL> CONF . import_opt ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> def _instance_in_resize_state ( instance ) : <EOL> """<STR_LIT>""" <EOL> vm = instance . vm_state <EOL> task = instance . task_state <EOL> if vm == vm_states . RESIZED : <EOL> return True <EOL> if ( vm in [ vm_states . ACTIVE , vm_states . STOPPED ] <EOL> and task in [ task_states . RESIZE_PREP , <EOL> task_states . RESIZE_MIGRATING , task_states . RESIZE_MIGRATED , <EOL> task_states . RESIZE_FINISH , task_states . REBUILDING ] ) : <EOL> return True <EOL> return False <EOL> class ResourceTracker ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , host , driver , nodename ) : <EOL> self . host = host <EOL> self . driver = driver <EOL> self . pci_tracker = None <EOL> self . nodename = nodename <EOL> self . compute_node = None <EOL> self . stats = importutils . import_object ( CONF . compute_stats_class ) <EOL> self . tracked_instances = { } <EOL> self . tracked_migrations = { } <EOL> monitor_handler = monitors . MonitorHandler ( self ) <EOL> self . monitors = monitor_handler . monitors <EOL> self . old_resources = objects . ComputeNode ( ) <EOL> self . scheduler_client = scheduler_client . SchedulerClient ( ) <EOL> self . ram_allocation_ratio = CONF . ram_allocation_ratio <EOL> self . cpu_allocation_ratio = CONF . cpu_allocation_ratio <EOL> self . disk_allocation_ratio = CONF . disk_allocation_ratio <EOL> @ utils . synchronized ( COMPUTE_RESOURCE_SEMAPHORE ) <EOL> def instance_claim ( self , context , instance_ref , limits = None ) : <EOL> """<STR_LIT>""" <EOL> if self . disabled : <EOL> self . _set_instance_host_and_node ( instance_ref ) <EOL> return claims . NopClaim ( ) <EOL> if instance_ref . host : <EOL> LOG . warning ( _LW ( "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> instance = instance_ref ) <EOL> if instance_ref . node : <EOL> LOG . warning ( _LW ( "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> instance = instance_ref ) <EOL> overhead = self . driver . estimate_instance_overhead ( instance_ref ) <EOL> LOG . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" , { '<STR_LIT>' : instance_ref . memory_mb , <EOL> '<STR_LIT>' : overhead [ '<STR_LIT>' ] } ) <EOL> claim = claims . Claim ( context , instance_ref , self , self . compute_node , <EOL> overhead = overhead , limits = limits ) <EOL> if self . pci_tracker : <EOL> self . pci_tracker . claim_instance ( context , instance_ref ) <EOL> instance_ref . numa_topology = claim . claimed_numa_topology <EOL> self . _set_instance_host_and_node ( instance_ref ) <EOL> self . _update_usage_from_instance ( context , instance_ref ) <EOL> elevated = context . elevated ( ) <EOL> self . _update ( elevated ) <EOL> return claim <EOL> @ utils . synchronized ( COMPUTE_RESOURCE_SEMAPHORE ) <EOL> def rebuild_claim ( self , context , instance , limits = None , image_meta = None , <EOL> migration = None ) : <EOL> """<STR_LIT>""" <EOL> instance_type = instance . flavor <EOL> return self . _move_claim ( context , instance , instance_type , <EOL> move_type = '<STR_LIT>' , limits = limits , <EOL> image_meta = image_meta , migration = migration ) <EOL> @ utils . synchronized ( COMPUTE_RESOURCE_SEMAPHORE ) <EOL> def resize_claim ( self , context , instance , instance_type , <EOL> image_meta = None , limits = None ) : <EOL> """<STR_LIT>""" <EOL> return self . _move_claim ( context , instance , instance_type , <EOL> image_meta = image_meta , limits = limits ) <EOL> def _move_claim ( self , context , instance , new_instance_type , move_type = None , <EOL> image_meta = None , limits = None , migration = None ) : <EOL> """<STR_LIT>""" <EOL> image_meta = image_meta or { } <EOL> if migration : <EOL> self . _claim_existing_migration ( migration ) <EOL> else : <EOL> migration = self . _create_migration ( context , instance , <EOL> new_instance_type , move_type ) <EOL> if self . disabled : <EOL> return claims . NopClaim ( migration = migration ) <EOL> overhead = self . driver . estimate_instance_overhead ( new_instance_type ) <EOL> LOG . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" , { '<STR_LIT>' : new_instance_type . memory_mb , <EOL> '<STR_LIT>' : overhead [ '<STR_LIT>' ] } ) <EOL> claim = claims . MoveClaim ( context , instance , new_instance_type , <EOL> image_meta , self , self . compute_node , <EOL> overhead = overhead , limits = limits ) <EOL> claim . migration = migration <EOL> instance . migration_context = claim . create_migration_context ( ) <EOL> instance . save ( ) <EOL> self . _update_usage_from_migration ( context , instance , image_meta , <EOL> migration ) <EOL> elevated = context . elevated ( ) <EOL> self . _update ( elevated ) <EOL> return claim <EOL> def _create_migration ( self , context , instance , new_instance_type , <EOL> move_type = None ) : <EOL> """<STR_LIT>""" <EOL> migration = objects . Migration ( context = context . elevated ( ) ) <EOL> migration . dest_compute = self . host <EOL> migration . dest_node = self . nodename <EOL> migration . dest_host = self . driver . get_host_ip_addr ( ) <EOL> migration . old_instance_type_id = instance . flavor . id <EOL> migration . new_instance_type_id = new_instance_type . id <EOL> migration . status = '<STR_LIT>' <EOL> migration . instance_uuid = instance . uuid <EOL> migration . source_compute = instance . host <EOL> migration . source_node = instance . node <EOL> if move_type : <EOL> migration . migration_type = move_type <EOL> else : <EOL> migration . migration_type = migration_obj . determine_migration_type ( <EOL> migration ) <EOL> migration . create ( ) <EOL> return migration <EOL> def _claim_existing_migration ( self , migration ) : <EOL> """<STR_LIT>""" <EOL> migration . dest_compute = self . host <EOL> migration . dest_node = self . nodename <EOL> migration . dest_host = self . driver . get_host_ip_addr ( ) <EOL> migration . status = '<STR_LIT>' <EOL> migration . save ( ) <EOL> def _set_instance_host_and_node ( self , instance ) : <EOL> """<STR_LIT>""" <EOL> instance . host = self . host <EOL> instance . launched_on = self . host <EOL> instance . node = self . nodename <EOL> instance . save ( ) <EOL> def _unset_instance_host_and_node ( self , instance ) : <EOL> """<STR_LIT>""" <EOL> instance . host = None <EOL> instance . node = None <EOL> instance . save ( ) <EOL> @ utils . synchronized ( COMPUTE_RESOURCE_SEMAPHORE ) <EOL> def abort_instance_claim ( self , context , instance ) : <EOL> """<STR_LIT>""" <EOL> self . _update_usage_from_instance ( context , instance , is_removed = True ) <EOL> instance . clear_numa_topology ( ) <EOL> self . _unset_instance_host_and_node ( instance ) <EOL> self . _update ( context . elevated ( ) ) <EOL> @ utils . synchronized ( COMPUTE_RESOURCE_SEMAPHORE ) <EOL> def drop_move_claim ( self , context , instance , instance_type = None , <EOL> prefix = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> if instance [ '<STR_LIT>' ] in self . tracked_migrations : <EOL> migration , itype = self . tracked_migrations . pop ( instance [ '<STR_LIT>' ] ) <EOL> if not instance_type : <EOL> ctxt = context . elevated ( ) <EOL> instance_type = self . _get_instance_type ( ctxt , instance , prefix , <EOL> migration ) <EOL> if instance_type is not None and instance_type . id == itype [ '<STR_LIT:id>' ] : <EOL> numa_topology = self . _get_migration_context_resource ( <EOL> '<STR_LIT>' , instance ) <EOL> usage = self . _get_usage_dict ( <EOL> itype , numa_topology = numa_topology ) <EOL> if self . pci_tracker : <EOL> self . pci_tracker . update_pci_for_migration ( context , <EOL> instance , <EOL> sign = - <NUM_LIT:1> ) <EOL> self . _update_usage ( usage , sign = - <NUM_LIT:1> ) <EOL> ctxt = context . elevated ( ) <EOL> self . _update ( ctxt ) <EOL> instance . drop_migration_context ( ) <EOL> @ utils . synchronized ( COMPUTE_RESOURCE_SEMAPHORE ) <EOL> def update_usage ( self , context , instance ) : <EOL> """<STR_LIT>""" <EOL> if self . disabled : <EOL> return <EOL> uuid = instance [ '<STR_LIT>' ] <EOL> if uuid in self . tracked_instances : <EOL> self . _update_usage_from_instance ( context , instance ) <EOL> self . _update ( context . elevated ( ) ) <EOL> @ property <EOL> def disabled ( self ) : <EOL> return self . compute_node is None <EOL> def _init_compute_node ( self , context , resources ) : <EOL> """<STR_LIT>""" <EOL> if self . compute_node : <EOL> self . _copy_resources ( resources ) <EOL> return <EOL> self . compute_node = self . _get_compute_node ( context ) <EOL> if self . compute_node : <EOL> self . _copy_resources ( resources ) <EOL> return <EOL> self . compute_node = objects . ComputeNode ( context ) <EOL> self . compute_node . host = self . host <EOL> self . _copy_resources ( resources ) <EOL> self . compute_node . create ( ) <EOL> LOG . info ( _LI ( '<STR_LIT>' <EOL> '<STR_LIT>' ) , <EOL> { '<STR_LIT:host>' : self . host , '<STR_LIT>' : self . nodename } ) <EOL> def _copy_resources ( self , resources ) : <EOL> """<STR_LIT>""" <EOL> self . stats . clear ( ) <EOL> self . stats . digest_stats ( resources . get ( '<STR_LIT>' ) ) <EOL> self . compute_node . stats = copy . deepcopy ( self . stats ) <EOL> self . compute_node . ram_allocation_ratio = self . ram_allocation_ratio <EOL> self . compute_node . cpu_allocation_ratio = self . cpu_allocation_ratio <EOL> self . compute_node . disk_allocation_ratio = self . disk_allocation_ratio <EOL> self . compute_node . update_from_virt_driver ( resources ) <EOL> def _get_host_metrics ( self , context , nodename ) : <EOL> """<STR_LIT>""" <EOL> metrics = objects . MonitorMetricList ( ) <EOL> metrics_info = { } <EOL> for monitor in self . monitors : <EOL> try : <EOL> monitor . add_metrics_to_list ( metrics ) <EOL> except Exception as exc : <EOL> LOG . warning ( _LW ( "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> { '<STR_LIT>' : monitor , '<STR_LIT>' : exc } ) <EOL> metrics = metrics . to_list ( ) <EOL> if len ( metrics ) : <EOL> metrics_info [ '<STR_LIT>' ] = nodename <EOL> metrics_info [ '<STR_LIT>' ] = metrics <EOL> metrics_info [ '<STR_LIT:host>' ] = self . host <EOL> metrics_info [ '<STR_LIT>' ] = CONF . my_ip <EOL> notifier = rpc . get_notifier ( service = '<STR_LIT>' , host = nodename ) <EOL> notifier . info ( context , '<STR_LIT>' , metrics_info ) <EOL> return metrics <EOL> def update_available_resource ( self , context ) : <EOL> """<STR_LIT>""" <EOL> LOG . info ( _LI ( "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> { '<STR_LIT>' : self . nodename } ) <EOL> resources = self . driver . get_available_resource ( self . nodename ) <EOL> if not resources : <EOL> LOG . info ( _LI ( "<STR_LIT>" <EOL> "<STR_LIT>" ) ) <EOL> self . compute_node = None <EOL> return <EOL> resources [ '<STR_LIT>' ] = CONF . my_ip <EOL> if "<STR_LIT>" not in resources or resources [ "<STR_LIT>" ] is None : <EOL> resources [ "<STR_LIT>" ] = '<STR_LIT>' <EOL> self . _verify_resources ( resources ) <EOL> self . _report_hypervisor_resource_view ( resources ) <EOL> self . _update_available_resource ( context , resources ) <EOL> def _pair_instances_to_migrations ( self , migrations , instances ) : <EOL> instance_by_uuid = { inst . uuid : inst for inst in instances } <EOL> for migration in migrations : <EOL> try : <EOL> migration . instance = instance_by_uuid [ migration . instance_uuid ] <EOL> except KeyError : <EOL> LOG . error ( _LE ( '<STR_LIT>' <EOL> '<STR_LIT>' ) , <EOL> { '<STR_LIT>' : migration . instance_uuid } ) <EOL> @ utils . synchronized ( COMPUTE_RESOURCE_SEMAPHORE ) <EOL> def _update_available_resource ( self , context , resources ) : <EOL> self . _init_compute_node ( context , resources ) <EOL> if self . disabled : <EOL> return <EOL> if '<STR_LIT>' in resources : <EOL> if not self . pci_tracker : <EOL> n_id = self . compute_node . id if self . compute_node else None <EOL> self . pci_tracker = pci_manager . PciDevTracker ( context , <EOL> node_id = n_id ) <EOL> dev_json = resources . pop ( '<STR_LIT>' ) <EOL> self . pci_tracker . update_devices_from_hypervisor_resources ( dev_json ) <EOL> instances = objects . InstanceList . get_by_host_and_node ( <EOL> context , self . host , self . nodename , <EOL> expected_attrs = [ '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> self . _update_usage_from_instances ( context , instances ) <EOL> migrations = objects . MigrationList . get_in_progress_by_host_and_node ( <EOL> context , self . host , self . nodename ) <EOL> self . _pair_instances_to_migrations ( migrations , instances ) <EOL> self . _update_usage_from_migrations ( context , migrations ) <EOL> orphans = self . _find_orphaned_instances ( ) <EOL> self . _update_usage_from_orphans ( orphans ) <EOL> if self . pci_tracker : <EOL> self . pci_tracker . clean_usage ( instances , migrations , orphans ) <EOL> dev_pools_obj = self . pci_tracker . stats . to_device_pools_obj ( ) <EOL> self . compute_node . pci_device_pools = dev_pools_obj <EOL> else : <EOL> self . compute_node . pci_device_pools = objects . PciDevicePoolList ( ) <EOL> self . _report_final_resource_view ( ) <EOL> metrics = self . _get_host_metrics ( context , self . nodename ) <EOL> self . compute_node . metrics = jsonutils . dumps ( metrics ) <EOL> self . _update ( context ) <EOL> LOG . info ( _LI ( '<STR_LIT>' ) , <EOL> { '<STR_LIT:host>' : self . host , '<STR_LIT>' : self . nodename } ) <EOL> def _get_compute_node ( self , context ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return objects . ComputeNode . get_by_host_and_nodename ( <EOL> context , self . host , self . nodename ) <EOL> except exception . NotFound : <EOL> LOG . warning ( _LW ( "<STR_LIT>" ) , <EOL> { '<STR_LIT:host>' : self . host , '<STR_LIT>' : self . nodename } ) <EOL> def _report_hypervisor_resource_view ( self , resources ) : <EOL> """<STR_LIT>""" <EOL> free_ram_mb = resources [ '<STR_LIT>' ] - resources [ '<STR_LIT>' ] <EOL> free_disk_gb = resources [ '<STR_LIT>' ] - resources [ '<STR_LIT>' ] <EOL> vcpus = resources [ '<STR_LIT>' ] <EOL> if vcpus : <EOL> free_vcpus = vcpus - resources [ '<STR_LIT>' ] <EOL> LOG . debug ( "<STR_LIT>" , free_vcpus ) <EOL> else : <EOL> free_vcpus = '<STR_LIT>' <EOL> LOG . debug ( "<STR_LIT>" ) <EOL> if ( '<STR_LIT>' in resources and <EOL> resources [ '<STR_LIT>' ] ) : <EOL> LOG . debug ( "<STR_LIT>" , <EOL> resources [ '<STR_LIT>' ] ) <EOL> pci_devices = resources . get ( '<STR_LIT>' ) <EOL> LOG . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> { '<STR_LIT>' : self . nodename , <EOL> '<STR_LIT>' : free_ram_mb , <EOL> '<STR_LIT>' : free_disk_gb , <EOL> '<STR_LIT>' : free_vcpus , <EOL> '<STR_LIT>' : pci_devices } ) <EOL> def _report_final_resource_view ( self ) : <EOL> """<STR_LIT>""" <EOL> vcpus = self . compute_node . vcpus <EOL> if vcpus : <EOL> tcpu = vcpus <EOL> ucpu = self . compute_node . vcpus_used <EOL> LOG . info ( _LI ( "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> { '<STR_LIT>' : vcpus , <EOL> '<STR_LIT>' : ucpu } ) <EOL> else : <EOL> tcpu = <NUM_LIT:0> <EOL> ucpu = <NUM_LIT:0> <EOL> pci_stats = ( list ( self . compute_node . pci_device_pools ) if <EOL> self . compute_node . pci_device_pools else [ ] ) <EOL> LOG . info ( _LI ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> { '<STR_LIT>' : self . nodename , <EOL> '<STR_LIT>' : self . compute_node . memory_mb , <EOL> '<STR_LIT>' : self . compute_node . memory_mb_used , <EOL> '<STR_LIT>' : self . compute_node . local_gb , <EOL> '<STR_LIT>' : self . compute_node . local_gb_used , <EOL> '<STR_LIT>' : tcpu , <EOL> '<STR_LIT>' : ucpu , <EOL> '<STR_LIT>' : pci_stats } ) <EOL> def _resource_change ( self ) : <EOL> """<STR_LIT>""" <EOL> if not obj_base . obj_equal_prims ( self . compute_node , self . old_resources ) : <EOL> self . old_resources = copy . deepcopy ( self . compute_node ) <EOL> return True <EOL> return False <EOL> def _update ( self , context ) : <EOL> """<STR_LIT>""" <EOL> if not self . _resource_change ( ) : <EOL> return <EOL> self . scheduler_client . update_resource_stats ( self . compute_node ) <EOL> if self . pci_tracker : <EOL> self . pci_tracker . save ( context ) <EOL> def _update_usage ( self , usage , sign = <NUM_LIT:1> ) : <EOL> mem_usage = usage [ '<STR_LIT>' ] <EOL> overhead = self . driver . estimate_instance_overhead ( usage ) <EOL> mem_usage += overhead [ '<STR_LIT>' ] <EOL> self . compute_node . memory_mb_used += sign * mem_usage <EOL> self . compute_node . local_gb_used += sign * usage . get ( '<STR_LIT>' , <NUM_LIT:0> ) <EOL> self . compute_node . local_gb_used += sign * usage . get ( '<STR_LIT>' , <NUM_LIT:0> ) <EOL> self . compute_node . vcpus_used += sign * usage . get ( '<STR_LIT>' , <NUM_LIT:0> ) <EOL> self . compute_node . free_ram_mb = ( self . compute_node . memory_mb - <EOL> self . compute_node . memory_mb_used ) <EOL> self . compute_node . free_disk_gb = ( self . compute_node . local_gb - <EOL> self . compute_node . local_gb_used ) <EOL> self . compute_node . running_vms = self . stats . num_instances <EOL> free = sign == - <NUM_LIT:1> <EOL> updated_numa_topology = hardware . get_host_numa_usage_from_instance ( <EOL> self . compute_node , usage , free ) <EOL> self . compute_node . numa_topology = updated_numa_topology <EOL> def _is_trackable_migration ( self , migration ) : <EOL> return migration . migration_type in ( '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' ) <EOL> def _get_migration_context_resource ( self , resource , instance , <EOL> prefix = '<STR_LIT>' , itype = None ) : <EOL> migration_context = instance . migration_context <EOL> if migration_context : <EOL> return getattr ( migration_context , prefix + resource ) <EOL> else : <EOL> return None <EOL> def _update_usage_from_migration ( self , context , instance , image_meta , <EOL> migration ) : <EOL> """<STR_LIT>""" <EOL> if not self . _is_trackable_migration ( migration ) : <EOL> return <EOL> uuid = migration . instance_uuid <EOL> LOG . info ( _LI ( "<STR_LIT>" ) , uuid ) <EOL> incoming = ( migration . dest_compute == self . host and <EOL> migration . dest_node == self . nodename ) <EOL> outbound = ( migration . source_compute == self . host and <EOL> migration . source_node == self . nodename ) <EOL> same_node = ( incoming and outbound ) <EOL> record = self . tracked_instances . get ( uuid , None ) <EOL> itype = None <EOL> numa_topology = None <EOL> if same_node : <EOL> if ( instance [ '<STR_LIT>' ] == <EOL> migration . old_instance_type_id ) : <EOL> itype = self . _get_instance_type ( context , instance , '<STR_LIT>' , <EOL> migration ) <EOL> numa_topology = self . _get_migration_context_resource ( <EOL> '<STR_LIT>' , instance ) <EOL> else : <EOL> itype = self . _get_instance_type ( context , instance , '<STR_LIT>' , <EOL> migration ) <EOL> numa_topology = self . _get_migration_context_resource ( <EOL> '<STR_LIT>' , instance , prefix = '<STR_LIT>' ) <EOL> elif incoming and not record : <EOL> itype = self . _get_instance_type ( context , instance , '<STR_LIT>' , <EOL> migration ) <EOL> numa_topology = self . _get_migration_context_resource ( <EOL> '<STR_LIT>' , instance ) <EOL> elif outbound and not record : <EOL> itype = self . _get_instance_type ( context , instance , '<STR_LIT>' , <EOL> migration ) <EOL> numa_topology = self . _get_migration_context_resource ( <EOL> '<STR_LIT>' , instance , prefix = '<STR_LIT>' ) <EOL> if image_meta is None : <EOL> image_meta = objects . ImageMeta . from_instance ( instance ) <EOL> elif not isinstance ( image_meta , objects . ImageMeta ) : <EOL> image_meta = objects . ImageMeta . from_dict ( image_meta ) <EOL> if itype : <EOL> usage = self . _get_usage_dict ( <EOL> itype , numa_topology = numa_topology ) <EOL> if self . pci_tracker : <EOL> self . pci_tracker . update_pci_for_migration ( context , instance ) <EOL> self . _update_usage ( usage ) <EOL> if self . pci_tracker : <EOL> obj = self . pci_tracker . stats . to_device_pools_obj ( ) <EOL> self . compute_node . pci_device_pools = obj <EOL> else : <EOL> obj = objects . PciDevicePoolList ( ) <EOL> self . compute_node . pci_device_pools = obj <EOL> self . tracked_migrations [ uuid ] = ( migration , itype ) <EOL> def _update_usage_from_migrations ( self , context , migrations ) : <EOL> filtered = { } <EOL> instances = { } <EOL> self . tracked_migrations . clear ( ) <EOL> for migration in migrations : <EOL> uuid = migration . instance_uuid <EOL> try : <EOL> if uuid not in instances : <EOL> instances [ uuid ] = migration . instance <EOL> except exception . InstanceNotFound as e : <EOL> LOG . debug ( '<STR_LIT>' , e ) <EOL> continue <EOL> if not _instance_in_resize_state ( instances [ uuid ] ) : <EOL> LOG . warning ( _LW ( "<STR_LIT>" ) , <EOL> instance_uuid = uuid ) <EOL> continue <EOL> other_migration = filtered . get ( uuid , None ) <EOL> if ( not other_migration or ( <EOL> migration . updated_at and other_migration . updated_at and <EOL> migration . updated_at >= other_migration . updated_at ) ) : <EOL> filtered [ uuid ] = migration <EOL> for migration in filtered . values ( ) : <EOL> instance = instances [ migration . instance_uuid ] <EOL> try : <EOL> self . _update_usage_from_migration ( context , instance , None , <EOL> migration ) <EOL> except exception . FlavorNotFound : <EOL> LOG . warning ( _LW ( "<STR_LIT>" <EOL> "<STR_LIT>" ) , instance_uuid = uuid ) <EOL> continue <EOL> def _update_usage_from_instance ( self , context , instance , is_removed = False ) : <EOL> """<STR_LIT>""" <EOL> uuid = instance [ '<STR_LIT>' ] <EOL> is_new_instance = uuid not in self . tracked_instances <EOL> is_removed_instance = ( <EOL> is_removed or <EOL> instance [ '<STR_LIT>' ] in vm_states . ALLOW_RESOURCE_REMOVAL ) <EOL> if is_new_instance : <EOL> self . tracked_instances [ uuid ] = obj_base . obj_to_primitive ( instance ) <EOL> sign = <NUM_LIT:1> <EOL> if is_removed_instance : <EOL> self . tracked_instances . pop ( uuid ) <EOL> sign = - <NUM_LIT:1> <EOL> self . stats . update_stats_for_instance ( instance , is_removed_instance ) <EOL> self . compute_node . stats = copy . deepcopy ( self . stats ) <EOL> if is_new_instance or is_removed_instance : <EOL> if self . pci_tracker : <EOL> self . pci_tracker . update_pci_for_instance ( context , <EOL> instance , <EOL> sign = sign ) <EOL> self . _update_usage ( instance , sign = sign ) <EOL> self . compute_node . current_workload = self . stats . calculate_workload ( ) <EOL> if self . pci_tracker : <EOL> obj = self . pci_tracker . stats . to_device_pools_obj ( ) <EOL> self . compute_node . pci_device_pools = obj <EOL> else : <EOL> self . compute_node . pci_device_pools = objects . PciDevicePoolList ( ) <EOL> def _update_usage_from_instances ( self , context , instances ) : <EOL> """<STR_LIT>""" <EOL> self . tracked_instances . clear ( ) <EOL> self . compute_node . local_gb_used = CONF . reserved_host_disk_mb / <NUM_LIT> <EOL> self . compute_node . memory_mb_used = CONF . reserved_host_memory_mb <EOL> self . compute_node . vcpus_used = <NUM_LIT:0> <EOL> self . compute_node . free_ram_mb = ( self . compute_node . memory_mb - <EOL> self . compute_node . memory_mb_used ) <EOL> self . compute_node . free_disk_gb = ( self . compute_node . local_gb - <EOL> self . compute_node . local_gb_used ) <EOL> self . compute_node . current_workload = <NUM_LIT:0> <EOL> self . compute_node . running_vms = <NUM_LIT:0> <EOL> for instance in instances : <EOL> if instance . vm_state not in vm_states . ALLOW_RESOURCE_REMOVAL : <EOL> self . _update_usage_from_instance ( context , instance ) <EOL> def _find_orphaned_instances ( self ) : <EOL> """<STR_LIT>""" <EOL> uuids1 = frozenset ( self . tracked_instances . keys ( ) ) <EOL> uuids2 = frozenset ( self . tracked_migrations . keys ( ) ) <EOL> uuids = uuids1 | uuids2 <EOL> usage = self . driver . get_per_instance_usage ( ) <EOL> vuuids = frozenset ( usage . keys ( ) ) <EOL> orphan_uuids = vuuids - uuids <EOL> orphans = [ usage [ uuid ] for uuid in orphan_uuids ] <EOL> return orphans <EOL> def _update_usage_from_orphans ( self , orphans ) : <EOL> """<STR_LIT>""" <EOL> for orphan in orphans : <EOL> memory_mb = orphan [ '<STR_LIT>' ] <EOL> LOG . warning ( _LW ( "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> { '<STR_LIT>' : orphan [ '<STR_LIT>' ] , '<STR_LIT>' : memory_mb } ) <EOL> usage = { '<STR_LIT>' : memory_mb } <EOL> self . _update_usage ( usage ) <EOL> def _verify_resources ( self , resources ) : <EOL> resource_keys = [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" ] <EOL> missing_keys = [ k for k in resource_keys if k not in resources ] <EOL> if missing_keys : <EOL> reason = _ ( "<STR_LIT>" ) % missing_keys <EOL> raise exception . InvalidInput ( reason = reason ) <EOL> def _get_instance_type ( self , context , instance , prefix , migration ) : <EOL> """<STR_LIT>""" <EOL> stashed_flavors = migration . migration_type in ( '<STR_LIT>' , ) <EOL> if stashed_flavors : <EOL> return getattr ( instance , '<STR_LIT>' % prefix ) <EOL> else : <EOL> return instance . flavor <EOL> def _get_usage_dict ( self , object_or_dict , ** updates ) : <EOL> """<STR_LIT>""" <EOL> usage = { } <EOL> if isinstance ( object_or_dict , objects . Instance ) : <EOL> usage = obj_base . obj_to_primitive ( object_or_dict ) <EOL> elif isinstance ( object_or_dict , objects . Flavor ) : <EOL> usage = obj_base . obj_to_primitive ( object_or_dict ) <EOL> else : <EOL> usage . update ( object_or_dict ) <EOL> for key in ( '<STR_LIT>' , ) : <EOL> if key in updates : <EOL> usage [ key ] = updates [ key ] <EOL> return usage </s>
