diff options
-rw-r--r-- | rumba/model.py | 99 | ||||
-rw-r--r-- | rumba/ssh_support.py | 2 | ||||
-rwxr-xr-x | tools/democonf2rumba.py | 248 |
3 files changed, 249 insertions, 100 deletions
diff --git a/rumba/model.py b/rumba/model.py index 5ec36cc..c2c4cfa 100644 --- a/rumba/model.py +++ b/rumba/model.py @@ -317,105 +317,6 @@ class Experiment: # Generate missing information self.generate() - @staticmethod - def from_config_file(testbed, filename='demo.conf'): - """ - :type testbed: Testbed - :rtype: Experiment - :param testbed: the testbed for the experiment - :param filename: name of the .conf file - :return: an Experiment object - """ - - shims = {} - nodes = {} - difs = {} - with open(filename, 'r') as conf: - - line_cnt = 0 - - while 1: - line = conf.readline() - if line == '': - break - line_cnt += 1 - - line = line.replace('\n', '').strip() - - if line.startswith('#') or line == "": - continue - - m = re.match(r'\s*eth\s+([\w-]+)\s+(\d+)([GMK])bps\s+(\w.*)$', line) - if m: - shim = m.group(1) - speed = int(m.group(2)) - speed_unit = m.group(3).lower() - vm_list = m.group(4).split() - - if shim in shims or shim in difs: - print('Error: Line %d: shim %s already defined' - % (line_cnt, shim)) - continue - - if speed_unit == 'K': - speed = speed // 1000 - if speed_unit == 'G': - speed = speed * 1000 - - shims[shim] = {'name': shim, 'speed': speed, 'type': 'eth'} - - for vm in vm_list: - nodes.setdefault(vm, {'name': vm, 'difs': [], 'dif_registrations': {}, 'registrations': {}}) - nodes[vm]['difs'].append(shim) - continue - - m = re.match(r'\s*dif\s+([\w-]+)\s+([\w-]+)\s+(\w.*)$', line) - if m: - dif = m.group(1) - vm = m.group(2) - dif_list = m.group(3).split() - - if dif in shims: - print('Error: Line %d: dif %s already defined as shim' - % (line_cnt, dif)) - continue - - difs.setdefault(dif, {'name': dif}) # Other dict contents might be policies. - - if vm in nodes and dif in nodes[vm]['dif_registrations']: - print('Error: Line %d: vm %s in dif %s already specified' - % (line_cnt, vm, dif)) - continue - - nodes.setdefault(vm, {'name': vm, 'difs': [], 'dif_registrations': {}, 'registrations': {}}) - nodes[vm]['difs'].append(dif) - nodes[vm]['dif_registrations'][dif] = dif_list # It is not defined yet, per check above. - - continue - - # No match, spit a warning - print('Warning: Line %d unrecognized and ignored' % line_cnt) - - # File parsed - - parsed_difs = {} - - for shim_name, shim in shims.items(): - parsed_difs[shim_name] = (ShimEthDIF(shim_name, link_speed=shim['speed'])) - - for dif_name, dif in difs.items(): - parsed_difs[dif_name] = (NormalDIF(dif_name)) - - parsed_nodes = [] - for node, node_data in nodes.items(): - name = node_data['name'] - difs = [parsed_difs[x] for x in node_data['difs']] - dif_registrations = {parsed_difs[x]: [parsed_difs[y] for y in l] - for x, l in node_data['dif_registrations'].items()} - parsed_nodes.append(Node(name, difs, dif_registrations)) - - return Experiment(testbed=testbed, nodes=parsed_nodes) - def __repr__(self): s = "" for n in self.nodes: diff --git a/rumba/ssh_support.py b/rumba/ssh_support.py index 4928a0d..c9ae687 100644 --- a/rumba/ssh_support.py +++ b/rumba/ssh_support.py @@ -41,7 +41,7 @@ def execute_commands(testbed, ssh_config, commands, time_out=3): @param testbed: testbed info @param ssh_config: ssh config of the node - @param command: *nix shell command + @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 diff --git a/tools/democonf2rumba.py b/tools/democonf2rumba.py new file mode 100755 index 0000000..cda112c --- /dev/null +++ b/tools/democonf2rumba.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python + +import argparse +import re + +import rumba.model as mod + + +def make_experiment(filename, experiment_class, experiment_kwargs, + testbed_class, testbed_kwargs): + """ + :type filename str + :param filename: path to the .conf file + :param experiment_class: subclass of mod.Experiment + :param experiment_kwargs: args dict for experiment constructor + (nodes will be overwritten) + :param testbed_class: subclass of mod.Testbed + :param testbed_kwargs: args dict for experiment constructor + (nodes will be overwritten) + """ + shims = {} + nodes = {} + difs = {} + + print('Reading file %s.' % (filename,)) + + with open(filename, 'r') as conf: + + line_cnt = 0 + + while 1: + line = conf.readline() + if line == '': + break + line_cnt += 1 + + line = line.replace('\n', '').strip() + + if line.startswith('#') or line == "": + continue + + m = re.match(r'\s*eth\s+([\w-]+)\s+(\d+)([GMK])bps\s+(\w.*)$', line) + if m: + shim = m.group(1) + speed = int(m.group(2)) + speed_unit = m.group(3).lower() + vm_list = m.group(4).split() + + if shim in shims or shim in difs: + print('Error: Line %d: shim %s already defined' + % (line_cnt, shim)) + continue + + if speed_unit == 'K': + speed = speed // 1000 + if speed_unit == 'G': + speed = speed * 1000 + + shims[shim] = {'name': shim, + 'speed': speed, + 'type': 'eth'} + + for vm in vm_list: + nodes.setdefault(vm, {'name': vm, 'difs': [], + 'dif_registrations': {}, + 'registrations': {}}) + nodes[vm]['difs'].append(shim) + continue + + m = re.match(r'\s*dif\s+([\w-]+)\s+([\w-]+)\s+(\w.*)$', line) + if m: + dif = m.group(1) + vm = m.group(2) + dif_list = m.group(3).split() + + if dif in shims: + print('Error: Line %d: dif %s already defined as shim' + % (line_cnt, dif)) + continue + + difs.setdefault(dif, { + 'name': dif}) # Other dict contents might be policies. + + if vm in nodes and dif in nodes[vm]['dif_registrations']: + print('Error: Line %d: vm %s in dif %s already specified' + % (line_cnt, vm, dif)) + continue + + nodes.setdefault(vm, {'name': vm, 'difs': [], + 'dif_registrations': {}, + 'registrations': {}}) + nodes[vm]['difs'].append(dif) + nodes[vm]['dif_registrations'] \ + [dif] = dif_list + # It is not defined yet, per check above. + + continue + + # No match, spit a warning + print('Warning: Line %d unrecognized and ignored' % line_cnt) + + # File parsed + + parsed_difs = {} + + for shim_name, shim in shims.items(): + parsed_difs[shim_name] = (mod.ShimEthDIF(shim_name, + link_speed=shim['speed'])) + + for dif_name, dif in difs.items(): + parsed_difs[dif_name] = (mod.NormalDIF(dif_name)) + + parsed_nodes = [] + for node, node_data in nodes.items(): + name = node_data['name'] + difs = [parsed_difs[x] for x in node_data['difs']] + dif_registrations = {parsed_difs[x]: [parsed_difs[y] for y in l] + for x, l in node_data['dif_registrations'] + .items()} + parsed_nodes.append(mod.Node(name, difs, dif_registrations)) + + testbed = testbed_class(**testbed_kwargs) + + experiment_kwargs['testbed'] = testbed + experiment_kwargs['nodes'] = parsed_nodes + + return experiment_class(**experiment_kwargs).run() + + +def setup_testbed_common_args(t_p): + + t_p.add_argument('-E', '--exp_name', metavar='EXP_NAME', type=str, + required=True, + help='Experiment name') + t_p.add_argument('-U', '--username', metavar='USERNAME', type=str, + required=True, + help='Testbed user name') + t_p.add_argument('-P', '--proj_name', metavar='PROJECT_NAME', type=str, + help='Project name') + t_p.add_argument('-W', '--password', metavar='PASSWORD', type=str, + help='Testbed password') + + +if __name__ == '__main__': + description = "Demonstrator config file to rumba script converter" + epilog = "2017 Marco Capitani <[email protected]>" + + parser = argparse.ArgumentParser(description=description, + epilog=epilog) + + parser.add_argument('-P', '--prototype', type=str, required=True, + choices=['irati', 'ouroboros', 'rlite'], + help='The kind of prototype plugin to use to run' + ' the experiment.') + + parser.add_argument('-C', '--conf', metavar='CONFIG', type=str, + required=True, + help='Path to the config file to parse') + + subparsers = parser.add_subparsers(dest='testbed') + emulab_p = subparsers.add_parser('emulab', help='Use emulab testbed') + jfed_p = subparsers.add_parser('jfed', help='Use jfed testbed') + qemu_p = subparsers.add_parser('qemu', help='Use qemu testbed') + fake_p = subparsers.add_parser('fake', help='Use fake testbed') + + for t in [emulab_p, jfed_p, qemu_p, fake_p]: + setup_testbed_common_args(t) + + qemu_p.add_argument('-B', '--bzimage', metavar='BZIMAGE', type=str, + required=True, + help='path to the bzImage file to use') + qemu_p.add_argument('-I', '--initramfs', metavar='INITRAMFS', type=str, + required=True, + help='path to the initramfs file to use') + qemu_p.add_argument('-V', '--use_vhost', action='store_true', + default=False, help='Use vhost') + qemu_p.add_argument('-Q', '--qemu_logs_dir', metavar='QEMU_LOGS', type=str, + default=None, help='path to the folder for qemu logs') + + emulab_p.add_argument('-R', '--url', metavar='URL', type=str, + default="wall2.ilabt.iminds.be", + help='Url') + emulab_p.add_argument('-I', '--image', metavar='IMG', type=str, + default="UBUNTU14-64-STD", + help='Ubuntu image') + + jfed_p.add_argument('-C', '--cert_file', metavar='CERT', type=str, + required=True, + help='Certificate file') + jfed_p.add_argument('-J', '--jar', metavar='JAR', type=str, + required=True, + help='Jfed jar') + jfed_p.add_argument('-H', '--exp_hours', metavar='HOURS', type=int, + default=2, help='Experiment hours') + jfed_p.add_argument('-A', '--authority', metavar='AUTH', type=str, + default="wall2.ilabt.iminds.be", + help='Authority') + + args = parser.parse_args() + + if args.testbed == 'emulab': + import rumba.testbeds.emulab as emulab + test_class = emulab.Testbed + testbed_args = {a.dest: getattr(args, a.dest) + for a in emulab_p._actions if a.dest != 'help'} + elif args.testbed == 'jfed': + import rumba.testbeds.jfed as jfed + test_class = jfed.Testbed + testbed_args = {a.dest: getattr(args, a.dest) + for a in jfed_p._actions if a.dest != 'help'} + elif args.testbed == 'qemu': + import rumba.testbeds.qemu as qemu + test_class = qemu.Testbed + testbed_args = {a.dest: getattr(args, a.dest) + for a in qemu_p._actions if a.dest != 'help'} + elif args.testbed == 'fake': + import rumba.testbeds.faketestbed as fake + test_class = fake.Testbed + testbed_args = {a.dest: getattr(args, a.dest) + for a in fake_p._actions if a.dest != 'help'} + else: + if args.testbed is None: + print('Testbed type must be specified!') + print(parser.format_help()) + exit(1) + raise ValueError('Unexpected testbed: %s.' % args.testbed) + + if args.prototype == 'irati': + import rumba.prototypes.irati as irati + exp_class = irati.Experiment + elif args.prototype == 'ouroboros': + import rumba.prototypes.ouroboros as ouroboros + exp_class = ouroboros.Experiment + elif args.prototype == 'rlite': + import rumba.prototypes.rlite as rlite + exp_class = rlite.Experiment + else: + raise ValueError('Unexpected prototype: %s.' % args.testbed) + + try: + make_experiment(args.conf, + experiment_class=exp_class, + experiment_kwargs={}, + testbed_class=test_class, + testbed_kwargs=testbed_args) + + except KeyboardInterrupt: + print("Interrupted. Closing down.") |