base_objects

This Model Component contains many of the basic objects necessary to create an experiment using FIREWHEEL. Most importantly, this includes basic objects which create VMs (e.g. VMEndpoint), Switch, graph Edges in the networks (e.g. QoSEdge) and various ScheduleEntry objects. Therefore, this MC will likely be depended on by most FIREWHEEL topologies.

Available Objects

class base_objects.AbstractDesktopEndpoint[source]

Bases: object

This class is used to identify the generic type {server, desktop} for a Vertex which can be useful for knowing what kinds of VMRs can run on the system. Decoration with this object is mutually exclusive from being decorated with base_objects.AbstractServerEndpoint.

__init__()[source]

Check for possible conflicts.

Raises:

TypeError – If the Vertex is already decorated with base_objects.AbstractServerEndpoint.

class base_objects.AbstractServerEndpoint[source]

Bases: object

This class is used to identify the generic type {server, desktop} for a Vertex which can be useful for knowing what kinds of VMRs can run on the system. Decoration with this object is mutually exclusive from being decorated with base_objects.AbstractDesktopEndpoint.

__init__()[source]

Check for possible conflicts.

Raises:

TypeError – If the Vertex is already decorated with base_objects.AbstractDesktopEndpoint.

class base_objects.AbstractUnixEndpoint[source]

Bases: object

This class is used to identify the generic operating system (OS) for a Vertex which can be useful for knowing what kinds of VMRs can run on the system. Decoration with this object is mutually exclusive from being decorated with base_objects.AbstractWindowsEndpoint.

__init__()[source]

Check for possible conflicts.

Raises:

TypeError – If the Vertex is already decorated with base_objects.AbstractWindowsEndpoint.

class base_objects.AbstractWindowsEndpoint[source]

Bases: object

This class is used to identify the generic OS for a Vertex which can be useful for knowing what kinds of VM Resources (VMRs) can run on the system. Decoration with this object is mutually exclusive from being decorated with base_objects.AbstractUnixEndpoint.

__init__()[source]

Check for possible conflicts.

Raises:

TypeError – If the Vertex is already decorated with base_objects.AbstractUnixEndpoint.

class base_objects.DropContentScheduleEntry(start_time, location, content, executable=False, preload_move_cmd=None)[source]

Bases: ScheduleEntry

This class facilitates writing content to a file within the VM. This content is generally dynamically generated based off the current graph.

__annotations__ = {}
__init__(start_time, location, content, executable=False, preload_move_cmd=None)[source]

Create a DropContentScheduleEntry.

Parameters:
  • start_time (int) – Start time of the schedule entry as an integer.

  • location (str) – Absolute, Unix-style path inside the VM to write the provided content, including filename. If the VM is Windows then omit the drive letter. (e.g. /windows/system32)

  • content (str) – Either the content to be written as a string or a Callable object (e.g. a function pointer to a function) that returns a string. The callback function gets called during the base_objects.VmResourceSchedule.get_schedule() method. The vm_resource.schedule model component which then calls get_schedule() for every Vertex in the graph.

  • executable (bool, optional) – Set the new file’s executable flag. Default is False.

  • preload_move_cmd (str, optional) – If set, instead of dropping the content directly into location at start_time, the content will be preloaded into a temporary location prior to any schedule entries running and then moved to location at start_time with preload_move_cmd. Defaults to None. This is particularly useful for placing content into directories which will be created by another VMR.

class base_objects.DropFileScheduleEntry(start_time, location, filename, executable=False, preload_move_cmd=None)[source]

Bases: ScheduleEntry

This class facilitates loading a given file into the VM.

__annotations__ = {}
__init__(start_time, location, filename, executable=False, preload_move_cmd=None)[source]

Create the DropFileScheduleEntry.

Parameters:
  • start_time (int) – Start time of the schedule entry as an integer.

  • location (str) – Absolute, Unix-style path inside the VM to write the provided content, including filename. If the VM is Windows then omit the drive letter. (e.g. /windows/system32)

  • filename (str) – Name of file to be written. 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.

  • executable (bool, optional) – Set the new file’s executable flag. Default is False.

  • preload_move_cmd (str, optional) – If set, instead of dropping the file directly into location at start_time, the file will be preloaded into a temporary location prior to any schedule entries running and then moved to location at start_time with preload_move_cmd. Defaults to None. This is particularly useful for placing files into directories which will be created by another VMR.

class base_objects.FalseEdge[source]

Bases: object

This class is intended to indicate that an Edge is a “false” Edge in the graph. That is, the Edge exists in the graph but won’t be used when the graph is instantiated. This is useful when using complex graph algorithms.

__init__()[source]

Creates self.false and sets it to True.

class base_objects.FileTransferScheduleEntry(in_vm_location, interval=10, start_time=-1000000, out_host_destination=None)[source]

Bases: ScheduleEntry

Facilitates programmatically pulling data out of a VM in an experiment. This is primarily accomplished by leveraging the add_file_transfer method.

__annotations__ = {}
__init__(in_vm_location, interval=10, start_time=-1000000, out_host_destination=None)[source]

Schedule extracting a file from a VM at a specified interval. If the VM is a Linux host then files only get pulled when they have changed (after the initial pull). If the VM is a Windows host then the file/directory will get pulled at every interval.

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:
  • in_vm_location (str) – Path inside the VM to the file or directory to be monitored and extracted from the VM.

  • interval (int, optional) – Interval specifying how often to check for file or directory updates. Defaults to 10. This enables extracting files which are constantly updating (e.g. logs).

  • start_time (int, optional) – When to schedule the transfer. Defaults to -1000000. Because of the highly negative start time, this will almost always run immediately.

  • out_host_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.

class base_objects.Interfaces(prefix='eth')[source]

Bases: object

This object represents a VMs network interfaces. It largely consists of a list of interfaces which are a dictionary of interface-related properties.

__init__(prefix='eth')[source]

Initialize the list of interfaces.

Parameters:

prefix (str, optional) – The default name of the interface (e.g. ens, eth, etc.). Defaults to "eth".

__str__()[source]

A custom string method for Interface Objects.

Returns:

A string representation of an base_objects.Interfaces.

Return type:

str

add_interface(address, netmask, qos=None, switch=None, control_network=False, l2_connection=False)[source]

Add a new interface to the list of interfaces.

Parameters:
  • address (str or netaddr.IPAddress) – The IP address for the interface. An IP address is not strictly required in the case where a new interface is needed but it is not a Layer-3 connection.

  • netmask (str or netaddr.IPAddress) – The netmask for the connecting interface. The netmask can either be in dotted decimal or CIDR (without the slash) notation. That is, both "255.255.255.0" and "24" would represent the same netmask.

  • qos (dict, optional) – A dictionary of QoS-specific parameters. It can include any of the following keys: {"loss", "delay", "rate"}. Defaults to None.

  • switch (base_objects.Switch, optional) – The switch which will be connected to the interface. Defaults to None.

  • control_network (bool, optional) – Identify if the interface will be part of the control network. Defaults to False.

  • l2_connection (bool) – Identify if the interface should be a Layer-2 interface. Defaults to False.

Returns:

A new interface dictionary containing the interface name, address, netmask, network, switch, and QoS dictionary.

Return type:

dict

del_interface(name)[source]

Delete an interface based on the Interfaces name.

Parameters:

name (str) – The name of an interface.

get_interface(name)[source]

Retrieve the interface dictionary with the given name.

Parameters:

name (str) – The name of the interface to return.

Returns:

The requested interface dictionary.

Return type:

dict

rekey_interfaces()[source]

A method to re-key the list of interfaces. That is, assuming the counter is 0, rename the interfaces in the list. This is useful after deleting an interface.

class base_objects.PauseScheduleEntry(start_time, duration=0)[source]

Bases: ScheduleEntry

Create a PAUSE schedule entry for the given VM.

__annotations__ = {}
__init__(start_time, duration=0)[source]

Create a base_objects.PauseScheduleEntry with the given parameters. While a start time of 0 is permitted for this schedule entry, in practice, this entry is really converted to the minimum representable positive normalized float via sys.float_info.min.

Note

When support for Python 3.8 is dropped, this could be converted to the smallest positive denormalized representable float via math.ulp() (e.g., math.ulp(0.0)).

Parameters:
  • start_time (int) – Start time of the schedule entry as an integer.

  • duration (int) – The length of the pause which should happen. If the duration is math.inf than this counts as a break.

Raises:
  • ValueError – If the start time is invalid (i.e., less than 0 and not infinity).

  • ValueError – If the duration is not positive.

class base_objects.QoSEdge[source]

Bases: object

This class can be used to add quality of service (QoS) attributes to a given Edge. It is important to note that these QoS constraints are only applied directionally on the egress side (e.g. transmitting) due to a limitation in minimega.

__init__()[source]

Initialize the qos property for the Edge.

add_delay(delay)[source]

Set the Edge's egress delay (e.g. latency).

Note

For emulation-based models, due to limitations of tc you can only add rate OR loss/delay to a VM. Enabling loss or delay will disable rate and vice versa.

Parameters:

delay (str) – The amount of egress delay to add for the link. This should be formatted like <delay><unit of delay>. For example, 100ms.

add_packet_loss_percent(packet_loss)[source]

Set the Edge's amount of egress packet loss (as a percentage).

Note

For emulation-based models, due to limitations of tc you can only add rate OR loss/delay to a VM. Enabling loss or delay will disable rate and vice versa.

Parameters:

packet_loss (int) – The packet loss as a percentage. For example, packet_loss = 25 is 25% packet loss.

add_rate_limit(rate, unit=None)[source]

Set the Edge's egress rate (e.g. bandwidth). The rate is set as a multiple of bits not bytes. That is, a rate of 1 kbit would equal 1000 bits, not 1000 bytes. For bytes, multiply the rate by 8 (e.g. 64 KBytes = 8 * 64 = 512 kbit).

Note

For emulation-based models, due to limitations of tc you can only add rate OR loss/delay to a VM. Enabling loss or delay will disable rate and vice versa.

Parameters:
  • rate (int) – The requested maximum bandwidth as a multiple of bits.

  • unit (str) – The bandwidth unit (one of {"kbit", "mbit", "gbit"}). Defaults to "mbit".

Raises:

TypeError – If the passed in unit is invalid.

class base_objects.RunExecutableScheduleEntry(start_time, program, arguments=None, vm_resource=False)[source]

Bases: ScheduleEntry

RunExecutableScheduleEntry facilitates specifying a program to run within the VM.

__annotations__ = {}
__init__(start_time, program, arguments=None, vm_resource=False)[source]

Create a base_objects.RunExecutableScheduleEntry with the given parameters.

Parameters:
  • start_time (int) – Start time of the schedule entry as an integer.

  • program (str) – The program to run. Unless vm_resource is set, it is safest to specify the absolute path of the program (in case the program is not on the system’s PATH).

  • arguments (str or list, optional) – Arguments to pass on the command line to the program. Must be a string or list of strings. Defaults to None.

  • vm_resource (bool, optional) – If the program is a VM resource, then the VM resource file needs to be loaded into the VM before it is run. Defaults to False.

class base_objects.Switch(name=None)[source]

Bases: object

Decorate a Vertex as a Switch. Switches represent a Layer 2 network. VMs will appear like they are connected directly to a network switch. In order to connect two (or more) VMs, users must first create a switch to facilitate connection.

Switches will not appear as VMs, but rather as Open vSwitch bridges. To use a physical VM as a “switch” users should refer to layer2.ovs or layer2.tap.

__init__(name=None)[source]

Initialize the Vertex as type=switch.

Parameters:

name (str, optional) – The name of the switch. Defaults to None. This is typically set at the time of Vertex creation.

Raises:

NameError – If the switch doesn’t have a name.

class base_objects.VMEndpoint(name=None)[source]

Bases: object

This class is the base class for all VM-based model components. It creates any necessary VM-based attributes and adds a base_objects.VmResourceSchedule to the Vertex.

This class also provides methods which are useful for all VM objects.

__init__(name=None)[source]

Initialize the VMEndpoint and its associated attributes.

Parameters:

name (str, optional) – The name of the VM. This can also be set on Vertex creation. Defaults to None.

Raises:
name

Every VM must have a unique name. Names must follow conventions of valid hostnames (e.g. cannot contain underscores, spaces, or commas).

Type:

str

vm

A dictionary of VM-related properties. These will be used by other model components to instantiate the graph (e.g. minimega.parse_experiment_graph). Most of these properties will be filled out be other model components either explicitly, or if not defined, a default value is provided. Common VM properties include

Listing 11 An example VM property dictionary.
{
    'image_store': {            # Location of where minimega should find the images
        'path': '/tmp/minimega/files/images',
        'name': 'images'
    },
    'architecture': 'x86_64',   # The CPU architecture
    'vcpu': {
        'model': 'qemu64',      # The QEMU vCPU model number
        'sockets': 1,           # The number of vCPU sockets
        'cores': 1,             # The number of vCPU cores
        'threads': 1            # The number of vCPU threads
    },
    'mem': 256,                 # The amount of memory for the VM
    'drives': [                 # Information about the disk image
        {
            'db_path': 'ubuntu-16.04.4-server-amd64.qcow2.xz',
            'file': 'ubuntu-16.04.4-server-amd64.qcow2',
            'interface': 'virtio',
            'cache': 'writeback'
        }
    ],
    'vga': 'std',               # The type of VGA display to use
    'image': 'ubuntu1604server' # A general image name.
}
Type:

dict

type

The type of the VM. It should be one of {"host", "router", "switch"}. Defaults to "host".

Type:

str

coschedule

The number of other VMs allowed to be schedule on the same host as this VM. A value of 0 means this VM will have its own host, and -1 (default) means there is no limit.

Type:

int

vm_resource_schedule

A new VMR schedule for the Vertex.

Type:

base_objects.VmResourceSchedule

_connect(switch, ip, netmask, delay, rate=None, rate_unit=None, packet_loss=None, control_network=False)[source]

Create a link between this host and the given base_objects.Switch using the given IP address.

Note

For emulation-based models, due to limitations of tc you can only add rate OR loss/delay to a VM. Enabling loss or delay will disable rate and vice versa.

Note

The rate is set as a multiple of bits not bytes. That is, a rate of 1 kbit would equal 1000 bits, not 1000 bytes. For bytes, multiply the rate by 8 (e.g. 64 KBytes = 8 * 64 = 512 kbit).

Parameters:
  • switch (base_objects.Switch) – The switch object to connect to.

  • ip (str or netaddr.IPAddress) – IP address to use on the connecting interface. This will eventually become the IP address on the VM’s interface.

  • netmask (str or netaddr.IPAddress) – The netmask for the connecting interface. The netmask can either be in dotted decimal or CIDR (without the slash) notation. That is, both "255.255.255.0" and "24" would represent the same netmask.

  • delay (str) – The amount of egress delay to add for the link. This should be formatted like <delay><unit of delay>. For example, 100ms. You must add this in the opposing direction if you want it to be bidirectional.

  • rate (int) – The maximum egress transmission rate (e.g. bandwidth of this link) as a multiple of bits. The rate_unit should also be set if the unit is not mbit.

  • rate_unit (str) – The bandwidth unit (one of {'kbit', 'mbit', 'gbit'}). Defaults to "mbit".

  • packet_loss (int) – Percent of packet loss on the link. For example, packet_loss = 25 is 25% packet loss.

  • control_network (bool) – Is this connection to the control network. Defaults to False.

Raises:

TypeError – If the switch is not of type base_objects.Switch.

Returns:

A tuple containing the name of the newly created VM interface and the Edge which connects the VM to a Switch.

Return type:

tuple(str, firewheel.control.experiment_graph.Edge)

add_vm_resource(start_time, vm_resource_name, dynamic_arg=None, static_arg=None)[source]

This method adds a base_objects.VmResourceScheduleEntry object to a Vertex's base_objects.VmResourceSchedule. This provides backwards compatibility for VMRs that were written for pre-2.0 versions of FIREWHEEL.

For VMRs which use this method, they should expect to be passed three file names: dynamic, static, and reboot. The first two files contain the content described in the dynamic_arg and static_arg. Finally, the VMR gets passed the path to a reboot file as their last argument on the command line. If the VMR creates that reboot file then the VM Resource Manager will restart the VM upon completion of the VMR (see Rebooting a VM for more details).

Parameters:
  • start_time (int) – The start time for the VMR. (See Start Time for more details).

  • vm_resource_name (str) – The name of the VMR that should be executed.

  • dynamic_arg (str, optional) – Any is content that is dependent on the configuration of the graph which should be passed to the VMR. This information can change from experiment to experiment. It generally takes the form of an ASCII string or a serialized object (i.e. a dictionary dumped into JSON format via json.dumps()). This content gets written into a file inside the VM and the filename is then passed to the VMR as the first command line parameter. Defaults to None. However if it is not specified, an empty dynamic file path is still passed to the VMR.

  • static_arg (str, optional) – The name of a file that needs to be loaded into the VM. That filename is then passed to the VMR as its second command line option. Static content generally takes the form of an installer or other binary blob that the VMR requires in order to accomplish its purpose. This is something that does not change regardless of the experiment that is using it. Defaults to None. However if it is not specified, an empty static file path is still passed to the VMR.

Returns:

The newly created schedule entry.

Return type:

base_objects.VmResourceScheduleEntry

Examples

The following is a skeleton of an VMR which can use this method. It should be noted that there is no requirement that the VMR is a Python script. It can be any executable as long as it accepts and understands the three command line arguments explained above.

Listing 12 Example VMR which can be used with the add_vm_resource() method.
 1#!/usr/bin/env python3
 2import sys
 3
 4class VmResource(object):
 5
 6    def __init_(self, dynamic_content_filename,
 7            static_filename, reboot_filename):
 8        self.dynamic_content_filename = dynamic_content_filename
 9        self.static_filename = static_filename
10        self.reboot_filename = reboot_filename
11
12    def run(self):
13        # VmResource logic implemented here
14        return 0
15
16if __name__ == '__main__':
17    if len(sys.argv) != 4:
18        print("VmResource did not receive expected arguments")
19        sys.exit(1)
20
21    dynamic_content_filename = sys.argv[1]
22    static_filename = sys.argv[2]
23    reboot_file = sys.argv[3]
24
25    vm_resource = VmResource(dynamic_content_filename, static_filename, reboot_file)
26    # Return with the result of the run method
27    sys.exit(vm_resource.run())

Scheduling this example VMR on a Vertex only requires that we pass the required information to the add_vm_resource() method for the Vertex. In this particular case, we’re assuming that the example VMR above is in a file called ex_vm_resource.py and the requirements in Using VMRs in an Experiment have been satisfied. Since this is just a example, it doesn’t use the arguments passed in, so there is no need to include them in the call to add_vm_resource().

host = Vertex(self.g, "host")
host.decorate(VMEndpoint)
host.add_vm_resource(-10, 'ex_vm_resource.py')

This will run the example VMR at configuration time -10 and it will do nothing but return 0.

connect(switch, ip, netmask, delay=None, rate=None, rate_unit=None, packet_loss=None, control_network=False)[source]

Create a link between this VM and the given base_objects.Switch using the given IP address. This method mostly relies on _connect for the primary logic.

Note

For emulation-based models, due to limitations of tc you can only add rate OR loss/delay to a VM. Enabling loss or delay will disable rate and vice versa.

Note

The rate is set as a multiple of bits not bytes. That is, a rate of 1 kbit would equal 1000 bits, not 1000 bytes. For bytes, multiply the rate by 8 (e.g. 64 KBytes = 8 * 64 = 512 kbit).

Parameters:
  • switch (base_objects.Switch) – The Switch object to connect to.

  • ip (str or netaddr.IPAddress) – IP address to use on the connecting interface. This will eventually become the IP address on the VM’s interface.

  • netmask (str or netaddr.IPAddress) – The netmask for the connecting interface. The netmask can either be in dotted decimal or CIDR (without the slash) notation. That is, both "255.255.255.0" and "24" would represent the same netmask.

  • delay (str) – The amount of egress delay to add for the link. This should be formatted like <delay><unit of delay>. For example, 100ms. You must add this in the opposing direction if you want it to be bidirectional.

  • rate (int) – The maximum egress transmission rate (e.g. bandwidth of this link) as a multiple of bits. The rate_unit should also be set if the unit is not mbit.

  • rate_unit (str) – The bandwidth unit (one of {'kbit', 'mbit', 'gbit'}). Defaults to "mbit".

  • packet_loss (int) – Percent of packet loss on the link. For example, packet_loss = 25 is 25% packet loss.

  • control_network (bool) – Is this connection to the control network. Defaults to False.

Returns:

A tuple containing the name of the newly created VM interface and the Edge which connects the VM to a Switch.

Return type:

tuple(str, firewheel.control.experiment_graph.Edge)

drop_content(start_time, location, content, executable=False, preload=True)[source]

This method is intended to take any string and write it to a specified location on a VM. This method adds a base_objects.DropContentScheduleEntry object to a Vertex's base_objects.VmResourceSchedule.

There are some use cases where content needs to be written to a file inside a VM, but the content can not be generated until all topology changes to the graph have been completed. To handle this situation, content can point to a callback function that returns a string instead of containing the string directly.

Router configuration is a good example of this. The router needs to look at the networks that are connected to it and its routing peers in order to know what must be included in its configuration. Since a router can be created in one model component, but the topology can change in subsequent model components, the router does not have all its required information at creation time. In the case of the VyOS router, its plugin drops a configuration file where the content argument points at a function that will return a string.

All callback functions are executed as part of the base_objects.VmResourceSchedule.get_schedule() method (see VM Resource Schedule). The vm_resource.schedule model component calls base_objects.VmResourceSchedule.get_schedule() for each Vertex in the graph.

Parameters:
  • start_time (int) – The schedule time (positive or negative) of when to perform the content write. (See Start Time for more details).

  • location (str) – The absolute Unix-style path (including filename) on the VM to write the content. For example, to write content to C:\Users\Administrator\Desktop\test.txt inside a Windows VM, the location would need to be /Users/Administrator/Documents/test.txt.

  • content (str) – The content to write out. This can be either a string, a serialized object (via json or pickle), or a function pointer. Function pointers can be passed in the content field for delayed content generation (see the examples below).

  • executable (bool, optional) – Should the file be made executable. This flag is ignored for Windows VMs. Defaults to False.

  • preload (bool, optional) – If set, instead of dropping the content directly into location at start_time, the content will be preloaded into a temporary location prior to any schedule entries running and then moved to location at start_time. Defaults to True. This is particularly useful for placing files into directories which will be created by another VMR.

Returns:

The newly created schedule entry.

Return type:

base_objects.DropContentScheduleEntry

Examples

Drop Content Example with a Callback Function

The following is an example of using drop_content() with a callback function. This is taken from the vyos model component. The callback function is implemented in the model component and is called self._configure_vyos. It returns a string containing the configuration file for the router. That string is then written to /opt/vyatta/etc/config/firewheel-config.sh.

# Path to write the configuration file inside the router
configuration_location = '/opt/vyatta/etc/config/firewheel-config.sh'

# Drop the configuration file on the router.
# This is done by supplying a callback to the ScheduleEntry.
# This will be called when the schedule is being generated to be uploaded
self.drop_content(-100, configuration_location, self._configure_vyos,
    executable=True)

Drop Content Example with a String

The following example is a bit more straightforward. In this case the drop_content() function is provided a string to be written to a file in the VM. Since this example is using a Windows VM, the location for the content is a Unix-style path that translates to C:\Users\User\Desktop\hello.txt in the VM.

host = Vertex(self.g, "host")
host.decorate(WindowsHost)

content = f"Hello World! My hostname is: {self.name}"
host.drop_content(-200, "/Users/User/Desktop/hello.txt", content)
drop_file(start_time, location, filename, executable=False, preload=True)[source]

This method is intended to take a file and load it on to a VM at a specified location. This method adds a base_objects.DropFileScheduleEntry object to a Vertex's base_objects.VmResourceSchedule.

Note

If the file happens to already exist on the VM, it will be overwritten.

Parameters:
  • start_time (int) – The schedule time (positive or negative) of when to execute the dropping of the file. (See Start Time for more details).

  • location (str) – The absolute path (including filename) on the VM to write the file.

  • filename (str) – The local name of the file (i.e. the name of the file within the model component). Since the file must live in the model component, the filename is not a path. Therefore, it should not include any directories in its name.

  • executable (bool, optional) – Should the file have its executable flag set. This flag is ignored for Windows VMs. Defaults to False.

  • preload (bool, optional) – If set, instead of dropping the file directly into location at start_time, the file will be preloaded into a temporary location prior to any schedule entries running and then moved to location at start_time. Defaults to True. This is particularly useful for placing files into directories which will be created by another VMR.

Returns:

The newly created schedule entry.

Return type:

base_objects.DropFileScheduleEntry

Examples

The following example shows dropping a static file on a VM. In this case, a vimrc file is being loaded onto a VM. This example assumes that the model component containing this code has declared vimrc as a VMR in its MANIFEST file and the vimrc file is located within the model component’s directory.

host = Vertex(self.g, "host")
host.decorate(Ubuntu1604Server)
host.drop_file(-200, "/home/ubuntu/.vimrc", "vimrc")
file_transfer(location, interval=60, start_time=1, destination=None)[source]

This method facilitates pulling a file or directory off of a VM at a regular time interval. If the VM is a Linux host then files only get pulled when they have changed (after the initial pull). If the VM is a Windows host then the file/directory will get pulled at every interval.

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) – Absolute path inside the VM to the file or directory to be monitored and pulled off the VM.

  • interval (int, optional) – Time interval in seconds to pull file or directory from the VM.

  • start_time (int, optional) – The schedule time to transfer the file or directory out of the VM.

  • 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.

Returns:

The newly created schedule entry.

Return type:

base_objects.FileTransferScheduleEntry

file_transfer_once(location, start_time=-1, destination=None)[source]

This method facilitates pulling a file or directory off of a VM in an experiment a single time.

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) – Absolute path inside the VM to the file or directory to be monitored and pulled off the VM.

  • start_time (int, optional) – The schedule time to transfer the file or directory out of the VM

  • 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.

Returns:

The newly created schedule entry.

Return type:

base_objects.FileTransferScheduleEntry

l2_connect(switch, mac=None)[source]

Create a Layer 2 link between this host and the given switch using a “blank” IP address.

Parameters:
  • switch (base_objects.Switch) – The switch object to connect to.

  • mac (str, optional) – A specific MAC address for the interface. Defaults to None.

Raises:

TypeError – If the switch is not of type base_objects.Switch.

Returns:

A tuple containing the name of the newly created VM interface and the Edge which connects the VM to a Switch.

Return type:

tuple(str, firewheel.control.experiment_graph.Edge)

run_executable(start_time, program, arguments=None, vm_resource=False)[source]

This method allows a user to specify an executable to run and the arguments to pass to it on the command line. It supports both programs that are natively included in the VM (e.g. /sbin/ip or C:\windows\system32\ipconfig.exe) as well as VM resources. This method adds a base_objects.RunExecutableScheduleEntry object to a Vertex's base_objects.VmResourceSchedule.

Parameters:
  • start_time (int) – The schedule time (positive or negative) of when to execute the specified program. (See Start Time for more details).

  • program (str) – The name of the program or script to run. In general, it’s safer to provide absolute paths for program names instead of relying on the environment of the VM to resolve the name.

  • arguments (str or list, optional) – This field allows a user to provide arguments for the program as either a single string or a list of strings. These get passed to the program on the command line. Defaults to None.

  • vm_resource (bool, optional) – This parameter indicates if program is the name of a script that needs to be loaded on to the VM before execution. If vm_resource is True then the specified program name is assumed to be the local filename of the file (i.e. not the full path, just the filename) to load on to the VM. That is, the file will be located within a model component. Defaults to False.

Returns:

The newly created schedule entry.

Return type:

base_objects.RunExecutableScheduleEntry

Examples

Native Executable Example

To run a program that is native to the VM, specify the Unix-style absolute path to the executable and optionally include arguments. For example, the ipconfig executable on a Windows VM is located at C:\Windows\system32\ipconfig.exe. The required Unix-style path for ipconfig would be /windows/system32/ipconfig.exe. The path being absolute is not strictly required, but it is generally safer than assuming the program is part of the VM’s PATH. For example, the following runs the hostname command on a Linux VM at negative time -100, passing in the name of the host as an argument.

host = Vertex(self.g, "host")
host.decorate(LinuxHost)
host.run_executable(-100, '/sbin/hostname', host.name)

VM Resource Executable Example

Running a VMR file on a VM where arguments can be passed to it via the command line is very similar. The program needs to be the name of the VMR file and the vm_resource flag needs to be set to True. For example, instead of calling the hostname command directly, let’s run a VMR that calls the hostname command and adds the hostname to the /etc/hosts file. The VMR file will be called set_hostname.sh:

echo $1 > /etc/hostname
sed -i '/127.0.0.1/127.0.0.1    localhost '$1 /etc/hosts

Standard VMR requirements for model components apply (see Using VMRs in an Experiment). Executing the set_hostname.sh VMR on a Vertex at time -100 passing in the name of the host as an argument is as follows:

host = Vertex(self.g, "host")
host.decorate(LinuxHost)
host.run_executable(-100, 'set_hostname.sh', host.name, vm_resource=True)
set_break(start_time)[source]

Create a break event for a VM at a given start time. A break event is an indefinitely long PAUSE event. Primarily, pausing will only stop a given VM’s schedule until a RESUME event is processed. To enable a user to trigger a resume (and thereby end the break), FIREWHEEL has a vm resume Helper.

Breaks are useful for enabling users to inspect VMs at a certain point within the experiment. Once the break is complete, the schedule will proceed as expected. More information about breaking and pausing can be found in VM Resource Schedule.

Parameters:

start_time (int) – The time where the break should happen. This should be one of negative math.inf, 0, or any positive time.

Returns:

The created schedule entry.

Return type:

ScheduleEntry

set_default_gateway(interface)[source]

This method sets the default_gateway attribute for VMs associated with the given router’s interface. If the VM host has a router as a neighbor than that router will become the VM’s default gateway. This can be used by other MCs to add the gateway to the VMs interface.

Parameters:

interface (dict) – An interface dictionary (see base_objects.Interfaces).

set_image(image_name)[source]

Add an image property to the VM dictionary. The name of the image is used by minimega.resolve_vm_images to verify that the Vertex has a bootable image. This property should be set by all MCs which add an image to a given model component.

See also

See the Image Creation Tutorial for more details.

Parameters:

image_name (str) – A generic name for the VM’s image (e.g. "ubuntu1604server").

set_pause(start_time, duration=0)[source]

Create a PAUSE event for a VM at a given start time for the given duration. Primarily, pausing will only stop a given VM’s schedule for the specified duration which will enable users to inspect VM’s at a certain point within the experiment. Once the pause is complete, the schedule will proceed as expected. More information about pausing can be found in VM Resource Schedule.

Parameters:
  • start_time (int) – The time where the pause should happen. This should be one of negative math.inf, 0, or any positive time.

  • duration (int) – The length of the pause.

Returns:

The created schedule entry.

Return type:

ScheduleEntry

class base_objects.VmResourceSchedule[source]

Bases: object

This object defines a VM resource schedule which will be used to keep track of all scheduled VM resources for a given VM. It provides methods to add new Schedule entries, retrieve the VM Resource Schedule, and serialize the schedule for use by the VM Resource Handler.

__init__()[source]

Create a new list to store schedule entries.

__str__()[source]

Create a human readable string representation of this object.

Returns:

A string representation of base_objects.VmResourceSchedule.

Return type:

str

add_vm_resource(new_entry)[source]

Add a new ScheduleEntry to the list.

Parameters:

new_entry (firewheel.vm_resource_manager.schedule_entry.ScheduleEntry) – The new VMR schedule entry. This type can also be any sub class of firewheel.vm_resource_manager.schedule_entry.ScheduleEntry.

Raises:

ValueError – If new_entry is not a subclass of firewheel.vm_resource_manager.schedule_entry.ScheduleEntry.

get_schedule()[source]

Retrieve the schedule, but first walk through the schedule entries looking for any that place content into a VM. Because the content field can actually be a callable (see DropContentScheduleEntry and VMEndpoint's drop_content() for more details), this method will check to see if any content is callable, and if so, invoke it in order to generate the string-based content to be used by the VM resource. Lastly, this method modifies all ScheduleEntries to ensure that their class is a ScheduleEntry rather than any subclass type. This facilitates the VM Resource Handler to unpickle the objects correctly.

Returns:

The full list of schedule entries.

Return type:

list

get_serialized_schedule()[source]

Serialize the schedule by pickling each schedule entry and then returning a tuple of pickled schedule entries.

Returns:

A tuple of pickled schedule entries.

Return type:

tuple

class base_objects.VmResourceScheduleEntry(vm_resource_name, start_time, dynamic_contents=None, static_filename=None)[source]

Bases: ScheduleEntry

This class provides backwards compatibility for VMRs that were written for pre-2.0 versions of FIREWHEEL.

Each VMR is provided with three command line arguments: dynamic_content, static_content, and a reboot file.

__annotations__ = {}
__init__(vm_resource_name, start_time, dynamic_contents=None, static_filename=None)[source]

Create a VmResourceScheduleEntry

Parameters:
  • vm_resource_name (str) – Name of VM resource to run. This VMR must be available to the experiment (i.e. must be specified in a model component’s MANIFEST file).

  • start_time (int) – Start time of the VM resource as an integer.

  • dynamic_contents (str, optional) – Content to be passed to the VM resource. Dynamic content gets written to a file and the filename gets passed to the VM resource as the first parameter. Defaults to None.

  • static_filename (str, optional) – File to be passed to the VM resource. The file must be in the VM resource’s database (like the VM resource itself). The file is loaded into the VM and then the file’s path is passed to the VM resource as the second parameter. Defaults to None.