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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
    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