class tunproxy(object): ''' Class for handling tunproxy ''' def __init__(self): if DEBUG: print "Init tunproxy..." self._controller = CONTROLLER # available PLE nodes self._ple_list = [] # number of PLE connections self._ple_conns = 0 # dict for RTT measurments of PLE nodes self._delays = {} # PLE nodes' config params (which we are to connect) self._ple_config = [] self._my_fqdn = None self._host_shortname = None self._qemu = False self._parse_args() # init JSONRPC proxy while 1: try: self._jsonrpc_proxy = ServiceProxy(self._controller) break except (JSONRPCException, IOError): print "Waiting for initializing JSONRPC Proxy..." self._ple_list = [] time.sleep(2) continue if DEBUG: print "Done." def _parse_args(self): ''' Parsing command line args ''' global DEBUG self._parser = argparse.ArgumentParser( description= 'Automatically managing connections to PlanetLab Europe (PLE)') parser = self._parser parser.add_argument('-d', '--debug', action='store_true', dest='debug', help='run in debug mode') parser.add_argument('-p', '--ple-nodes', action='store', dest='ple_list', nargs='+', help='PLE node candidates for connection') parser.add_argument('-c', '--conns', action='store', dest='ple_conns', type=int, nargs=1, help='number of connections to PLE we want to use') parser.add_argument('-n', '--name', action='store', dest='name', nargs=1, help='short name of the host') parser.add_argument('-C', '--controller', action='store', dest='controller', nargs=1, help='url of the POX controller') parser.add_argument( '-q', '--qemu', action='store_true', dest='qemu', help='generate config file for qemu VM instead of network setup') p = parser.parse_args() if p.debug: DEBUG = 1 if p.ple_conns and p.ple_conns[0] > 0: self.set_ple_conns(p.ple_conns[0]) if p.ple_list and len(p.ple_list) > 0: self.set_ple_list(p.ple_list) if p.name: self._host_shortname = ''.join(p.name) if p.controller: self._controller = ''.join(p.controller) if p.qemu: self._qemu = True def usage(self, status=0): ''' Print usage information on the program ''' self._parser.print_help() sys.exit(status) def _read_args(self, opts): ''' Old args reader ''' # parse command line args self._config = {'tunmode': IFF_TUN, 'remote_ip': None} for opt, optarg in opts[0]: if opt == "-h": self.usage_old() elif opt == "-d": global DEBUG DEBUG = 1 elif opt == "-p": self.set_ple_list(str(optarg).split(",")) # elif opt == "-p": # self._config['local_port'] = int(optarg) elif opt == "-t": self._config['remote_ip'], remote_port = optarg.split(":") self._config['remote_port'] = int(remote_port) elif opt == "-e": self._config['tunmode'] = IFF_TAP elif opt == "-a": self._config['addr_ip'] = optarg elif opt == "-E": self._config['addr_eth'] = optarg else: self.usage_old(1) def usage_old(status=0): print "Usage: tunproxy [-p local_port] [-t targetip:port] [-e]" "[-a local_ip] [-E eth_adrr]" sys.exit(status) def get_ip_addr(self): s = socket(AF_INET, SOCK_DGRAM) s.connect(("8.8.8.8", 80)) ip_addr = s.getsockname()[0] s.close() return ip_addr def get_my_fqdn(self): if self._my_fqdn: return self._my_fqdn #fqdn = subprocess.check_output(['hostname', '-A']) # python 2.7 fqdn = subprocess.Popen(['hostname', '-A'], stdout=subprocess.PIPE).communicate()[0] fqdn = fqdn.strip() fqdn = [n for n in fqdn.split(' ') if not n.endswith('.local')] if fqdn == [] or fqdn == ['']: fqdn = self.get_ip_addr() else: fqdn = fqdn[0] fqdn = fqdn.strip() self._my_fqdn = fqdn return self._my_fqdn def _download_config(self, baseurl): ''' Use this if config.json is available at baseurl/hostname ''' fqdn = self.get_my_fqdn() url = baseurl + fqdn + '/vars.json' print 'Downloading config from: %s' % url data = None while not data: try: data = urllib2.urlopen(url).read() except urllib2.URLError as err: print '%s. Retrying after 2 sec' % err time.sleep(2) data = json.loads(data) return data def _configure_interface(self, ifname=None, addr_ip=None, addr_eth=None): ''' Configure single interface ''' if addr_ip is None or ifname is None: return cmd = 'ip addr add %s/24 dev %s' % (addr_ip, ifname) print cmd os.system(cmd) cmd = 'ip link set dev %s mtu 1400' % ifname print cmd os.system(cmd) if addr_eth: cmd = 'ip link set dev %s address %s' % (ifname, addr_eth) print cmd os.system(cmd) cmd = 'ip link set dev %s up' % ifname print cmd os.system(cmd) net = re.sub('\.[0-9]*$', '.0', addr_ip) cmd = 'ip route add %s/24 dev %s' % (net, ifname) print cmd os.system(cmd) def _start_service_single(self, config): ''' Start single tunnel (connection with remote peer) ''' f = os.open("/dev/net/tun", os.O_RDWR) tunmode = config['tunmode'] | IFF_NO_PI ifs = ioctl(f, TUNSETIFF, struct.pack("16sH", "allegra_%d", tunmode)) ifname = ifs[:16].strip("\x00") print "Allocated interface %s. Configure it and use it" % ifname return 0 self._configure_interface(ifname, config['addr_ip'], config['addr_eth']) s = socket(AF_INET, SOCK_DGRAM) if config['remote_ip'] is None or config['remote_port'] is None: print 'Missing remote_ip or remote_port \n' self.usage(1) try: peer = (config['remote_ip'], int(config['remote_port'])) s.bind(("", int(config['local_port']))) print "Connection with %s:%i established" % peer while 1: r = select([f, s], [], [])[0][0] if r == f: if DEBUG: os.write(1, ">") s.sendto(os.read(f, 1500), peer) else: buf, p = s.recvfrom(1500) if p != peer: print "Got packet from %s:%i instead of %s:%i" % (p + peer) print '===================' os.close(f) return if DEBUG: os.write(1, "<") os.write(f, buf) except KeyboardInterrupt: print "Stopped by user." exit() def _start_service(self, config): ''' Start tunnels. Parameters are given in config dict list. ''' fd = [] ifname = [] sock = [] peer = [] for i in range(len(config)): fd.append(os.open("/dev/net/tun", os.O_RDWR)) if config[i]['tunmode'] == 'tun': tunmode = IFF_TUN | IFF_NO_PI else: tunmode = IFF_TAP | IFF_NO_PI ifs = ioctl(fd[i], TUNSETIFF, struct.pack("16sH", "allegra_%d", tunmode)) ifname.append(ifs[:16].strip("\x00")) print "Allocated interface %s. Configure it and use it" % ifname[i] self._configure_interface(ifname[i], config[i]['addr_ip'], config[i]['addr_eth']) sock.append(socket(AF_INET, SOCK_DGRAM)) if config[i]['remote_ip'] is None or config[i][ 'remote_port'] is None: print 'Missing remote_ip or remote_port \n' self.usage(1) peer.append( (config[i]['remote_ip'], int(config[i]['remote_port']))) sock[i].bind(("", int(config[i]['local_port']))) print "Connection with %s:%i established" % peer[i] try: while 1: r_list = select(fd + sock, [], [])[0] for r in r_list: if r in fd: # read from tun/tap device and send to peer i = fd.index(r) if DEBUG: os.write(1, ">") sock[i].sendto(os.read(fd[i], 1500), peer[i]) else: # receive from peer and send to tun/tap device i = sock.index(r) buf, p = sock[i].recvfrom(1500) if DEBUG: print "Pkt from %s:%i" % p if p != peer[i]: print "Got packet from %s:%i instead of %s:%i" % ( p + peer[i]) print '===================' for f in fd: os.close(f) return if DEBUG: os.write(1, "<") os.write(fd[i], buf) except KeyboardInterrupt: print "Stopped by user." exit() def set_ple_list(self, ple_list): ''' Set potential PLE nodes to connect to ''' self._ple_list = ple_list self.set_ple_conns() if DEBUG: print "Set ple_list: " + str(self._ple_list) def set_ple_conns(self, ple_conns=None): ''' Set number of intended PLE connections to input parameter or command line arg (-c) if given or try to find a default value ''' if ple_conns: self._ple_conns = ple_conns elif self._ple_conns == 0: # set default connection number to list len, max:2 # if -c is not given as input if len(self._ple_list) < 3: self._ple_conns = len(ple_list) else: self._ple_conns = 2 if DEBUG: print "Set ple_conns: " + str(self._ple_conns) def set_ple_config(self, ple_config): ''' Set ple_config dict ''' self._ple_config = ple_config def get_ple_config(self): ''' Get current ple_config dict ''' return self._ple_config def get_ple_list_from_controller(self): ''' Available PLE nodes list is requested from CONTROLLER ''' while 1: try: self._ple_list = self._jsonrpc_proxy.get_ple_list() break except (JSONRPCException, IOError): print "Waiting for JSONRPC connection..." self._ple_list = [] time.sleep(2) continue # set number of connections to a default value if it is not set yet self.set_ple_conns() if DEBUG: print self._ple_list def sort_given_ple_nodes(self, ple_list): ''' Sort given PLE nodes based on RTT measurements Return: sorted list of PLE nodes, 1st: min ''' for node in ple_list: # ignore first ping if (ping.Ping(node, timeout=2000).do()) is None: # in case of timeout break self._delays[node] = 0 for i in range(PING_NO): delay = ping.Ping(node, timeout=2000).do() if delay is not None: self._delays[node] += delay if DEBUG: print self._delays[node] else: # timeout occurs at least once: # dont use the node del self._delays[node] break else: # calculate average self._delays[node] /= PING_NO if DEBUG: print "delays: " + str(self._delays) # ordered ple list, 1st: min return sorted(self._delays, key=self._delays.get) def sort_ple_nodes(self): ''' Sort available PLE nodes based on RTT measurements Available nodes list is requested from CONTROLLER if it's empty ''' self._delays = {} if len(self._ple_list) == 0: self.get_ple_list_from_controller() # Sort the list self._ple_list = self.sort_given_ple_nodes(self._ple_list) if DEBUG: print self._ple_list def sort_given_ple_nodes_multi(self, ple_list): ''' Sort given PLE nodes based on PARALLEL RTT measurements using multiprocess Return: sorted list of PLE nodes, 1st: min ''' pool = multiprocessing.dummy.Pool(len(ple_list)) print "Starting RTT measurement..." delays = dict(pool.map(ping_measurement, ple_list)) #filter out None values self._delays = dict( filter(lambda item: item[1] is not None, delays.items())) if DEBUG: print self._delays # ordered ple list, 1st: min print "Sorted list:" for node in sorted(self._delays, key=self._delays.get): print "%s: %f ms" % (node, self._delays[node]) # print sorted(self._delays, key=self._delays.get) print "Done." return sorted(self._delays, key=self._delays.get) def sort_ple_nodes_multi(self): ''' Sort available PLE nodes based on PARALLEL RTT measurements using sort_given_ple_nodes_multi Available nodes list is requested from CONTROLLER if it's empty ''' self._delays = {} if len(self._ple_list) == 0: self.get_ple_list_from_controller() # Sort the list self._ple_list = self.sort_given_ple_nodes_multi(self._ple_list) if DEBUG: print self._ple_list def req_connect_given_ple_nodes(self, ple_conns=None, ple_list=None, host_shortname=None): ''' Connection request to ple_conns No. of PLE nodes from ple_list. If params are not given self vars are used ''' if ple_conns is None: ple_conns = self._ple_conns if ple_list is None: ple_list = self._ple_list if len(ple_list) < ple_conns: error(1) if host_shortname is None: host_shortname = self._host_shortname ple_config = [] my_fqdn = self.get_my_fqdn() # for hostname in ple_list[:ple_conns]: # try: # ple_config.append( # self._jsonrpc_proxy.connect_ple(hostname, my_fqdn)) # except JSONRPCException as e: # print 'failed to get info of connection to %s' % hostname try: hostnames = ple_list[:ple_conns] ple_config = self._jsonrpc_proxy.connect_ple( hostnames, my_fqdn, host_shortname) except JSONRPCException as e: print 'failed to get info of connection to %s' % hostnames self._ple_config = ple_config if DEBUG: print self._ple_config def req_connect_ple_nodes(self, ple_conns=None, host_shortname=None): ''' Connection request to closest PLE nodes (ple_conns No. of nodes) Get PLE node list and sort if necessary ''' if len(self._ple_list) == 0: # get the list from controller self.get_ple_list_from_controller() # sort the list parallel self.sort_ple_nodes_multi() if ple_conns is None: ple_conns = self._ple_conns else: self._ple_conns = ple_conns self.req_connect_given_ple_nodes(ple_conns, self._ple_list, host_shortname) if DEBUG: print self._ple_config def connect_ple_nodes(self): ''' Connect PLE nodes based on current _ple_config, configure peer interfaces ''' self._start_service(self._ple_config) def dump_config(self, ple_config): ''' Dump ple_config dict to be used by qemu startup scripts ''' my_fqdn = self.get_my_fqdn() ports = [] for conf in ple_config: dir = 'planetlab/%s/port%s' % (my_fqdn, conf['port_num']) make_dir_if_needed(dir) write_var(conf, dir + '/vars.json', json) for var in conf.keys(): write_var(conf[var], dir + '/' + var) ports.append('port' + conf['port_num']) dir = 'planetlab/%s' % my_fqdn with open(dir + '/neighbors', 'w') as f: for neighbor in ports: f.write('%s\n' % neighbor) def dump_current_config(self): ''' Dump current ple_config dict to be used by qemu startup scripts ''' self.dump_config(self._ple_config)
class tunproxy (object): ''' Class for handling tunproxy ''' def __init__ (self): if DEBUG: print "Init tunproxy..." self._controller = CONTROLLER # available PLE nodes self._ple_list = [] # number of PLE connections self._ple_conns = 0 # dict for RTT measurments of PLE nodes self._delays = {} # PLE nodes' config params (which we are to connect) self._ple_config = [] self._my_fqdn = None self._host_shortname = None self._qemu = False self._parse_args() # init JSONRPC proxy while 1: try: self._jsonrpc_proxy = ServiceProxy(self._controller) break except (JSONRPCException, IOError): print "Waiting for initializing JSONRPC Proxy..." self._ple_list = [] time.sleep(2) continue if DEBUG: print "Done." def _parse_args (self): ''' Parsing command line args ''' global DEBUG self._parser = argparse.ArgumentParser( description='Automatically managing connections to PlanetLab Europe (PLE)') parser = self._parser parser.add_argument('-d', '--debug', action='store_true', dest='debug', help='run in debug mode') parser.add_argument('-p', '--ple-nodes', action='store', dest='ple_list', nargs='+', help='PLE node candidates for connection') parser.add_argument('-c', '--conns', action='store', dest='ple_conns', type=int, nargs=1, help='number of connections to PLE we want to use') parser.add_argument('-n', '--name', action='store', dest='name', nargs=1, help='short name of the host') parser.add_argument('-C', '--controller', action='store', dest='controller', nargs=1, help='url of the POX controller') parser.add_argument('-q', '--qemu', action='store_true', dest='qemu', help='generate config file for qemu VM instead of network setup') p = parser.parse_args() if p.debug: DEBUG = 1 if p.ple_conns and p.ple_conns[0] > 0: self.set_ple_conns(p.ple_conns[0]) if p.ple_list and len(p.ple_list) > 0: self.set_ple_list(p.ple_list) if p.name: self._host_shortname = ''.join(p.name) if p.controller: self._controller = ''.join(p.controller) if p.qemu: self._qemu = True def usage (self, status = 0): ''' Print usage information on the program ''' self._parser.print_help() sys.exit(status) def _read_args (self, opts): ''' Old args reader ''' # parse command line args self._config = { 'tunmode': IFF_TUN, 'remote_ip': None } for opt,optarg in opts[0]: if opt == "-h": self.usage_old() elif opt == "-d": global DEBUG DEBUG = 1 elif opt == "-p": self.set_ple_list(str(optarg).split(",")) # elif opt == "-p": # self._config['local_port'] = int(optarg) elif opt == "-t": self._config['remote_ip'], remote_port = optarg.split(":") self._config['remote_port'] = int(remote_port) elif opt == "-e": self._config['tunmode'] = IFF_TAP elif opt == "-a": self._config['addr_ip'] = optarg elif opt == "-E": self._config['addr_eth'] = optarg else: self.usage_old(1) def usage_old (status = 0): print "Usage: tunproxy [-p local_port] [-t targetip:port] [-e]" "[-a local_ip] [-E eth_adrr]" sys.exit(status) def get_ip_addr (self): s = socket(AF_INET, SOCK_DGRAM) s.connect(("8.8.8.8", 80)) ip_addr = s.getsockname()[0] s.close() return ip_addr def get_my_fqdn (self): if self._my_fqdn: return self._my_fqdn #fqdn = subprocess.check_output(['hostname', '-A']) # python 2.7 fqdn = subprocess.Popen(['hostname', '-A'], stdout=subprocess.PIPE).communicate()[0] fqdn = fqdn.strip() fqdn = [n for n in fqdn.split(' ') if not n.endswith('.local')] if fqdn == [] or fqdn == ['']: fqdn = self.get_ip_addr() else: fqdn = fqdn[0] fqdn = fqdn.strip() self._my_fqdn = fqdn return self._my_fqdn def _download_config (self, baseurl): ''' Use this if config.json is available at baseurl/hostname ''' fqdn = self.get_my_fqdn() url = baseurl + fqdn + '/vars.json' print 'Downloading config from: %s' % url data = None while not data: try: data = urllib2.urlopen(url).read() except urllib2.URLError as err: print '%s. Retrying after 2 sec' % err time.sleep(2) data = json.loads(data) return data def _configure_interface (self, ifname = None, addr_ip = None, addr_eth = None): ''' Configure single interface ''' if addr_ip is None or ifname is None: return cmd = 'ip addr add %s/24 dev %s' % (addr_ip, ifname) print cmd os.system(cmd) cmd = 'ip link set dev %s mtu 1400' % ifname print cmd os.system(cmd) if addr_eth: cmd = 'ip link set dev %s address %s' % (ifname, addr_eth) print cmd os.system(cmd) cmd = 'ip link set dev %s up' % ifname print cmd os.system(cmd) net = re.sub('\.[0-9]*$', '.0', addr_ip) cmd = 'ip route add %s/24 dev %s' % (net, ifname) print cmd os.system(cmd) def _start_service_single (self, config): ''' Start single tunnel (connection with remote peer) ''' f = os.open("/dev/net/tun", os.O_RDWR) tunmode = config['tunmode'] | IFF_NO_PI ifs = ioctl(f, TUNSETIFF, struct.pack("16sH", "allegra_%d", tunmode)) ifname = ifs[:16].strip("\x00") print "Allocated interface %s. Configure it and use it" % ifname return 0 self._configure_interface(ifname, config['addr_ip'], config['addr_eth']) s = socket(AF_INET, SOCK_DGRAM) if config['remote_ip'] is None or config['remote_port'] is None: print 'Missing remote_ip or remote_port \n' self.usage(1) try: peer = (config['remote_ip'], int(config['remote_port'])) s.bind(("", int(config['local_port']))) print "Connection with %s:%i established" % peer while 1: r = select([f,s],[],[])[0][0] if r == f: if DEBUG: os.write(1, ">") s.sendto(os.read(f,1500), peer) else: buf, p = s.recvfrom(1500) if p != peer: print "Got packet from %s:%i instead of %s:%i" % (p + peer) print '===================' os.close(f) return if DEBUG: os.write(1, "<") os.write(f, buf) except KeyboardInterrupt: print "Stopped by user." exit() def _start_service (self, config): ''' Start tunnels. Parameters are given in config dict list. ''' fd = [] ifname = [] sock = [] peer = [] for i in range(len(config)): fd.append(os.open("/dev/net/tun", os.O_RDWR)) if config[i]['tunmode'] == 'tun': tunmode = IFF_TUN | IFF_NO_PI else: tunmode = IFF_TAP | IFF_NO_PI ifs = ioctl(fd[i], TUNSETIFF, struct.pack("16sH", "allegra_%d", tunmode)) ifname.append(ifs[:16].strip("\x00")) print "Allocated interface %s. Configure it and use it" % ifname[i] self._configure_interface(ifname[i], config[i]['addr_ip'], config[i]['addr_eth']) sock.append(socket(AF_INET, SOCK_DGRAM)) if config[i]['remote_ip'] is None or config[i]['remote_port'] is None: print 'Missing remote_ip or remote_port \n' self.usage(1) peer.append( (config[i]['remote_ip'], int(config[i]['remote_port'])) ) sock[i].bind(("", int(config[i]['local_port']))) print "Connection with %s:%i established" % peer[i] try: while 1: r_list = select(fd + sock, [], [])[0] for r in r_list: if r in fd: # read from tun/tap device and send to peer i = fd.index(r) if DEBUG: os.write(1, ">") sock[i].sendto(os.read(fd[i], 1500), peer[i]) else: # receive from peer and send to tun/tap device i = sock.index(r) buf, p = sock[i].recvfrom(1500) if DEBUG: print "Pkt from %s:%i" % p if p != peer[i]: print "Got packet from %s:%i instead of %s:%i" % (p + peer[i]) print '===================' for f in fd: os.close(f) return if DEBUG: os.write(1, "<") os.write(fd[i], buf) except KeyboardInterrupt: print "Stopped by user." exit() def set_ple_list (self, ple_list): ''' Set potential PLE nodes to connect to ''' self._ple_list = ple_list self.set_ple_conns() if DEBUG: print "Set ple_list: " + str(self._ple_list) def set_ple_conns (self, ple_conns = None): ''' Set number of intended PLE connections to input parameter or command line arg (-c) if given or try to find a default value ''' if ple_conns: self._ple_conns = ple_conns elif self._ple_conns == 0: # set default connection number to list len, max:2 # if -c is not given as input if len(self._ple_list) < 3: self._ple_conns = len(ple_list) else: self._ple_conns = 2 if DEBUG: print "Set ple_conns: " + str(self._ple_conns) def set_ple_config (self, ple_config): ''' Set ple_config dict ''' self._ple_config = ple_config def get_ple_config (self): ''' Get current ple_config dict ''' return self._ple_config def get_ple_list_from_controller (self): ''' Available PLE nodes list is requested from CONTROLLER ''' while 1: try: self._ple_list = self._jsonrpc_proxy.get_ple_list() break except (JSONRPCException, IOError): print "Waiting for JSONRPC connection..." self._ple_list = [] time.sleep(2) continue # set number of connections to a default value if it is not set yet self.set_ple_conns() if DEBUG: print self._ple_list def sort_given_ple_nodes (self, ple_list): ''' Sort given PLE nodes based on RTT measurements Return: sorted list of PLE nodes, 1st: min ''' for node in ple_list: # ignore first ping if (ping.Ping(node, timeout = 2000).do()) is None: # in case of timeout break self._delays[node] = 0 for i in range(PING_NO): delay = ping.Ping(node, timeout = 2000).do() if delay is not None: self._delays[node] += delay if DEBUG: print self._delays[node] else: # timeout occurs at least once: # dont use the node del self._delays[node] break else: # calculate average self._delays[node] /= PING_NO if DEBUG: print "delays: " + str(self._delays) # ordered ple list, 1st: min return sorted(self._delays, key=self._delays.get) def sort_ple_nodes (self): ''' Sort available PLE nodes based on RTT measurements Available nodes list is requested from CONTROLLER if it's empty ''' self._delays = {} if len(self._ple_list) == 0: self.get_ple_list_from_controller() # Sort the list self._ple_list = self.sort_given_ple_nodes(self._ple_list) if DEBUG: print self._ple_list def sort_given_ple_nodes_multi (self, ple_list): ''' Sort given PLE nodes based on PARALLEL RTT measurements using multiprocess Return: sorted list of PLE nodes, 1st: min ''' pool = multiprocessing.dummy.Pool(len(ple_list)) print "Starting RTT measurement..." delays = dict(pool.map(ping_measurement, ple_list)) #filter out None values self._delays = dict(filter(lambda item: item[1] is not None, delays.items())) if DEBUG: print self._delays # ordered ple list, 1st: min print "Sorted list:" for node in sorted(self._delays, key=self._delays.get): print "%s: %f ms" % (node, self._delays[node]) # print sorted(self._delays, key=self._delays.get) print "Done." return sorted(self._delays, key=self._delays.get) def sort_ple_nodes_multi (self): ''' Sort available PLE nodes based on PARALLEL RTT measurements using sort_given_ple_nodes_multi Available nodes list is requested from CONTROLLER if it's empty ''' self._delays = {} if len(self._ple_list) == 0: self.get_ple_list_from_controller() # Sort the list self._ple_list = self.sort_given_ple_nodes_multi(self._ple_list) if DEBUG: print self._ple_list def req_connect_given_ple_nodes (self, ple_conns = None, ple_list = None, host_shortname = None): ''' Connection request to ple_conns No. of PLE nodes from ple_list. If params are not given self vars are used ''' if ple_conns is None: ple_conns = self._ple_conns if ple_list is None: ple_list = self._ple_list if len(ple_list) < ple_conns: error(1) if host_shortname is None: host_shortname = self._host_shortname ple_config = [] my_fqdn = self.get_my_fqdn() # for hostname in ple_list[:ple_conns]: # try: # ple_config.append( # self._jsonrpc_proxy.connect_ple(hostname, my_fqdn)) # except JSONRPCException as e: # print 'failed to get info of connection to %s' % hostname try: hostnames = ple_list[:ple_conns] ple_config = self._jsonrpc_proxy.connect_ple(hostnames, my_fqdn, host_shortname) except JSONRPCException as e: print 'failed to get info of connection to %s' % hostnames self._ple_config = ple_config if DEBUG: print self._ple_config def req_connect_ple_nodes (self, ple_conns = None, host_shortname = None): ''' Connection request to closest PLE nodes (ple_conns No. of nodes) Get PLE node list and sort if necessary ''' if len(self._ple_list) == 0: # get the list from controller self.get_ple_list_from_controller() # sort the list parallel self.sort_ple_nodes_multi() if ple_conns is None: ple_conns = self._ple_conns else: self._ple_conns = ple_conns self.req_connect_given_ple_nodes(ple_conns, self._ple_list, host_shortname) if DEBUG: print self._ple_config def connect_ple_nodes (self): ''' Connect PLE nodes based on current _ple_config, configure peer interfaces ''' self._start_service(self._ple_config) def dump_config (self, ple_config): ''' Dump ple_config dict to be used by qemu startup scripts ''' my_fqdn = self.get_my_fqdn() ports = [] for conf in ple_config: dir = 'planetlab/%s/port%s' % (my_fqdn, conf['port_num']) make_dir_if_needed(dir) write_var(conf, dir + '/vars.json', json) for var in conf.keys(): write_var(conf[var], dir + '/' + var) ports.append('port' + conf['port_num']) dir = 'planetlab/%s' % my_fqdn with open(dir + '/neighbors', 'w') as f: for neighbor in ports: f.write('%s\n' % neighbor) def dump_current_config (self): ''' Dump current ple_config dict to be used by qemu startup scripts ''' self.dump_config(self._ple_config)