def test_call_function_by_name(self): with MockTransaction: arg1 = 'a' arg2 = 'b' expect(common).func_to_call(arg1, arg2).and_return('res').once() assert common.call_function_by_name('neat.common.func_to_call', [arg1, arg2]) == 'res'
def execute_overload(config, state, host, vm_uuids): """ Process an overloaded host: migrate the selected VMs from it. 1. Prepare the data about the current states of the hosts and VMs. 2. Call the function specified in the `algorithm_vm_placement_factory` configuration option and pass the data on the states of the hosts and VMs. 3. Call the Nova API to migrate the VMs according to the placement determined by the `algorithm_vm_placement_factory` algorithm. 4. Switch on the inactive hosts required to accommodate the VMs. :param config: A config dictionary. :type config: dict(str: *) :param state: A state dictionary. :type state: dict(str: *) :param host: A host name. :type host: str :param vm_uuids: A list of VM UUIDs to migrate from the host. :type vm_uuids: list(str) :return: The updated state dictionary. :rtype: dict(str: *) """ log.info('Started processing an overload request') overloaded_host = host hosts_cpu_total, _, hosts_ram_total = state['db'].select_host_characteristics() hosts_to_vms = vms_by_hosts(state['nova'], state['compute_hosts']) vms_last_cpu = state['db'].select_last_cpu_mhz_for_vms() hosts_last_cpu = state['db'].select_last_cpu_mhz_for_hosts() # Remove VMs from hosts_to_vms that are not in vms_last_cpu # These VMs are new and no data have been collected from them for host, vms in hosts_to_vms.items(): for i, vm in enumerate(vms): if not vm in vms_last_cpu: del hosts_to_vms[host][i] hosts_cpu_usage = {} hosts_ram_usage = {} inactive_hosts_cpu = {} inactive_hosts_ram = {} for host, vms in hosts_to_vms.items(): if vms: host_cpu_mhz = hosts_last_cpu[host] for vm in vms: if vm not in vms_last_cpu: log.info('No data yet for VM: %s - skipping host %s', vm, host) del hosts_cpu_total[host] del hosts_ram_total[host] if host in hosts_cpu_usage: del hosts_cpu_usage[host] if host in hosts_ram_usage: del hosts_ram_usage[host] break host_cpu_mhz += vms_last_cpu[vm] else: hosts_cpu_usage[host] = host_cpu_mhz hosts_ram_usage[host] = host_used_ram(state['nova'], host) else: inactive_hosts_cpu[host] = hosts_cpu_total[host] inactive_hosts_ram[host] = hosts_ram_total[host] del hosts_cpu_total[host] del hosts_ram_total[host] # Exclude the overloaded host del hosts_cpu_usage[overloaded_host] del hosts_cpu_total[overloaded_host] del hosts_ram_usage[overloaded_host] del hosts_ram_total[overloaded_host] if log.isEnabledFor(logging.DEBUG): log.debug('Host CPU usage: %s', str(hosts_last_cpu)) log.debug('Host total CPU usage: %s', str(hosts_cpu_usage)) vms_to_migrate = vm_uuids vms_cpu = {} for vm in vms_to_migrate: if vm not in vms_last_cpu: log.info('No data yet for VM: %s - dropping the request', vm) log.info('Skipped an underload request') return state vms_cpu[vm] = state['db'].select_cpu_mhz_for_vm( vm, int(config['data_collector_data_length'])) vms_ram = vms_ram_limit(state['nova'], vms_to_migrate) # Remove VMs that are not in vms_ram # These instances might have been deleted for i, vm in enumerate(vms_to_migrate): if not vm in vms_ram: del vms_to_migrate[i] for vm in vms_cpu.keys(): if not vm in vms_ram: del vms_cpu[vm] time_step = int(config['data_collector_interval']) migration_time = common.calculate_migration_time( vms_ram, float(config['network_migration_bandwidth'])) if 'vm_placement' not in state: vm_placement_params = common.parse_parameters( config['algorithm_vm_placement_parameters']) vm_placement_state = None vm_placement = common.call_function_by_name( config['algorithm_vm_placement_factory'], [time_step, migration_time, vm_placement_params]) state['vm_placement'] = vm_placement state['vm_placement_state'] = {} else: vm_placement = state['vm_placement'] vm_placement_state = state['vm_placement_state'] log.info('Started overload VM placement') placement, vm_placement_state = vm_placement( hosts_cpu_usage, hosts_cpu_total, hosts_ram_usage, hosts_ram_total, inactive_hosts_cpu, inactive_hosts_ram, vms_cpu, vms_ram, vm_placement_state) log.info('Completed overload VM placement') state['vm_placement_state'] = vm_placement_state if log.isEnabledFor(logging.INFO): log.info('Overload: obtained a new placement %s', str(placement)) if not placement: log.info('Nothing to migrate') else: hosts_to_activate = list( set(inactive_hosts_cpu.keys()).intersection( set(placement.values()))) if hosts_to_activate: switch_hosts_on(state['db'], config['ether_wake_interface'], state['host_macs'], hosts_to_activate) log.info('Started overload VM migrations') migrate_vms(state['db'], state['nova'], config['vm_instance_directory'], placement) log.info('Completed overload VM migrations') log.info('Completed processing an overload request') return state
def execute_overload(config, state, host, vm_uuids): """ Process an overloaded host: migrate the selected VMs from it. 1. Prepare the data about the current states of the hosts and VMs. 2. Call the function specified in the `algorithm_vm_placement_factory` configuration option and pass the data on the states of the hosts and VMs. 3. Call the Nova API to migrate the VMs according to the placement determined by the `algorithm_vm_placement_factory` algorithm. 4. Switch on the inactive hosts required to accommodate the VMs. :param config: A config dictionary. :type config: dict(str: *) :param state: A state dictionary. :type state: dict(str: *) :param host: A host name. :type host: str :param vm_uuids: A list of VM UUIDs to migrate from the host. :type vm_uuids: list(str) :return: The updated state dictionary. :rtype: dict(str: *) """ log.info('Started processing an overload request') overloaded_host = host hosts_cpu_total, _, hosts_ram_total = state['db'].select_host_characteristics() hosts_to_vms = vms_by_hosts(state['nova'], state['compute_hosts']) vms_last_cpu = state['db'].select_last_cpu_mhz_for_vms() hosts_last_cpu = state['db'].select_last_cpu_mhz_for_hosts() # Remove VMs from hosts_to_vms that are not in vms_last_cpu # These VMs are new and no data have been collected from them for host, vms in hosts_to_vms.items(): for i, vm in enumerate(vms): if not vm in vms_last_cpu: del hosts_to_vms[host][i] hosts_cpu_usage = {} hosts_ram_usage = {} inactive_hosts_cpu = {} inactive_hosts_ram = {} for host, vms in hosts_to_vms.items(): if vms: host_cpu_mhz = hosts_last_cpu[host] for vm in vms: if vm not in vms_last_cpu: log.info('No data yet for VM: %s - skipping host %s', vm, host) hosts_cpu_total.pop(host, None) hosts_ram_total.pop(host, None) hosts_cpu_usage.pop(host, None) hosts_ram_usage.pop(host, None) break host_cpu_mhz += vms_last_cpu[vm] else: hosts_cpu_usage[host] = host_cpu_mhz hosts_ram_usage[host] = host_used_ram(state['nova'], host) else: inactive_hosts_cpu[host] = hosts_cpu_total[host] inactive_hosts_ram[host] = hosts_ram_total[host] hosts_cpu_total.pop(host, None) hosts_ram_total.pop(host, None) # Exclude the overloaded host hosts_cpu_usage.pop(overloaded_host, None) hosts_cpu_total.pop(overloaded_host, None) hosts_ram_usage.pop(overloaded_host, None) hosts_ram_total.pop(overloaded_host, None) if log.isEnabledFor(logging.DEBUG): log.debug('Host CPU usage: %s', str(hosts_last_cpu)) log.debug('Host total CPU usage: %s', str(hosts_cpu_usage)) vms_to_migrate = vm_uuids vms_cpu = {} for vm in vms_to_migrate: if vm not in vms_last_cpu: log.info('No data yet for VM: %s - dropping the request', vm) log.info('Skipped an underload request') return state vms_cpu[vm] = state['db'].select_cpu_mhz_for_vm( vm, int(config['data_collector_data_length'])) vms_ram = vms_ram_limit(state['nova'], vms_to_migrate) # Remove VMs that are not in vms_ram # These instances might have been deleted for i, vm in enumerate(vms_to_migrate): if not vm in vms_ram: del vms_to_migrate[i] if not vms_to_migrate: log.info('No VMs to migrate - completed the overload request') return state for vm in vms_cpu.keys(): if not vm in vms_ram: del vms_cpu[vm] time_step = int(config['data_collector_interval']) migration_time = common.calculate_migration_time( vms_ram, float(config['network_migration_bandwidth'])) if 'vm_placement' not in state: vm_placement_params = common.parse_parameters( config['algorithm_vm_placement_parameters']) vm_placement_state = None vm_placement = common.call_function_by_name( config['algorithm_vm_placement_factory'], [time_step, migration_time, vm_placement_params]) state['vm_placement'] = vm_placement state['vm_placement_state'] = {} else: vm_placement = state['vm_placement'] vm_placement_state = state['vm_placement_state'] log.info('Started overload VM placement') placement, vm_placement_state = vm_placement( hosts_cpu_usage, hosts_cpu_total, hosts_ram_usage, hosts_ram_total, inactive_hosts_cpu, inactive_hosts_ram, vms_cpu, vms_ram, vm_placement_state) log.info('Completed overload VM placement') state['vm_placement_state'] = vm_placement_state if log.isEnabledFor(logging.INFO): log.info('Overload: obtained a new placement %s', str(placement)) if not placement: log.info('Nothing to migrate') else: hosts_to_activate = list( set(inactive_hosts_cpu.keys()).intersection( set(placement.values()))) if hosts_to_activate: switch_hosts_on(state['db'], config['ether_wake_interface'], state['host_macs'], hosts_to_activate) log.info('Started overload VM migrations') migrate_vms(state['db'], state['nova'], config['vm_instance_directory'], placement, bool(config['block_migration'])) log.info('Completed overload VM migrations') log.info('Completed processing an overload request') return state
def execute_underload(config, state, host): """ Process an underloaded host: migrate all VMs from the host. 1. Prepare the data about the current states of the hosts and VMs. 2. Call the function specified in the `algorithm_vm_placement_factory` configuration option and pass the data on the states of the hosts and VMs. 3. Call the Nova API to migrate the VMs according to the placement determined by the `algorithm_vm_placement_factory` algorithm. 4. Switch off the host at the end of the VM migration. :param config: A config dictionary. :type config: dict(str: *) :param state: A state dictionary. :type state: dict(str: *) :param host: A host name. :type host: str :return: The updated state dictionary. :rtype: dict(str: *) """ log.info('Started processing an underload request') underloaded_host = host hosts_cpu_total, _, hosts_ram_total = state['db'].select_host_characteristics() hosts_to_vms = vms_by_hosts(state['nova'], state['compute_hosts']) vms_last_cpu = state['db'].select_last_cpu_mhz_for_vms() hosts_last_cpu = state['db'].select_last_cpu_mhz_for_hosts() # Remove VMs from hosts_to_vms that are not in vms_last_cpu # These VMs are new and no data have been collected from them for host, vms in hosts_to_vms.items(): for i, vm in enumerate(vms): if not vm in vms_last_cpu: del hosts_to_vms[host][i] if log.isEnabledFor(logging.DEBUG): log.debug('hosts_to_vms: %s', str(hosts_to_vms)) hosts_cpu_usage = {} hosts_ram_usage = {} hosts_to_keep_active = set() for host, vms in hosts_to_vms.items(): if vms: host_cpu_mhz = hosts_last_cpu[host] for vm in vms: if vm not in vms_last_cpu: log.info('No data yet for VM: %s - skipping host %s', vm, host) hosts_to_keep_active.add(host) hosts_cpu_total.pop(host, None) hosts_ram_total.pop(host, None) hosts_cpu_usage.pop(host, None) hosts_ram_usage.pop(host, None) break host_cpu_mhz += vms_last_cpu[vm] else: hosts_cpu_usage[host] = host_cpu_mhz hosts_ram_usage[host] = host_used_ram(state['nova'], host) else: # Exclude inactive hosts hosts_cpu_total.pop(host, None) hosts_ram_total.pop(host, None) if log.isEnabledFor(logging.DEBUG): log.debug('Host CPU usage: %s', str(hosts_last_cpu)) log.debug('Host total CPU usage: %s', str(hosts_cpu_usage)) # Exclude the underloaded host hosts_cpu_usage.pop(underloaded_host, None) hosts_cpu_total.pop(underloaded_host, None) hosts_ram_usage.pop(underloaded_host, None) hosts_ram_total.pop(underloaded_host, None) if log.isEnabledFor(logging.DEBUG): log.debug('Excluded the underloaded host %s', underloaded_host) log.debug('Host CPU usage: %s', str(hosts_last_cpu)) log.debug('Host total CPU usage: %s', str(hosts_cpu_usage)) vms_to_migrate = vms_by_host(state['nova'], underloaded_host) vms_cpu = {} for vm in vms_to_migrate: if vm not in vms_last_cpu: log.info('No data yet for VM: %s - dropping the request', vm) log.info('Skipped an underload request') return state vms_cpu[vm] = state['db'].select_cpu_mhz_for_vm( vm, int(config['data_collector_data_length'])) vms_ram = vms_ram_limit(state['nova'], vms_to_migrate) # Remove VMs that are not in vms_ram # These instances might have been deleted for i, vm in enumerate(vms_to_migrate): if not vm in vms_ram: del vms_to_migrate[i] if not vms_to_migrate: log.info('No VMs to migrate - completed the underload request') return state for vm in vms_cpu.keys(): if not vm in vms_ram: del vms_cpu[vm] time_step = int(config['data_collector_interval']) migration_time = common.calculate_migration_time( vms_ram, float(config['network_migration_bandwidth'])) if 'vm_placement' not in state: vm_placement_params = common.parse_parameters( config['algorithm_vm_placement_parameters']) vm_placement_state = None vm_placement = common.call_function_by_name( config['algorithm_vm_placement_factory'], [time_step, migration_time, vm_placement_params]) state['vm_placement'] = vm_placement state['vm_placement_state'] = {} else: vm_placement = state['vm_placement'] vm_placement_state = state['vm_placement_state'] log.info('Started underload VM placement') placement, vm_placement_state = vm_placement( hosts_cpu_usage, hosts_cpu_total, hosts_ram_usage, hosts_ram_total, {}, {}, vms_cpu, vms_ram, vm_placement_state) log.info('Completed underload VM placement') state['vm_placement_state'] = vm_placement_state if log.isEnabledFor(logging.INFO): log.info('Underload: obtained a new placement %s', str(placement)) active_hosts = hosts_cpu_total.keys() inactive_hosts = set(state['compute_hosts']) - set(active_hosts) prev_inactive_hosts = set(state['db'].select_inactive_hosts()) hosts_to_deactivate = list(inactive_hosts - prev_inactive_hosts - hosts_to_keep_active) if not placement: log.info('Nothing to migrate') if underloaded_host in hosts_to_deactivate: hosts_to_deactivate.remove(underloaded_host) else: log.info('Started underload VM migrations') migrate_vms(state['db'], state['nova'], config['vm_instance_directory'], placement, bool(config['block_migration'])) log.info('Completed underload VM migrations') if hosts_to_deactivate: switch_hosts_off(state['db'], config['sleep_command'], hosts_to_deactivate) log.info('Completed processing an underload request') return state
def execute(config, state): """ Execute an iteration of the local manager. 1. Read the data on resource usage by the VMs running on the host from the <local_data_directory>/vm directory. 2. Call the function specified in the algorithm_underload_detection configuration option and pass the data on the resource usage by the VMs, as well as the frequency of the CPU as arguments. 3. If the host is underloaded, send a request to the REST API of the global manager and pass a list of the UUIDs of all the VMs currently running on the host in the vm_uuids parameter, as well as the reason for migration as being 0. 4. If the host is not underloaded, call the function specified in the algorithm_overload_detection configuration option and pass the data on the resource usage by the VMs, as well as the frequency of the host's CPU as arguments. 5. If the host is overloaded, call the function specified in the algorithm_vm_selection configuration option and pass the data on the resource usage by the VMs, as well as the frequency of the host's CPU as arguments 6. If the host is overloaded, send a request to the REST API of the global manager and pass a list of the UUIDs of the VMs selected by the VM selection algorithm in the vm_uuids parameter, as well as the reason for migration as being 1. :param config: A config dictionary. :type config: dict(str: *) :param state: A state dictionary. :type state: dict(str: *) :return: The updated state dictionary. :rtype: dict(str: *) """ log.info('Started an iteration') vm_path = common.build_local_vm_path(config['local_data_directory']) vm_cpu_mhz = get_local_vm_data(vm_path) vm_ram = get_ram(state['vir_connection'], vm_cpu_mhz.keys()) vm_cpu_mhz = cleanup_vm_data(vm_cpu_mhz, vm_ram.keys()) if not vm_cpu_mhz: if log.isEnabledFor(logging.INFO): log.info('The host is idle') log.info('Skipped an iteration') return state host_path = common.build_local_host_path(config['local_data_directory']) host_cpu_mhz = get_local_host_data(host_path) host_cpu_utilization = vm_mhz_to_percentage( vm_cpu_mhz.values(), host_cpu_mhz, state['physical_cpu_mhz_total']) if log.isEnabledFor(logging.DEBUG): log.debug('The total physical CPU Mhz: %s', str(state['physical_cpu_mhz_total'])) log.debug('VM CPU MHz: %s', str(vm_cpu_mhz)) log.debug('Host CPU MHz: %s', str(host_cpu_mhz)) log.debug('CPU utilization: %s', str(host_cpu_utilization)) if not host_cpu_utilization: log.info('Not enough data yet - skipping to the next iteration') log.info('Skipped an iteration') return state time_step = int(config['data_collector_interval']) migration_time = common.calculate_migration_time( vm_ram, float(config['network_migration_bandwidth'])) if 'underload_detection' not in state: underload_detection_params = common.parse_parameters( config['algorithm_underload_detection_parameters']) underload_detection = common.call_function_by_name( config['algorithm_underload_detection_factory'], [time_step, migration_time, underload_detection_params]) state['underload_detection'] = underload_detection state['underload_detection_state'] = {} overload_detection_params = common.parse_parameters( config['algorithm_overload_detection_parameters']) overload_detection = common.call_function_by_name( config['algorithm_overload_detection_factory'], [time_step, migration_time, overload_detection_params]) state['overload_detection'] = overload_detection state['overload_detection_state'] = {} vm_selection_params = common.parse_parameters( config['algorithm_vm_selection_parameters']) vm_selection = common.call_function_by_name( config['algorithm_vm_selection_factory'], [time_step, migration_time, vm_selection_params]) state['vm_selection'] = vm_selection state['vm_selection_state'] = {} else: underload_detection = state['underload_detection'] overload_detection = state['overload_detection'] vm_selection = state['vm_selection'] if log.isEnabledFor(logging.INFO): log.info('Started underload detection') underload, state['underload_detection_state'] = underload_detection( host_cpu_utilization, state['underload_detection_state']) if log.isEnabledFor(logging.INFO): log.info('Completed underload detection') if log.isEnabledFor(logging.INFO): log.info('Started overload detection') overload, state['overload_detection_state'] = overload_detection( host_cpu_utilization, state['overload_detection_state']) if log.isEnabledFor(logging.INFO): log.info('Completed overload detection') if underload: if log.isEnabledFor(logging.INFO): log.info('Underload detected') try: r = requests.put('http://' + config['global_manager_host'] + ':' + config['global_manager_port'], {'username': state['hashed_username'], 'password': state['hashed_password'], 'time': time.time(), 'host': state['hostname'], 'reason': 0}) if log.isEnabledFor(logging.INFO): log.info('Received response: [%s] %s', r.status_code, r.content) except requests.exceptions.ConnectionError: log.exception('Exception at underload request:') else: if overload: if log.isEnabledFor(logging.INFO): log.info('Overload detected') log.info('Started VM selection') vm_uuids, state['vm_selection_state'] = vm_selection( vm_cpu_mhz, vm_ram, state['vm_selection_state']) log.info('Completed VM selection') if log.isEnabledFor(logging.INFO): log.info('Selected VMs to migrate: %s', str(vm_uuids)) try: r = requests.put('http://' + config['global_manager_host'] + ':' + config['global_manager_port'], {'username': state['hashed_username'], 'password': state['hashed_password'], 'time': time.time(), 'host': state['hostname'], 'reason': 1, 'vm_uuids': ','.join(vm_uuids)}) if log.isEnabledFor(logging.INFO): log.info('Received response: [%s] %s', r.status_code, r.content) except requests.exceptions.ConnectionError: log.exception('Exception at overload request:') else: if log.isEnabledFor(logging.INFO): log.info('No underload or overload detected') if log.isEnabledFor(logging.INFO): log.info('Completed an iteration') return state
def execute_underload(config, state, host): """ Process an underloaded host: migrate all VMs from the host. 1. Prepare the data about the current states of the hosts and VMs. 2. Call the function specified in the `algorithm_vm_placement_factory` configuration option and pass the data on the states of the hosts and VMs. 3. Call the Nova API to migrate the VMs according to the placement determined by the `algorithm_vm_placement_factory` algorithm. 4. Switch off the host at the end of the VM migration. :param config: A config dictionary. :type config: dict(str: *) :param state: A state dictionary. :type state: dict(str: *) :param host: A host name. :type host: str :return: The updated state dictionary. :rtype: dict(str: *) """ log.info('Started processing an underload request') underloaded_host = host hosts_cpu_total, _, hosts_ram_total = state[ 'db'].select_host_characteristics() hosts_to_vms = vms_by_hosts(state['nova'], state['compute_hosts']) vms_last_cpu = state['db'].select_last_cpu_mhz_for_vms() hosts_last_cpu = state['db'].select_last_cpu_mhz_for_hosts() # Remove VMs from hosts_to_vms that are not in vms_last_cpu # These VMs are new and no data have been collected from them for host, vms in hosts_to_vms.items(): for i, vm in enumerate(vms): if not vm in vms_last_cpu: del hosts_to_vms[host][i] if log.isEnabledFor(logging.DEBUG): log.debug('hosts_to_vms: %s', str(hosts_to_vms)) hosts_cpu_usage = {} hosts_ram_usage = {} hosts_to_keep_active = set() for host, vms in hosts_to_vms.items(): if vms: host_cpu_mhz = hosts_last_cpu[host] for vm in vms: if vm not in vms_last_cpu: log.info('No data yet for VM: %s - skipping host %s', vm, host) hosts_to_keep_active.add(host) del hosts_cpu_total[host] del hosts_ram_total[host] if host in hosts_cpu_usage: del hosts_cpu_usage[host] if host in hosts_ram_usage: del hosts_ram_usage[host] break host_cpu_mhz += vms_last_cpu[vm] else: hosts_cpu_usage[host] = host_cpu_mhz hosts_ram_usage[host] = host_used_ram(state['nova'], host) else: # Exclude inactive hosts del hosts_cpu_total[host] del hosts_ram_total[host] if log.isEnabledFor(logging.DEBUG): log.debug('Host CPU usage: %s', str(hosts_last_cpu)) log.debug('Host total CPU usage: %s', str(hosts_cpu_usage)) # Exclude the underloaded host del hosts_cpu_usage[underloaded_host] del hosts_cpu_total[underloaded_host] del hosts_ram_usage[underloaded_host] del hosts_ram_total[underloaded_host] if log.isEnabledFor(logging.DEBUG): log.debug('Excluded the underloaded host %s', underloaded_host) log.debug('Host CPU usage: %s', str(hosts_last_cpu)) log.debug('Host total CPU usage: %s', str(hosts_cpu_usage)) vms_to_migrate = vms_by_host(state['nova'], underloaded_host) vms_cpu = {} for vm in vms_to_migrate: if vm not in vms_last_cpu: log.info('No data yet for VM: %s - dropping the request', vm) log.info('Skipped an underload request') return state vms_cpu[vm] = state['db'].select_cpu_mhz_for_vm( vm, int(config['data_collector_data_length'])) vms_ram = vms_ram_limit(state['nova'], vms_to_migrate) # Remove VMs that are not in vms_ram # These instances might have been deleted for i, vm in enumerate(vms_to_migrate): if not vm in vms_ram: del vms_to_migrate[i] for vm in vms_cpu.keys(): if not vm in vms_ram: del vms_cpu[vm] time_step = int(config['data_collector_interval']) migration_time = common.calculate_migration_time( vms_ram, float(config['network_migration_bandwidth'])) if 'vm_placement' not in state: vm_placement_params = common.parse_parameters( config['algorithm_vm_placement_parameters']) vm_placement_state = None vm_placement = common.call_function_by_name( config['algorithm_vm_placement_factory'], [time_step, migration_time, vm_placement_params]) state['vm_placement'] = vm_placement state['vm_placement_state'] = {} else: vm_placement = state['vm_placement'] vm_placement_state = state['vm_placement_state'] log.info('Started underload VM placement') placement, vm_placement_state = vm_placement( hosts_cpu_usage, hosts_cpu_total, hosts_ram_usage, hosts_ram_total, {}, {}, vms_cpu, vms_ram, vm_placement_state) log.info('Completed underload VM placement') state['vm_placement_state'] = vm_placement_state if log.isEnabledFor(logging.INFO): log.info('Underload: obtained a new placement %s', str(placement)) active_hosts = hosts_cpu_total.keys() inactive_hosts = set(state['compute_hosts']) - set(active_hosts) prev_inactive_hosts = set(state['db'].select_inactive_hosts()) hosts_to_deactivate = list(inactive_hosts - prev_inactive_hosts - hosts_to_keep_active) if not placement: log.info('Nothing to migrate') if underloaded_host in hosts_to_deactivate: hosts_to_deactivate.remove(underloaded_host) else: log.info('Started underload VM migrations') migrate_vms(state['db'], state['nova'], config['vm_instance_directory'], placement) log.info('Completed underload VM migrations') if hosts_to_deactivate: switch_hosts_off(state['db'], config['sleep_command'], hosts_to_deactivate) log.info('Completed processing an underload request') return state