aboutsummaryrefslogtreecommitdiff
path: root/rumba/prototypes/irati.py
diff options
context:
space:
mode:
authorMarco Capitani <m.capitani@nextworks.it>2017-04-13 10:32:10 +0200
committerMarco Capitani <m.capitani@nextworks.it>2017-04-13 10:32:10 +0200
commitaf692809383b55ec3b9d7cb96e50b553ffbcd496 (patch)
treecf32ed1a1e046cc9c98fb8c5c46140a6d4ceb4d3 /rumba/prototypes/irati.py
parentc83ea6f4b791cd85cd248b039b353c522f2f1f3e (diff)
downloadrumba-af692809383b55ec3b9d7cb96e50b553ffbcd496.tar.gz
rumba-af692809383b55ec3b9d7cb96e50b553ffbcd496.zip
IRATI prototype: bootstrap_network method. Now complete & to be tested.
Diffstat (limited to 'rumba/prototypes/irati.py')
-rw-r--r--rumba/prototypes/irati.py147
1 files changed, 130 insertions, 17 deletions
diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py
index e06610d..ba8a152 100644
--- a/rumba/prototypes/irati.py
+++ b/rumba/prototypes/irati.py
@@ -21,16 +21,38 @@
import copy
import json
+import subprocess
+
import rumba.ssh_support as ssh
import rumba.model as mod
import rumba.prototypes.irati_templates as irati_templates
+
# An experiment over the IRATI implementation
+from rumba import ssh_support
+
+
class Experiment(mod.Experiment):
+
+ @staticmethod
+ def real_sudo(s):
+ return 'sudo ' + s
+
+ @staticmethod
+ def fake_sudo(s):
+ return s
+
def __init__(self, testbed, nodes=None):
mod.Experiment.__init__(self, testbed, nodes)
+ self.manager = False
+
+ if self.testbed.username == 'root':
+ self.sudo = self.fake_sudo
+ else:
+ self.sudo = self.real_sudo
def setup(self):
+ """Installs IRATI on the vms."""
cmds = list()
cmds.append("sudo apt-get update")
@@ -45,36 +67,129 @@ class Experiment(mod.Experiment):
ssh.execute_commands(self.testbed, node.ssh_config,
cmds, time_out=None)
+ def bootstrap_network(self):
+ """Creates the network by enrolling and configuring the nodes"""
+ for node in self.nodes:
+ self.process_node(node)
+ self.enroll_nodes()
+
def run_prototype(self):
print("[IRATI experiment] start")
print("Setting up IRATI on the nodes...")
self.setup()
print("[IRATI experiment] end")
+ def process_node(self, node):
+ """
+ Installs the configuration and boots up rina on a node
+ :type node: mod.Node
+ :param node:
+ :return:
+ """
+ name = node.name
+ gen_files_conf = 'shimeth.%(name)s.*.dif da.map %(name)s.ipcm.conf' % {
+ 'name': name}
+ if any(name in dif.members for dif in self.dif_ordering):
+ gen_files_conf = ' '.join(
+ [gen_files_conf, 'normal.%(name)s.*.dif' % {'name': name}])
+ gen_files_bin = 'enroll.py'
+
+ ipcm_components = ['scripting', 'console']
+ if self.manager:
+ ipcm_components.append('mad')
+ ipcm_components = ', '.join(ipcm_components)
+
+ gen_files = ' '.join([gen_files_conf, gen_files_bin])
+
+ sshopts = ('-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
+ ' -o IdentityFile=buildroot/irati_rsa')
+ format_args = {'name': name,
+ 'ssh': node.ssh_config.port,
+ 'username': self.testbed.username,
+ 'genfiles': gen_files,
+ 'genfilesconf': gen_files_conf,
+ 'genfilesbin': gen_files_bin,
+ 'sshopts': sshopts,
+ 'installpath': '/usr',
+ 'verb': 'DBG',
+ 'ipcmcomps': ipcm_components}
+ try:
+ subprocess.check_call(('scp %(sshopts)s -r -P %(ssh)s '
+ '%(genfiles)s %(username)s@localhost:'
+ % format_args).split())
+ except subprocess.CalledProcessError as e:
+ raise Exception(str(e))
+
+ # TODO: review ssh opts through ssh support
+
+ cmds = [self.sudo('hostname %(name)s' % format_args),
+ self.sudo('chmd a+rw /dev/irati'),
+ self.sudo('mv %(genfilesconf)s /etc' % format_args),
+ self.sudo('mv %(genfilesbin)s /usr/bin') % format_args]
+
+ # TODO: is the port up on the VM at this point?
+
+ cmds += [self.sudo('modprobe rina-default-plugin'),
+ self.sudo('%(installpath)s/bin/ipcm -a \"%(ipcmcomps)s\" '
+ '-c /etc/%(name)s.ipcm.conf -l %(verb)s &> log &'
+ % format_args)]
+
+ ssh_support.execute_commands(self.testbed, node.ssh_config, cmds)
+
+ def enroll_nodes(self):
+ """Runs the enrollments one by one, respecting dependencies"""
+ for enrollment_list in self.enrollments:
+ for e in enrollment_list:
+ print(
+ 'I am going to enroll %s to DIF %s against neighbor %s,'
+ ' through lower DIF %s'
+ % (e['enrollee'],
+ e['dif'].name,
+ e['enroller'],
+ e['lower_dif'].name))
+
+ subprocess.check_call('sleep 2'. split()) # Important!
+
+ e_args = {'ldif': e['lower_dif'].name,
+ 'dif': e['dif'].name,
+ 'name': e['enrollee'].name,
+ 'o_name': e['enroller'].name}
+
+ cmd = self.sudo('enroll.py --lower-dif %(ldif)s --dif %(dif)s '
+ '--ipcm-conf /etc/%(name)s.ipcm.conf '
+ '--enrollee-name %(dif)s.%(name)s.IPCP '
+ '--enroller-name %(dif)s.%(o_name)s.IPCP'
+ % e_args)
+ ssh_support.execute_command(self.testbed,
+ e['enrollee'].ssh_config,
+ cmd)
+
class ConfBuilder(object):
- def __init__(self, experiment):
- self.write_conf(experiment)
+ def __init__(self, experiment, manager):
+ self.write_conf(experiment, manager)
@staticmethod
- def write_conf(experiment):
+ def write_conf(experiment, manager):
"""
:type experiment: Experiment
:param experiment: the experiment to be configured
+ :param manager: boolean indicating if a manager is requested
"""
# Constants and initializations
ipcmconfs = dict()
difconfs = dict()
ipcp2shim_map = {}
node2id_map = {}
- manager = False
mgmt_dif_name = 'NMS'
- # TODO ask: what are these, and how are they represented in experiment?
- # Are these bindings or registration (in node)?
- # In gen.py these are given on a per-dif basis...
+ # TODO: what format are the mappings registered in? Is this ok?
app_mappings = []
+ for node in experiment.nodes:
+ app_mappings += [{'name': app, 'dif': dif.name}
+ 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
@@ -84,14 +199,13 @@ class ConfBuilder(object):
for adm in \
irati_templates.da_map_base["applicationToDIFMappings"]:
adm["difName"] = "%s" % (experiment.dif_ordering[-1],)
- # else:
- # irati_templates.da_map_base["applicationToDIFMappings"] = []
- # for apm in app_mappings:
- # irati_templates.da_map_base["applicationToDIFMappings"]\
- # .append({
- # "encodedAppName": apm['name'],
- # "difName": "%s.DIF" % (apm['dif'])
- # })
+ else:
+ irati_templates.da_map_base["applicationToDIFMappings"] = []
+ for apm in app_mappings:
+ irati_templates.da_map_base["applicationToDIFMappings"]\
+ .append({"encodedAppName": apm['name'],
+ "difName": "%s" % (apm['dif'])
+ })
# TODO ask: I guess this will need to be added,
# and in that case we should add it to the qemu plugin too...
@@ -201,8 +315,7 @@ class ConfBuilder(object):
"address": 16 + node2id_map[node_name]})
for path, ps in dif.policies.items():
# if policy['nodes'] == [] or vmname in policy['nodes']:
- # TODO: policies can be applied per-node
- # (and not just per-dif) in rumba? With what syntax?
+ # TODO: manage per-node-policies
irati_templates.translate_policy(
difconfs[dif.name][node_name], path, ps, parms=[])