VM Resource Manager
VM Resource Manager API Reference
Public interface for interacting with the VM Resource Manager. These functions should be callable with only information available from experiment Control.
- firewheel.vm_resource_manager.api.add_experiment_start_time(start=None)[source]
Set the start time of the currently running experiment. All parameters to this function are only present to enable unit testing and may be safely ignored.
- Parameters:
start (ExperimentStart) – ExperimentStart instance to use as a database. Present for unit testing, safely ignored.
- Returns:
A datetime object containing the start time for the currently running experiment. The time is defined to be in the UTC time zone.
- Return type:
- firewheel.vm_resource_manager.api.add_vm(server_uuid, server_name, control_ip, use_vm_manager=True, mapping=None, log=None)[source]
Add a VM to the vm resource database.
The VM is in the default vm resource state (uninitialized) after insertion.
- Parameters:
server_uuid (str) – The uuid of the VM, as specified in the Control graph.
server_name (str) – The name of the system, as specified in the Control graph.
control_ip (str) – The address for this VM on the control network.
use_vm_manager (bool) – This VM uses the VM Resource Manager. If False, the vm resource state is set to ‘N/A’ and the VM is subsequently ignored for VM Resource Manager calculations like experiment start time. Default is True.
mapping (firewheel.vm_resource_manager.vm_mapping.VMMapping) – VMMapping instance to use as a database. Present for unit testing, safely ignored.
log (logging.Logger) – An optional logger that can to output results.
- firewheel.vm_resource_manager.api.add_vm_resource_file(filename, store=None, log=None)[source]
Add a file to the VmResourceStore.
- Parameters:
filename (str) – The path to the (locally stored) file to add to the VmResourceStore.
store (VmResourceStore) – VmResourceStore instance to use as a database. Present for unit testing, safely ignored.
log (logging.Logger) – An optional logger that can to output results.
- firewheel.vm_resource_manager.api.destroy_all(mapping=None, schedule=None, start=None, log=None, ignore_grpc_connection_errors=False)[source]
Clears the VMMapping, Schedule, and ExperimentStart databases.
All arguments are only present to enable unit testing and may be safely ignored.
- Parameters:
mapping (firewheel.vm_resource_manager.vm_mapping.VMMapping) – VMMapping instance to use as a database. Present for unit testing, safely ignored.
schedule (ScheduleDb) – ScheduleDb instance to use as a database. Present for unit testing, safely ignored.
start (ExperimentStart) – ExperimentStart instance to use as a database. Present for unit testing, safely ignored.
log (logging.Logger) – An optional logger that can to output results.
ignore_grpc_connection_errors (bool) – Whether to ignore gRPC errors or not.
- Raises:
ConnectionError – If ignore_grpc_connection_errors=False and there is an error connecting to the gRPC server.
- firewheel.vm_resource_manager.api.get_experiment_launch_time(start=None)[source]
Get the launch time of the currently running experiment. All parameters to this function are only present to enable unit testing and may be safely ignored.
- Parameters:
start (ExperimentStart) – ExperimentStart instance to use as a database. Present for unit testing, safely ignored.
- Returns:
A datetime object containing the launch time for the currently running experiment. The time is defined to be in the UTC time zone. None if no launch time has been determined yet.
- Return type:
- firewheel.vm_resource_manager.api.get_experiment_start_time(start=None)[source]
Get the start time of the currently running experiment. All parameters to this function are only present to enable unit testing and may be safely ignored.
- Parameters:
start (ExperimentStart) – ExperimentStart instance to use as a database. Present for unit testing, safely ignored.
- Returns:
A datetime object containing the start time for the currently running experiment. The time is defined to be in the UTC time zone. None if no start time has been determined yet.
- Return type:
- firewheel.vm_resource_manager.api.get_experiment_time_since_start(start=None)[source]
Get the time since the experiment configured. All parameters to this function are only present to enable unit testing and may be safely ignored.
- Parameters:
start (ExperimentStart) – ExperimentStart instance to use as a database. Present for unit testing, safely ignored.
- Returns:
The time in seconds since when the experiment configured. None if experiment hasn’t started yet.
- Return type:
- firewheel.vm_resource_manager.api.get_experiment_time_to_start(start=None)[source]
Get the time it took for the experiment to configure. All parameters to this function are only present to enable unit testing and may be safely ignored.
- Parameters:
start (ExperimentStart) – ExperimentStart instance to use as a database. Present for unit testing, safely ignored.
- Returns:
The time in seconds from when the experiment launched to configured. None if experiment hasn’t started yet.
- Return type:
- firewheel.vm_resource_manager.api.get_vm_states(filter_state=None, mapping=None, log=None)[source]
Get the current vm resources state of all known VMs.
- Parameters:
filter_state (str) – Only return VMs in this state.
mapping (firewheel.vm_resource_manager.vm_mapping.VMMapping) – VMMapping instance to use as a database. Present for unit testing, safely ignored.
log (logging.Logger) – An optional logger that can to output results.
- Returns:
A dictionary keyed on the VM server name, with string values for the vm resources state.
- Return type:
- firewheel.vm_resource_manager.api.get_vm_times(filter_time=None, mapping=None, log=None)[source]
Get the current negative times of known VMs.
- Parameters:
filter_time (int) – Return only VMs with this negative time value.
mapping (firewheel.vm_resource_manager.vm_mapping.VMMapping) – VMMapping instance to use as a database. Present for unit testing, safely ignored.
log (logging.Logger) – An optional logger that can to output results.
- Returns:
Dictionary keyed on server name, values of the current negative time for that VM.
- Return type:
- firewheel.vm_resource_manager.api.set_experiment_launch_time(start=None)[source]
Set the launch time of the currently running experiment. All parameters to this function are only present to enable unit testing and may be safely ignored.
- Parameters:
start (ExperimentStart) – ExperimentStart instance to use as a database. Present for unit testing, safely ignored.
- Returns:
A datetime object containing the launch time for the currently running experiment. The time is defined to be in the UTC time zone.
- Return type:
- firewheel.vm_resource_manager.api.vm_resource_list(store=None, log=None)[source]
List the available vm resources in the VmResourceStore. All parameters to this function all only present to enable unit testing and may be safely ignored.
- Parameters:
store (VmResourceStore) – VmResourceStore instance to use as a database. Present for unit testing, safely ignored.
log (logging.Logger) – An optional logger that can to output results.
- Returns:
A list of (unique) file names in the VmResourceStore.
- Return type:
experiment_start.py
Subsystem to determine and report an experiment start time.
- class firewheel.vm_resource_manager.experiment_start.ExperimentStart(hostname='', port=50051, db='prod')[source]
Bases:
object
Interface to determine and report an experiment start time. Different start times may reported as desired, but a consistent value will always be reported as the start time. If no start times have yet been reported, a value of None will be reported.
This is currently implemented using the GRPC database as a synchronization mechanism: the current time is reported and recorded into the DB. When determining the consistent start time value, the values from the DB are sorted and the first-recorded returned.
- __init__(hostname='', port=50051, db='prod')[source]
All arguments are present only for unit testing and may be safely ignored.
- add_start_time()[source]
Report the current time as a new start time for the database. May be called arbitrary many times without affecting the consistency of the time returned by get_start_time().
- Returns:
A datetime object representing the time value as added to the database: 1-second resolution, UTC.
- Return type:
- clear_start_time()[source]
Clear the current start time. The system is then uninitialized until a new time is reported–after this call, get_start_time() returns None until add_start_time() is called.
- Returns:
The response dictionary from GRPC initializing the start time.
- Return type:
- get_launch_time()[source]
Return the experiment launch time.
- Returns:
datetime object representing the start time (in UTC), 1-second resolution or None is no launch time has been reported yet.
- Return type:
- get_start_time()[source]
Return a consistent value for the experiment start time, as determined by the reported times using add_start_time().
- Returns:
datetime object representing the start time (in UTC), 1-second resolution or None is no start time has been reported yet.
- Return type:
- get_time_since_start()[source]
Get the amount of time that has elapsed since the experiment has been configured.
- Returns:
The time in seconds since when the experiment configured or None if experiment hasn’t started yet.
- Return type:
- get_time_to_start()[source]
Get the amount of time it takes from when an experiment is launched to when it is configured.
- Returns:
The time in seconds from when the experiment launched to configured. or None if experiment hasn’t started yet.
- Return type:
schedule_db.py
Subsystem for the storage and retrieval of vm_resource schedules.
- class firewheel.vm_resource_manager.schedule_db.ScheduleDb(cache_name='schedules', log=None)[source]
Bases:
object
Class to represent the experiment schedule database. This is currently backed by a minimega store, but the interface should remain general enough that this could change without modifying users of this class.
- __init__(cache_name='schedules', log=None)[source]
Initialize the ScheduleDb.
All arguments are present only for unit testing and may be safely ignored.
- Parameters:
cache_name (str) – Override the default minimega cache dir.
log (firewheel.lib.log.Log) – Override the default FIREWHEEL log.
- Raises:
RuntimeError – If there is an invalid value for FileStore connections.
- destroy_one(server_name)[source]
Remove the schedule for a particular VM.
- Parameters:
server_name (str) – The name of the VM whose schedule will be removed.
schedule_entry.py
- class firewheel.vm_resource_manager.schedule_entry.ScheduleEntry(start_time, ignore_failure=False)[source]
Bases:
object
This class is the base class for all types of schedule entries. It is in this class that all necessary instance variables are declared. It is important that all variables within the
base_objects.ScheduleEntry
be instance variables, as opposed to class variables. This is because a VM’s schedule (i.e.base_objects.VmResourceSchedule
, which contains a list ofbase_objects.ScheduleEntry
objects) is serialized viapickle
and passed to the VM Resource Handler. Only instance variables get preserved through thepickle
process.Schedule entries have a set of general instance variables. The type of schedule entry determines which variables are required. The only variable that all ScheduleEntries require is
start_time
. This class is not intended to be used directly, but through its subclasses.- __init__(start_time, ignore_failure=False)[source]
Create a new ScheduleEntry
- start_time
Relative time to handle the VM resource. (See Start Time for more details).
- Type:
- data
List of dictionaries specifying required files:
Paths can be either absolute or relative to the VMR. Dictionary to drop specified content on VM { "location": <string>, # Path on VM to place content "content": <string>, # Content to be placed at location "executable": <bool> # Optionally set file's executable flag } Dictionary to load a file into the VM { "location": <string>, # Path on VM to place file "filename": <string>, # Name of file to be loaded on the VM "executable": <bool> # Optionally set file's executable flag }
- Parameters:
- Raises:
ValueError – If a start time of 0 is provided.
- __str__()[source]
A custom string method for ScheduleEntry Objects.
- Returns:
A string representation of a ScheduleEntry.
- Return type:
- add_content(location, content, executable=False)[source]
Add a block of content to be loaded into the VM at the specified location.
- Parameters:
location (str) – Path inside the VM to write the provided content, including filename. This path can be absolute or relative to the VM resource.
content (str) – Content to be written or a callback function that will return a string.
executable (bool, optional) – Set the new file’s executable flag. Defaults to False.
- add_file(location, filename, executable=False)[source]
Drop a file on the VM at the specified location. This file needs to be available to FIREWHEEL. This only happens when the files are included in the list of “vm_resources” that are specified in a model component’s
MANIFEST
file.- Parameters:
location (str) – Path inside the VM to write the file, including filename This path can be absolute or relative to the VM resource.
filename (str) – Name of file in the vm_resource’s database to be written.
executable (bool, optional) – Boolean for setting the new file’s executable flag. Defaults to False.
- add_file_transfer(location, interval=30, destination=None)[source]
Specifies that a file or directory needs to be monitored and pulled off the VM.
Note
If specifying a destination, the FIREWHEEL group (if any) must have permissions to modify and write to that directory. See the system configuration options to add FIREWHEEL group permissions.
- Parameters:
location (str) – Path inside the VM to the file or directory to be monitored and pulled off the VM.
interval (int, optional) – Interval specifying how often to check for file or directory updates.
destination (str, optional) – Absolute path on compute node of the directory where transferred files are to be placed:
<destination>/<vm_name>/<location>
. If no destination is provided, files will be written to<logging.root_dir>/transfers/
. See_transfer_data
for more details.
- add_pause(duration)[source]
Add data to the schedule entry that indicates that it should pause all following events. The duration (seconds) can be any positive number where a duration of
math.inf
indicates a break event which requires a resume to occur prior to advancing the schedule.Note
To ensure the exact ordering of events within a time-window (e.g. multiple events scheduled at the same time) the pause/break is technically added at the
start_time + sys.float_info.min
.- Parameters:
duration (float) – The duration (seconds) of the pause where
math.inf
is an break event.- Raises:
ValueError – If the
duration
is not positive.
- append_arguments(arguments)[source]
Append an argument to be passed on the command line to the executable
- set_executable(path, arguments=None)[source]
Specify the name of a program to run within the VM.
- Parameters:
- Raises:
RuntimeError – If the executable name is not a string.
schedule_event.py
- class firewheel.vm_resource_manager.schedule_event.ScheduleEvent(event_type, data)[source]
Bases:
object
These objects get added to the event queue and processed by the VM Resource Handler launcher.
- __init__(event_type, data)[source]
Create an event.
- Parameters:
event_type (ScheduleEventType) – Type of event
data (object) – Event data to be processed
- __lt__(other)[source]
Comparison function. If two events have the same start time then the ScheduleEvents will be compared on insert into the priority queue. If both event have the same start time then it doesn’t matter which one gets put first in the queue, they will all be processed at the same time regardless. Therefore, just return True every time to create an arbitrary order of the ScheduleEvents in the priority queue.
- class firewheel.vm_resource_manager.schedule_event.ScheduleEventType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]
Bases:
Enum
The possible types of allowed schedule events.
- EMPTY_SCHEDULE = 1
- EXIT = 4
- EXPERIMENT_START_TIME_SET = 0
- NEW_ITEM = 2
- PAUSE = 5
- RESUME = 6
- TRANSFER = 3
- UNKNOWN = 7
schedule_updater.py
- class firewheel.vm_resource_manager.schedule_updater.ScheduleUpdater(config, priority_queue, condition, vm_resource_store, schedule_db, repository_db, log, log_filename, load_balance_factor, interval_time=5)[source]
Bases:
Thread
ScheduleUpdater checks for updates to a VM’s schedule at specified intervals.
It then passes those updates to the main processing loop via a
queue.PriorityQueue
ofScheduleEvents
.- __init__(config, priority_queue, condition, vm_resource_store, schedule_db, repository_db, log, log_filename, load_balance_factor, interval_time=5)[source]
Initialize the updater class.
- Parameters:
config (dict) – config for the VM
priority_queue (PriorityQueue) – Queue to place new vm_resource events to get picked up by the VMResourceHandler
condition (Condition) – Lock for the priority queue
vm_resource_store (VmResourceStore) – A resource store to use.
schedule_db (ScheduleDb) – A ScheduleDb to use.
repository_db (RepositoryDb) – A RepositoryDb to use.
log (Logger) – The vm_resource launcher’s logger for output
log_filename (str) – A filename for the log.
load_balance_factor (float) – Amount of time to scale sleeps by.
interval_time (int) – Amount of time to sleep between checking for updates
- _run()[source]
Main loop for the thread. Checks for updates and adds events to the event queue for processing by the VM Resource Handler. The logic for this function gets rather complex and provides for the ability to accommodate all event types include
PAUSE
andRESUME
events.
- enqueue_event(priority, event)[source]
Put a single event in the priority queue to pass information back to the main processing loop.
- Parameters:
priority (int) – The priority of the event.
event (ScheduleEvent) – Event to be processed.
- get_schedule(name)[source]
Get the schedule for a specified VM.
Note
In general, loading pickle data can have some serious security implications. Please review Security for more details.
- Parameters:
name (str) – Name of the VM.
- Returns:
List of ScheduleEntry objects.
- Return type:
- Raises:
RuntimeError – If there is an exception getting the schedule.
- get_start_time()[source]
Queries the database to see if a start time for the experiment has been set.
- Returns:
- Experiment start time if available, None if start time has
not been set yet
- Return type:
- run()[source]
Main loop for the thread. Checks for updates and adds events to the event queue for processing by the vm_resource launcher. queue for processing by the VM Resource Handler. The logic for this function gets rather complex and provides for the ability to accommodate all event types include
PAUSE
andRESUME
events.
utils.py
Utility functions for common high-level operations performed by the Vm Resource Manager.
These are high-level functions that may be useful in Modules, but should not be needed outside the VM Resource Manager and its Modules.
- firewheel.vm_resource_manager.utils.get_vm_count_not_ready(mapping=None, log=None)[source]
Returns the number of VMs not in the “configured” or “N/A” states. These VMs are not ready in the sense that they are not prepared to begin the experiment (set an experiment schedule start time). For reference: The configured state means the bootstrap vm_resource has completed all negative-start-time vm_resources and checked in as ready and the N/A state means there is no vm_resource system present on a VM.
- Parameters:
mapping (firewheel.vm_resource_manager.vm_mapping.VMMapping) – VMMapping instance to use as a database. Present for unit testing, safely ignored.
log (logging.Logger) – An optional logger that can to output results.
- Returns:
- Count of the number of VMs not in the “configured” or
”N/A” vm_resources state.
- Return type:
- firewheel.vm_resource_manager.utils.set_vm_state(vm_uuid, new_state, mapping=None, log=None)[source]
Set the vm_resources state of a given VM.
- Parameters:
vm_uuid (str) – The UUID of the VM to set the state of.
new_state (str) – A string representing the new vm_resources state of the VM. There is no validation for strings matching expected states.
mapping (firewheel.vm_resource_manager.vm_mapping.VMMapping) – VMMapping instance to use as a database. Present for unit testing, safely ignored.
log (logging.Logger) – An optional logger that can to output results.
- Raises:
RuntimeError – If the VMMapping database could not be created.
- firewheel.vm_resource_manager.utils.set_vm_time(vm_uuid, new_time, mapping=None, log=None)[source]
Set the current time reported by a VM.
- Parameters:
vm_uuid (str) – The uuid of the VM to set the state of.
new_time (str) – A string representing the current time.
mapping (firewheel.vm_resource_manager.vm_mapping.VMMapping) – VMMapping instance to use as a database. Present for unit testing, safely ignored.
log (logging.Logger) – An optional logger that can to output results.
- Raises:
RuntimeError – If the VMMapping database could not be created.
vm_mapping.py
Interface to the mapping between VMs, their current (vm resource) state, and other metadata.
- class firewheel.vm_resource_manager.vm_mapping.VMMapping(hostname='', port=50051, db='prod')[source]
Bases:
object
Database interface for the mapping between VM name, VM control IP, and vm_resources state or other metadata.
Access may use name or IP as a key.
- __init__(hostname='', port=50051, db='prod')[source]
All arguments are present only for unit testing and may be safely ignored.
- batch_put(server_list)[source]
Add a list of VM information to the database as a batch update. Each entry in the list is a dictionary specifying the relevant information.
- Parameters:
server_list (list) –
List of dictionaries where each entry looks like:
{ 'server_uuid': '', 'server_name': '', 'state': '', 'current_time': '', 'control_ip': '' }
Default values apply to the state and current_time fields. These values match those in put(). Only server_uuid and server_name fields are required for each entry in the list.
- destroy_one(server_uuid)[source]
Remove a single entry from the database.
- Parameters:
server_uuid (str) – UUID for the entry to remove.
- get(server_uuid=None)[source]
Retrieve a single entry from the database. This can only retrieve by using the server_uuid.
- Parameters:
server_uuid (str) – UUID of the VM to be retrieved.
- Returns:
Dictionary with the information about the VM as stored. Includes current vm_resource state for the VM.
- Return type:
- Raises:
ValueError – If the server_uuid is not provided.
- get_all(filter_time=None, filter_state=None, project_dict=None, length=False)[source]
Retrieve multiple entries from the database. May filter on current (relative) time or vm resource state.
NOTE: This will not allow filtering for VMs where the time has been not been initialized yet, since both that condition and no filter is represented with None.
- Parameters:
filter_time (int) – Only return VM information when the current relative time matches this value.
filter_state (str) – Only return VM information when the current vm resource state matches this value.
project_dict (dict) – Only return VM information from these keys.
length (bool) – Should the function return how many VMs are in the list or should it return the list itself.
- Returns:
If length is False, return a list of dictionaries, where each dictionary is the same as would be returned for the VM if retrieved using get(). If length is True, returns the length of the list.
- Return type:
- get_count_vm_not_ready()[source]
Get the number of VMs that are not yet in the “Configured” state.
- Returns:
The count of VMs which are not in the “Configured” state.
- Return type:
- prepare_put(entry)[source]
Validate that the provided entry has the necessary fields and if it does not, provide details or raise an error in the case of a required field. The two required fields are server_uuid and server_name.
- Parameters:
entry (dict) –
A dictionary which contains a subset of the following fields:
{ 'server_uuid': '', 'server_name': '', 'state': '', 'current_time': '', 'control_ip': '' }
Default values apply to state, current_time, and control_ip fields. These values match those in put(). Only server_uuid and server_name fields are required for each entry in the list.
- Returns:
An entry dictionary which can be put into the database.
- Return type:
- Raises:
ValueError – If the entry does not contain the server_uuid field.
ValueError – If the entry does not contain the server_name field.
- put(server_uuid, server_name, state='uninitialized', current_time='', server_address='')[source]
Add a set of new VM information to the database.
- Parameters:
server_uuid (str) – UUID of the VM.
server_name (str) – Hostname of the VM.
state (str) – Vm Resource state the VM starts in. Defaults to the configured default state (located in the FIREWHEEL configuration).
current_time (str) – The current (relative) time for the VM. Defaults to ‘’, meaning the VM has not contacted the server yet.
server_address (str) – The control_ip of the host where the VM Resource is found.
vm_resource_handler.py
This module contains the class enable the vm_resource_handler
to
run. This runs as a process for each VM that is launched with FIREWHEEL and
controls the interaction with the QEMU Guest Agent.
- class firewheel.vm_resource_manager.vm_resource_handler.VMResourceHandler(config, check_interval=10)[source]
Bases:
object
Main class for communicating with a VM. Kicks off the ScheduleUpdater thread and handles all ScheduleEvents and their side effects.
- _import_drivers()[source]
Import available drivers from the driver directory.
Walk the drivers directory looking for all available drivers that can talk to a booted VM. A qualifying driver must be a subclass of the abstract driver class, implementing all required methods of the driver interface.
- Returns:
A set of available driver classes.
- Return type:
- _run()[source]
This is the main processing loop for the VMResourceHandler.
It kicks off the ScheduleUpdater thread and threads to run the individual vm_resources.
- _run_vm_resource(schedule_entry, queue=None)[source]
Function to handle starting a VM resource.
- Parameters:
schedule_entry (ScheduleEntry) –
ScheduleEntry
object specifying the VM resource to run.queue (Queue) – Queue to pass messages, specifically reboot requests, back to the main processing loop. Defaults to
None
.
- _transfer_data(name, location, interval=None, destination=None)[source]
The helper function which transfers data from the VM to the physical host based on the input parameters.
- Parameters:
- Raises:
RuntimeError – If the transfer path is not absolute.
RuntimeError – If it is unable to list files at the location.
- connect_to_driver()[source]
Instantiate the driver class to communicate to the VM
- Returns:
True if the driver is connected, False otherwise.
- Return type:
- get_events()[source]
Get all eligible events from the priority queue.
- Returns:
List of events that are ready to be processed.
- Return type:
- import_driver()[source]
Walk through all the available drivers and find the one that matches the type of VM that has been booted.
- Returns:
The driver class that matches the VM’s type
- Return type:
- load_files_in_target(schedule_entry)[source]
Copy the vm_resource file to the VM’s local cache so that it is available when the vm_resource gets called.
- Parameters:
schedule_entry (ScheduleEntry) – The schedule entry to be copied into the VM.
- Returns:
Success or failure of loading files into the VM.
- Return type:
- preload_files()[source]
This method loads all VM Resources into the VM before the schedule is executed. This minimizes the number of after-boot disk alterations. This is particularly important for Windows VMs as, in our experience, Windows does not appear to appreciate having files modified or created on disk immediately after a reboot.
- print_output(schedule_entry, pid)[source]
Print any output from an vm_resource to the log.
- Parameters:
schedule_entry (ScheduleEntry) –
ScheduleEntry
object specifying the VM resource to run.pid (int) – The PID of the VM resource process within the VM.
- reboot()[source]
Reboot the VM. Function doesn’t return until the driver can communicate with the VM again.
- run_vm_resource(schedule_entry, queue=None)[source]
Wrapper around the logic of running an vm_resource.
The new thread calls this wrapper, which can output errors to the log file. This gives a convenient way to pass information back to the user via the log (with few good alternatives).
- Parameters:
schedule_entry (ScheduleEntry) –
ScheduleEntry
object specifying the VM resource to run.queue (Queue) – Queue to pass messages, specifically reboot requests, back to the main processing loop. Defaults to
None
.
- set_current_time(cur_time)[source]
Tell the infrastructure the current configuration time of the VM.
- Parameters:
cur_time (int) – Current VM schedule time
- set_state(state)[source]
Tell the infrastructure the state of the VM. If the state is ‘configured’, then check to see if this VM is the last VM to be configured. If it is the last VM to be configured, then set the experiment start time.
- Parameters:
state (str) – State of the VM
- stop(exitcode)[source]
Stop the vm resource handler. This is used for unit testing.
- Parameters:
exitcode (int) – exit code to use when exiting the program
vm_resource_store.py
- class firewheel.vm_resource_manager.vm_resource_store.VmResourceStore(store='vm_resources', decompress=False)[source]
Bases:
FileStore
A repository for VM resources that uses the minimega FileStore for easy access on all hosts in a Firewheel cluster.
- __annotations__ = {}
- __init__(store='vm_resources', decompress=False)[source]
Initialize the
VmResourceStore
.
abstract_driver.py
- class firewheel.vm_resource_manager.abstract_driver.AbstractDriver(config, log)[source]
Bases:
ABC
An abstract driver class for communicating with all in-VM agents that work with FIREWHEEL. All driver-specific implementation is left to subclasses.
- _EXEC_ERROR_MSG = '`execute` returned `None` indicating an error has occurred.'
- __abstractmethods__ = frozenset({'_write', 'close', 'connect', 'exec_status', 'execute', 'file_flush', 'get_engine', 'get_os', 'get_time', 'network_get_interfaces', 'ping', 'read_file', 'reboot', 'set_time', 'set_user_password', 'store_captured_output', 'sync', 'write_from_file'})
- __annotations__ = {}
- __init__(config, log)[source]
An abstract driver class for communicating with all in-VM agents that work with FIREWHEEL. All driver-specific implementation is left to subclasses.
- log
Logger for output
- Type:
Logger
- lock
Only one connection to the serial port is allowed, therefore access to the port needs to be thread safe.
- Type:
- used_agent_paths
Agents need a unique directory to hold their relevant files. This keeps track of paths that have already been used.
- Type:
- output_cache
The output cache is a cache of all output resulting from calling programs within a VM. This data lives as long as the process runs. It allows streaming output from an agent to be collected and agent output to be requested multiple times if needed. The output cache has the following format:
{ <pid>: { 'exited': True or False, 'exitcode': <integer status code>, 'signal': <Optional: signal or unhandled exception code>, 'stdout': <Optional: output from stdout>, 'stdout_trunc': <Optional: True if stdout was truncated>, 'stderr': <Optional: output from stderr>, 'stderr_trunc': <Optional: True if stder was truncated> } }
The output cache is cleared on system reboot.
- Type:
- Parameters:
config (dict) – vm config which is used to find the Virtio serial port socket that the guest agent uses to communicate to the VM with.
log (logging.Logger) – A logger which can be used by this class.
- Raises:
FileNotFoundError – If no path was given to the QGA serial device.
- _abc_impl = <_abc._abc_data object>
- _delete_parent_directories(directory)[source]
Delete the directory and any (empty) parent directories.
Recursively delete the given directory and all parent directories until encountering a directory that is not empty.
- Parameters:
directory (PurePosixPath) – The directory to remove. Parent directories of this directory will also be deleted if otherwise empty.
- _get_stream(stream_name, pid)[source]
Set a set of information from a given stream (stdout, stderr, etc.).
- abstract _write(filename, data, mode='w')[source]
Write the provided data at the provided filename within the guest VM.
- Parameters:
- Raises:
NotImplementedError – This should be implemented by a subclass.
- abstract close()[source]
Close the connection to the socket used for agent.
- Raises:
NotImplementedError – This should be implemented by a subclass.
- abstract connect()[source]
This method sets up the driver connection with the agent within the VM so that they can communicate. It then should call
sync()
. The return value of this method is typically a random synchronization token used in the sync request/response exchange.- Raises:
NotImplementedError – This should be implemented by a subclass.
- connected(timeout=10)[source]
Check that the driver is currently connected to the guest agent inside the VM.
- create_directories(directory)[source]
The guest agent does not allow interacting with a new file if the file’s path does not exist. Therefore, this function creates the path for a file if it does not exist.
- create_paths(schedule_entry)[source]
Since the paths that need to be created are dependent on what the driver accepts (i.e. QGA doesn’t want C: to be prepended on Windows paths, but the agent needs the path to the reboot file, which will need the drive letter prepended to the path) it is the driver’s job to determine the paths for the agent.
- Parameters:
schedule_entry (ScheduleEntry) – The schedule_entry object.
- deconflict_agent_path(path)[source]
Create unique path names for agents.
- Parameters:
path (str) – Desired path name.
- Returns:
A
pathlib.Path
object which is unique.- Return type:
Path
- evaluate_process_success(pid, interval=1)[source]
Wait for a process to complete, and return a success indicator.
- abstract exec_status(pid)[source]
Get the status of a program that was run. It should return a dictionary with the exit code and other information about the status (STDOUT, STDERR, etc.)
- Parameters:
pid (int) – The PID that for the process that was returned from guest-exec-status.
- Raises:
NotImplementedError – This should be implemented by a subclass.
- abstract execute(path, arg=None, env=None, input_data=None, capture_output=True)[source]
Run a program inside the guest VM. This should return process’s PID on success or
None
on failure.- Parameters:
path (str) – Path or executable name to execute.
arg (str) – Argument list to pass to executable. Must be a list or string. Defaults to None.
env (list) – Environment variables to pass to executable. List of “<key>=<value>” strings. Defaults to None.
input_data (str) – Data to be passed to process stdin. Defaults to
None
.capture_output (bool) – Flag to enable capture of stdout/stderr. Defaults to True.
- Raises:
NotImplementedError – This should be implemented by a subclass.
- file_exists(path)[source]
Check if a file exists inside the VM. If a user used a shell-globbing wildcard (e.g.
*
) in the path (and shell-globbing is supported by the VM) then this function only checks to see if at least one file matching the wildcard exists.
- abstract file_flush(handle)[source]
Flush a file to disk inside the guest VM
- Parameters:
handle (File) – file handle returned from guest-file-open.
- Raises:
NotImplementedError – This should be implemented by a subclass.
- abstract static get_engine()[source]
Get the virtualization engine that this driver supports.
- Raises:
NotImplementedError – This should be implemented by a subclass.
- get_files(path, timestamp=None)[source]
Get all filenames at a specified path.
- Parameters:
- Returns:
A list of filenames at the specified location or
None
if an error occurs.- Return type:
- abstract get_os()[source]
Get the Operating System details for the VM. It should return the “pretty” name for the OS.
- Raises:
NotImplementedError – This should be implemented by a subclass.
- abstract get_time()[source]
Get the time inside the VM in nanoseconds since the epoch.
- Raises:
NotImplementedError – This should be implemented by a subclass.
- make_file_executable(path)[source]
If the guest VM is not a Windows VM then set the executable flag for the file at the provided path.
- abstract network_get_interfaces()[source]
Gets a list of network interface info. This is typically returned as a list of JSON objects.
- Raises:
NotImplementedError – This should be implemented by a subclass.
- abstract ping(timeout=10)[source]
Check if connection to the in-VM agent was successful.
- Parameters:
timeout (int) – The time in seconds until the socket times out.
- Raises:
NotImplementedError – This should be implemented by a subclass.
- abstract read_file(filename, local_destination, mode='rb')[source]
Read a file from a VM and put it onto the physical host.
- Parameters:
filename (str) – The file to read from inside the VM. This should be the full path.
local_destination (pathlib.PurePosixPath) – The path on the physical host where the file should be read to.
mode (str) – The mode of reading the file. Defaults to
'rb'
.
- Raises:
NotImplementedError – This should be implemented by a subclass.
- abstract set_time()[source]
Set the time in the VM to the current host time.
- Raises:
NotImplementedError – This should be implemented by a subclass.
- abstract set_user_password(username, password)[source]
Sets a user’s password.
- Parameters:
- Raises:
NotImplementedError – This should be implemented by a subclass.
- abstract store_captured_output(pid, output)[source]
Store output from a VM program.
Hold on to output that has been returned from a program that was run inside the VM via the
exec
method.- Parameters:
- Raises:
NotImplementedError – This should be implemented by a subclass.
- abstract sync(timeout=5)[source]
Synchronize the buffer for the agent. This method should return a random synchronization token used in the sync request/response
- Parameters:
timeout (int) – Socket timeout in seconds. Defaults to 5.
- Raises:
NotImplementedError – This should be implemented by a subclass.
- wait_for_exitcode(pid, interval=1)[source]
Repeatedly query for the exit code of a process run via exec_status.
- write(filename, data, mode='w')[source]
Write the provided data at the provided filename within the guest VM.
This will also create required directories in the filename’s path.
- abstract write_from_file(filename, local_filename, mode='w')[source]
Given a local filename, open that file to read its data and write that data to a location (provided in filename) in the guest VM.
- Parameters:
- Raises:
NotImplementedError – This should be implemented by a subclass.
Qemu Guest Agent
Driver API Reference
- class firewheel.vm_resource_manager.drivers.qemu_guest_agent_driver.QemuGuestAgentDriver(config, log)[source]
Bases:
AbstractDriver
Driver class for the QEMU Guest Agent (QGA). This class can communicate to a QGA inside a VM via a serial port.
- __abstractmethods__ = frozenset({})
- __annotations__ = {}
- __init__(config, log)[source]
- Parameters:
config (dict) – vm config which is used to find the Virtio serial port socket that the guest agent uses to communicate to the VM with.
log (logging.Logger) – A logger which can be used by this class.
- _abc_impl = <_abc._abc_data object>
- _prep_async_exec(path, arg=None, env=None, input_data=None, capture_output=True)[source]
Run a program inside the guest VM.
- Parameters:
path (str) – Path or executable name to execute.
arg (str) – Argument list to pass to executable. Must be a list or string. Defaults to None.
env (list) – Environment variables to pass to executable. List of “<key>=<value>” strings. Defaults to None.
input_data (str) – Data to be passed to process stdin. Defaults to
None
.capture_output (bool) – Flag to enable capture of stdout/stderr. Defaults to True.
- Returns:
The process’s PID is returned on success or
None
on failure.- Return type:
- _write(filename, data, mode='w')[source]
Write the provided data at the provided filename within the guest VM.
- async_exec(path, arg=None, env=None, input_data=None, capture_output=True)[source]
Run a program inside the guest VM as an async process.
- Parameters:
path (str) – Path or executable name to execute.
arg (str) – Argument list to pass to executable. Must be a list or string. Defaults to None.
env (list) – Environment variables to pass to executable. List of “<key>=<value>” strings. Defaults to None.
input_data (str) – Data to be passed to process stdin. Defaults to
None
.capture_output (bool) – Flag to enable capture of stdout/stderr. Defaults to True.
- Returns:
The process’s PID is returned on success or
None
on failure.- Return type:
- connect()[source]
This method sets up the QMP connection with the QGA within the VM so that they can communicate. It then calls
sync()
.
- exec_status(pid)[source]
Get the status of a program that was run using guest-exec-status.
- Parameters:
pid (int) – The PID that for the process that was returned from guest-exec-status.
- Returns:
- The dictionary with the exit code and other information
returned from the guest-exec-status command.
- Return type:
- Raises:
TimeoutError – If the QGA status check times out.
OSError – If the QGA fails to execute the guest-exec-status command.
- execute(path, arg=None, env=None, input_data=None, capture_output=True)[source]
Run a program inside the guest VM.
- Parameters:
path (str) – Path or executable name to execute.
arg (str) – Argument list to pass to executable. Must be a list or string. Defaults to None.
env (list) – Environment variables to pass to executable. List of “<key>=<value>” strings. Defaults to None.
input_data (str) – Data to be passed to process stdin. Defaults to
None
.capture_output (bool) – Flag to enable capture of stdout/stderr. Defaults to True.
- Returns:
The process’s PID is returned on success or
None
on failure.- Return type:
- file_flush(handle)[source]
Flush a file to disk inside the guest VM
- Parameters:
handle (File) – file handle returned from guest-file-open.
- file_write_content(handle, content)[source]
Given content (i.e. ASCII data), write the content to a file inside the VM. The given handle is a handle to an open file inside the guest VM.
- file_write_from_file(handle, filename)[source]
Given a local filename, read the contents from that file and write them to the provided file handle. The file handle is a handle to an open file within the guest VM.
- Parameters:
handle (File) – file handle returned from guest-file-open.
filename (str) – Name of file to read content from and then send to the VM.
- Returns:
True on success, False on failure.
- Return type:
- Raises:
RuntimeError – An error occurred.
RuntimeError – The file write didn’t have a byte count.
RuntimeError – The returned size does not match the read size.
- static get_engine()[source]
Get the virtualization engine that this driver supports.
- Returns:
The name of the virtualization engine that this driver supports. Currently this is only ‘QemuVM’.
- Return type:
- get_time()[source]
Get the time inside the VM.
- Returns:
Time in nanoseconds since the epoch.
- Return type:
- network_get_interfaces()[source]
Gets a list of network interface info.
- Returns:
List of GuestNetworkInfo JSON objects.
- Return type:
- ping(timeout=10)[source]
Use the guest-ping command to check if connection to the guest agent was successful.
- read_file(filename, local_destination, mode='rb')[source]
Read a file from a VM and put it onto the physical host.
QGA has issues detecting EOF on Windows VMs. Therefore, if two reads from the file have the exact same data (e.g. 4K bytes per read) this method makes an assumption that all the data has been read. This approach can possibly cause issues. For example, if the file has two chunks of 4K bytes that are the same but then additional data, this will truncate the reading of the file. For that reason, we only apply this method for Windows VMs. If this becomes an issue with a particular experiment, it is possible to change the default number of bytes from 4K to a higher number (up to 48MB). You can see https://qemu-project.gitlab.io/qemu/interop/qemu-ga-ref.html#qapidoc-47 for more details.
- Parameters:
filename (str) – The file to read from inside the VM. This should be the full path.
local_destination (pathlib.PurePosixPath) – The path on the physical host where the file should be read to.
mode (str) – The mode of reading the file. Defaults to
'rb'
.
- Returns:
True if the read was successful, False otherwise.
- Return type:
- Raises:
RuntimeError – There is a read error.
RuntimeError – The return didn’t have a byte count.
RuntimeError – The returned size does not match the read size.
- store_captured_output(pid, output)[source]
Store output from a VM program.
Hold on to output that has been returned from a program that was run inside the VM via the
async_exec
method.
- sync(timeout=5)[source]
Use the guest-sync command to synchronize the buffer.
This works by putting a marker into the buffer and then draining the buffer until the marker is returned. Once the marker has been returned, the buffer is then synchronized.
- Parameters:
timeout (int) – Socket timeout in seconds. Defaults to 5.
- Returns:
A random synchronization token used in the guest-sync request/response exchange. If the sync fails, returns
None
.- Return type:
- Raises:
EnvironmentError – When the QEMU Guest Agent not alive yet.
- write_from_file(filename, local_filename, mode='w')[source]
Given a local filename, open that file to read its data and write that data to a location (provided in filename) in the guest VM.
- Parameters:
- Returns:
True or False indicating success.
- Return type:
- Raises:
OSError – If an issue occurs writing the file.