aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Capitani <m.capitani@nextworks.it>2017-06-07 11:08:39 +0200
committerMarco Capitani <m.capitani@nextworks.it>2017-06-07 11:08:39 +0200
commitd62b0595ab660d6c23ab24bd94cd79453f0129ff (patch)
tree06e6db10120307f9091db907cfc562384110bc9d
parent77dccda7380679447fd8ad3176d239901301ba16 (diff)
parentdb18f01116739a2854c4305a7ad72da8c56d446d (diff)
downloadrumba-d62b0595ab660d6c23ab24bd94cd79453f0129ff.tar.gz
rumba-d62b0595ab660d6c23ab24bd94cd79453f0129ff.zip
Merge branch 'master' into jfed-irati-fixes
-rw-r--r--README.md68
-rw-r--r--examples/mouse.py105
-rwxr-xr-xexamples/two-layers.py10
-rw-r--r--rumba/model.py83
-rw-r--r--rumba/prototypes/irati.py13
-rw-r--r--rumba/prototypes/ouroboros.py28
-rw-r--r--rumba/prototypes/rlite.py13
-rw-r--r--rumba/ssh_support.py45
-rw-r--r--rumba/testbeds/jfed.py7
-rw-r--r--rumba/testbeds/qemu.py24
-rwxr-xr-xtools/rumba-access31
11 files changed, 312 insertions, 115 deletions
diff --git a/README.md b/README.md
index 9bd7d38..cbe1015 100644
--- a/README.md
+++ b/README.md
@@ -3,17 +3,20 @@
Rumba is part of ARCFIRE 2020, Work Package 3. It is a framework in
Python which allows user to write a Python script to define a RINA
network. The physical graph needed for this RINA network is then
-calculated and realised on one of the supported testbeds. Next, one of
-the supported RINA prototypes is installed. After installation, the
-network is bootstrapped. For an example of such a Python script, have
-a look at the examples/ folder.
+calculated and realised on one of the supported testbeds. Next, if the
+user requests this, one of the supported RINA prototypes is
+installed. The network is then bootstrapped on the available
+nodes. Finally, the experiment can be swapped out of the testbed. For
+an example of such a Python script, have a look at the examples/
+folder.
## Workflow, both external and internal:
1. User defines the network graph, creating instances of model.Node
- and model.DIF classes
+ and model.DIF classes
- 2. User creates an instance of a Testbed class
+ 2. User creates an instance of a Testbed class. See below for
+ testbed specific configuration
3. User creates an instance of prototype.Experiment class, passing
the testbed instance and a list of Node instances
@@ -23,17 +26,19 @@ a look at the examples/ folder.
per-node IPCPs, registrations and enrollment, ready to be
used by the plugins
- 4. User calls run() on the prototype.Experiment instance:
+ 4. User calls methods on the prototype.Experiment instance:
- 1. run() calls Testbed.swap_in(), passing the Experiment, and
- filling in the missing information
+ 1. swap_in() swaps the experiment in on the testbed, and fills in
+ the missing information in the model.
- 2. run() calls a prototype-specific setup function, to create the
- required IPCPs, perform registrations, enrollments, etc.
+ 2. install_prototype() installs the chosen prototype on the
+ testbed. Currently an Ubuntu image is assumed.
- 3. Perform tests (TODO)
+ 3. bootstrap_prototype() calls a prototype-specific setup function,
+ to create the required IPCPs, perform registrations,
+ enrollments, etc.
- 4. run() calls Testbed.swap_out()
+ 4. swap_out() swaps the experiment out of the testbed.
## Installation
@@ -69,10 +74,30 @@ a look at the examples/ folder.
* [QEMU](http://wiki.qemu-project.org/Main_Page) is a generic and
open source machine emulator and virtualizer.
+ A minimal QEMU testbed is defined as follows:
+
+ tb = qemu.Testbed(exp_name = "twolayers",
+ username = "root",
+ password = "root")
+
+ A user can optionally also specify the path to a bzImage and to an
+ initramfs. If they are not specified, the latest buildroot image
+ for the specific prototype will be downloaded. (Around 40 MB in
+ size) The login to those images is root/root.
+
* [Emulab](https://www.emulab.net/) is a network testbed, giving
researchers a wide range of environments in which to develop,
debug, and evaluate their systems.
+ An emulab testbed instance is defined as follows:
+
+ tb = emulab.Testbed(exp_name = "rochefort10",
+ username = "ricksanchez")
+
+ A password can also be provided but is not necessary when an SSH
+ key has been added. Optionally, a project name, a different testbed
+ URL and a custom image can be specified.
+
* [jFed](http://jfed.iminds.be/) is a Java-based framework for
testbed federation.
@@ -89,7 +114,8 @@ a look at the examples/ folder.
Here the experiment name is rochefort10, the user's name is
ricksanchez, and the certificate can be found in
- /home/morty/cert.pem. An absolute path must be used for cert_file.
+ /home/morty/cert.pem. An absolute path must be used for
+ cert_file. Optionally a custom image can be selected.
Before running the rumba you must run an SSH agent in same terminal.
This will also avoid you having to enter the passphrase for every
@@ -102,15 +128,15 @@ a look at the examples/ folder.
$ eval `ssh-agent`
$ ssh-add /home/morty/cert.pem
- To access a node once the experiment swapped in, use the following
- command (in the same terminal where ssh-agent was run):
+ To access a node once the experiment swapped in, use the following
+ command (in the same terminal where ssh-agent was run):
- $ ssh -A -oProxyCommand="ssh -i $CERTPATH
+ $ ssh -A -oProxyCommand="ssh -i $CERTPATH
-o StrictHostKeyChecking=no $USER@bastion.test.iminds.be
nc $NODENAME.$EXP.wall2-ilabt-iminds-be.wall2.ilabt.iminds.be 22"
$USER@$NODENAME.$EXP.wall2-ilabt-iminds-be.wall2.ilabt.iminds.be
- where $CERTPATH is the absolute path of the certificate (e.g.
- /home/morty/cert.pem), $USER is the jFed username (e.g. "ricksanchez"),
- $NODENAME is the name of the node you want to access (e.g. "a"),
- and $EXP is the name of the experiment (e.g. "rochefort10").
+ where $CERTPATH is the absolute path of the certificate (e.g.
+ /home/morty/cert.pem), $USER is the jFed username (e.g. "ricksanchez"),
+ $NODENAME is the name of the node you want to access (e.g. "a"),
+ and $EXP is the name of the experiment (e.g. "rochefort10").
diff --git a/examples/mouse.py b/examples/mouse.py
new file mode 100644
index 0000000..25e2487
--- /dev/null
+++ b/examples/mouse.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+
+# An example script using the rumba package
+
+from rumba.model import *
+
+# import testbed plugins
+import rumba.testbeds.emulab as emulab
+import rumba.testbeds.jfed as jfed
+import rumba.testbeds.faketestbed as fake
+import rumba.testbeds.qemu as qemu
+
+# import prototype plugins
+import rumba.prototypes.ouroboros as our
+import rumba.prototypes.rlite as rl
+import rumba.prototypes.irati as irati
+
+n01 = NormalDIF("n01")
+
+e01 = ShimEthDIF("e01")
+e02 = ShimEthDIF("e02")
+e03 = ShimEthDIF("e03")
+e04 = ShimEthDIF("e04")
+e05 = ShimEthDIF("e05")
+e06 = ShimEthDIF("e06")
+e07 = ShimEthDIF("e07")
+e08 = ShimEthDIF("e08")
+e09 = ShimEthDIF("e09")
+e10 = ShimEthDIF("e10")
+e11 = ShimEthDIF("e11")
+e12 = ShimEthDIF("e12")
+e13 = ShimEthDIF("e13")
+e14 = ShimEthDIF("e14")
+e15 = ShimEthDIF("e15")
+e16 = ShimEthDIF("e16")
+e17 = ShimEthDIF("e17")
+
+
+a = Node("a",
+ difs = [n01, e01, e06, e13 ],
+ dif_registrations = {n01 : [e01, e06, e13]})
+
+b = Node("b",
+ difs = [n01, e01, e02, e04],
+ dif_registrations = {n01 : [e01, e02, e04]})
+
+c = Node("c",
+ difs = [n01, e02, e03],
+ dif_registrations = {n01 : [e02, e03]})
+
+d = Node("d",
+ difs = [n01, e03, e04, e05],
+ dif_registrations = {n01 : [e03, e04, e05]})
+
+e = Node("e",
+ difs = [n01, e05, e06, e07],
+ dif_registrations = {n01 : [e05, e06, e07]})
+
+f = Node("f",
+ difs = [n01, e07, e08],
+ dif_registrations = {n01 : [e07, e08]})
+
+g = Node("g",
+ difs = [n01, e08, e09, e14],
+ dif_registrations = {n01 : [e08, e09, e14]})
+
+h = Node("h",
+ difs = [n01, e09, e10, e15],
+ dif_registrations = {n01 : [e09, e10, e15]})
+
+i = Node("i",
+ difs = [n01, e10, e11, e16],
+ dif_registrations = {n01 : [e10, e11, e16]})
+
+j = Node("j",
+ difs = [n01, e11, e12],
+ dif_registrations = {n01 : [e11, e12]})
+
+k = Node("k",
+ difs = [n01, e12, e13],
+ dif_registrations = {n01 : [e12, e13]})
+
+l = Node("l",
+ difs = [n01, e14, e15],
+ dif_registrations = {n01 : [e14, e15]})
+
+m = Node("m",
+ difs = [n01, e16, e17],
+ dif_registrations = {n01 : [e16, e17]})
+
+n = Node("n",
+ difs = [n01, e17],
+ dif_registrations = {n01 : [e17]})
+
+tb = jfed.Testbed(exp_name = "mouse2",
+ cert_file = "/home/sander/cert.pem",
+ username = "sander")
+
+exp = rl.Experiment(tb, nodes = [a, b, c, d, e, f, g, h, i, j, k, l, m, n])
+
+print(exp)
+
+exp.swap_in()
+exp.install_prototype()
+exp.bootstrap_prototype()
diff --git a/examples/two-layers.py b/examples/two-layers.py
index 9d1a6b3..b3622fd 100755
--- a/examples/two-layers.py
+++ b/examples/two-layers.py
@@ -32,9 +32,7 @@ e3 = ShimEthDIF("e3")
a = Node("a",
difs = [n3, n4, n1, e1],
- dif_registrations = {n4: [n1], n3: [n1], n1 : [e1]},
- registrations = {"rinaperf.server" : [n3]},
- bindings = {"rinaperf.server" : "/usr/bin/rinaperf"})
+ dif_registrations = {n4: [n1], n3: [n1], n1 : [e1]})
b = Node("b",
difs = [n1, e1, e2],
@@ -50,11 +48,9 @@ d = Node("d",
tb = qemu.Testbed(exp_name = "twolayers",
username = "root",
- password = "root",
- bzimage = '/home/vmaffione/git/rlite/demo/buildroot/bzImage',
- initramfs = '/home/vmaffione/git/rlite/demo/buildroot/rootfs.cpio')
+ password = "root")
-exp = rl.Experiment(tb, nodes = [a, b, c, d])
+exp = irati.Experiment(tb, nodes = [a, b, c, d])
print(exp)
diff --git a/rumba/model.py b/rumba/model.py
index 285d937..941cba8 100644
--- a/rumba/model.py
+++ b/rumba/model.py
@@ -38,11 +38,17 @@ logger = log.get_logger(__name__)
# @exp_name [string] experiment name
#
class Testbed:
- def __init__(self, exp_name, username, password, proj_name):
+ def __init__(self,
+ exp_name,
+ username,
+ password,
+ proj_name,
+ http_proxy=None):
self.username = username
self.password = password
self.proj_name = proj_name
self.exp_name = exp_name
+ self.http_proxy = http_proxy
@abc.abstractmethod
def swap_in(self, experiment):
@@ -150,12 +156,10 @@ class SSHConfig:
#
# @difs: DIFs the node will have an IPCP in
# @dif_registrations: Which DIF is registered in which DIF
-# @registrations: Registrations of names in DIFs
-# @bindings: Binding of names on the processing system
#
class Node:
def __init__(self, name, difs=None, dif_registrations=None,
- registrations=None, bindings=None, client=False):
+ client=False):
self.name = name
if difs is None:
difs = list()
@@ -165,12 +169,6 @@ class Node:
if dif_registrations is None:
dif_registrations = dict()
self.dif_registrations = dif_registrations
- if registrations is None:
- registrations = dict()
- self.registrations = registrations
- if bindings is None:
- bindings = dict()
- self.bindings = bindings
self.ssh_config = SSHConfig(name)
self.ipcps = []
self.client = client
@@ -188,17 +186,13 @@ class Node:
"to be part of DIF %s" % (self.name, dif.name))
def _validate(self):
- # Check that DIFs referenced in self.dif_registrations and
- # in self.registrations are part of self.difs
+ # Check that DIFs referenced in self.dif_registrations
+ # are part of self.difs
for upper in self.dif_registrations:
self._undeclared_dif(upper)
for lower in self.dif_registrations[upper]:
self._undeclared_dif(lower)
- for appl in self.registrations:
- for dif in self.registrations[appl]:
- self._undeclared_dif(dif)
-
def __repr__(self):
s = "Node " + self.name + ":\n"
@@ -217,19 +211,6 @@ class Node:
s += ", ".join(rl)
s += " ]\n"
- s += " Name registrations: [ "
- for name in self.registrations:
- difs = self.registrations[name]
- s += "%s => [ " % name
- s += ", ".join([dif.name for dif in difs])
- s += " ]"
- s += " ]\n"
-
- s += " Bindings: [ "
- s += ", ".join(["'%s' => '%s'" % (ap, self.bindings[ap])
- for ap in self.bindings])
- s += " ]\n"
-
return s
def __hash__(self):
@@ -259,22 +240,6 @@ class Node:
self.dif_registrations[upper].remove(lower)
self._validate()
- def add_registration(self, name, dif):
- self.dif_registrations[name].append(dif)
- self._validate()
-
- def del_registration(self, name, dif):
- self.dif_registrations[name].remove(dif)
- self._validate()
-
- def add_binding(self, name, ap):
- self.bindings[name] = ap
- self._validate()
-
- def del_binding(self, name):
- del self.bindings[name]
- self._validate()
-
# Base class representing an IPC Process to be created in the experiment
#
@@ -363,6 +328,10 @@ class Experiment:
difsdeps_inc = dict()
for node in self.nodes:
+ for dif in node.difs:
+ if dif not in difsdeps_adj:
+ difsdeps_adj[dif] = set()
+
for upper in node.dif_registrations:
for lower in node.dif_registrations[upper]:
if upper not in difsdeps_inc:
@@ -384,6 +353,14 @@ class Experiment:
difsdeps_inc_cnt[dif] = len(difsdeps_inc[dif])
del difsdeps_inc
+ # Init difsdeps_inc_cnt for those DIFs that do not
+ # act as lower IPCPs nor upper IPCPs for registration
+ # operations
+ for node in self.nodes:
+ for dif in node.difs:
+ if dif not in difsdeps_inc_cnt:
+ difsdeps_inc_cnt[dif] = 0
+
# Run Kahn's algorithm to compute topological
# ordering on the DIFs graph.
frontier = set()
@@ -543,6 +520,13 @@ class Experiment:
if not ipcp.dif_bootstrapper:
break
+ def dump_ssh_info(self):
+ f = open('ssh_info', 'w')
+ for node in self.nodes:
+ f.write("%s %s %s %s\n" % (node.name, self.testbed.username,
+ node.ssh_config.hostname, node.ssh_config.port))
+ f.close()
+
# Examine the nodes and DIFs, compute the registration and enrollment
# order, the list of IPCPs to create, registrations, ...
def generate(self):
@@ -555,15 +539,20 @@ class Experiment:
@abc.abstractmethod
def install_prototype(self):
- raise Exception('run_prototype() method not implemented')
+ raise Exception('install_prototype() method not implemented')
@abc.abstractmethod
def bootstrap_prototype(self):
- raise Exception('run_prototype() method not implemented')
+ raise Exception('bootstrap_prototype() method not implemented')
+
+ @abc.abstractmethod
+ def prototype_name(self):
+ raise Exception('prototype_name() method not implemented')
def swap_in(self):
# Realize the experiment testbed (testbed-specific)
self.testbed.swap_in(self)
+ self.dump_ssh_info()
def swap_out(self):
# Undo the testbed (testbed-specific)
diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py
index c47d0d2..1e75efc 100644
--- a/rumba/prototypes/irati.py
+++ b/rumba/prototypes/irati.py
@@ -36,6 +36,9 @@ logger = log.get_logger(__name__)
# An experiment over the IRATI implementation
class Experiment(mod.Experiment):
+ def prototype_name(self):
+ return 'irati'
+
@staticmethod
def real_sudo(s):
return 'sudo ' + s
@@ -82,7 +85,7 @@ class Experiment(mod.Experiment):
+ self.sudo("./install-from-scratch")]
for node in self.nodes:
- ssh.execute_commands(self.testbed, node.ssh_config,
+ ssh.execute_proxy_commands(self.testbed, node.ssh_config,
cmds, time_out=None)
def setup(self):
@@ -230,16 +233,10 @@ class Experiment(mod.Experiment):
next_vlan += 10
self.shim2vlan[dif.name] = vlan
- # TODO: what format are the mappings registered in? Is this ok?
- app_mappings = []
- for node in self.nodes:
- app_mappings += [{'name': app, 'dif': self.dif_name(dif)}
- for app in node.registrations
- for dif in node.registrations[app]]
-
# If some app directives were specified, use those to build da.map.
# Otherwise, assume the standard applications are to be mapped in
# the DIF with the highest rank.
+ app_mappings = []
if len(app_mappings) == 0:
if len(self.dif_ordering) > 0:
for adm in \
diff --git a/rumba/prototypes/ouroboros.py b/rumba/prototypes/ouroboros.py
index 9c164e7..9ac1425 100644
--- a/rumba/prototypes/ouroboros.py
+++ b/rumba/prototypes/ouroboros.py
@@ -32,6 +32,9 @@ class Experiment(mod.Experiment):
def __init__(self, testbed, nodes=None):
mod.Experiment.__init__(self, testbed, nodes)
+ def prototype_name(self):
+ return 'ouroboros'
+
def setup_ouroboros(self):
for node in self.nodes:
ssh.execute_command(self.testbed, node.ssh_config,
@@ -50,27 +53,6 @@ class Experiment(mod.Experiment):
ssh.execute_commands(self.testbed, node.ssh_config,
cmds, time_out=None)
- def bind_names(self):
- for node in self.nodes:
- cmds = list()
- for name, ap in node.bindings.items():
- cmds.append("irm b ap " + ap + " n " + name)
-
- ssh.execute_commands(self.testbed, node.ssh_config,
- cmds, time_out=None)
-
- def reg_names(self):
- for node in self.nodes:
- cmds = list()
- for name, difs in node.registrations.items():
- cmd = "irm r n " + name
- for dif in difs:
- cmd += " dif " + dif.name
- cmds.append(cmd)
-
- ssh.execute_commands(self.testbed, node.ssh_config, cmds,
- time_out=None)
-
def create_ipcps(self):
for node in self.nodes:
cmds = list()
@@ -147,12 +129,8 @@ class Experiment(mod.Experiment):
def bootstrap_prototype(self):
logger.info("Starting IRMd on all nodes...")
self.setup_ouroboros()
- logger.info("Binding names...")
- self.bind_names()
logger.info("Creating IPCPs")
self.create_ipcps()
logger.info("Enrolling IPCPs...")
self.enroll_ipcps()
- logger.info("Registering names...")
- self.reg_names()
logger.info("All done, have fun!")
diff --git a/rumba/prototypes/rlite.py b/rumba/prototypes/rlite.py
index 625668d..cc38255 100644
--- a/rumba/prototypes/rlite.py
+++ b/rumba/prototypes/rlite.py
@@ -34,10 +34,17 @@ class Experiment(mod.Experiment):
def __init__(self, testbed, nodes=None):
mod.Experiment.__init__(self, testbed, nodes)
+ def prototype_name(self):
+ return 'rlite'
+
def execute_commands(self, node, cmds):
ssh.execute_commands(self.testbed, node.ssh_config,
cmds, time_out=None)
+ def execute_proxy_commands(self, node, cmds):
+ ssh.execute_proxy_commands(self.testbed, node.ssh_config,
+ cmds, time_out=None)
+
# Prepend sudo to all commands if the user is not 'root'
def may_sudo(self, cmds):
if self.testbed.username != 'root':
@@ -117,17 +124,17 @@ class Experiment(mod.Experiment):
def install_prototype(self):
logger.info("installing rlite on all nodes")
cmds = ["sudo apt-get update",
- "export https_proxy=\"https://proxy.atlantis.ugent.be:8080\"; sudo -E apt-get install g++ gcc cmake "
+ "sudo -E apt-get install g++ gcc cmake "
"linux-headers-$(uname -r) "
"protobuf-compiler libprotobuf-dev git --yes",
"rm -rf ~/rlite",
- "cd ~; export https_proxy=\"https://proxy.atlantis.ugent.be:8080\"; git clone https://github.com/vmaffione/rlite",
+ "cd ~; git clone https://github.com/vmaffione/rlite",
"cd ~/rlite && ./configure && make && sudo make install",
"cd ~/rlite && sudo make depmod"
]
for node in self.nodes:
- self.execute_commands(node, cmds)
+ self.execute_proxy_commands(node, cmds)
logger.info("installation complete")
def bootstrap_prototype(self):
diff --git a/rumba/ssh_support.py b/rumba/ssh_support.py
index cb36910..f8ba03b 100644
--- a/rumba/ssh_support.py
+++ b/rumba/ssh_support.py
@@ -43,6 +43,51 @@ def _print_stream(stream):
return o
+def execute_proxy_commands(testbed, ssh_config, commands, time_out=3):
+ """
+ Remote execution of a list of shell command on hostname, using the
+ http and https proxy specified by the testbed. By
+ default this function will exit (timeout) after 3 seconds.
+
+ @param testbed: testbed info
+ @param ssh_config: ssh config of the node
+ @param commands: *nix shell command
+ @param time_out: time_out value in seconds, error will be generated if
+ no result received in given number of seconds, the value None can
+ be used when no timeout is needed
+ """
+ new_commands = []
+ for command in commands:
+ proxy = testbed.http_proxy
+ if proxy is not None:
+ proxy_command = 'export http_proxy=' + proxy + '; ' \
+ + 'export https_proxy=' + proxy + ';'
+ new_commands.append(proxy_command + ' ' + command)
+ else:
+ new_commands.append(command)
+ return execute_commands(testbed, ssh_config, new_commands, time_out)
+
+
+def execute_proxy_command(testbed, ssh_config, command, time_out=3):
+ """
+ Remote execution of a list of shell command on hostname, using
+ a proxy http and https.
+ By default this function will exit (timeout) after 3 seconds.
+
+ @param testbed: testbed info
+ @param ssh_config: ssh config of the node
+ @param command: *nix shell command
+ @param time_out: time_out value in seconds, error will be generated if
+ no result received in given number of seconds, the value None can
+ be used when no timeout is needed
+
+ @return: stdout resulting from the command
+ """
+ o = execute_proxy_commands(testbed, ssh_config, [command], time_out)
+ if o is not None:
+ return o
+
+
def execute_commands(testbed, ssh_config, commands, time_out=3):
"""
Remote execution of a list of shell command on hostname. By
diff --git a/rumba/testbeds/jfed.py b/rumba/testbeds/jfed.py
index 54ad860..1e1c732 100644
--- a/rumba/testbeds/jfed.py
+++ b/rumba/testbeds/jfed.py
@@ -38,7 +38,12 @@ class Testbed(mod.Testbed):
proj_name="ARCFIRE", authority="wall2.ilabt.iminds.be",
image=None):
passwd = getpass.getpass(prompt="Password for certificate file: ")
- mod.Testbed.__init__(self, exp_name, username, passwd, proj_name)
+ mod.Testbed.__init__(self,
+ exp_name,
+ username,
+ passwd,
+ proj_name,
+ http_proxy="https://proxy.atlantis.ugent.be:8080")
self.authority = "urn:publicid:IDN+" + authority + "+authority+cm"
self.auth_name = authority
self.cert_file = cert_file
diff --git a/rumba/testbeds/qemu.py b/rumba/testbeds/qemu.py
index a916525..b7ebef9 100644
--- a/rumba/testbeds/qemu.py
+++ b/rumba/testbeds/qemu.py
@@ -26,24 +26,25 @@ import os
import rumba.model as mod
import rumba.log as log
import rumba.ssh_support as ssh_support
+import wget
logger = log.get_logger(__name__)
class Testbed(mod.Testbed):
- def __init__(self, exp_name, bzimage, initramfs, proj_name="ARCFIRE",
+ def __init__(self, exp_name, bzimage=None, initramfs=None, proj_name="ARCFIRE",
password="root", username="root",
use_vhost=True, qemu_logs_dir=None):
mod.Testbed.__init__(self, exp_name, username, password, proj_name)
self.vms = {}
self.shims = []
- self.bzimage = bzimage
- self.initramfs = initramfs
self.vhost = use_vhost
self.qemu_logs_dir = os.getcwd() if qemu_logs_dir is None \
else qemu_logs_dir
self.boot_processes = []
+ self.bzimage = bzimage
+ self.initramfs = initramfs
@staticmethod
def _run_command_chain(commands, results_queue,
@@ -114,6 +115,23 @@ class Testbed(mod.Testbed):
raise Exception('Not authenticated')
logger.info("swapping in")
+
+ # Download the proper buildroot images, if the user did not specify
+ # local images
+ url_prefix = "https://bitbucket.org/vmaffione/rina-images/downloads/"
+ if not self.bzimage:
+ self.bzimage = '%s.bzImage' % (experiment.prototype_name())
+ if not os.path.exists(self.bzimage):
+ logger.info("Downloading %s" % (url_prefix + self.bzimage))
+ wget.download(url_prefix + self.bzimage)
+ print("\n")
+ if not self.initramfs:
+ self.initramfs = '%s.rootfs.cpio' % (experiment.prototype_name())
+ if not os.path.exists(self.initramfs):
+ logger.info("Downloading %s" % (url_prefix + self.initramfs))
+ wget.download(url_prefix + self.initramfs)
+ print("\n")
+
logger.info('Setting up interfaces.')
# Building bridges and taps
diff --git a/tools/rumba-access b/tools/rumba-access
new file mode 100755
index 0000000..06b0a02
--- /dev/null
+++ b/tools/rumba-access
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+FILE=ssh_info
+
+MACHINE_ID=$1
+if [ "$MACHINE_ID" == "" ]; then
+ echo "usage: $0 NODE_NAME"
+ exit 255
+fi
+
+USER=$(grep "\<${MACHINE_ID}\>" ${FILE} | awk '{print $2}')
+if [ "$USER" == "" ]; then
+ echo "Error: Node ${MACHINE_ID} unknown"
+ exit 255
+fi
+
+HOST=$(grep "\<${MACHINE_ID}\>" ${FILE} | awk '{print $3}')
+if [ "$HOST" == "" ]; then
+ echo "Error: Node ${MACHINE_ID} unknown"
+ exit 255
+fi
+
+SSH_PORT=$(grep "\<${MACHINE_ID}\>" ${FILE} | awk '{print $4}')
+if [ "$SSH_PORT" == "" ]; then
+ echo "Error: Node ${MACHINE_ID} unknown"
+ exit 255
+fi
+
+echo "Accessing Rumba node ${MACHINE_ID}"
+# -o IdentityFile=buildroot/irati_rsa
+ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p ${SSH_PORT} ${USER}@${HOST}