aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rumba/model.py93
-rw-r--r--rumba/testbeds/emulab.py67
-rw-r--r--rumba/testbeds/faketestbed.py2
-rw-r--r--rumba/testbeds/jfed.py78
-rw-r--r--rumba/testbeds/qemu.py3
5 files changed, 88 insertions, 155 deletions
diff --git a/rumba/model.py b/rumba/model.py
index 098930a..0659cb1 100644
--- a/rumba/model.py
+++ b/rumba/model.py
@@ -36,56 +36,9 @@ class Testbed:
self.exp_name = exp_name
@abc.abstractmethod
- def create_experiment(self, nodes, links):
+ def create_experiment(self, experiment):
raise Exception('create_experiment() not implemented')
-
-# Represents an interface on a node
-#
-# @name [string] interface name
-# @ip [int] IP address of that interface
-#
-class Interface:
- def __init__(self, name = "", ip = ""):
- self.name = name
- self.ip = ip
-
- def __repr__(self):
- return self.name
-
-# Represents a link in the physical graph
-#
-# @name [string] Link name
-#
-class Link:
- def __init__(self, name):
- self.name = name
-
- def __repr__(self):
- return self.name
-
-# Represents a point-to-point link in the physical graph
-#
-# @name [string] DIF name
-#
-class P2PLink(Link):
- def __init__(self, name, node_a, node_b,
- int_a = None,
- int_b = None):
- Link.__init__(self, name)
- self.node_a = node_a
- self.node_b = node_b
- if int_a is None:
- int_a = Interface()
- self.int_a = int_a
- if int_b is None:
- int_b = Interface()
- self.int_b = int_b
-
- def __repr__(self):
- return '%s:%s--%s:%s' % (self.node_a.name, self.int_a,
- self.node_b.name, self.int_b)
-
# Base class for DIFs
#
# @name [string] DIF name
@@ -96,6 +49,7 @@ class DIF:
if members is None:
members = list()
self.members = members
+ self.ipcps = list()
def __repr__(self):
s = "DIF %s" % self.name
@@ -359,25 +313,6 @@ class Experiment:
return s
- def get_links(self):
- difs = set()
- links = list()
- for node in self.nodes:
- for dif in node.difs:
- if type(dif) is ShimEthDIF:
- difs.add(dif)
-
- for dif in difs:
- # Point-to-point link
- if len(dif.members) == 2:
- node_a = dif.members[0]
- node_b = dif.members[1]
- link = P2PLink(node_a.name + "-" + node_b.name,
- node_a, node_b)
- links.append(link)
-
- return links
-
def add_node(self, node):
self.nodes.append(node)
self.generate()
@@ -417,7 +352,8 @@ class Experiment:
#print(difsdeps_adj)
#print(difsdeps_inc_cnt)
- # Run Kahn's algorithm to compute topological ordering on the DIFs graph.
+ # Run Kahn's algorithm to compute topological
+ # ordering on the DIFs graph.
frontier = set()
self.dif_ordering = []
for dif in difsdeps_inc_cnt:
@@ -433,11 +369,13 @@ class Experiment:
frontier.add(nxt)
difsdeps_adj[cur] = set()
- circular_set = [dif for dif in difsdeps_inc_cnt if difsdeps_inc_cnt[dif] != 0]
+ circular_set = [dif for dif in difsdeps_inc_cnt \
+ if difsdeps_inc_cnt[dif] != 0]
if len(circular_set):
- raise Exception("Fatal error: The specified DIFs topology has one or more"\
- "circular dependencies, involving the following"\
- " DIFs: %s" % circular_set)
+ raise Exception("Fatal error: The specified DIFs topology" \
+ "has one or more" \
+ "circular dependencies, involving the following" \
+ " DIFs: %s" % circular_set)
print("DIF topological ordering: %s" % self.dif_ordering)
@@ -451,8 +389,8 @@ class Experiment:
dif_graphs[dif] = dict()
first = None
- # For each N-1-DIF supporting this DIF, compute the set of nodes that
- # share such N-1-DIF. This set will be called the 'neighset' of
+ # For each N-1-DIF supporting this DIF, compute the set of nodes
+ # that share such N-1-DIF. This set will be called the 'neighset' of
# the N-1-DIF for the current DIF.
for node in self.nodes:
@@ -482,7 +420,9 @@ class Experiment:
er = []
for node in dif_graphs[dif]:
for edge in dif_graphs[dif][node]:
- er.append("%s --[%s]--> %s" % (node.name, edge[1].name, edge[0].name))
+ er.append("%s --[%s]--> %s" % (node.name,
+ edge[1].name,
+ edge[0].name))
print("DIF graph for %s: %s" % (dif, ', '.join(er)))
if self.enrollment_strategy == 'minimal':
@@ -556,6 +496,7 @@ class Experiment:
break
node.ipcps.append(ipcp)
+ dif.ipcps.append(ipcp)
print("IPCP for node %s: %s" % (node.name, node.ipcps))
@@ -568,7 +509,7 @@ class Experiment:
# Realize the experiment, using a testbed-specific setup
def swap_in(self):
- self.testbed.create_experiment(self.nodes, self.get_links())
+ self.testbed.create_experiment(self)
@abc.abstractmethod
def run(self):
diff --git a/rumba/testbeds/emulab.py b/rumba/testbeds/emulab.py
index cbaa730..c696fbb 100644
--- a/rumba/testbeds/emulab.py
+++ b/rumba/testbeds/emulab.py
@@ -37,7 +37,7 @@ warnings.filterwarnings("ignore")
#
class Testbed(mod.Testbed):
def __init__(self, exp_name, username, password = "",
- proj_name = "ARCFIRE", url = "wall1.ilabt.iminds.be",
+ proj_name = "ARCFIRE", url = "wall2.ilabt.iminds.be",
image = "UBUNTU14-64-STD"):
mod.Testbed.__init__(self, exp_name, username, password, proj_name)
self.url = url
@@ -101,13 +101,12 @@ class Testbed(mod.Testbed):
return output
- def _create_experiment(self, nodes, links):
+ def _create_experiment(self, experiment):
'''
Creates an emulab experiment
@param self: testbed info
- @param nodes: holds the nodes in the experiment
- @param links: holds the links in the experiment
+ @param experiment: the experiment
'''
proj_name = self.proj_name
exp_name = self.exp_name
@@ -121,7 +120,7 @@ class Testbed(mod.Testbed):
except:
print("First experiment to be created for that project.")
- ns = self.generate_ns_script(nodes, links)
+ ns = self.generate_ns_script(experiment)
dest_file_name = '/users/'+ self.username + \
'/temp_ns_file.%s.ns' % os.getpid()
ssh.copy_file_to_testbed(self, self.ops_server(), ns, dest_file_name)
@@ -135,13 +134,12 @@ class Testbed(mod.Testbed):
ssh.execute_command(self, self.ops_server(),'rm ' + dest_file_name)
print("New experiment succesfully created.")
- def generate_ns_script(self, nodes, p2plinks):
+ def generate_ns_script(self, experiment):
'''
Generate ns script based on network graph.
Enables to customize default node image.
- @param nodes: holds the nodes in the experiment
- @param links: holds the links in the experiment
+ @param experiment: the experiment
@param self: testbed info
@return: ns2 script for Emulab experiment
@@ -151,16 +149,19 @@ class Testbed(mod.Testbed):
ns2_script += "set ns [new Simulator]\n"
ns2_script += "source tb_compat.tcl\n"
- for node in nodes:
+ for node in experiment.nodes:
ns2_script += "set " + node.name + " [$ns node]\n"
ns2_script += "tb-set-node-os $" + node.name + " " + \
self.image + "\n"
- for link in p2plinks:
- ns2_script += "set " + link.name + \
+ for dif in experiment.dif_ordering:
+ if type(dif) is mod.ShimEthDIF:
+ if len(dif.ipcps) != 2:
+ continue
+ ns2_script += "set " + dif.name + \
" [$ns duplex-link $" + \
- link.node_a.name + " $" + \
- link.node_b.name + " 1000Mb 0ms DropTail]\n"
+ dif.members[0].name + " $" + \
+ dif.members[1].name + " 1000Mb 0ms DropTail]\n"
ns2_script += "$ns run\n"
@@ -191,16 +192,15 @@ class Testbed(mod.Testbed):
print("Still waiting")
time.sleep(5)
- def complete_experiment_graph(self, nodes, p2plinks):
+ def complete_experiment_graph(self, experiment):
'''
Gets the interface (ethx) to link mapping
@param self: testbed info
- @param nodes: holds the nodes in the experiment
- @param links: holds the links in the experiment
+ @param experiment: the experiment
'''
- node_full_name = self.full_name(nodes[0].name)
+ node_full_name = self.full_name(experiment.nodes[0].name)
cmd = 'cat /var/emulab/boot/topomap'
topomap = ssh.execute_command(self, node_full_name, cmd)
# Almost as ugly as yo momma
@@ -214,31 +214,28 @@ class Testbed(mod.Testbed):
item2 = item2.split(':')
link_name = item2[0]
link_ip = item2[1]
- for link in p2plinks:
- if link.name == link_name:
- if link.node_a.name == node_name:
- link.int_a.ip = link_ip
- elif link.node_b.name == node_name:
- link.int_b.ip = link_ip
-
- for node in nodes:
+ for node in experiment.nodes:
+ if node.name != node_name:
+ continue
+ for ipcp in node.ipcps:
+ if ipcp.dif.name == link_name:
+ ipcp.ip = link_ip
+
+ for node in experiment.nodes:
cmd = 'cat /var/emulab/boot/ifmap'
node_full_name = self.full_name(node.name)
output = ssh.execute_command(self, node_full_name, cmd)
output = re.split('\\\\n', output)
for item in output:
item = item.split()
- for link in p2plinks:
- if link.node_a.name == node.name and \
- link.int_a.ip == item[1]:
- link.int_a.name = item[0]
- elif link.node_b.name == node.name and \
- link.int_b.ip == item[1]:
- link.int_b.name = item[0]
+ for ipcp in node.ipcps:
+ if type(ipcp) is mod.ShimEthIPCP:
+ if ipcp.ip == item[1]:
+ ipcp.ifname = item[0]
node.full_name = self.full_name(node.name)
- def create_experiment(self, nodes, links):
- self._create_experiment(nodes, links)
+ def create_experiment(self, experiment):
+ self._create_experiment(experiment)
self.swap_exp_in()
self.wait_until_nodes_up()
- self.complete_experiment_graph(nodes, links)
+ self.complete_experiment_graph(experiment)
diff --git a/rumba/testbeds/faketestbed.py b/rumba/testbeds/faketestbed.py
index e47eb85..8d5e724 100644
--- a/rumba/testbeds/faketestbed.py
+++ b/rumba/testbeds/faketestbed.py
@@ -26,5 +26,5 @@ class Testbed(mod.Testbed):
password = ""):
mod.Testbed.__init__(self, exp_name, username, password, proj_name)
- def create_experiment(self, nodes, links):
+ def create_experiment(self, experiment):
print("[Fake testbed] experiment swapped in")
diff --git a/rumba/testbeds/jfed.py b/rumba/testbeds/jfed.py
index 92e615f..04c57ba 100644
--- a/rumba/testbeds/jfed.py
+++ b/rumba/testbeds/jfed.py
@@ -35,7 +35,7 @@ class Testbed(mod.Testbed):
self.jfed_jar = jfed_jar
self.exp_hours = exp_hours
- def create_rspec(self, nodes, links):
+ def create_rspec(self, experiment):
self.rspec = self.exp_name + ".rspec"
impl = xml.getDOMImplementation()
@@ -66,7 +66,7 @@ class Testbed(mod.Testbed):
"resources/rspec/3 http://www.geni.net/" +
"resources/rspec/3/request.xsd")
- for node in nodes:
+ for node in experiment.nodes:
el = doc.createElement("node")
top_el.appendChild(el)
el.setAttribute("client_id", node.name)
@@ -78,50 +78,41 @@ class Testbed(mod.Testbed):
el2.setAttribute("name", "raw-pc")
node.ifs = 0
- for link in links:
- if link.node_a == node or link.node_b == node:
+ for ipcp in node.ipcps:
+ if type(ipcp) is mod.ShimEthIPCP:
el3 = doc.createElement("interface")
- if link.node_a == node:
- link.int_a.id = node.name + ":if" + str(node.ifs)
- link_id = link.int_a.id
- if link.node_b == node:
- link.int_b.id = node.name + ":if" + str(node.ifs)
- link_id = link.int_b.id
-
- el3.setAttribute("client_id", link_id)
+ ipcp.if_id = node.name + ":if" + str(node.ifs)
+ el3.setAttribute("client_id", ipcp.if_id)
node.ifs += 1
el.appendChild(el3)
- for link in links:
- el = doc.createElement("link")
- top_el.appendChild(el)
- el.setAttribute("client_id", link.name)
-
- el2 = doc.createElement("component_manager_id")
- el2.setAttribute("name", self.authority)
- el.appendChild(el2)
+ for dif in experiment.dif_ordering:
+ if type(dif) is mod.ShimEthDIF:
+ el = doc.createElement("link")
+ top_el.appendChild(el)
+ el.setAttribute("client_id", dif.name)
- el3 = doc.createElement("interface_ref")
- el3.setAttribute("client_id", link.int_a.id)
- el.appendChild(el3)
+ el2 = doc.createElement("component_manager_id")
+ el2.setAttribute("name", self.authority)
+ el.appendChild(el2)
- el4 = doc.createElement("interface_ref")
- el4.setAttribute("client_id", link.int_b.id)
- el.appendChild(el4)
+ for ipcp in dif.ipcps:
+ el3 = doc.createElement("interface_ref")
+ el3.setAttribute("client_id", ipcp.if_id)
+ el.appendChild(el3)
file = open(self.rspec, "w")
file.write(doc.toprettyxml())
file.close()
- def create_experiment(self, nodes, links):
- self.create_rspec(nodes, links)
+ def create_experiment(self, experiment):
+ self.create_rspec(experiment)
self.manifest = self.exp_name + ".rrspec"
- for node in nodes:
+ for node in experiment.nodes:
auth_name_r = self.auth_name.replace(".", "-")
node.full_name = node.name + "." + self.exp_name + "." + \
- self.proj_name + "." + auth_name_r + \
- "." + self.auth_name
+ auth_name_r + "." + self.auth_name
subprocess.call(["java", "-jar", self.jfed_jar, "create", "-S", \
self.proj_name, "--rspec", \
@@ -136,17 +127,22 @@ class Testbed(mod.Testbed):
rspec = xml.parse(self.manifest)
xml_nodes = rspec.getElementsByTagName("node")
+ # Complete details of the nodes after swapin
for xml_node in xml_nodes:
n_name = xml_node.getAttribute("client_id")
intfs = xml_node.getElementsByTagName("interface")
- for link in links:
- if link.node_a.name == n_name:
- interface = link.int_a
- if link.node_b.name == n_name:
- interface = link.int_b
+
+ for node in experiment.nodes:
+ if node.name == n_name:
+ node_n = node
+
for intf in intfs:
- comp_id = intf.getAttribute("component_id")
- comp_arr = comp_id.split(":")
- interface.name = comp_arr[-1]
- xml_ip = intf.getElementsByTagName("ip")
- interface.ip = xml_ip[0].getAttribute("address")
+ i_name = intf.getAttribute("client_id")
+ for ipcp in node_n.ipcps:
+ if type(ipcp) is mod.ShimEthIPCP:
+ if ipcp.if_id == i_name:
+ comp_id = intf.getAttribute("component_id")
+ comp_arr = comp_id.split(":")
+ ipcp.ifname = comp_arr[-1]
+ #xml_ip = intf.getElementsByTagName("ip")
+ #interface.ip = xml_ip[0].getAttribute("address")
diff --git a/rumba/testbeds/qemu.py b/rumba/testbeds/qemu.py
index d44bb3e..3f4cb4a 100644
--- a/rumba/testbeds/qemu.py
+++ b/rumba/testbeds/qemu.py
@@ -26,8 +26,7 @@ class Testbed(mod.Testbed):
password = ""):
mod.Testbed.__init__(self, exp_name, username, password, proj_name)
- def create_experiment(self, nodes, links):
- print(links)
+ def create_experiment(self, experiment):
print("[QEMU testbed] experiment swapped in")
def __del__(self):