AUTHOR
FIREWHEEL Team
DONE
DESCRIPTION

Submit a :py:attr:`RESUME <firewheel.vm_resource_manager.schedule_event.ScheduleEventType.RESUME>` event to a set of VMs within an experiment. This can be applied to a set of
VMs or to all VMs within the experiment. This is primarily used for resuming VMs which have
created a *break* within the VM resource schedule. For more information see :ref:`vm-resource-schedule`.

**Usage:**  ``firewheel vm resume [-h] (-a | vm_name [vm_name ...])``

Arguments
+++++++++

Named Arguments
^^^^^^^^^^^^^^^

.. option:: -h, --help

    Show help message and exit.

.. option:: -a, --all

    Send a :py:attr:`RESUME <firewheel.vm_resource_manager.schedule_event.ScheduleEventType.RESUME>` event for all VMs in the experiment.

Positional Arguments
^^^^^^^^^^^^^^^^^^^^

.. option:: <vm_name>

    The hostname of the VM within the experiment whose schedule should resume.


Example
+++++++

``firewheel vm resume host.root.net``

``firewheel vm resume host.root.net bgp.root.net``

``firewheel vm resume --all``

DONE
RUN LocalPython ON control
#!/usr/bin/env python

import sys
import math
import pickle
import argparse

from rich.console import Console

from firewheel.lib.minimega.api import minimegaAPI
from firewheel.vm_resource_manager.schedule_db import ScheduleDb
from firewheel.vm_resource_manager.schedule_entry import ScheduleEntry


def handle_schedule_entry(sched_db, con, vm_name):
    """
    Create a schedule entry for a RESUME event.

    Args:
        sched_db (ScheduleDb): A schedule database instance.
        con (rich.console.Console): A console instance to use.
        vm_name (str): The name of a VM for which the schedule was resumed.

    Returns:
        list: A list of :py:class:`ScheduleEntry` objects.
    """
    pickled_schedule = sched_db.get(vm_name)
    if not pickled_schedule:
        con.print(f"[b red]Unable to get schedule for VM: [cyan]{name}")
        sys.exit(1)
    schedule = pickle.loads(pickled_schedule)

    # ScheduleEntry will have been loaded prior to this point automatically.
    sched_entry = ScheduleEntry(-math.inf)
    entry = {"resume": True}
    sched_entry.data.append(entry)
    schedule.append(sched_entry)
    return schedule


if __name__ == "__main__":
    # Set the arguments
    parser = argparse.ArgumentParser(
        description="Resume any VMs that were paused via a `break` VM Resource.",
        prog="firewheel vm resume",
    )

    grouping = parser.add_mutually_exclusive_group(required=True)
    grouping.add_argument(
        "-a",
        "--all",
        action="store_true",
        default=False,
        help="Resume all paused VMs.",
    )

    grouping.add_argument(
        "vm_name",
        nargs="*",
        default=[],
        help="The hostname of the VM within the experiment from which to pull the files",
    )

    args = parser.parse_args()

    console = Console()
    schedule_db = ScheduleDb()
    # Check if we need all VMs
    schedules = []
    mm_api = minimegaAPI()
    mm_dict = mm_api.mm_vms()
    if not args.all:
        for name in args.vm_name:
            try:
                valid = mm_dict[name]
                sched = handle_schedule_entry(schedule_db, console, name)
                schedules.append(
                    {"server_name": name, "text": pickle.dumps(sched), "ip": None}
                )
            except KeyError:
                console.print(f"[b red]ERROR: VM `[cyan]{name}[/cyan]` does not exist!")
                sys.exit(1)
    else:
        for name in mm_dict:
            sched = handle_schedule_entry(schedule_db, console, name)
            schedules.append(
                {"server_name": name, "text": pickle.dumps(sched), "ip": None}
            )

    schedule_db.batch_put(schedules, True)
    console.print(f"[b green]Resumed VM Resource Handling for {len(schedules)} VMs.")
DONE
