X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Ftools%2Fscripts%2Ftopo_reservation.py;h=c1b5c4658e544ae2674ea7a4b810b59aa5f4e9e6;hp=9f26677f427f9fa8dbc563c985ee5baf823552a6;hb=HEAD;hpb=6f1ff57c83763556450e8bfcb4571a9c017abe70 diff --git a/resources/tools/scripts/topo_reservation.py b/resources/tools/scripts/topo_reservation.py index 9f26677f42..f2d18bcafd 100755 --- a/resources/tools/scripts/topo_reservation.py +++ b/resources/tools/scripts/topo_reservation.py @@ -1,6 +1,6 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 -# Copyright (c) 2019 Cisco and/or its affiliates. +# Copyright (c) 2022 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -20,14 +20,15 @@ simultaneous use of nodes listed in topology file. As source of truth, TG node from the topology file is used. """ -import sys import argparse +import sys import yaml from resources.libraries.python.ssh import exec_cmd -RESERVATION_DIR = "/tmp/reservation_dir" +RESERVATION_DIR = u"/tmp/reservation_dir" +RESERVATION_NODE = u"TG" def diag_cmd(node, cmd): @@ -35,12 +36,12 @@ def diag_cmd(node, cmd): :param node: Node object as parsed from topology file to execute cmd on. :param cmd: Command to execute. - :type ssh: dict + :type node: dict :type cmd: str """ - print "+", cmd + print(f"+ {cmd}") _, stdout, _ = exec_cmd(node, cmd) - print stdout + print(stdout) def main(): @@ -53,23 +54,11 @@ def main(): 2. List contents of test.url file in the dir. 3. Create reservation dir. 4. Touch file according to -r option. - 5. Put -u option string to file test.url - From these 5 steps, 1 and 2 are performed always, their RC ignored. + From these 4 steps, 1 and 2 are performed always, their RC ignored. RC of step 3 gives the overall result. - If the result is success, steps 4-5 are executed without any output, + If the result is success, step 4 is executed without any output, their RC is ignored. - The two files in reservation dir are there for reporting - which test run holds the reservation, so people can manually fix the testbed - if the rest run has been aborted, or otherwise failed to unregister. - - The two files have different audiences. - - The URL content is useful for people scheduling their test runs - and wondering why the reservation takes so long. - For them, a URL (if available) to copy and paste into browser - to see which test runs are blocking testbeds is the most convenient. - The "run tag" as a filename is useful for admins accessing the testbed via a graphical terminal, which does not allow copying of text, as they need less keypresses to identify the test run holding the testbed. @@ -85,61 +74,60 @@ def main(): Python returns on encountering and unexcepted exception. """ parser = argparse.ArgumentParser() - parser.add_argument("-t", "--topo", required=True, - help="Topology file") - parser.add_argument("-c", "--cancel", help="Cancel reservation", - action="store_true") - parser.add_argument("-r", "--runtag", required=False, default="Unknown", - help="Identifier for test run suitable as filename") - parser.add_argument("-u", "--url", required=False, default="Unknown", - help="Identifier for test run suitable as URL") + parser.add_argument(u"-t", u"--topo", required=True, help=u"Topology file") + parser.add_argument( + u"-c", u"--cancel", help=u"Cancel reservation", action=u"store_true" + ) + parser.add_argument( + u"-r", u"--runtag", required=False, default=u"Unknown", + help=u"Identifier for test run suitable as filename" + ) args = parser.parse_args() - with open(args.topo, "r") as topo_file: - topology = yaml.load(topo_file.read())['nodes'] + with open(args.topo, u"rt") as topo_file: + topology = yaml.safe_load(topo_file.read())[u"nodes"] # Even if TG is not guaranteed to be a Linux host, # we are using it, because testing shows SSH access to DUT # during test affects its performance (bursts of lost packets). try: - tgn = topology["TG"] + node = topology[RESERVATION_NODE] except KeyError: - print "Topology file does not contain 'TG' node" + print(f"Topology file does not contain '{RESERVATION_NODE}' node") return 1 # For system reservation we use mkdir it is an atomic operation and we can # store additional data (time, client_ID, ..) within reservation directory. if args.cancel: - ret, _, err = exec_cmd(tgn, "rm -r {}".format(RESERVATION_DIR)) - if ret: - print "Cancellation unsuccessful:\n{}".format(err) - return ret + ret, _, err = exec_cmd(node, f"rm -r {RESERVATION_DIR}") + # If connection is refused, ret==None. + if ret != 0: + print(f"Cancellation unsuccessful:\n{err!r}") + return 1 + return 0 # Before critical section, output can be outdated already. - print "Diagnostic commands:" - # -d and * are to supress "total ", see https://askubuntu.com/a/61190 - diag_cmd(tgn, "ls --full-time -cd '{dir}'/*".format(dir=RESERVATION_DIR)) - diag_cmd(tgn, "head -1 '{dir}/run.url'".format(dir=RESERVATION_DIR)) - print "Attempting reservation." + print(u"Diagnostic commands:") + # -d and * are to suppress "total ", see https://askubuntu.com/a/61190 + diag_cmd(node, f"ls --full-time -cd '{RESERVATION_DIR}'/*") + print(u"Attempting testbed reservation.") # Entering critical section. - # TODO: Add optional argument to exec_cmd_no_error to make it - # sys.exit(ret) instead raising? We do not want to deal with stacktrace. - ret, _, err = exec_cmd(tgn, "mkdir '{dir}'".format(dir=RESERVATION_DIR)) + ret, _, _ = exec_cmd(node, f"mkdir '{RESERVATION_DIR}'") # Critical section is over. - if ret: - print "Already reserved by another job:\n{}".format(err) + if ret is None: + print(u"Failed to connect to testbed.") + return 1 + if ret != 0: + _, stdo, _ = exec_cmd(node, f"ls '{RESERVATION_DIR}'/*") + print(f"Testbed already reserved by:\n{stdo}") return 2 # Here the script knows it is the only owner of the testbed. - print "Success, writing test run info to reservation dir." - # TODO: Add optional argument to exec_cmd_no_error to print message - # to console instead raising? We do not want to deal with stacktrace. - ret2, _, err = exec_cmd( - tgn, "touch '{dir}/{runtag}' && ( echo '{url}' > '{dir}/run.url' )"\ - .format(dir=RESERVATION_DIR, runtag=args.runtag, url=args.url)) - if ret2: - print "Writing test run info failed, but continuing anyway:\n{}".format( - err) + print(u"Reservation success, writing additional info to reservation dir.") + ret, _, err = exec_cmd( + node, f"touch '{RESERVATION_DIR}/{args.runtag}'") + if ret != 0: + print(f"Writing test run info failed, but continuing anyway:\n{err!r}") return 0 -if __name__ == "__main__": +if __name__ == u"__main__": sys.exit(main())