diff options
-rw-r--r-- | rumba/prototypes/irati.py | 56 | ||||
-rw-r--r-- | rumba/prototypes/irati_rsa | 27 | ||||
-rw-r--r-- | rumba/ssh_support.py | 96 | ||||
-rw-r--r-- | rumba/testbeds/qemu.py | 13 |
4 files changed, 107 insertions, 85 deletions
diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py index edc49c6..89c4fe4 100644 --- a/rumba/prototypes/irati.py +++ b/rumba/prototypes/irati.py @@ -31,9 +31,6 @@ import rumba.prototypes.irati_templates as irati_templates # An experiment over the IRATI implementation -from rumba import ssh_support - - class Experiment(mod.Experiment): @staticmethod @@ -47,6 +44,7 @@ class Experiment(mod.Experiment): def __init__(self, testbed, nodes=None): mod.Experiment.__init__(self, testbed, nodes) self.manager = False + self.conf_files = None if self.testbed.username == 'root': self.sudo = self.fake_sudo @@ -94,7 +92,7 @@ class Experiment(mod.Experiment): print("[IRATI experiment] start") print("Setting up IRATI on the nodes...") self.setup() - self.write_conf() + self.conf_files = self.write_conf() self.bootstrap_network() self.run_experiment() print("[IRATI experiment] end") @@ -107,45 +105,34 @@ class Experiment(mod.Experiment): :return: """ name = node.name - gen_files_conf = 'shimeth.%(name)s.*.dif da.map %(name)s.ipcm.conf' % { - 'name': name} - if any(node in dif.members for dif in self.dif_ordering): - gen_files_conf = ' '.join( - [gen_files_conf, 'normal.%(name)s.*.dif' % {'name': name}]) + gen_files_conf = self.conf_files[node] + ['da.map'] dir_path = os.path.dirname(os.path.abspath(__file__)) gen_files_bin = 'enroll.py' - gen_files_conf_full = \ - ' '.join([self.conf_dir(x) for x in gen_files_conf.split()]) - gen_files_bin_full = os.path.join(dir_path, 'enroll.py') + gen_files_conf_full = [self.conf_dir(x) for x in gen_files_conf] + gen_files_bin_full = [os.path.join(dir_path, 'enroll.py')] ipcm_components = ['scripting', 'console'] if self.manager: ipcm_components.append('mad') ipcm_components = ', '.join(ipcm_components) - gen_files = ' '.join([gen_files_conf_full, gen_files_bin_full]) + gen_files = gen_files_conf_full + gen_files_bin_full - sshopts = ('-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' - ' -o IdentityFile=%s' - % (os.path.join(dir_path, 'irati_rsa',))) format_args = {'name': name, 'ssh': node.ssh_config.port, 'username': self.testbed.username, 'genfiles': gen_files, - 'genfilesconf': gen_files_conf, + 'genfilesconf': ' '.join(gen_files_conf), 'genfilesbin': gen_files_bin, - 'sshopts': sshopts, 'installpath': '/usr', 'verb': 'DBG', 'ipcmcomps': ipcm_components} try: - print('DEBUG: executing >> ' - 'scp %(sshopts)s -r -P %(ssh)s ' - '%(genfiles)s %(username)s@localhost:' - % format_args) - subprocess.check_call(('scp %(sshopts)s -r -P %(ssh)s ' - '%(genfiles)s %(username)s@localhost:' - % format_args), shell=True) + # TODO: watch out for empty path... + ssh.copy_paths_to_testbed(self.testbed, + node.ssh_config, + gen_files, + '') except subprocess.CalledProcessError as e: raise Exception(str(e)) @@ -154,7 +141,8 @@ class Experiment(mod.Experiment): cmds = [self.sudo('hostname %(name)s' % format_args), self.sudo('chmod a+rw /dev/irati'), self.sudo('mv %(genfilesconf)s /etc' % format_args), - self.sudo('mv %(genfilesbin)s /usr/bin') % format_args] + self.sudo('mv %(genfilesbin)s /usr/bin') % format_args, + self.sudo('chmod a+x /usr/bin/enroll.py') % format_args] # TODO: is the port up on the VM at this point? @@ -167,7 +155,7 @@ class Experiment(mod.Experiment): # print('Credentials:') # print(node.ssh_config.hostname, node.ssh_config.port, # self.testbed.username, self.testbed.password) - ssh_support.execute_commands(self.testbed, node.ssh_config, cmds) + ssh.execute_commands(self.testbed, node.ssh_config, cmds) def enroll_nodes(self): """Runs the enrollments one by one, respecting dependencies""" @@ -198,9 +186,9 @@ class Experiment(mod.Experiment): # print(e['enrollee'].ssh_config.hostname, # e['enrollee'].ssh_config.port, # self.testbed.username, self.testbed.password) - ssh_support.execute_command(self.testbed, - e['enrollee'].ssh_config, - cmd) + ssh.execute_command(self.testbed, + e['enrollee'].ssh_config, + cmd) def write_conf(self): """Write the configuration files""" @@ -210,6 +198,7 @@ class Experiment(mod.Experiment): ipcp2shim_map = {} node2id_map = {} mgmt_dif_name = 'NMS' + conf_files = {} # dict of per-nod conf files # TODO: what format are the mappings registered in? Is this ok? app_mappings = [] @@ -298,6 +287,8 @@ class Experiment(mod.Experiment): }, indent=4, sort_keys=True)) fout.close() + conf_files.setdefault(node, []).append( + 'shimeth.%s.%s.dif' % (node.name, shim.name)) # Run over dif_ordering array, to make sure each IPCM config has # the correct ordering for the ipcProcessesToCreate list of operations. @@ -360,6 +351,8 @@ class Experiment(mod.Experiment): node_file, indent=4, sort_keys=True) + conf_files.setdefault(node, []).append( + '%s.ipcm.conf' % (node.name,)) for dif in self.dif_ordering: # type: mod.DIF dif_conf = difconfs.get(dif.name, None) @@ -373,3 +366,6 @@ class Experiment(mod.Experiment): dif_conf_file, indent=4, sort_keys=True) + conf_files.setdefault(node, []).append( + 'normal.%s.%s.dif' % (node.name, dif.name)) + return conf_files diff --git a/rumba/prototypes/irati_rsa b/rumba/prototypes/irati_rsa deleted file mode 100644 index 8119a76..0000000 --- a/rumba/prototypes/irati_rsa +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAyfuwhIYMa2pCcbLYfeDblxaXNxLcJS8aJFjpwPVdXQoTwO79 -BmbZXFObrdxy3paaYyJBAIpOyAcn4B9oEcpHF7J6+IvDA6TpOf45tZzqVRdZxFd7 -ESPlleCpRxTWTmIFiR8j734v8sj0CXYjiegjhS9izhPobjz3ZaTDO4xfQbQs37JF -7Xdcbjph/8ExqYyvz9yxU5rbCr3u7AurBRM/o5kfV5Ps+52WXNJT2RTjgQjmL1PQ -0/K8DATPKW9ns1d90Zguf0cE2oZiUn85ukuvVAAOsvO0GOpncFhEUrTLCw/DMayP -Wk1mjL1jJDeYbqf1cnOG+Wzt5glueKzSGhh6ewIDAQABAoIBAGN62QeMVhWZcjw5 -j7L/ymdxsuxnF5IgzslUGVz1/BPU4MHHc0tx4GA+tZA94T2MA2IL/uPbOs396D/U -eBc6/yTGvRYpD9V9pXjwo0+1hxx9sbKoO27HtU3KJtVhh+N3F67fbX2JMuhq3PbD -/uDvOn9gRVOmLnYNBPRE3/s2ObxLtkbT4QIuSF/XItxECBOwWNyTYdOmqhoz6XzA -OPN9mGsKPMevWoKTfLffuMncIEyEEtV2Jnck/cHPha2GGuzty+faOGSF7GwHOpfu -DQTK30lUFRmlHnId5UIRG0J+MfSJhk/VillJwvUFmCYgH5Ur7htDTER7JIeU8ym6 -YxY3HDECgYEA+fnqiqmst9LNXnjGnIAtnIi11DsmwDQaxW+kNvXvJsEWWboUbcPs -q/Fzm0ACMLHARje4wynzIrBY5Iw8qzTswzPFo9CO4MNw/hvMO1iB0Dvo8rWqMJv4 -b2qsuo9r4QkVt53K6WVG/h9Ua/mqr2AQOaATj1ScGKpx0g10GjVqDGcCgYEAztm1 -NKxwqw/j1Pn5AnRRIMkDgO2O6fXKZEgoBdXDWrlHn4vr8fspNE+DMuonQS8GY7Xd -a+APpPqNk32WKDCfeuKNZX7gXCnV39GOhNrhpfT14/dea1YEQ03vcxVD1aqkw2jl -Y+qOG2kDBpYkPPEf5od6cfFvUet15d8NBwJXlM0CgYBypkcGNe/7l3mNvMMLAFbr -FmCe6EpLmRo2N5APjRiUo7aGjKvV9ChWbDVjnSXkA4J2MhRRnqne3RbIK/GfbHSy -ysn46iy9taXbRhCTn3JaeT/MIbne9YoqP7jdD+6glbQaNQrdpQ+8ec4Uf7vjF6IZ -a+vMrzewsGvntTfs1VbAPQKBgQCl+8LRkrISQnzzEOfFFWtoYIUENxxgFxCiadhb -3k2Vhmm32EKr+Xv18vv3pjd7se1xo6UbBD/phfiHatZMR8Ahjpwh3q7Qpe1uXaz8 -ZNt/HVMW7BADF5HyJB7J/T1ivjzaZVj1VWlVC24XIfHQSTjs9rfFqRRH6ya/H75H -apS23QKBgCj4TWnRtMsEaZZIamgzxMw1eUdYH27ZeaG0Do+hZ1XGixq4CWxCqxVg -nwbXRkRYwqI+2zzsaeNji4OX6wJdO7lZntuk4v6O0WeY9aJxGaLkYaRk5eF2TLyW -IVQbpcC/q1fnCo3HjWxR3w8QYmsQi97AC7xUMsjqwntIGV1QrR7s ------END RSA PRIVATE KEY----- diff --git a/rumba/ssh_support.py b/rumba/ssh_support.py index 30ada62..3ed4208 100644 --- a/rumba/ssh_support.py +++ b/rumba/ssh_support.py @@ -17,9 +17,10 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301 USA - +import os import paramiko + def get_ssh_client(): ssh_client = paramiko.SSHClient() ssh_client.load_system_host_keys() @@ -27,6 +28,7 @@ def get_ssh_client(): return ssh_client + def _print_stream(stream): o = str(stream.read()).strip('b\'\"\\n') if o != "": @@ -35,6 +37,7 @@ def _print_stream(stream): print(oi) return o + def execute_commands(testbed, ssh_config, commands, time_out=3): ''' Remote execution of a list of shell command on hostname. By @@ -71,6 +74,7 @@ def execute_commands(testbed, ssh_config, commands, time_out=3): print(str(e)) return + def execute_command(testbed, ssh_config, command, time_out=3): ''' Remote execution of a list of shell command on hostname. By @@ -89,6 +93,7 @@ def execute_command(testbed, ssh_config, command, time_out=3): if o != None: return o + def copy_file_to_testbed(testbed, ssh_config, text, file_name): ''' Write a string to a given remote file. @@ -125,6 +130,58 @@ def copy_file_to_testbed(testbed, ssh_config, text, file_name): except Exception as e: print(str(e)) + +def copy_paths_to_testbed(testbed, ssh_config, paths, destination): + ''' + Write a string to a given remote file. + Overwrite the complete file if it already exists! + + @param testbed: testbed info + @param ssh_config: ssh config of the node + @param paths: source paths (local) as an iterable + @param destination: destination folder name (remote) + ''' + ssh_client = get_ssh_client() + + if destination is not '' and not destination.endswith('/'): + destination = destination + '/' + + try: + ssh_client.connect(ssh_config.hostname, ssh_config.port, + testbed.username, + testbed.password, + look_for_keys=True) + + sftp_client = ssh_client.open_sftp() + + for path in paths: + file_name = os.path.basename(path) + dest_file = destination + file_name + print("Copying %s to %s@%s:%s path %s" % ( + path, + testbed.username, + ssh_config.hostname, + ssh_config.port, + dest_file)) + sftp_client.put(path, dest_file) + + except Exception as e: + print(str(e)) + + +def copy_path_to_testbed(testbed, ssh_config, path, destination): + ''' + Write a string to a given remote file. + Overwrite the complete file if it already exists! + + @param testbed: testbed info + @param ssh_config: ssh config of the node + @param path: source path (local) + @param destination: destination folder name (remote) + ''' + copy_paths_to_testbed(testbed, ssh_config, [path], destination) + + def setup_vlan(testbed, node, vlan_id, int_name): ''' Gets the interface (ethx) to link mapping @@ -134,22 +191,27 @@ def setup_vlan(testbed, node, vlan_id, int_name): @param vlan_id: the VLAN id @param int_name: the name of the interface ''' + if testbed.username == 'root': + def sudo(s): + return s + else: + def sudo(s): + return 'sudo ' + s + print("Setting up VLAN on node " + node.name) - cmds = list() - cmd = "sudo ip link add link " + \ - str(int_name) + \ - " name " + str(int_name) + \ - "." + str(vlan_id) + \ - " type vlan id " + str(vlan_id) - cmds.append(cmd) - cmd = "sudo ifconfig " + \ - str(int_name) + "." + \ - str(vlan_id) + " up" - cmds.append(cmd) - cmd = "sudo ethtool -K " + \ - str(int_name) + " rxvlan off" - cmds.append(cmd) - cmd = "sudo ethtool -K " + \ - str(int_name) + " txvlan off" + args = {'ifname': str(int_name), 'vlan': str(vlan_id)} + + cmds = [sudo("ip link set %(ifname)s up" + % args), + sudo("ip link add link %(ifname)s name " + "%(ifname)s.%(vlan)s type vlan id %(vlan)s" + % args), + sudo("ifconfig %(ifname)s.%(vlan)s up" + % args)] + # TODO: is ethtool needed? Should install or check if it is present. + # cmds += [sudo("ethtool -K %(ifname)s rxvlan off" + # % args), + # sudo("ethtool -K %(ifname)s txvlan off" + # % args)] execute_commands(testbed, node.ssh_config, cmds) diff --git a/rumba/testbeds/qemu.py b/rumba/testbeds/qemu.py index 8ccc704..174b860 100644 --- a/rumba/testbeds/qemu.py +++ b/rumba/testbeds/qemu.py @@ -103,17 +103,8 @@ class Testbed(mod.Testbed): vlan = next_vlan next_vlan += 10 assigned_vlan[port['shim'].name] = vlan - args = {'vlan': vlan, 'port': ipcp.ifname} - cmds = ['ip link set %(port)s up' - % args, - 'ip link add link %(port)s name %(port)s.%(vlan)s ' - 'type vlan id %(vlan)s' - % args, - 'ip link set %(port)s.%(vlan)s up' - % args] - ssh_support.execute_commands(self, - node.ssh_config, - cmds) + ssh_support.setup_vlan(self, node, + vlan, ipcp.ifname) def swap_in(self, experiment): """ |