From: Anton Chevychalov Date: Wed, 30 Nov 2016 11:59:51 +0000 (+0300) Subject: [Jenkins] ssh access refactoring X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=f807e6b44add97c098d15669e8ccfe434650a9d7;p=tools%2Fsustaining.git [Jenkins] ssh access refactoring Add .gitignore and class for common ssh operations. Change-Id: I01cacf7b0527a849d6ccff1db5d65ca3d6ea689b --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d111a46 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/jenkins/build_cluster/*pyc +/jenkins/build_cluster/.*sw? + diff --git a/jenkins/build_cluster/build_cluster.py b/jenkins/build_cluster/build_cluster.py index b076afb..a279b94 100755 --- a/jenkins/build_cluster/build_cluster.py +++ b/jenkins/build_cluster/build_cluster.py @@ -15,7 +15,9 @@ import netaddr import scancodes # CONST -UPDATE_HELPER="update_helper.sh" +UPDATE_HELPER = "update_helper.sh" +SSH_PARAMS = ["-o", "UserKnownHostsFile=/dev/null", + "-o", "StrictHostKeyChecking=no"] cfg = dict() is_new = False @@ -73,6 +75,33 @@ try: except: dnl = None +class SSHHost: + def __init__(self, conn_line=None, usr=None, subnet=None, pswd="r00tme"): + if subnet is not None: + self.conn_line = self._calculate_conn_line(usr, subnet) + + if conn_line is not None: + self.conn_line = conn_line + + self.pswd=pswd + + def _calculate_conn_line(self, usr, subnet): + admip = str(subnet.ip + 2) + return "{usr}@{admip}".format(usr=usr, admip=admip) + + def execute(self, command): + return sshpass( + psw = self.pswd, + ssh_cmd = ["ssh"]+SSH_PARAMS+[self.conn_line]+command, + ) + + def put_file(self, filename, dest="/tmp/"): + return sshpass ( + psw = self.pswd, + ssh_cmd = ["scp"]+SSH_PARAMS+['./'+filename,self.conn_line+":"+dest], + ) + + def pprint_dict(subj): if not isinstance(subj, dict): return False @@ -443,15 +472,13 @@ def inject_ifconfig_ssh(): print("{0}...".format(retries), end='') time.sleep(60) -def sshpass_admin_node(psw,ssh_cmd): +def sshpass(psw,ssh_cmd): cmd = [ "sshpass", "-p", psw, ] + ssh_cmd - print (cmd) - proc = subprocess.Popen( cmd, stdin=dnl, @@ -462,43 +489,25 @@ def sshpass_admin_node(psw,ssh_cmd): if proc.returncode == 0: return True else: + print("ERROR: command "+' '.join(cmd)+" failed.") return False -def admin_ssh_conn_line(usr,subnet): - admip = str(subnet.ip + 2) - return "{usr}@{admip}".format(usr=usr, admip=admip) -def copy_update_helper(conn_line,psw): - return sshpass_admin_node (psw,ssh_cmd=[ - "scp", - "-o", - "UserKnownHostsFile=/dev/null", - "-o", - "StrictHostKeyChecking=no", - "./"+UPDATE_HELPER, - conn_line+":/tmp/",]) - -def do_update(conn_line,psw): - if copy_update_helper(conn_line,psw): - return sshpass_admin_node( - psw=psw, - ssh_cmd=["ssh", - "-o", - "UserKnownHostsFile=/dev/null", - "-o", - "StrictHostKeyChecking=no", - conn_line, - "/tmp/"+UPDATE_HELPER,],) +def do_update(node): + if node.put_file(UPDATE_HELPER): + return node.execute(["/tmp/"+UPDATE_HELPER]) else: print ("ERROR: Unable to copy update script to admin node") return False + def start_slaves(): for num in range(cfg["NODES_COUNT"]): name = "{0}_slave_{1}".format(cfg["ENV_NAME"], num) print ("Starting: {0}".format(name)) start_node(name) + def wait_for_api_is_ready(): cmd = ["sshpass", "-p", cfg["FUEL_SSH_PASSWORD"], "ssh", "-o" "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", @@ -706,10 +715,12 @@ def main(): wait_for_api_is_ready() + admin_node=SSHHost(usr = cfg["FUEL_SSH_USERNAME"], + subnet=cfg["ADMIN_SUBNET"], + psw = cfg["FUEL_SSH_PASSWORD"],) + if cfg["UPDATE_FUEL"]=="true": - if do_update( - admin_ssh_conn_line(usr = cfg["FUEL_SSH_USERNAME"],subnet=cfg["ADMIN_SUBNET"]), - psw = cfg["FUEL_SSH_PASSWORD"],): + if do_update(admin_node): print("fuel update complete") else: print("ERROR: unable to update fuel") diff --git a/jenkins/build_cluster/build_cluster_test.py b/jenkins/build_cluster/build_cluster_test.py index d09ff58..53e6571 100755 --- a/jenkins/build_cluster/build_cluster_test.py +++ b/jenkins/build_cluster/build_cluster_test.py @@ -1,41 +1,47 @@ #!/usr/bin/env python import build_cluster +import netaddr -CONNECT_LINE = "root@621_admin" -PSWD= "r00tme" +CONNECT_LINE = "root@780_admin" +PSWD = "r00tme" -def test_bool(name,func): + +def test_bool(name, func): if func: print "\033[32mOK\033[00m - "+name else: print "\033[31mOK\033[00m - "+name + def main(): - test_bool("sshpass_admin_node", - build_cluster.sshpass_admin_node ( - psw=PSWD, - ssh_cmd=["ssh", CONNECT_LINE , "hostname"] - ) - ) - - test_bool("sshpass_admin_node fail exit code", - not build_cluster.sshpass_admin_node ( - psw=PSWD, - ssh_cmd=["ssh", CONNECT_LINE , "exit 1"] - ) - ) - - test_bool("copy_update_helper", - build_cluster.copy_update_helper (CONNECT_LINE, PSWD) - ) - -# NOTE: can take to many time... -# test_bool("do update", -# build_cluster.do_update (CONNECT_LINE, PSWD) -# ) + node = build_cluster.SSHHost(conn_line=CONNECT_LINE, + pswd=PSWD) + + test_bool("ssh execute", + node.execute(["hostname"])) + + test_bool("ssh execute fail", + not node.execute(["exit", "1"])) + + test_bool("scp put file", + node.put_file("./update_helper.sh")) + + test_bool("scp put file check file", + node.execute(["test", "-f","/tmp/update_helper.sh"])) + + test_bool("scp put file remove file", + node.execute(["rm", "-f","/tmp/update_helper.sh"])) + + test_bool("scp put file check file", + not node.execute(["test", "-f","/tmp/update_helper.sh"])) + + # NOTE: can take too many time... + test_bool("do update", + build_cluster.do_update (node)) + if __name__ == "__main__": main()