def create_servers(): """ Creates Server objects according to user-specified parameters. """ for _ in range(SERVERS): # Creating object server = Server(id=None, cpu=None, memory=None, disk=None, updated=None) # Defining values for the object attributes server.id = Server.count() server.cpu_capacity = SERVERS_CAPACITY[0][0] server.memory_capacity = SERVERS_CAPACITY[0][1] server.disk_capacity = SERVERS_CAPACITY[0][2] server.updated = SERVERS_UPDATE_STATUS[0] server.patch_duration = SERVERS_PATCH_DURATION[0][0] server.sanity_check_duration = SERVERS_PATCH_DURATION[0][1] # Updating attribute lists after the object is created SERVERS_CAPACITY.pop(0) SERVERS_UPDATE_STATUS.pop(0) SERVERS_PATCH_DURATION.pop(0)
def collect_metrics(env, strategy, servers_patched, servers_being_emptied, migrations_data): """ Gather metrics from the current maintenance step. Supported metrics: - Simulation steps - Number of servers being updated - Number of servers being emptied - Number of updated servers - Number of nonupdated servers - Vulnerability Surface (Severo et al. 2020) - Number of VM migrations - Overall migrations duration (amount of time spent with migrations in the current step) - Longer migration - Shorter migration - Average migration duration - Servers occupation rate - Servers consolidation rate Parameters ========== env : SimPy.Environment Used to quantity the amount of simulation time spent by the migration strategy : String Name of the used maintenance strategy servers_patched : List List of servers updated in the current maintenance step servers_being_emptied : List List of servers being emptied in the current maintenance step migrations_data : List Information on each migration performed in the current maintenance step Returns ======= output : Dictionary List of metrics collected during the current maintenance step """ output = {} # Number of simulation steps output['simulation_steps'] = env.now # Name of the used maintenance strategy output['strategy'] = strategy # Other simulation metrics output['metrics'] = {} # Number of updated and nonupdated servers output['metrics']['updated_servers'] = len(Server.updated()) output['metrics']['nonupdated_servers'] = len(Server.nonupdated()) # Vulnerability Surface (Severo et al. 2020) = Number of non-updated servers * Elapsed time output['metrics']['vulnerability_surface'] = env.now * output['metrics'][ 'nonupdated_servers'] # Gathering VM migration metrics output['metrics']['vm_migrations'] = 0 output['metrics']['migrations_duration'] = 0 output['metrics']['longer_migration'] = 0 output['metrics']['shorter_migration'] = 0 output['metrics']['avg_migration_duration'] = 0 if len(migrations_data) > 0: # Number of VM migrations performed in this interval output['metrics']['vm_migrations'] = len(migrations_data) # Time spent performing VM migrations migrations_duration = sum(migr['duration'] for migr in migrations_data) output['metrics']['migrations_duration'] = migrations_duration # Longer migration output['metrics']['longer_migration'] = max( migr['duration'] for migr in migrations_data) # Shorter migration output['metrics']['shorter_migration'] = min( migr['duration'] for migr in migrations_data) # Average migration duration output['metrics'][ 'avg_migration_duration'] = migrations_duration / len( migrations_data) # Gathering server-related metrics # Occupation rate aggregated_occupation_rate = sum(sv.occupation_rate() for sv in Server.all()) output['metrics']['occupation_rate'] = aggregated_occupation_rate / len( Server.used_servers()) # Consolidation rate output['metrics']['consolidation_rate'] = Server.consolidation_rate() # Servers being updated output['metrics']['servers_being_updated'] = len(servers_patched) # Servers being emptied output['metrics']['servers_being_emptied'] = len(servers_being_emptied) return (output)
def load_dataset(cls, input_file): """ Creates simulation objects according to data from a JSON input file Parameters ========== file : string Path location of the JSON input file initial_edge_node_connection : boolean, optional Informs if the input file provides information on which clients are initially connected to edge nodes initial_placement : boolean, optional Informs if the input file provides information on the services initial placement """ with open(f'data/{input_file}.json', 'r') as read_file: data = json.load(read_file) read_file.close() # Informing the simulation environment what's the dataset that will be used during the simulation Simulator.environment.dataset = input_file ########################## # SIMULATION COMPONENTS ## ########################## # Servers for server_data in data['servers']: # Creating object server = Server(id=None, cpu=None, memory=None, disk=None, updated=None) # Defining object attributes server.id = server_data['id'] server.cpu_capacity = server_data['cpu_capacity'] server.memory_capacity = server_data['memory_capacity'] server.disk_capacity = server_data['disk_capacity'] server.updated = server_data['updated'] server.patch_duration = server_data['patch_duration'] server.sanity_check_duration = server_data['sanity_check_duration'] # Virtual Machines for vm_data in data['virtual_machines']: # Creating object vm = VirtualMachine(id=None, cpu=None, memory=None, disk=None) # Defining object attributes vm.id = vm_data['id'] vm.cpu_demand = vm_data['cpu_demand'] vm.memory_demand = vm_data['memory_demand'] vm.disk_demand = vm_data['disk_demand'] # Initial Placement server = Server.find_by_id(vm_data['server']) server.cpu_demand += vm.cpu_demand server.memory_demand += vm.memory_demand server.disk_demand += vm.disk_demand vm.server = server server.virtual_machines.append(vm) ###################### ## Network Topology ## ###################### topology = FatTree() # Creating links and nodes for link in data['network_topology']: # Creating nodes if link['nodes'][0]['type'] == 'Server': node_1 = Server.find_by_id(link['nodes'][0]['id']) else: node_1 = link['nodes'][0]['id'] # Creating node 1 if it doesn't exists yet if node_1 not in topology: topology.add_node(node_1) for key, value in link['nodes'][0]['data'].items(): topology.nodes[node_1][key] = value if link['nodes'][1]['type'] == 'Server': node_2 = Server.find_by_id(link['nodes'][1]['id']) else: node_2 = link['nodes'][1]['id'] # Creating node 2 if it doesn't exists yet if node_2 not in topology: topology.add_node(node_2) for key, value in link['nodes'][1]['data'].items(): topology.nodes[node_2][key] = value # Creating link if it wasn't created yet if not topology.has_edge(node_1, node_2): topology.add_edge(node_1, node_2) # Adding attributes to the link topology[node_1][node_2]['bandwidth'] = link['bandwidth'] # Assigning 'topology' and 'simulation_environment' attributes to created objects objects = Server.all() + VirtualMachine.all() for obj in objects: obj.topology = topology obj.simulation_environment = Simulator.environment