예제 #1
0
def vulnerability_surface(env, maintenance_data):
    """
    Maintenance strategy proposed by Severo et al. 2020
    ===================================================
    Note: We use the term "empty" to refer to servers that are not hosting VMs

    When choosing which servers to empty, this heuristic prioritizes servers that
    take less time to be emptied, which can be achieved by having a small number
    of VMs or by hosting small VMs (that will take a negligible time to be migrated).

    The maintenance process is divided in two tasks:
    (i) Patching empty servers (lines 31-38)
    (ii) Migrating VMs to empty more servers (lines 42-90)

    Parameters
    ==========
    env : SimPy.Environment
        Used to quantity the amount of simulation time spent by the migration

    maintenance_data : List
        Object that will be filled during the maintenance, storing metrics on each maintenance step
    """

    while len(Server.nonupdated()) > 0:
        # Patching servers nonupdated servers that are not hosting VMs
        servers_to_patch = Server.ready_to_patch()
        if len(servers_to_patch) > 0:
            for server in servers_to_patch:
                server.updated = True

            # As servers are updated simultaneously, we don't need to call the function
            # that quantifies the server maintenance duration for each server being patched
            yield env.process(server_update(env, constants.PATCHING_TIME))

        # Migrating VMs

        servers_being_emptied = []

        # Sorts the servers to empty based on its update score. This score considers
        # the amount of time needed to migrate all VMs hosted by the server
        servers_to_empty = sorted(
            Server.nonupdated(),
            key=lambda cand_server: cand_server.update_cost())

        migrations_data = [
        ]  # Stores data on the migrations performed to allow future analysis

        for server in servers_to_empty:

            vms_to_migrate = len(server.virtual_machines)
            servers_checked = 0

            # We consider as candidate hosts for the VMs every server
            # not being emptied in the current iteration
            candidate_servers = [
                cand_server for cand_server in Server.all()
                if cand_server not in servers_being_emptied
                and cand_server != server
            ]

            while len(server.virtual_machines
                      ) > 0 and servers_checked < vms_to_migrate * len(
                          candidate_servers):
                # Sorting VMs by its demand (decreasing)
                vms = sorted(
                    server.virtual_machines,
                    key=lambda vm:
                    (-vm.cpu_demand, -vm.memory_demand, -vm.disk_demand))

                vm = server.virtual_machines[0]

                # Sorting servers by update status (updated ones first) and demand (decreasing)
                candidate_servers = sorted(
                    candidate_servers,
                    key=lambda cand_server:
                    (-cand_server.updated, -cand_server.cpu_demand,
                     -cand_server.memory_demand, -cand_server.disk_demand))

                if Server.can_host_vms(candidate_servers, vms):
                    # Using a First-Fit Decreasing strategy to select a candidate host for each VM
                    for cand_server in candidate_servers:
                        servers_checked += 1
                        if cand_server.has_capacity_to_host(vm):

                            # Migrating the VM and storing the migration duration to allow future analysis
                            migration_duration = yield env.process(
                                vm.migrate(env, cand_server))

                            migrations_data.append({
                                'origin':
                                server,
                                'destination':
                                cand_server,
                                'vm':
                                vm,
                                'duration':
                                migration_duration
                            })

                            break
                else:
                    break

            if len(server.virtual_machines) == 0:
                servers_being_emptied.append(server)

        # Collecting metrics gathered in the current maintenance step (i.e., outer while loop iteration)
        maintenance_data.append(
            collect_metrics(env, 'VS Heuristic', servers_to_patch,
                            servers_being_emptied, migrations_data))
예제 #2
0
def first_fit(env, maintenance_data):
    """
    First-Fit like maintenance strategy (presented by Severo et al. 2020)
    ====================================================================
    Note: We use the term "empty" to refer to servers that are not hosting VMs.

    The maintenance process is divided in two tasks:
    (i) Patching empty servers (lines 29-36)
    (ii) Migrating VMs to empty more servers (lines 40-73)

    When choosing which servers will host the VMs, this strategy uses the First-Fit heuristic.

    Parameters
    ==========
    env : SimPy.Environment
        Used to quantity the amount of simulation time spent by the migration

    maintenance_data : List
        Object that will be filled during the maintenance, storing metrics on each maintenance step
    """

    while len(Server.nonupdated()) > 0:
        # (i) Patching servers nonupdated servers that are not hosting VMs (lines 30-37)
        servers_to_patch = Server.ready_to_patch()
        if len(servers_to_patch) > 0:
            for server in servers_to_patch:
                server.updated = True

            # As servers are updated simultaneously, we don't need to call the function
            # that quantifies the server maintenance duration for each server being patched
            yield env.process(server_update(env, constants.PATCHING_TIME))

        # (ii) Migrating VMs to empty more servers (lines 41-74)

        servers_being_emptied = []

        # Getting the list of servers that still need to receive the patch
        servers_to_empty = Server.nonupdated()
        migrations_data = [
        ]  # Stores data on the migrations performed to allow future analysis

        for server in servers_to_empty:

            candidate_servers = [
                cand_server for cand_server in Server.all()
                if cand_server != server
                and cand_server not in servers_being_emptied
            ]

            vms_to_migrate = len(server.virtual_machines)
            servers_checked = 0

            while len(server.virtual_machines
                      ) > 0 and servers_checked <= vms_to_migrate * len(
                          candidate_servers):

                vm = server.virtual_machines[0]

                # Migrating VMs using the First-Fit heuristic, which suggests the
                # migration of VMs to the first server that has resources to host it
                for cand_server in candidate_servers:
                    servers_checked += 1
                    if cand_server.has_capacity_to_host(vm):

                        # Migrating the VM and storing the migration duration to allow future analysis
                        migration_duration = yield env.process(
                            vm.migrate(env, cand_server))

                        migrations_data.append({
                            'origin': server,
                            'destination': cand_server,
                            'vm': vm,
                            'duration': migration_duration
                        })

                        break

            if len(server.virtual_machines) == 0:
                servers_being_emptied.append(server)

        # Collecting metrics gathered in the current maintenance step (i.e., outer while loop iteration)
        maintenance_data.append(
            collect_metrics(env, 'First-Fit', servers_to_patch,
                            servers_being_emptied, migrations_data))