Creating the Simple Server Topology
Recall that the network will look like:
The actual code that builds the topology is the Simple Server Model Component’s plugin
which we specified as plugin.py
in the MANIFEST
file.
Therefore, open the file /opt/firewheel/model_components/simple_server/plugin.py
to get started.
Opening Our Plugin
Within every plugin file, FIREWHEEL automatically looks for a plugin class to define the plugin’s execution. This class must meet two criteria.
First, the class that gets declared must inherit from AbstractPlugin
.
This guarantees that the Experiment Graph instance is properly handled and located in the variable self.g
.
Additionally, this inheritance also provides a logger in self.log
to each plugin to facilitate easy debugging.
Second, the plugin must have a run
method.
This is the method that gets invoked by FIREWHEEL to kick off the plugin.
The run
method can also take parameters, if needed, for the topology.
As a note, only one such plugin class may be defined per plugin file (more would be ambiguous and therefore will cause FIREWHEEL to raise an error).
With this context in mind, we will be editing the run
method first.
Open the file /opt/firewheel/model_components/simple_server/plugin.py
to get started.
It should look something like this:
from firewheel.control.experiment_graph import AbstractPlugin, Vertex class Plugin(AbstractPlugin): """tutorials.simple_server plugin documentation.""" def run(self): """Run method documentation.""" # TODO: Implement plugin actions here pass
Implementing the Plugin
We will start by just creating the topology and then adding the necessary VM resources to provide the web server and client with the necessary functionality.
Set up
Before working on any particular part of the topology, we should first add a few necessary import statements.
Add the following to the top of plugin.py
.
from base_objects import Switch
from linux.ubuntu1604 import Ubuntu1604Server
These imports provide the necessary graph objects needed to create the topology.
Adding the Basic Topology
We create a vertex by instantiating a Vertex
object and passing it the graph (self.g
) as well as the name of the vertex.
The plugin.py
template has already imported Vertex
for you from firewheel.control.experiment_graph
.
Once we have created a Vertex
, we can decorate it as a specific object type.
In this case, we want the server to be a Ubuntu 16.04 server.
We have imported the the Ubuntu1604Server
object already (from the linux.ubuntu1604_mc MC) so we can use it to decorate our server.
def run(self):
"""Run method documentation."""
# Create the Server
server = Vertex(self.g, name="Server")
server.decorate(Ubuntu1604Server)
In FIREWHEEL Switches
are essentially virtual network bridges which help connect two VMs.
Users can make a Switch into a VM if some specific switching technique is being evaluated, but typically, they will just be instantiated as an Open vSwitch bridge.
A Switch
is created in a way that is very similar to the routers.
The only difference is that we decorate the Vertex
with Switch
.
Switches
can be imported from base_objects_mc.
We can now create our switch.
def run(self):
"""Run method documentation."""
# Create the Server
server = Vertex(self.g, name="Server")
server.decorate(Ubuntu1604Server)
# Create the switch
switch = Vertex(self.g, name="Switch")
switch.decorate(Switch)
Now that we have the Switch
and the server, we can connect them together.
Initially, we will use a hard-coded IP address.
Note
For more complex topologies, we recommend using netaddr
to generate IP address. As we add more clients later in this tutorial, we will switch to using it.
Note
While we use IPv4 addresses for this tutorial, FIREWHEEL is also capable of using IPv6 addresses.
def run(self):
"""Run method documentation."""
# Create the Server
server = Vertex(self.g, name="Server")
server.decorate(Ubuntu1604Server)
# Create the switch
switch = Vertex(self.g, name="Switch")
switch.decorate(Switch)
# Connect the server and the switch
server.connect(
switch, # The Switch Vertex
"1.0.0.1", # The IP address for the server
"255.255.255.0" # The subnet mask for the IP address network
)
We then do the same thing to create the client and connect it to the switch.
# Create the client
client = Vertex(self.g, name="Client")
client.decorate(Ubuntu1604Server)
# Connect the client and the switch
client.connect(
switch, # The Switch Vertex
"1.0.0.2", # The IP address for the client
"255.255.255.0" # The subnet mask for the IP address network
)
Completed Initial Topology
The full plugin.py
now looks like:
from firewheel.control.experiment_graph import AbstractPlugin, Vertex
from base_objects import Switch
from linux.ubuntu1604 import Ubuntu1604Server
class Plugin(AbstractPlugin):
"""tutorials.simple_server plugin documentation."""
def run(self):
"""Run method documentation."""
# Create the Server
server = Vertex(self.g, name="Server")
server.decorate(Ubuntu1604Server)
# Create the switch
switch = Vertex(self.g, name="Switch")
switch.decorate(Switch)
# Connect the server and the switch
server.connect(
switch, # The Switch Vertex
"1.0.0.1", # The IP address for the server
"255.255.255.0" # The subnet mask for the IP address network
)
# Create the client
client = Vertex(self.g, name="Client")
client.decorate(Ubuntu1604Server)
# Connect the client and the switch
client.connect(
switch, # The Switch Vertex
"1.0.0.2", # The IP address for the client
"255.255.255.0" # The subnet mask for the IP address network
)