#!/usr/bin/env/python import argparse import re def make_experiment(filename, bzImage, initramfs): """ :type filename str :param filename: path to the .conf file :param bzImage: path to the bzImage file :param initramfs: path to the rootfs.cpio file :return: """ shims = {} nodes = {} difs = {} ex_name = filename.split('/')[-1].split('.')[0] print('Reading file %s, under project name %s.' % (filename, ex_name)) 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' + shim] = {'name': 'shim' + 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 output = '#!/usr/bin/env/python\n\n' output += ( "from rumba.model import *\n\n" "# import testbed plugins\n" "import rumba.testbeds.emulab as emulab\n" "import rumba.testbeds.jfed as jfed\n" "import rumba.testbeds.faketestbed as fake\n" "import rumba.testbeds.qemu as qemu\n\n" "# import prototype plugins\n" "import rumba.prototypes.ouroboros as our\n" "import rumba.prototypes.rlite as rl\n" "import rumba.prototypes.irati as irati\n\n" ) for shim_name, shim in shims.items(): output += '%(n)s = ShimEthDIF("%(n)s", link_speed=%(speed)s))\n' \ % {'n': shim_name, 'speed': shim["speed"]} output += '\n' for dif_name, dif in difs.items(): output += '%(n)s = NormalDIF("%(n)s")\n' % {'n': dif_name} output += '\n' def str_of_list(i): return '[' + ', '.join(i) + ']' def str_of_dict(d): return '{' + ', '.join(['%s: %s' % (k, str_of_list(v)) for (k, v) in d.items()]) + '}' for node, node_data in nodes.items(): name = node_data['name'] output += '%(n)s = Node("%(n)s",\n' % {'n': name} output += ' difs=%s,\n' \ % (str_of_list(node_data['difs'])) output += ' dif_registrations=%s)\n\n' \ % (str_of_dict(node_data['dif_registrations'])) output += ('tb = qemu.Testbed(exp_name = "%(ex_name)s",\n' ' bzimage = "%(bzImage)s",\n' ' initramfs = "%(initramfs)s")\n\n' 'exp = rl.Experiment(tb, nodes = [a, b, c, d])\n\n' 'print(exp)\n\n' 'exp.run()\n' % {'ex_name': ex_name, 'bzImage': bzImage, 'initramfs': initramfs}) with open(ex_name + '.py', 'w') as out_file: out_file.write(output) if __name__ == '__main__': description = "Demonstrator config file to rumba script converter" epilog = "2017 Marco Capitani " parser = argparse.ArgumentParser(description=description, epilog=epilog) parser.add_argument('config', metavar='CONFIG', type=str, help='Path to the config file to parse') parser.add_argument('bz_image', metavar='BZIMAGE', type=str, help='path to the bzImage file to use') parser.add_argument('initramfs', metavar='INITRAMFS', type=str, help='path to the initramfs file to use') args = parser.parse_args() try: make_experiment(args.config, args.bz_image, args.initramfs) except KeyboardInterrupt: print("Interrupted. Closing down.")