From 580b41a86db3b33111159479c1fe15967e96aa87 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Tue, 16 Apr 2013 15:12:15 +0200 Subject: [PATCH] rework to move KVM machines in /vservers, and for more usable ssh-derived commands in dry-run mode --- system/TestBoxQemu.py | 17 ++++++----- system/TestNode.py | 24 +++++++++------ system/TestPlc.py | 2 +- system/TestSsh.py | 71 +++++++++++++++++++++++++------------------ 4 files changed, 67 insertions(+), 47 deletions(-) diff --git a/system/TestBoxQemu.py b/system/TestBoxQemu.py index e2527e7..6d118a1 100644 --- a/system/TestBoxQemu.py +++ b/system/TestBoxQemu.py @@ -7,6 +7,9 @@ import os.path import utils from TestSsh import TestSsh +# Apriol 2013 - using /vservers/ for hosting this stuff as well, making IT-like stuff easier +KVMROOT="/vservers" + # xxx this should probably inherit TestSsh class TestBoxQemu: @@ -14,7 +17,7 @@ class TestBoxQemu: self.hostname_value=hostname self.buildname=buildname self.key=key - self.test_ssh=TestSsh(self.hostname_value,self.buildname,self.key) + self.test_ssh=TestSsh(self.hostname_value,self.buildname,self.key,root=KVMROOT) def hostname (self): return self.hostname_value @@ -22,18 +25,18 @@ class TestBoxQemu: def is_local(self): return self.test_ssh.is_local() - def run_in_buildname (self,command,background=False): + def run_in_buildname (self,command,background=False, dry_run=False): message="On %s: running %s"%(self.hostname(),command) if background: message += " &" utils.header(message) - return self.test_ssh.run_in_buildname (command,background) + return self.test_ssh.run_in_buildname (command,background, dry_run) # xxx could/should use rsync instead - def copy (self,local_file,recursive=False): - return self.test_ssh.copy (local_file,recursive) + def copy (self,local_file,recursive=False,dry_run=False): + return self.test_ssh.copy (local_file,recursive,dry_run=dry_run) - def clean_dir (self,dirname): - return self.test_ssh.clean_dir(dirname) + def rmdir (self,dirname, dry_run=False): + return self.test_ssh.rmdir(dirname, dry_run=dry_run) def mkdir (self,dirname): return self.test_ssh.mkdir(dirname) diff --git a/system/TestNode.py b/system/TestNode.py index 9a980f5..fa8281a 100644 --- a/system/TestNode.py +++ b/system/TestNode.py @@ -18,6 +18,8 @@ class TestNode: def name(self): return self.node_spec['node_fields']['hostname'] + def dry_run (self): + return self.test_plc.options.dry_run @staticmethod def is_qemu_model (model): return model.find("qemu") >= 0 @@ -142,7 +144,7 @@ class TestNode: filename="%s/%s.iso"%(self.nodedir(),self.name()) utils.header('Storing boot medium into %s'%filename) - if self.test_plc.options.dry_run: + if self.dry_run(): print "Dry_run: skipped writing of iso image" return True else: @@ -169,7 +171,7 @@ class TestNode: def nodestate_show (self): "all nodes: show PLCAPI boot_state" - if self.test_plc.options.dry_run: + if self.dry_run(): print "Dry_run: skipped getting current node state" return True state=self.test_plc.apiserver.GetNodes(self.test_plc.auth_root(), self.name(), ['boot_state'])[0]['boot_state'] @@ -186,7 +188,7 @@ class TestNode: auth=self.test_plc.auth_root() target_arch=self.test_plc.apiserver.GetPlcRelease(auth)['build']['target-arch'] conf_filename="%s/qemu.conf"%(self.nodedir()) - if self.test_plc.options.dry_run: + if self.dry_run(): print "dry_run: skipped actual storage of qemu.conf" return True utils.header('Storing qemu config for %s in %s'%(self.name(),conf_filename)) @@ -204,10 +206,11 @@ class TestNode: # if relevant, push the qemu area onto the host box if self.test_box().is_local(): return True + dry_run=self.dry_run() utils.header ("Cleaning any former sequel of %s on %s"%(self.name(),self.host_box())) - self.test_box().run_in_buildname("rm -rf %s"%self.nodedir()) + self.test_box().rmdir(self.nodedir(), dry_run=dry_run) utils.header ("Transferring configuration files for node %s onto %s"%(self.name(),self.host_box())) - return self.test_box().copy(self.nodedir(),recursive=True)==0 + return self.test_box().copy(self.nodedir(),recursive=True,dry_run=dry_run)==0 def qemu_start (self): "all nodes: start the qemu instance (also runs qemu-bridge-init start)" @@ -222,22 +225,23 @@ class TestNode: def timestamp_qemu (self): "all nodes: start the qemu instance (also runs qemu-bridge-init start)" test_box = self.test_box() - test_box.run_in_buildname("mkdir -p %s"%self.nodedir()) + test_box.run_in_buildname("mkdir -p %s"%self.nodedir(), dry_run=self.dry_run()) now=int(time.time()) - return test_box.run_in_buildname("echo %d > %s/timestamp"%(now,self.nodedir()))==0 + return test_box.run_in_buildname("echo %d > %s/timestamp"%(now,self.nodedir()), dry_run=self.dry_run())==0 def start_qemu (self): test_box = self.test_box() utils.header("Starting qemu node %s on %s"%(self.name(),test_box.hostname())) - test_box.run_in_buildname("%s/qemu-bridge-init start >> %s/log.txt"%(self.nodedir(),self.nodedir())) + test_box.run_in_buildname("%s/qemu-bridge-init start >> %s/log.txt"%(self.nodedir(),self.nodedir()), + dry_run=self.dry_run()) # kick it off in background, as it would otherwise hang test_box.run_in_buildname("%s/qemu-start-node 2>&1 >> %s/log.txt"%(self.nodedir(),self.nodedir())) def list_qemu (self): utils.header("Listing qemu for host %s on box %s"%(self.name(),self.test_box().hostname())) command="%s/qemu-kill-node -l %s"%(self.nodedir(),self.name()) - self.test_box().run_in_buildname(command) + self.test_box().run_in_buildname(command, dry_run=self.dry_run()) return True def kill_qemu (self): @@ -246,7 +250,7 @@ class TestNode: # kill the right processes utils.header("Stopping qemu for node %s on box %s"%(self.name(),self.test_box().hostname())) command="%s/qemu-kill-node %s"%(self.nodedir(),self.name()) - self.test_box().run_in_buildname(command) + self.test_box().run_in_buildname(command, dry_run=self.dry_run()) return True def gather_qemu_logs (self): diff --git a/system/TestPlc.py b/system/TestPlc.py index 3d9bf84..1f1eb37 100644 --- a/system/TestPlc.py +++ b/system/TestPlc.py @@ -192,7 +192,7 @@ class TestPlc: return utils.system(self.actual_command_in_guest(command)) def run_in_host (self,command): - return self.test_ssh.run_in_buildname(command) + return self.test_ssh.run_in_buildname(command, dry_run=self.options.dry_run) #command gets run in the plc's vm def host_to_guest(self,command): diff --git a/system/TestSsh.py b/system/TestSsh.py index 1f70b40..81b7fe8 100644 --- a/system/TestSsh.py +++ b/system/TestSsh.py @@ -48,12 +48,16 @@ class TestSsh: utils.header("WARNING : something wrong in is_local_hostname with hostname=%s"%hostname) return False - def __init__(self,hostname,buildname=None,key=None, username=None,unknown_host=True): + # some boxes have their working space in user's homedir (/root), + # some others in a dedicated area with max. space (/vservers) + # when root is not specified we use the homedir + def __init__(self,hostname,buildname=None,key=None, username=None,unknown_host=True, root=None): self.hostname=hostname self.buildname=buildname self.key=key self.username=username self.unknown_host=unknown_host + self.root=root def is_local(self): return TestSsh.is_local_hostname(self.hostname) @@ -73,27 +77,29 @@ class TestSsh: return "%s@%s"%(self.username,self.hostname) # command gets run on the right box - def actual_command (self, command,keep_stdin=False): + def actual_command (self, command, keep_stdin=False, dry_run=False): if self.is_local(): return command ssh_command = "ssh " - if not keep_stdin: - ssh_command += "-n " - ssh_command += TestSsh.std_options - if self.unknown_host: ssh_command += TestSsh.unknown_option + if not dry_run: + if not keep_stdin: + ssh_command += "-n " + ssh_command += TestSsh.std_options + if self.unknown_host: ssh_command += TestSsh.unknown_option ssh_command += self.key_part() ssh_command += "%s %s" %(self.hostname_part(),TestSsh.backslash_shell_specials(command)) return ssh_command # same in argv form - def actual_argv (self, argv,keep_stdin=False): + def actual_argv (self, argv,keep_stdin=False, dry_run=False): if self.is_local(): return argv ssh_argv=[] ssh_argv.append('ssh') - if not keep_stdin: ssh_argv.append('-n') - ssh_argv += TestSsh.std_options.split() - if self.unknown_host: ssh_argv += TestSsh.unknown_option.split() + if not dry_run: + if not keep_stdin: ssh_argv.append('-n') + ssh_argv += TestSsh.std_options.split() + if self.unknown_host: ssh_argv += TestSsh.unknown_option.split() ssh_argv += self.key_part().split() ssh_argv.append(self.hostname_part()) ssh_argv += argv @@ -105,7 +111,7 @@ class TestSsh: sys.stdout.flush() def run(self, command,message=None,background=False,dry_run=False): - local_command = self.actual_command(command) + local_command = self.actual_command(command, dry_run=dry_run) if dry_run: utils.header("DRY RUN " + local_command) return 0 @@ -113,25 +119,33 @@ class TestSsh: self.header(message) return utils.system(local_command,background) - def clean_dir (self,dirname): + def run_in_buildname (self,command, background=False, dry_run=False): if self.is_local(): - return 0 - return self.run("rm -rf %s"%dirname) + return utils.system(command,background) + self.create_buildname_once(dry_run) + return self.run("cd %s ; %s"%(self.fullname(self.buildname),command), + background=background, dry_run=dry_run) - def mkdir (self,dirname=None,abs=False): + def fullname (self,dirname): + if self.root==None: return dirname + else: return os.path.join(self.root,dirname) + + def mkdir (self,dirname=None,abs=False,dry_run=False): if self.is_local(): if dirname: return os.path.mkdir(dirname) return 0 + # ab. paths remain as-is if not abs: if dirname: dirname="%s/%s"%(self.buildname,dirname) else: dirname=self.buildname + dirname=self.fullname(dirname) if dirname=='.': return - return self.run("mkdir -p %s"%dirname) + return self.run("mkdir -p %s"%dirname,dry_run=dry_run) - def rmdir (self,dirname=None): + def rmdir (self,dirname=None, dry_run=False): if self.is_local(): if dirname: return shutil.rmtree(dirname) @@ -140,34 +154,33 @@ class TestSsh: dirname="%s/%s"%(self.buildname,dirname) else: dirname=self.buildname - return self.run("rm -rf %s"%dirname) + dirname=self.fullname(dirname) + return self.run("rm -rf %s"%dirname, dry_run=dry_run) - def create_buildname_once (self): + def create_buildname_once (self, dry_run): if self.is_local(): return # create remote buildname on demand try: self.buildname_created except: - self.mkdir() + self.mkdir(dry_run=dry_run) self.buildname_created=True - def run_in_buildname (self,command, background=False): - if self.is_local(): - return utils.system(command,background) - self.create_buildname_once() - return self.run("cd %s ; %s"%(self.buildname,command),background) - - def copy (self,local_file,recursive=False): + def copy (self,local_file,recursive=False,dry_run=False): if self.is_local(): return 0 self.create_buildname_once() scp_command="scp " - scp_command += TestSsh.std_options + if not dry_run: + scp_command += TestSsh.std_options if recursive: scp_command += "-r " scp_command += self.key_part() scp_command += "%s %s:%s/%s"%(local_file,self.hostname_part(), - self.buildname,os.path.basename(local_file) or ".") + self.fullname(self.buildname),os.path.basename(local_file) or ".") + if dry_run: + utils.header ("DRY RUN TestSsh.copy %s"%scp_command) + return True return utils.system(scp_command) def copy_abs (self,local_file,remote_file,recursive=False): -- 2.43.0