From c7eb2002bcd007520309feb3e11a26ff847a4e05 Mon Sep 17 00:00:00 2001 From: Gabriel Ganne Date: Mon, 27 Nov 2017 15:38:53 +0100 Subject: add new topology parameter: arch if unset, arch variable will default to "x86_64" * Note on "arm64" vs "aarch64" debian-based uses arm64 rhel-based uses aarch64 qemu binaries of both distribs uses aarch64 dpdk uses arm64 vpp uses aarch64 python machine modules uses aarch64 => prefer aarch64 to use the same nomenclature as vpp * add ARCH argument to: init_dpdk.sh, install_dpdk.sh, run_l2fwd.sh, install_tldk.sh, run_tldk.sh. default to x86_64 converts "aarch64" if needed for dpdk naming convention * fixed terminal end detection to allow "~]# " add dut node arch as param to all robot set bin calls * add --target-list flag to qemu_build.sh defaults to x86_64-softmmu * add arch flag to all the topology files * topologies/available/ (and example file) * resources/tools/virl/topologies/ * set _qemu_bin path using node['arch'] in qemu_set_node() Change-Id: If46d88d064d213d3e4c6fc584bb8e0d4b6428cb8 Signed-off-by: Gabriel Ganne --- resources/libraries/bash/qemu_build.sh | 6 +++++- resources/libraries/python/DPDK/DPDKTools.py | 8 ++++++-- resources/libraries/python/DPDK/L2fwdTest.py | 6 ++++-- resources/libraries/python/DPDK/SetupDPDKTest.py | 25 ++++++++++++++++++------ resources/libraries/python/QemuUtils.py | 13 ++++++++---- resources/libraries/python/TLDK/SetupTLDKTest.py | 24 +++++++++++++++++------ resources/libraries/python/VatExecutor.py | 2 +- resources/libraries/python/ssh.py | 2 +- resources/libraries/python/topology.py | 16 +++++++++++++++ 9 files changed, 79 insertions(+), 23 deletions(-) (limited to 'resources/libraries') diff --git a/resources/libraries/bash/qemu_build.sh b/resources/libraries/bash/qemu_build.sh index 5fbbef809e..57520a9b5e 100755 --- a/resources/libraries/bash/qemu_build.sh +++ b/resources/libraries/bash/qemu_build.sh @@ -18,6 +18,7 @@ QEMU_DOWNLOAD_PACKAGE="${QEMU_VERSION}.tar.xz" QEMU_PACKAGE_URL="${QEMU_DOWNLOAD_REPO}${QEMU_DOWNLOAD_PACKAGE}" QEMU_INSTALL_DIR="/opt/${QEMU_VERSION}" SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TARGET_LIST="x86_64-softmmu" for i in "$@"; do case $i in @@ -33,6 +34,9 @@ for i in "$@"; do --force) FORCE=1 shift ;; + --target-list) + TARGET_LIST="${i#*=}" + shift ;; *) ;; esac @@ -78,7 +82,7 @@ then fi # Build -./configure --target-list=x86_64-softmmu --prefix=${QEMU_INSTALL_DIR} || \ +./configure --target-list=${TARGET_LIST} --prefix=${QEMU_INSTALL_DIR} || \ { echo "Failed to configure ${QEMU_VERSION}"; exit 1; } make -j`nproc` || \ { echo "Failed to compile ${QEMU_VERSION}"; exit 1; } diff --git a/resources/libraries/python/DPDK/DPDKTools.py b/resources/libraries/python/DPDK/DPDKTools.py index 6d9eeddc19..5435dffe51 100644 --- a/resources/libraries/python/DPDK/DPDKTools.py +++ b/resources/libraries/python/DPDK/DPDKTools.py @@ -46,8 +46,12 @@ class DPDKTools(object): ssh = SSH() ssh.connect(dut_node) - cmd = 'cd {0}/tests/dpdk/dpdk_scripts/ && sudo ./init_dpdk.sh {1} {2}' \ - .format(con.REMOTE_FW_DIR, pci_address1, pci_address2) + arch = Topology.get_node_arch(dut_node) + cmd = 'cd {0}/tests/dpdk/dpdk_scripts/ &&'\ + 'sudo ./init_dpdk.sh {1} {2} {3}' .format(con.REMOTE_FW_DIR, + pci_address1, + pci_address2, + arch) (ret_code, _, _) = ssh.exec_command(cmd, timeout=600) if ret_code != 0: diff --git a/resources/libraries/python/DPDK/L2fwdTest.py b/resources/libraries/python/DPDK/L2fwdTest.py index f5f714a3e9..b662eeb5d0 100644 --- a/resources/libraries/python/DPDK/L2fwdTest.py +++ b/resources/libraries/python/DPDK/L2fwdTest.py @@ -17,6 +17,7 @@ DUT nodes. from resources.libraries.python.ssh import SSH from resources.libraries.python.constants import Constants as con +from resources.libraries.python.topology import Topology class L2fwdTest(object): @@ -46,8 +47,9 @@ class L2fwdTest(object): ssh.connect(dut_node) cmd = 'cd {0}/tests/dpdk/dpdk_scripts/ && sudo ./run_l2fwd.sh {1} ' \ - '{2} {3} {4}'.format(con.REMOTE_FW_DIR, cpu_cores, nb_cores, - queue_nums, jumbo_frames) + '{2} {3} {4} {5}'.format(con.REMOTE_FW_DIR, cpu_cores, nb_cores, + queue_nums, jumbo_frames, + Topology.get_node_arch(dut_node)) (ret_code, _, _) = ssh.exec_command(cmd, timeout=600) if ret_code != 0: diff --git a/resources/libraries/python/DPDK/SetupDPDKTest.py b/resources/libraries/python/DPDK/SetupDPDKTest.py index 0f70803ed7..d3725d9e9b 100644 --- a/resources/libraries/python/DPDK/SetupDPDKTest.py +++ b/resources/libraries/python/DPDK/SetupDPDKTest.py @@ -28,6 +28,7 @@ from robot.libraries.BuiltIn import BuiltIn from resources.libraries.python.ssh import SSH from resources.libraries.python.constants import Constants as con from resources.libraries.python.topology import NodeType +from resources.libraries.python.topology import Topology __all__ = ["SetupDPDKTest"] @@ -125,14 +126,16 @@ def install_dpdk_test(node): :type node: dict :returns: nothing """ - logger.console('Install the DPDK on {0}'.format(node['host'])) + arch = Topology.get_node_arch(node) + logger.console('Install the DPDK on {0} ({1})'.format(node['host'], + arch)) ssh = SSH() ssh.connect(node) (ret_code, _, stderr) = ssh.exec_command( - 'cd {0}/tests/dpdk/dpdk_scripts/ && ./install_dpdk.sh' - .format(con.REMOTE_FW_DIR), timeout=600) + 'cd {0}/tests/dpdk/dpdk_scripts/ && ./install_dpdk.sh {1}' + .format(con.REMOTE_FW_DIR, arch), timeout=600) if ret_code != 0: logger.error('Install the DPDK error: {0}'.format(stderr)) @@ -153,6 +156,11 @@ def setup_node(args): :rtype: bool """ tarball, remote_tarball, node = args + + # if unset, arch defaults to x86_64 + if 'arch' not in node or not node['arch']: + node['arch'] = 'x86_64' + try: copy_tarball_to_node(tarball, node) extract_tarball_at_node(remote_tarball, node) @@ -166,6 +174,7 @@ def setup_node(args): else: logger.console('Setup of node {0} done'.format(node['host'])) return True +#pylint: enable=broad-except def delete_local_tarball(tarball): """Delete local tarball to prevent disk pollution. @@ -210,9 +219,13 @@ class SetupDPDKTest(object): 'Executed node setups in parallel, waiting for processes to end') result.wait() - logger.info('Results: {0}'.format(result.get())) + results = result.get() + node_setup_success = all(results) + logger.info('Results: {0}'.format(results)) logger.trace('Test framework copied to all topology nodes') delete_local_tarball(tarball) - logger.console('All nodes are ready') - + if node_setup_success: + logger.console('All nodes are ready') + else: + logger.console('Failed to setup dpdk on all the nodes') diff --git a/resources/libraries/python/QemuUtils.py b/resources/libraries/python/QemuUtils.py index 428599be83..6426394bf4 100644 --- a/resources/libraries/python/QemuUtils.py +++ b/resources/libraries/python/QemuUtils.py @@ -20,7 +20,7 @@ from robot.api import logger from resources.libraries.python.ssh import SSH, SSHTimeout from resources.libraries.python.constants import Constants -from resources.libraries.python.topology import NodeType +from resources.libraries.python.topology import NodeType, Topology class QemuUtils(object): @@ -28,7 +28,7 @@ class QemuUtils(object): def __init__(self, qemu_id=1): self._qemu_id = qemu_id - # Path to QEMU binary + # Path to QEMU binary. Use x86_64 by default self._qemu_bin = '/usr/bin/qemu-system-x86_64' # QEMU Machine Protocol socket self._qmp_sock = '/tmp/qmp{0}.sock'.format(self._qemu_id) @@ -188,6 +188,9 @@ class QemuUtils(object): self._ssh.connect(node) self._vm_info['host'] = node['host'] + arch = Topology.get_node_arch(node) + self._qemu_bin = '/usr/bin/qemu-system-{0}'.format(arch) + def qemu_add_vhost_user_if(self, socket, server=True, mac=None): """Add Vhost-user interface. @@ -677,12 +680,14 @@ class QemuUtils(object): version = ' --version={0}'.format(Constants.QEMU_INSTALL_VERSION) force = ' --force' if force_install else '' patch = ' --patch' if apply_patch else '' + arch = Topology.get_node_arch(node) + target_list = ' --target-list={0}-softmmu'.format(arch) (ret_code, stdout, stderr) = \ ssh.exec_command( - "sudo -E sh -c '{0}/{1}/qemu_build.sh{2}{3}{4}{5}'"\ + "sudo -E sh -c '{0}/{1}/qemu_build.sh{2}{3}{4}{5}{6}'"\ .format(Constants.REMOTE_FW_DIR, Constants.RESOURCES_LIB_SH, - version, directory, force, patch), 1000) + version, directory, force, patch, target_list), 1000) if int(ret_code) != 0: logger.debug('QEMU build failed {0}'.format(stdout + stderr)) diff --git a/resources/libraries/python/TLDK/SetupTLDKTest.py b/resources/libraries/python/TLDK/SetupTLDKTest.py index 3d9685f198..7692902b7c 100644 --- a/resources/libraries/python/TLDK/SetupTLDKTest.py +++ b/resources/libraries/python/TLDK/SetupTLDKTest.py @@ -28,7 +28,7 @@ from robot.libraries.BuiltIn import BuiltIn from resources.libraries.python.ssh import SSH from resources.libraries.python.TLDK.TLDKConstants import TLDKConstants as con -from resources.libraries.python.topology import NodeType +from resources.libraries.python.topology import NodeType, Topology from resources.libraries.python.TLDK.gen_pcap import gen_all_pcap __all__ = ["SetupTLDKTest"] @@ -147,14 +147,17 @@ def install_tldk_test(node): :returns: nothing. :raises RuntimeError: If install tldk failed. """ - logger.console('Install the TLDK on {0}'.format(node['host'])) + + arch = Topology.get_node_arch(node) + logger.console('Install the TLDK on {0} ({1})'.format(node['host'], + arch)) ssh = SSH() ssh.connect(node) (ret_code, _, stderr) = ssh.exec_command( - 'cd {0}/{1} && ./install_tldk.sh' - .format(con.REMOTE_FW_DIR, con.TLDK_SCRIPTS), timeout=600) + 'cd {0}/{1} && ./install_tldk.sh {2}' + .format(con.REMOTE_FW_DIR, con.TLDK_SCRIPTS, arch), timeout=600) if ret_code != 0: logger.error('Install the TLDK error: {0}'.format(stderr)) @@ -175,6 +178,10 @@ def setup_node(args): :raises RuntimeError: If node setup failed. """ tarball, remote_tarball, node = args + + # if unset, arch defaults to x86_64 + Topology.get_node_arch(node) + try: copy_tarball_to_node(tarball, node) extract_tarball_at_node(remote_tarball, node) @@ -232,8 +239,13 @@ class SetupTLDKTest(object): 'Executed node setups in parallel, waiting for processes to end') result.wait() - logger.info('Results: {0}'.format(result.get())) + results = result.get() + node_setup_success = all(results) + logger.info('Results: {0}'.format(results)) logger.trace('Test framework copied to all topology nodes') delete_local_tarball(tarball) - logger.console('All nodes are ready') + if node_setup_success: + logger.console('All nodes are ready') + else: + logger.console('Failed to setup dpdk on all the nodes') diff --git a/resources/libraries/python/VatExecutor.py b/resources/libraries/python/VatExecutor.py index de6baababe..c50fdbaf9a 100644 --- a/resources/libraries/python/VatExecutor.py +++ b/resources/libraries/python/VatExecutor.py @@ -304,7 +304,7 @@ class VatTerminal(object): """ __VAT_PROMPT = ("vat# ", ) - __LINUX_PROMPT = (":~$ ", "~]$ ") + __LINUX_PROMPT = (":~$ ", "~]$ ", "~]# ") def __init__(self, node, json_param=True): json_text = ' json' if json_param else '' diff --git a/resources/libraries/python/ssh.py b/resources/libraries/python/ssh.py index 87fc02d3dd..11b05837bf 100644 --- a/resources/libraries/python/ssh.py +++ b/resources/libraries/python/ssh.py @@ -250,7 +250,7 @@ class SSH(object): chan.set_combine_stderr(True) buf = '' - while not buf.endswith((":~$ ", "~]$ ")): + while not buf.endswith((":~$ ", "~]$ ", "~]# ")): try: chunk = chan.recv(self.__MAX_RECV_BUF) if not chunk: diff --git a/resources/libraries/python/topology.py b/resources/libraries/python/topology.py index 38e08d23d3..13dbdddb07 100644 --- a/resources/libraries/python/topology.py +++ b/resources/libraries/python/topology.py @@ -904,6 +904,22 @@ class Topology(object): """ return node['host'] + @staticmethod + def get_node_arch(node): + """Return arch of the node. + Default to x86_64 if no arch present + + :param node: Node created from topology. + :type node: dict + :returns: Node architecture + :rtype: str + """ + try: + return node['arch'] + except KeyError: + node['arch'] = 'x86_64' + return 'x86_64' + @staticmethod def get_cryptodev(node): """Return Crytodev configuration of the node. -- cgit 1.2.3-korg