def __run_optimized_migrations(self, bucket_index): # Create allocations lists for GOAP # Assignment curr_assignment = self.placement.assignment_list[bucket_index] # Previous assignment prev_assignment = self.placement.assignment_list[(bucket_index - 1) % NUM_BUCKETS] as_current = [0 for _ in xrange(conf_domains.count())] as_next = [0 for _ in xrange(conf_domains.count())] for index_domain in xrange(conf_domains.count()): as_current[index_domain] = prev_assignment[index_domain] as_next[index_domain] = curr_assignment[index_domain] # Get current domain loads domain_load = [] for mapping in conf_domains.initial_domains: domain_name = mapping.domain load = self.model.get_host(domain_name).mean_load(20) domain_load.append(conf_nodes.to_node_load(load, conf_domainsize.DEFAULT)) # Schedule migrations from ai import astar migrations = astar.plan(conf_nodes.NODE_COUNT, as_current, as_next, domain_load) # Trigger migrations dep = None for migration in migrations: domain_name = conf_domains.initial_domains[migration[0]].domain source_node = conf_nodes.get_node_name(migration[1]) target_node = conf_nodes.get_node_name(migration[2]) print 'domain %s - source %s - target %s' % (domain_name, source_node, target_node) model_domain = self.model.get_host(domain_name) model_source = self.model.get_host(source_node) model_target = self.model.get_host(target_node) # dep = self.migration_queue.add(model_domain, model_source, model_target, dep) dep = self.migration_queue.add(model_domain, model_source, model_target) return
def _count_active_servers(self, assignment): buckets = [True for _ in xrange(len(conf_nodes.NODES))] active_servers = 0 active_server_list = [] for service in assignment.keys(): inode = assignment[service] if buckets[inode]: buckets[inode] = False active_servers += 1 active_server_list.append(conf_nodes.get_node_name(inode)) return active_servers, active_server_list
def __run_migrations(self, bucket_index): # Assignment curr_assignment = self.placement.assignment_list[bucket_index] # Previous assignment (based on model data - not uncertain calculation data) # Calculated data might be different from model data due to failed migrations # prev_assignment = self.placement.assignment_list[(bucket_index - 1) % NUM_BUCKETS] prev_assignment = self.model.get_assignment_list() for index_domain in curr_assignment.keys(): # Get data domain_name = conf_domains.initial_domains[index_domain].name source_node = conf_nodes.get_node_name(prev_assignment[index_domain]) target_node = conf_nodes.get_node_name(curr_assignment[index_domain]) # Find current node for domain source_node = self.model.get_host_for_domain(domain_name).name # Trigger migration model_domain = self.model.get_host(domain_name) model_source = self.model.get_host(source_node) model_target = self.model.get_host(target_node) self.migration_queue.add(model_domain, model_source, model_target)
def migrateAllocation(migrations): """ Gets a list of migrations. Each list element is a tupel of the structure: (domain name, target node index in the nodes model) """ # trigger migrations for migration in migrations: # Get domain and target node domain_name = migration[0] target_node = conf_nodes.get_node_name(migration[1]) # Search the node which currently holds the domain lv_domain, lv_connection_source = util.find_domain(domain_name) if lv_domain == None: print "WARN: Skipping migration - could not find domain: %s" % (domain_name) continue # Check if domain is running (parater is an unused flag) domain_state = lv_domain.state(0)[0] if domain_state != 1: # Destroy print "(Re)starting the domain %s" % (domain_name) # If domain is not shut off if domain_state != 5: try: lv_domain.destroy() except: pass # Start domain and wait for it try: lv_domain.create() time.sleep(10) except: pass # Is migration necessary source_host = util.get_hostname(lv_connection_source) target_host = target_node # Skip if migration is not necessesary if source_host == target_host: print "Skipping migration - identical source and target node %s = %s" % (source_host, target_host) continue # Check if mig try: # Get target node connection lv_connection_target = util.connections[target_node] # Trigger migration without bandwith limitation (last parameter) print "Migrating domain: %s -> %s" % (domain_name, target_host) lv_domain = lv_domain.migrate( lv_connection_target, VIR_MIGRATE_LIVE | VIR_MIGRATE_UNDEFINE_SOURCE | VIR_MIGRATE_PERSIST_DEST, domain_name, None, 0, ) except: print "Skipping - migration failed" traceback.print_exc(file=sys.stdout)
def __run_migrations(self): conversion_table = {} prev_assignment = {} i = 0 for node in self.model.get_hosts(types.NODE): for domain_name in node.domains.keys(): conversion_table[i] = domain_name prev_assignment[i] = conf_nodes.index_of(node.name) i +=1 inverse_conversion_table = {domain_name : i for i, domain_name in conversion_table.iteritems()} demand_cpu = {} demand_mem = {} for domain in self.model.get_hosts(types.DOMAIN): if domain in conf_domains.initial_domains: domain_size = conf_domains.initial_domains[conf_domains.initial_domain_index(domain.name)].size else: domain_size = conf_domains.available_domains[conf_domains.available_domain_index(domain.name)].size domain_index = inverse_conversion_table[domain.name] cpu_readings = domain.get_readings() domain_load = conf_nodes.to_node_load(np.mean(cpu_readings[-NUM_CPU_READINGS:]), domain_size) demand_cpu[domain_index] = domain_load demand_mem[domain_index] = domain.domain_configuration.get_domain_spec().total_memory() print 'domain : %d, demand_cpu : %d, demand_memory : %d' % (domain_index, domain_load, domain.domain_configuration.get_domain_spec().total_memory()) # Assignment try: _, curr_assignment = dsapp.solve(conf_nodes.NODE_COUNT, conf_nodes.UTIL, conf_nodes.NODE_MEM, demand_cpu, demand_mem, prev_assignment, MIG_OVERHEAD_SOURCE, MIG_OVERHEAD_TARGET) except: print 'invalid solution #######################' # don't change anything and just return in case the model was infeasible return assignment_changed = dsapp.AssignmentChanged(prev_assignment, curr_assignment) print 'CHANGE in the Assignment : %s' % assignment_changed if not assignment_changed: # there is no change in the assignment, we can just return logger.info("Returning because the previous assignment was optimal...") return for index_domain in curr_assignment.keys(): domain_name = conversion_table[index_domain] source_node = conf_nodes.get_node_name(prev_assignment[index_domain]) target_node = conf_nodes.get_node_name(curr_assignment[index_domain]) # Find current node for domain source_node = self.model.get_host_for_domain(domain_name).name # Trigger migration model_domain = self.model.get_host(domain_name) model_source = self.model.get_host(source_node) model_target = self.model.get_host(target_node) self.migration_queue.add(model_domain, model_source, model_target)