From fac816d969d1fd4fcd5e4f9ee1729da4c6be3f7f Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Mon, 15 May 2023 14:18:47 +0800 Subject: [PATCH] [TestbedV2]Add a script to get duts version. (#8290) Description of PR In TestbedV2, we need a script to get duts version for futher process. So, we add this script using new sonichost, and this script will return a list contains the output of show version command. What is the motivation for this PR? In TestbedV2, we need a script to get duts version for futher process. So, we add this script using new sonichost, and this script will return a list contains the output of show version command. How did you verify/test it? ``` yutongzhang@89d3967bee2a:/data/sonic-mgmt/tests$ python ../.azure-pipelines/get_dut_version.py -i veos_vtb -t vms-kvm-t0 --tbfile vtestbed.yaml --log-level info /usr/local/lib/python2.7/dist-packages/ansible/parsing/vault/__init__.py:44: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in the next release. from cryptography.exceptions import InvalidSignature 2023-05-12 05:55:59,156 get_dut_version.py#53 INFO - Initializing hosts Friday 12 May 2023 05:55:59 +0000 (0:00:00.048) 0:00:00.048 ************ {u'vlab-01': [u'', u'SONiC Software Version: SONiC.master.217155-43683d8ce', u'Distribution: Debian 11.6', u'Kernel: 5.10.0-18-2-amd64', u'Build commit: 43683d8ce', u'Build date: Sun Feb 12 12:36:40 UTC 2023', u'Built by: AzDevOps@vmss-soni000H4X', u'', u'Platform: x86_64-kvm_x86_64-r0', u'HwSKU: Force10-S6000', u'ASIC: vs', u'ASIC Count: 1', u'Serial Number: N/A', u'Model Number: N/A', u'Hardware Revision: N/A', u'Uptime: 05:55:59 up 2:58, 0 users, load average: 0.19, 0.09, 0.06', u'Date: Fri 12 May 2023 05:55:59', u'', u'Docker images:', u'REPOSITORY TAG IMAGE ID SIZE', u'docker-orchagent latest fab81f7965ca 385MB', u'docker-orchagent master.217155-43683d8ce fab81f7965ca 385MB', u'docker-dhcp-relay latest 798c1d8e105e 366MB', u'docker-fpm-frr latest b90063fc114e 403MB', u'docker-fpm-frr master.217155-43683d8ce b90063fc114e 403MB', u'docker-macsec latest a5d96f600dde 376MB', u'docker-eventd latest b078e56f320c 357MB', u'docker-eventd master.217155-43683d8ce b078e56f320c 357MB', u'docker-teamd latest 48c07e3fb87b 374MB', u'docker-teamd master.217155-43683d8ce 48c07e3fb87b 374MB', u'docker-snmp latest 89d581a798c9 397MB', u'docker-snmp master.217155-43683d8ce 89d581a798c9 397MB', u'docker-platform-monitor latest 59d1ec13726a 479MB', u'docker-platform-monitor master.217155-43683d8ce 59d1ec13726a 479MB', u'docker-gbsyncd-vs latest b16d861d199a 367MB', u'docker-gbsyncd-vs master.217155-43683d8ce b16d861d199a 367MB', u'docker-sonic-telemetry latest 28213beda767 655MB', u'docker-sonic-telemetry master.217155-43683d8ce 28213beda767 655MB', u'docker-sonic-p4rt latest 49c358ff0d13 927MB', u'docker-sonic-p4rt master.217155-43683d8ce 49c358ff0d13 927MB', u'docker-mux latest 14a8564a6e4e 405MB', u'docker-mux master.217155-43683d8ce 14a8564a6e4e 405MB', u'docker-lldp latest 6e2eff7f72fb 399MB', u'docker-lldp master.217155-43683d8ce 6e2eff7f72fb 399MB', u'docker-database latest 62cfbd21d70a 357MB', u'docker-database master.217155-43683d8ce 62cfbd21d70a 357MB', u'docker-router-advertiser latest a95354dff017 357MB', u'docker-router-advertiser master.217155-43683d8ce a95354dff017 357MB', u'docker-nat latest 13fbcda3340f 351MB', u'docker-nat master.217155-43683d8ce 13fbcda3340f 351MB', u'docker-sflow latest a3c41fe14a6b 349MB', u'docker-sflow master.217155-43683d8ce a3c41fe14a6b 349MB', u'docker-sonic-mgmt-framework latest b7065fdb0839 477MB', u'docker-sonic-mgmt-framework master.217155-43683d8ce b7065fdb0839 477MB', u'docker-syncd-vs latest 34101b26e558 346MB', u'docker-syncd-vs master.217155-43683d8ce 34101b26e558 346MB']} ``` Signed-off-by: Yutong Zhang --- .azure-pipelines/get_dut_version.py | 112 ++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 .azure-pipelines/get_dut_version.py diff --git a/.azure-pipelines/get_dut_version.py b/.azure-pipelines/get_dut_version.py new file mode 100644 index 00000000000..47736bfd572 --- /dev/null +++ b/.azure-pipelines/get_dut_version.py @@ -0,0 +1,112 @@ +import argparse +import logging +import os +import sys + +_self_dir = os.path.dirname(os.path.abspath(__file__)) +base_path = os.path.realpath(os.path.join(_self_dir, "..")) +if base_path not in sys.path: + sys.path.append(base_path) +ansible_path = os.path.realpath(os.path.join(_self_dir, "../ansible")) +if ansible_path not in sys.path: + sys.path.append(ansible_path) + +from devutil.devices import init_localhost, init_testbed_sonichosts # noqa E402 + +logger = logging.getLogger(__name__) + +RC_INIT_FAILED = 1 +RC_GET_DUT_VERSION_FAILED = 2 + + +def get_duts_version(sonichosts): + try: + ret = {} + duts_version = sonichosts.command("show version") + for dut, version in duts_version.items(): + ret[dut] = version["stdout_lines"] + return ret + except Exception as e: + logger.error("Failed to get DUT version: {}".format(e)) + sys.exit(RC_GET_DUT_VERSION_FAILED) + + +def validate_args(args): + _log_level_map = { + "debug": logging.DEBUG, + "info": logging.INFO, + "warning": logging.WARNING, + "error": logging.ERROR, + "critical": logging.CRITICAL + } + logging.basicConfig( + stream=sys.stdout, + level=_log_level_map[args.log_level], + format="%(asctime)s %(filename)s#%(lineno)d %(levelname)s - %(message)s" + ) + + +def main(args): + logger.info("Validating arguments") + validate_args(args) + + logger.info("Initializing hosts") + localhost = init_localhost(args.inventory, options={"verbosity": args.verbosity}) + sonichosts = init_testbed_sonichosts( + args.inventory, args.testbed_name, testbed_file=args.tbfile, options={"verbosity": args.verbosity} + ) + + if not localhost or not sonichosts: + sys.exit(RC_INIT_FAILED) + + return get_duts_version(sonichosts) + + +if __name__ == "__main__": + + parser = argparse.ArgumentParser( + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + description="Tool for getting sonic device version.") + + parser.add_argument( + "-i", "--inventory", + type=str, + dest="inventory", + required=True, + help="Ansible inventory file") + + parser.add_argument( + "-t", "--testbed-name", + type=str, + required=True, + dest="testbed_name", + help="Testbed name." + ) + + parser.add_argument( + "--tbfile", + type=str, + dest="tbfile", + default="testbed.yaml", + help="Testbed definition file." + ) + + parser.add_argument( + "-v", "--verbosity", + type=int, + dest="verbosity", + default=2, + help="Log verbosity (0-3)." + ) + + parser.add_argument( + "--log-level", + type=str, + dest="log_level", + choices=["debug", "info", "warning", "error", "critical"], + default="debug", + help="Loglevel" + ) + + args = parser.parse_args() + main(args)