From 2a778b5ab1a8cd894fc662f3a9c9c5ba7cbc0710 Mon Sep 17 00:00:00 2001 From: pablo Date: Tue, 4 Aug 2020 15:04:25 +0200 Subject: [PATCH 01/34] PPM-30: Changes on class ALEntityDocker for compose Use directly the hostname instead of querying for the ip Signed-off-by: pablo --- tests/environment.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/tests/environment.py b/tests/environment.py index 7da67bb6b0..888ff0fe71 100644 --- a/tests/environment.py +++ b/tests/environment.py @@ -191,6 +191,9 @@ def _docker_wait_for_log(container: str, programs: [str], regex: str, start_line timeout: float) -> bool: def logfilename(program): logfilename = os.path.join(rootdir, 'logs', container, 'beerocks_{}.log'.format(program)) + + print(' --- logfilename: {}'.format(logfilename)) + # WSL doesn't support symlinks on NTFS, so resolve the symlink manually if on_wsl: logfilename = os.path.join( @@ -249,9 +252,9 @@ class ALEntityDocker(ALEntity): The entity is defined from the name of the container, the rest is derived from that. ''' - # NOTE: name arg can be also extracted from the device class itself, but test_flows.py - # don't have it. We can remove this arg as soon, as we drop test_flows.py - def __init__(self, name: str, device: None = None, is_controller: bool = False): + def __init__(self, name: str, device: None = None, is_controller: bool = False, + compose: bool = False): + self.name = name self.bridge_name = 'br-lan' if device: @@ -268,16 +271,19 @@ def __init__(self, name: str, device: None = None, is_controller: bool = False): config_file.read()).group('port') # On WSL, connect to the locally exposed container port - if on_wsl: - published_port_output = subprocess.check_output( - ["docker", "port", name, ucc_port]).decode('utf-8').split(":") - device_ip = published_port_output[0] - ucc_port = int(published_port_output[1]) + if not compose: + if on_wsl: + published_port_output = subprocess.check_output( + ["docker", "port", name, ucc_port]).decode('utf-8').split(":") + device_ip = published_port_output[0] + ucc_port = int(published_port_output[1]) + else: + device_ip_output = self.command( + 'ip', '-f', 'inet', 'addr', 'show', self.bridge_name) + device_ip = re.search( + r'inet (?P[0-9.]+)', device_ip_output.decode('utf-8')).group('ip') else: - device_ip_output = self.command( - 'ip', '-f', 'inet', 'addr', 'show', self.bridge_name) - device_ip = re.search(r'inet (?P[0-9.]+)', - device_ip_output.decode('utf-8')).group('ip') + device_ip = name ucc_socket = UCCSocket(device_ip, ucc_port) mac = ucc_socket.dev_get_parameter('ALid') From 9f26b8ae80b5866b28fbb0c3519ba382e6ccd739 Mon Sep 17 00:00:00 2001 From: pablo Date: Tue, 4 Aug 2020 15:06:16 +0200 Subject: [PATCH 02/34] PPM-30: Define test entrypoint and json config Entrypoint calls the json for "in compose" tests Signed-off-by: pablo --- .../prplmesh_config_compose.json | 55 +++++++++++++++++++ tests/run_bf_compose.sh | 18 ++++++ 2 files changed, 73 insertions(+) create mode 100644 tests/boardfarm_plugins/boardfarm_prplmesh/prplmesh_config_compose.json create mode 100755 tests/run_bf_compose.sh diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/prplmesh_config_compose.json b/tests/boardfarm_plugins/boardfarm_prplmesh/prplmesh_config_compose.json new file mode 100644 index 0000000000..4697ddb022 --- /dev/null +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/prplmesh_config_compose.json @@ -0,0 +1,55 @@ +{ + "prplmesh_compose": { + "name": "agent", + "board_type": "prplmesh_compose", + "role": "agent", + "conn_cmd": "", + "devices": [ + { + "name": "lan", + "type": "prplmesh_compose", + "role": "controller", + "delay" : 7, + "conn_cmd": "" + }, + { + "name": "lan2", + "type": "prplmesh_compose", + "role": "agent", + "delay" : 30, + "conn_cmd": "" + }, + { + "name": "wifi", + "type": "STA_dummy", + "mac": "51:a1:10:20:00:01", + "conn_cmd": "" + } + ] + }, + "netgear-rax40-1": { + "name": "agent-rax40", + "board_type": "prplWRT", + "role": "agent", + "docker_network": "prplMesh-net-rax40-1", + "conn_cmd": "cu -s 115200 -l /dev/ttyUSB0", + "devices": [ + { + "name": "lan", + "type": "prplmesh_compose", + "role": "controller", + "docker_network": "prplMesh-net-rax40-1", + "conn_cmd": "" + }, + { + "name": "wifi", + "type": "prplWRT_STA", + "iface": "wlan0", + "driver": "nl80211,wext", + "connection_type": "local_cmd", + "conn_cmd": "bash", + "color": "yellow" + } + ] + } +} diff --git a/tests/run_bf_compose.sh b/tests/run_bf_compose.sh new file mode 100755 index 0000000000..8ff3d24816 --- /dev/null +++ b/tests/run_bf_compose.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# SPDX-License-Identifier: BSD-2-Clause-Patent +# SPDX-FileCopyrightText: 2020 the prplMesh contributors (see AUTHORS.md) +# This code is subject to the terms of the BSD+Patent license. +# See LICENSE file for more details. + +scriptdir=$(dirname "$(readlink -f "${0}")") +bf_plugins_dir=${scriptdir}/boardfarm_plugins + +if [ -n "${PYTHONPATH}" ]; then + PYTHONPATH="${bf_plugins_dir}:${scriptdir}:${PYTHONPATH}" +else + PYTHONPATH="${bf_plugins_dir}:${scriptdir}" +fi +echo "$PYTHONPATH" +export PYTHONPATH +export BFT_DEBUG=y +exec bft -c "${bf_plugins_dir}"/boardfarm_prplmesh/prplmesh_config_compose.json -n prplmesh_compose -x test_flows From bd599826f1e2199792cff13fb43c488b15c416b9 Mon Sep 17 00:00:00 2001 From: pablo Date: Tue, 4 Aug 2020 15:10:11 +0200 Subject: [PATCH 03/34] PPM-30: Dockerfile and docker-compose.yml Dockerfile to create boardfarm docker image and docker-compose.yml with the configuration for boardfarm, controller and extender Signed-off-by: pablo --- tools/docker/boardfarm-ci/Dockerfile | 30 +++------- tools/docker/boardfarm-ci/docker-compose.yml | 60 ++++++++++++++++++++ 2 files changed, 69 insertions(+), 21 deletions(-) create mode 100644 tools/docker/boardfarm-ci/docker-compose.yml diff --git a/tools/docker/boardfarm-ci/Dockerfile b/tools/docker/boardfarm-ci/Dockerfile index 67fd3ed294..a5d2979de6 100644 --- a/tools/docker/boardfarm-ci/Dockerfile +++ b/tools/docker/boardfarm-ci/Dockerfile @@ -1,41 +1,29 @@ FROM python:3.8-slim-buster +# FROM tiangolo/docker-with-compose RUN apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - apt-transport-https \ - ca-certificates curl \ - curl \ - gcc \ - git \ - gnupg \ - gnupg-agent \ - libsnmp-dev \ - netcat \ - software-properties-common \ - wireshark-common \ - && rm -rf /var/lib/apt/lists/* +&& apt-get install gcc libsnmp-dev -y \ +&& apt-get clean COPY requirements.txt /app/requirements.txt WORKDIR app RUN pip3 install -r requirements.txt -# TODO: what needs this? -#RUN pip3 install jsonschema distro +RUN apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common -y +RUN apt-get install curl -y RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - docker-ce \ - docker-ce-cli \ - containerd.io \ - && rm -rf /var/lib/apt/lists/* - +&& apt-get install docker-ce docker-ce-cli containerd.io -y RUN curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose RUN chmod 755 /usr/local/bin/docker-compose +RUN DEBIAN_FRONTEND=noninteractive apt-get install wireshark-common -y +# VOLUME "/home/pablo/assia/prpl/git" +# ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] RUN git clone https://github.com/mattsm/boardfarm.git \ && cd boardfarm \ && git checkout 100521fde1fb67536682cafecc2f91a6e2e8a6f8 \ diff --git a/tools/docker/boardfarm-ci/docker-compose.yml b/tools/docker/boardfarm-ci/docker-compose.yml new file mode 100644 index 0000000000..1f50b9cc75 --- /dev/null +++ b/tools/docker/boardfarm-ci/docker-compose.yml @@ -0,0 +1,60 @@ +version: '3' +services: + # Controller and agent are run from inside the boardfarm container + controller: + image: registry.gitlab.com/prpl-foundation/prplmesh/prplmesh-runner:${CI_PIPELINE_ID} + privileged: true # For the creation of the bridge to work + container_name: controller + environment: + - USER + - INSTALL_DIR=${FINAL_ROOT_DIR}/build/install + - ROOT_DIR=${FINAL_ROOT_DIR} + - CURRENT_ID + - CI_PIPELINE_ID + expose: + - "5000" + - "8002" + volumes: + - "$ROOT_DIR:${FINAL_ROOT_DIR}" + entrypoint: ["/root/entrypoint.sh", "/usr/bin/start-controller-agent"] + + agent: + image: registry.gitlab.com/prpl-foundation/prplmesh/prplmesh-runner:${CI_PIPELINE_ID} + privileged: true + container_name: agent + environment: + - USER + - INSTALL_DIR=${FINAL_ROOT_DIR}/build/install + - ROOT_DIR=${FINAL_ROOT_DIR} + # /builds/prpl-foundation/prplMesh + - CURRENT_ID + - CI_PIPELINE_ID + expose: + - "5000" + - "8002" + volumes: + - "$ROOT_DIR:${FINAL_ROOT_DIR}" + entrypoint: ["/root/entrypoint.sh", "/usr/bin/start-agent"] + + # Boardfarm image is launched from dctest.py, TARGET_DIR refers to the + # path inside the controller, will be referred as $ROOT_DIR inside + boardfarm: + build: . + privileged: true + container_name: boardfarm + environment: + - USER + - ROOT_DIR + - CURRENT_ID + - RUN_ID + - CI_PIPELINE_ID + - FINAL_ROOT_DIR + ports: + - "5000:5000" + volumes: + - "$ROOT_DIR:$ROOT_DIR" + - "/var/run/docker:/var/run/docker" + - "/var/run/docker.sock:/var/run/docker.sock" + user: ${CURRENT_UID} + working_dir: $ROOT_DIR/tests + entrypoint: ["bash", "run_bf_compose.sh"] From 1444905975c462e074a057e608ebd5c0d6061d69 Mon Sep 17 00:00:00 2001 From: pablo Date: Tue, 4 Aug 2020 15:11:33 +0200 Subject: [PATCH 04/34] PPM-30: dctest.py script to wrap docker-compose It wraps docker-compose tests - Verifies versions of docker and docker-compose - Creates and launches boardfarm image with the correct environment variables - Cleans images after building - Returns value from boardfarm process inside the image Signed-off-by: pablo --- dctest.py | 255 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100755 dctest.py diff --git a/dctest.py b/dctest.py new file mode 100755 index 0000000000..3855209703 --- /dev/null +++ b/dctest.py @@ -0,0 +1,255 @@ +#!/usr/bin/env python3 +# +# Launch the test suite using docker and docker-compose. This script wraps +# the creation of the bridge(s) to be able to connect external devices with +# the docker network, launching the service for boardfarm. +# +# As this script is run outside containers, it does not use anything apart +# from Python 3.5 (will work on later versions but only uses 3.5 features) +# +# The best way to make sure no Python 3.5+ features are used is running the +# script with a Python 3.5.0 interpreter. Compile it from: +# +# https://www.python.org/ftp/python/3.5.0/Python-3.5.0.tgz +# +# Also, when calling a function look for 'New in version 3.X' where X > 5 +# +from __future__ import print_function # To check for python2 or < 3.5 execution +import argparse +import fcntl +import os +import grp +import shutil +import getpass +import sys +from subprocess import Popen, PIPE + + +if not (sys.version_info.major == 3 and sys.version_info.minor >= 5): + print("This script requires Python 3.5 or higher!") + print("You are using Python {}.{}.".format(sys.version_info.major, sys.version_info.minor)) + sys.exit(1) + + +def check_docker_versions(): + DOCKER_MAJOR = 19 + DC_MAJOR = 1 + DC_MINOR = 25 + docker_version = os.popen('docker --version').read().split(' ')[2] + docker_major = int(docker_version.split('.')[0]) + if docker_major < DOCKER_MAJOR: + fmt = "This script requires docker {}.0 or higher" + print(fmt.format(DOCKER_MAJOR)) + print("You are usng version {}".format(docker_version)) + sys.exit(1) + dc_version = os.popen('docker-compose --version').read().split(' ')[2] + dc_major = int(dc_version.split('.')[0]) + dc_minor = int(dc_version.split('.')[1]) + if dc_major < DC_MAJOR: + fmt = "This script requires docker-compose {}.{} or higher" + print(fmt.format(DC_MAJOR, DC_MINOR)) + print("You are usng version {}".format(dc_version)) + sys.exit(1) + if dc_minor < DC_MINOR: + fmt = "This script requires docker-compose {}.{} or higher" + print(fmt.format(DC_MAJOR, DC_MINOR)) + print("You are usng version {}".format(dc_version)) + sys.exit(1) + + +class Services: + def __init__(self, bid=None): + self.scriptdir = os.path.dirname(os.path.realpath(__file__)) + os.chdir(self.scriptdir) + self.rootdir = self.scriptdir + + if bid is not None: + self.build_id = bid + print('Using ID {}'.format(self.build_id)) + # return + else: + self.build_id = self.get_build_id() + + self.logdir = os.path.join(self.scriptdir, 'logs') + device_name = 'dockerized_device-{}'.format(self.build_id) + self.devicedir = os.path.join(self.logdir, device_name) + repeater_name = 'repeater1-{}'.format(self.build_id) + self.repeaterdir = os.path.join(self.logdir, repeater_name) + if not os.path.exists(self.logdir): + os.makedirs(self.logdir) + if not os.path.exists(self.devicedir): + print('Making {}'.format(self.devicedir)) + os.makedirs(self.devicedir) + if not os.path.exists(self.repeaterdir): + print('Making {}'.format(self.repeaterdir)) + os.makedirs(self.repeaterdir) + + def cleanlogs(self): + shutil.rmtree(os.path.join(self.scriptdir, 'logs')) + + def _setNonBlocking(fd): + """ + Set the file description of the given file descriptor to non-blocking. + """ + flags = fcntl.fcntl(fd, fcntl.F_GETFL) + flags = flags | os.O_NONBLOCK + fcntl.fcntl(fd, fcntl.F_SETFL, flags) + + def get_build_id(self): + ci_pipeline_id = os.getenv('CI_PIPELINE_ID') + if ci_pipeline_id is not None: + return ci_pipeline_id + + # Otherwise we are running on the local machine, just find last id + # created and add one + last_id = 0 + if not os.path.exists('logs'): + return str(1) + for d in os.listdir('logs'): + if d.startswith('dockerized_device-'): + suffix = d[len('dockerized_device-'):] + isuffix = int(suffix) + if isuffix > last_id: + last_id = isuffix + if last_id == 0: + new_id = 1 + else: + new_id = last_id + 1 + return str(new_id) + + def copy_build_dir(self): + new_id = self.build_id + self.build_dir = 'build-{}'.format(new_id) + shutil.copytree('build', 'build-{}'.format(self.build_dir)) + print('Copied build/ into {}'.format(self.build_dir)) + + def dc(self, args, interactive=False): + params = ['docker-compose', '-f', + 'tools/docker/boardfarm-ci/docker-compose.yml'] + # params += ['-p', 'boardfarm-ci-{}'.format(self.build_id)] + params += args + local_env = os.environ + local_env['ROOT_DIR'] = self.rootdir + docker_gid = grp.getgrnam('docker')[2] + local_env['CURRENT_UID'] = str(os.getuid()) + ':' + str(docker_gid) + local_env['CURRENT_ID'] = str(os.getuid()) + local_env['RUN_ID'] = self.build_id + + if os.getenv('CI_PIPELINE_ID') is None: + # Running locally + local_env['CI_PIPELINE_ID'] = 'latest' + local_env['FINAL_ROOT_DIR'] = self.rootdir + else: + # Running inside gitlab-ci + local_env['FINAL_ROOT_DIR'] = '/builds/prpl-foundation/prplMesh' + + # local_env['CURRENT_UID']= str(os.getuid()) + ':' + str(os.getgid()) + if not interactive: + proc = Popen(params, stdout=PIPE, stderr=PIPE) + for line in proc.stdout: + print(line.decode(), end='') + proc.stdout.close() + else: + proc = Popen(params) + return_code = proc.wait() + return return_code + + +def vararg_callback(option, opt_str, value, parser): + assert value is None + value = [] + + def floatable(str): + try: + float(str) + return True + except ValueError: + return False + + for arg in parser.rargs: + # stop on --foo like options + if arg[:2] == "--" and len(arg) > 2: + break + # stop on -a, but not on -3 or -3.0 + if arg[:1] == "-" and len(arg) > 1 and not floatable(arg): + break + value.append(arg) + + del parser.rargs[:len(value)] + setattr(parser.values, option.dest, value) + + +def cleanup(rc): + if rc != 0: + print('Return code !=0 -> {}'.format(rc)) + if getpass.getuser() == 'gitlab-runner': + os.system('chown -R gitlab-runner:gitlab-runner .') + sys.exit(rc) + + +if __name__ == '__main__': + check_docker_versions() + parser = argparse.ArgumentParser(description='Dockerized test launcher') + parser.add_argument('--test', dest='test', type=str, help='Test to be run') + parser.add_argument('--clean', dest='clean', action='store_true', + help='Clean containers images and networks') + parser.add_argument('--build', dest='build', action='store_true', + help='Rebuild containers') + parser.add_argument('--shell', dest='shell', action='store_true', + help='Run a shell on the bf container') + parser.add_argument('--comp', dest='comp', action='store_true', + help='Pass the rest of arguments to docker-compose') + parser.add_argument('--id', dest='bid', type=str, + help='Specify the id to use for build/shell/comp/clean') + args, rest = parser.parse_known_args() + + if os.getenv('CI_PIPELINE_ID') is not None: + args.bid == os.getenv('CI_PIPELINE_ID') + + if args.comp: + if args.bid is None: + print('Specify --id for the --comp parameter') + sys.exit(0) + services = Services(bid=args.bid) + if len(rest) == 0: + print('Usage: dctest --id --comp ') + sys.exit(1) + sys.exit(services.dc(rest, interactive=True)) + else: + if len(rest) > 0: + print('Unknown parameters: {}'.format(rest)) + sys.exit(1) + + if args.clean: + if args.bid is None: + print('Specify --id for the --clean parameter') + sys.exit(0) + services = Services(bid=args.bid) + rc = services.dc(['down', '--remove-orphans', '--rmi', 'all']) + cleanup(rc) + elif args.shell: + if not args.bid: + print('Specify --id for the shell parameter') + sys.exit(0) + services = Services(bid=args.bid) + rc = services.dc(['run', '--rm', '--service-ports', '--entrypoint', + '/bin/bash', 'boardfarm'], interactive=True) + cleanup(rc) + elif args.build: + if not args.bid: + print('Specify --id for the build parameter') + sys.exit(0) + services = Services(bid=args.bid) + rc = services.dc(['build'], interactive=True) + cleanup(rc) + else: + if args.bid: + services = Services(bid=args.bid) # With new build id + else: + services = Services() # With new build id + # rc = services.dc(['up', 'boardfarm']) + # rc = services.dc(['run', '--service-ports', '--entrypoint', + # '/bin/bash', 'boardfarm'], interactive=True) + rc = services.dc(['run', '--rm', '--service-ports', '--use-aliases', + 'boardfarm'], interactive=True) + cleanup(rc) From 856854b347ffc2c49190c78882c3aa5e46cef432 Mon Sep 17 00:00:00 2001 From: pablo Date: Tue, 4 Aug 2020 16:48:34 +0200 Subject: [PATCH 05/34] PPM-30: Add test to boardfarm-ci Signed-off-by: pablo --- .gitlab-ci.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 090b7315eb..fe4e1882ef 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -198,6 +198,20 @@ bwl_dummy_unit_tests: bcl_unit_tests: extends: .run-test-in-docker +dctest_one_test: + stage: test + script: + - ./dctest.py + artifacts: + paths: + - logs + - results + when: always + tags: + - boardfarm-compose + needs: + - job: build-in-docker + mapf_common_encryption_tests: extends: .run-test-in-docker From bb1645d74e96c8e37c560e1719cffe7b15a82b03 Mon Sep 17 00:00:00 2001 From: pablo Date: Tue, 4 Aug 2020 17:52:38 +0200 Subject: [PATCH 06/34] PPM-30: Check return error on _run_shell Signed-off-by: pablo --- .../boardfarm_prplmesh/devices/prplmesh_base.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_base.py b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_base.py index 700c5c2863..c30bf08e28 100644 --- a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_base.py +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_base.py @@ -4,6 +4,7 @@ # See LICENSE file for more details. import pexpect +from typing import Dict from boardfarm.devices import linux @@ -16,14 +17,18 @@ class CommandError(Exception): class PrplMeshBase(linux.LinuxDevice): """PrplMesh abstract device.""" - def _run_shell_cmd(self, cmd: str = "", args: list = None, timeout: int = 30): + def _run_shell_cmd(self, cmd: str = "", args: list = None, timeout: int = 30, + env: Dict[str, str] = None): """Wrapper that executes command with specified args on host machine and logs output.""" - - res, exitstatus = pexpect.run(cmd, args=args, timeout=timeout, encoding="utf-8", - withexitstatus=1) + if env is not None: + res, exitstatus = pexpect.run(cmd, args=args, timeout=timeout, encoding="utf-8", + withexitstatus=1, env=env) + else: + res, exitstatus = pexpect.run(cmd, args=args, timeout=timeout, encoding="utf-8", + withexitstatus=1) entry = " ".join((cmd, " ".join(args))) if exitstatus != 0: - raise CommandError("Error executing {}:\n{}".format(entry, res)) + raise CommandError("Error executing {}".format(entry)) self.log_calls += entry self.log += "$ " + entry + "\r\n" + res From 3d819a890de0f6cf8a9fe75c1ae7534e741242c2 Mon Sep 17 00:00:00 2001 From: pablo Date: Tue, 4 Aug 2020 18:13:21 +0200 Subject: [PATCH 07/34] Added device prplmesh_compose.py Signed-off-by: pablo --- .../devices/prplmesh_compose.py | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py new file mode 100644 index 0000000000..7fba4b93ac --- /dev/null +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py @@ -0,0 +1,116 @@ +# SPDX-License-Identifier: BSD-2-Clause-Patent +# SPDX-FileCopyrightText: 2020 the prplMesh contributors (see AUTHORS.md) +# This code is subject to the terms of the BSD+Patent license. +# See LICENSE file for more details. + +import os +import time + +import boardfarm +from environment import ALEntityDocker, _get_bridge_interface +from .prplmesh_base import PrplMeshBase +from sniffer import Sniffer + +rootdir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..')) + + +class PrplMeshCompose(PrplMeshBase): + """Dockerized prplMesh device.""" + + model = ("prplmesh_compose") + agent_entity = None + controller_entity = None + + def __init__(self, *args, **kwargs): + self.args = args + self.kwargs = kwargs + + config = kwargs.get("config", kwargs) + + # List of device's consoles test can interact with + self.consoles = [self] + + # Getting unic ID to distinguish devices and network they belong to + self.unique_id = os.getenv("RUN_ID") + self.user_id = os.getenv("SUDO_USER", os.getenv("USER", "")) + + self.docker_name = "-".join((config.get("name", "prplmesh_compose"), self.unique_id)) + self.name = config.get("name", "prplmesh_compose") + print('config.get("name") {}'.format(config.get("name"))) + self.role = config.get("role", "agent") + self.cleanup_cmd = config.get("cleanup_cmd", None) + self.conn_cmd = config.get("conn_cmd", None) + self.delay = config.get("delay", 7) + self.docker_network = "boardfarm-ci_default" + + if self.role == "controller": + self._docker_compose(["-d", "--name", self.docker_name, "controller"], + "run", "start-controller-agent") + time.sleep(self.delay) + self.controller_entity = \ + ALEntityDocker(self.name, device=self, is_controller=True, compose=True) + else: + self._docker_compose(["-d", "--name", self.docker_name, "agent"], + "run", "start-agent") + time.sleep(self.delay) + self.agent_entity = ALEntityDocker(self.name, device=self, is_controller=False, compose=True) + + self.wired_sniffer = Sniffer(_get_bridge_interface(self.docker_network), + boardfarm.config.output_dir) + self.check_status() + + def _docker_compose(self, args, parameter=None, start=None): + print('_docker_compose: args {}'.format(args)) + yml_path = "tools/docker/boardfarm-ci/docker-compose.yml" + full_args = ["-f", os.path.join(rootdir, yml_path)] + if parameter == "run": + log_path = os.path.join(rootdir, "logs/{}".format(self.docker_name)) + if not os.path.exists(log_path): + os.mkdir(log_path) + + pipeline_id = os.getenv('CI_PIPELINE_ID') + if pipeline_id is None or pipeline_id == 'latest': + vol = '{}:/tmp/{}/beerocks/logs'.format(log_path, self.user_id) + else: + vol = '{}:/tmp/beerocks/logs'.format(log_path) + + full_args += ["run", "--rm", "-v", vol] + # full_args += ["--entrypoint", entrypoint + ' ' + start] + full_args += args + + print('_docker_compose: {}'.format(' '.join(full_args))) + # os.environ['CURRENT_UID'] = '1000:998' + if os.getenv('CI_PIPELINE_ID') is None: + print('Setting CI_PIPELINE_ID "latest"') + os.environ['CI_PIPELINE_ID'] = 'latest' + self._run_shell_cmd("/usr/local/bin/docker-compose", + full_args, env=os.environ) + else: + self._run_shell_cmd("/usr/local/bin/docker-compose", full_args) + + def __del__(self): + self._run_shell_cmd("docker", ["stop", self.docker_name]) + self._run_shell_cmd("docker", ["container", "rm", "-f", self.docker_name]) + + def check_status(self): + """Method required by boardfarm. + + It is used by boardfarm to indicate that spawned device instance is ready for test + and also after test - to insure that device still operational. + """ + self._run_shell_cmd("printf", + ["device_get_info", "|", "nc", "-w", "1", "controller-rme", "8002"]) + + + def isalive(self): + """Method required by boardfarm. + + States that device is operational and its consoles are accessible. + + """ + return True + + def prprlmesh_status_check(self): + self.check_status() + return True + From c108e2f863621d5c9031a2e0f87ee186e7b0a942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= Date: Thu, 6 Aug 2020 17:07:32 +0200 Subject: [PATCH 08/34] boardfarm: use the name of the container for the status check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The status are failing in CI. The name of the container was hardcoded by mistake, use docker_name instead. Signed-off-by: Raphaël Mélotte --- .../boardfarm_prplmesh/devices/prplmesh_docker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_docker.py b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_docker.py index 7e890c800d..c017b0402c 100644 --- a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_docker.py +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_docker.py @@ -78,7 +78,7 @@ def check_status(self): and also after test - to insure that device still operational. """ self._run_shell_cmd("printf", - ["device_get_info", "|", "nc", "-w", "1", "controller-rme", "8002"]) + ["device_get_info", "|", "nc", "-w", "1", self.docker_name, "8002"]) def isalive(self): """Method required by boardfarm. From 7ec7a92c3f8fdb347955403f5ec1d9cf72c3b459 Mon Sep 17 00:00:00 2001 From: odkq Date: Thu, 6 Aug 2020 12:44:55 +0200 Subject: [PATCH 09/34] Use original name and docker-name for hostname in environment.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: odkq Signed-off-by: Raphaël Mélotte --- tests/environment.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/environment.py b/tests/environment.py index 888ff0fe71..3892a299c6 100644 --- a/tests/environment.py +++ b/tests/environment.py @@ -283,7 +283,7 @@ def __init__(self, name: str, device: None = None, is_controller: bool = False, device_ip = re.search( r'inet (?P[0-9.]+)', device_ip_output.decode('utf-8')).group('ip') else: - device_ip = name + device_ip = self.device.docker_name ucc_socket = UCCSocket(device_ip, ucc_port) mac = ucc_socket.dev_get_parameter('ALid') @@ -296,12 +296,12 @@ def __init__(self, name: str, device: None = None, is_controller: bool = False, def command(self, *command: str) -> bytes: '''Execute `command` in docker container and return its output.''' - return subprocess.check_output(("docker", "exec", self.name) + command) + return subprocess.check_output(("docker", "exec", self.device.docker_name) + command) def wait_for_log(self, regex: str, start_line: int, timeout: float) -> bool: '''Poll the entity's logfile until it contains "regex" or times out.''' program = "controller" if self.is_controller else "agent" - return _docker_wait_for_log(self.name, [program], regex, start_line, timeout) + return _docker_wait_for_log(self.device.docker_name, [program], regex, start_line, timeout) def prprlmesh_status_check(self): return self.device.prprlmesh_status_check() @@ -323,7 +323,7 @@ def __init__(self, agent: ALEntityDocker, iface_name: str): def wait_for_log(self, regex: str, start_line: int, timeout: float) -> bool: '''Poll the radio's logfile until it contains "regex" or times out.''' programs = ("agent_" + self.iface_name, "ap_manager_" + self.iface_name) - return _docker_wait_for_log(self.agent.name, programs, regex, start_line, timeout) + return _docker_wait_for_log(self.agent.device.docker_name, programs, regex, start_line, timeout) def send_bwl_event(self, event: str) -> None: # The file is only available within the docker container so we need to use an echo command. From 61cc3b7450337285dfe78e76339c53d0490e293b Mon Sep 17 00:00:00 2001 From: pablo Date: Tue, 11 Aug 2020 10:32:12 +0200 Subject: [PATCH 10/34] boardfarm-ci: Remove unused code Signed-off-by: pablo --- dctest.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/dctest.py b/dctest.py index 3855209703..b36bf16a22 100755 --- a/dctest.py +++ b/dctest.py @@ -84,17 +84,6 @@ def __init__(self, bid=None): print('Making {}'.format(self.repeaterdir)) os.makedirs(self.repeaterdir) - def cleanlogs(self): - shutil.rmtree(os.path.join(self.scriptdir, 'logs')) - - def _setNonBlocking(fd): - """ - Set the file description of the given file descriptor to non-blocking. - """ - flags = fcntl.fcntl(fd, fcntl.F_GETFL) - flags = flags | os.O_NONBLOCK - fcntl.fcntl(fd, fcntl.F_SETFL, flags) - def get_build_id(self): ci_pipeline_id = os.getenv('CI_PIPELINE_ID') if ci_pipeline_id is not None: From dd55701fcc80c056cf9a3869b50bd428cc52293f Mon Sep 17 00:00:00 2001 From: pablo Date: Tue, 11 Aug 2020 11:06:24 +0200 Subject: [PATCH 11/34] boardfarm-ci: Commented and reordered Dockerfile Reordered the file with this ordering, from the less likely to change to the most: - Dependencies to install docker and docker-compose - Installation of docker and docker-compose - Installation of boardfarm (from github) - Debian dependencies to install python packages (for tests) - Installation of the python packages (for tests) - Debian dependencies used by the tests themselves Signed-off-by: pablo --- tools/docker/boardfarm-ci/Dockerfile | 33 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/tools/docker/boardfarm-ci/Dockerfile b/tools/docker/boardfarm-ci/Dockerfile index a5d2979de6..ac996d0da9 100644 --- a/tools/docker/boardfarm-ci/Dockerfile +++ b/tools/docker/boardfarm-ci/Dockerfile @@ -1,30 +1,31 @@ FROM python:3.8-slim-buster -# FROM tiangolo/docker-with-compose -RUN apt-get update \ -&& apt-get install gcc libsnmp-dev -y \ -&& apt-get clean - -COPY requirements.txt /app/requirements.txt - -WORKDIR app -RUN pip3 install -r requirements.txt - -RUN apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common -y +RUN apt-get update -RUN apt-get install curl -y +# Debian dependencies to install docker and docker compose from docker.com +RUN apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common curl -y && apt-get clean +# Install docker and docker-compose from docker.com repositories RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" RUN apt-get update \ -&& apt-get install docker-ce docker-ce-cli containerd.io -y +&& apt-get install docker-ce docker-ce-cli containerd.io -y && apt-get clean RUN curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose RUN chmod 755 /usr/local/bin/docker-compose -RUN DEBIAN_FRONTEND=noninteractive apt-get install wireshark-common -y -# VOLUME "/home/pablo/assia/prpl/git" -# ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +# Installation of boardfarm RUN git clone https://github.com/mattsm/boardfarm.git \ && cd boardfarm \ && git checkout 100521fde1fb67536682cafecc2f91a6e2e8a6f8 \ && python3 setup.py install + +# Debian dependencies for installing the Python packages on requirements.txt +RUN apt-get install gcc libsnmp-dev -y && apt-get clean + +# Installation of the python packages needed by the tests +COPY requirements.txt /app/requirements.txt +WORKDIR app +RUN pip3 install -r requirements.txt + +# Installation of Debian dependencies needed by the tests +RUN DEBIAN_FRONTEND=noninteractive apt-get install wireshark-common -y && apt-get clean From 0e1458da88156b3577a29671643906961f3aafba Mon Sep 17 00:00:00 2001 From: pablo Date: Tue, 11 Aug 2020 13:01:10 +0200 Subject: [PATCH 12/34] boardfarm-ci: Scan device names This change scans prplmesh_config_compose.js for device names and creates the log directory for each of them found. The scanning is also used to look for the previous run ID when running locally, by looking for logs/-, and then using X+1 as the new ID. Signed-off-by: pablo --- dctest.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/dctest.py b/dctest.py index b36bf16a22..081dc28abe 100755 --- a/dctest.py +++ b/dctest.py @@ -22,6 +22,7 @@ import shutil import getpass import sys +import json from subprocess import Popen, PIPE @@ -71,18 +72,22 @@ def __init__(self, bid=None): self.build_id = self.get_build_id() self.logdir = os.path.join(self.scriptdir, 'logs') - device_name = 'dockerized_device-{}'.format(self.build_id) - self.devicedir = os.path.join(self.logdir, device_name) - repeater_name = 'repeater1-{}'.format(self.build_id) - self.repeaterdir = os.path.join(self.logdir, repeater_name) if not os.path.exists(self.logdir): os.makedirs(self.logdir) - if not os.path.exists(self.devicedir): - print('Making {}'.format(self.devicedir)) - os.makedirs(self.devicedir) - if not os.path.exists(self.repeaterdir): - print('Making {}'.format(self.repeaterdir)) - os.makedirs(self.repeaterdir) + for device in self._get_device_names(): + device_name = '{}-{}'.format(device, self.build_id) + devicedir = os.path.join(self.logdir, device_name) + if not os.path.exists(devicedir): + print('Making {}'.format(devicedir)) + os.makedirs(devicedir) + + def _get_device_names(self): + jspath = './tests/boardfarm_plugins/boardfarm_prplmesh/prplmesh_config_compose.json' + js = json.loads(open(jspath, 'r').read()) + devices = [] + for device in js['prplmesh_compose']['devices']: + devices.append(device['name']) + return devices def get_build_id(self): ci_pipeline_id = os.getenv('CI_PIPELINE_ID') @@ -94,9 +99,13 @@ def get_build_id(self): last_id = 0 if not os.path.exists('logs'): return str(1) + + # Search if a directory exists with logs/- and use X+1 as + # id. Get the first device from the json list + search_prefix = self._get_device_names()[0] + '-' for d in os.listdir('logs'): - if d.startswith('dockerized_device-'): - suffix = d[len('dockerized_device-'):] + if d.startswith(search_prefix): + suffix = d[len(search_prefix):] isuffix = int(suffix) if isuffix > last_id: last_id = isuffix From d53c32a859527dff90e0aca9a38847167be47b11 Mon Sep 17 00:00:00 2001 From: pablo Date: Tue, 11 Aug 2020 13:13:24 +0200 Subject: [PATCH 13/34] boardfarm-ci: Fixes for PEP-8 compliance Signed-off-by: pablo --- dctest.py | 1 - .../boardfarm_prplmesh/devices/prplmesh_compose.py | 5 ++--- tests/environment.py | 3 ++- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/dctest.py b/dctest.py index 081dc28abe..d3a71fc14a 100755 --- a/dctest.py +++ b/dctest.py @@ -16,7 +16,6 @@ # from __future__ import print_function # To check for python2 or < 3.5 execution import argparse -import fcntl import os import grp import shutil diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py index 7fba4b93ac..7402921039 100644 --- a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py @@ -53,7 +53,8 @@ def __init__(self, *args, **kwargs): self._docker_compose(["-d", "--name", self.docker_name, "agent"], "run", "start-agent") time.sleep(self.delay) - self.agent_entity = ALEntityDocker(self.name, device=self, is_controller=False, compose=True) + self.agent_entity = ALEntityDocker(self.name, device=self, + is_controller=False, compose=True) self.wired_sniffer = Sniffer(_get_bridge_interface(self.docker_network), boardfarm.config.output_dir) @@ -101,7 +102,6 @@ def check_status(self): self._run_shell_cmd("printf", ["device_get_info", "|", "nc", "-w", "1", "controller-rme", "8002"]) - def isalive(self): """Method required by boardfarm. @@ -113,4 +113,3 @@ def isalive(self): def prprlmesh_status_check(self): self.check_status() return True - diff --git a/tests/environment.py b/tests/environment.py index 3892a299c6..daa56012a3 100644 --- a/tests/environment.py +++ b/tests/environment.py @@ -323,7 +323,8 @@ def __init__(self, agent: ALEntityDocker, iface_name: str): def wait_for_log(self, regex: str, start_line: int, timeout: float) -> bool: '''Poll the radio's logfile until it contains "regex" or times out.''' programs = ("agent_" + self.iface_name, "ap_manager_" + self.iface_name) - return _docker_wait_for_log(self.agent.device.docker_name, programs, regex, start_line, timeout) + return _docker_wait_for_log(self.agent.device.docker_name, programs, regex, + start_line, timeout) def send_bwl_event(self, event: str) -> None: # The file is only available within the docker container so we need to use an echo command. From a0d8fe7be1b5046ba4cf23ad14a5dd825f750ca4 Mon Sep 17 00:00:00 2001 From: pablo Date: Wed, 12 Aug 2020 13:40:58 +0200 Subject: [PATCH 14/34] boardfarm-ci: Remove unused code Signed-off-by: pablo --- dctest.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dctest.py b/dctest.py index d3a71fc14a..840e50dedd 100755 --- a/dctest.py +++ b/dctest.py @@ -114,12 +114,6 @@ def get_build_id(self): new_id = last_id + 1 return str(new_id) - def copy_build_dir(self): - new_id = self.build_id - self.build_dir = 'build-{}'.format(new_id) - shutil.copytree('build', 'build-{}'.format(self.build_dir)) - print('Copied build/ into {}'.format(self.build_dir)) - def dc(self, args, interactive=False): params = ['docker-compose', '-f', 'tools/docker/boardfarm-ci/docker-compose.yml'] From 727d8360c6635ecc7175de75a0f8276284e9c48f Mon Sep 17 00:00:00 2001 From: pablo Date: Wed, 12 Aug 2020 13:42:25 +0200 Subject: [PATCH 15/34] boardfarm-ci: Remove commented out line Signed-off-by: pablo --- dctest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/dctest.py b/dctest.py index 840e50dedd..ecf66007ad 100755 --- a/dctest.py +++ b/dctest.py @@ -117,7 +117,6 @@ def get_build_id(self): def dc(self, args, interactive=False): params = ['docker-compose', '-f', 'tools/docker/boardfarm-ci/docker-compose.yml'] - # params += ['-p', 'boardfarm-ci-{}'.format(self.build_id)] params += args local_env = os.environ local_env['ROOT_DIR'] = self.rootdir From 9355d53f44e2a0cb33d681d89488e85fbe40fcf9 Mon Sep 17 00:00:00 2001 From: pablo Date: Wed, 12 Aug 2020 13:46:30 +0200 Subject: [PATCH 16/34] boardfarm-ci: Removed more unused code Signed-off-by: pablo --- dctest.py | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/dctest.py b/dctest.py index ecf66007ad..91b6ae21ae 100755 --- a/dctest.py +++ b/dctest.py @@ -145,30 +145,6 @@ def dc(self, args, interactive=False): return return_code -def vararg_callback(option, opt_str, value, parser): - assert value is None - value = [] - - def floatable(str): - try: - float(str) - return True - except ValueError: - return False - - for arg in parser.rargs: - # stop on --foo like options - if arg[:2] == "--" and len(arg) > 2: - break - # stop on -a, but not on -3 or -3.0 - if arg[:1] == "-" and len(arg) > 1 and not floatable(arg): - break - value.append(arg) - - del parser.rargs[:len(value)] - setattr(parser.values, option.dest, value) - - def cleanup(rc): if rc != 0: print('Return code !=0 -> {}'.format(rc)) From 44af58b55e2946262e5b981652ed2f9f035c537a Mon Sep 17 00:00:00 2001 From: pablo Date: Wed, 12 Aug 2020 13:47:24 +0200 Subject: [PATCH 17/34] boardfarm-ci: Removed commented out code Signed-off-by: pablo --- dctest.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/dctest.py b/dctest.py index 91b6ae21ae..475e1030cb 100755 --- a/dctest.py +++ b/dctest.py @@ -213,9 +213,6 @@ def cleanup(rc): services = Services(bid=args.bid) # With new build id else: services = Services() # With new build id - # rc = services.dc(['up', 'boardfarm']) - # rc = services.dc(['run', '--service-ports', '--entrypoint', - # '/bin/bash', 'boardfarm'], interactive=True) rc = services.dc(['run', '--rm', '--service-ports', '--use-aliases', 'boardfarm'], interactive=True) cleanup(rc) From 28e53f283cc6c0988bca4a41f229c1f638897993 Mon Sep 17 00:00:00 2001 From: pablo Date: Wed, 12 Aug 2020 13:49:51 +0200 Subject: [PATCH 18/34] boardfarm-ci: Removed commented-out code Signed-off-by: pablo --- .../boardfarm_prplmesh/devices/prplmesh_compose.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py index 7402921039..46d374a0e7 100644 --- a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py @@ -76,11 +76,9 @@ def _docker_compose(self, args, parameter=None, start=None): vol = '{}:/tmp/beerocks/logs'.format(log_path) full_args += ["run", "--rm", "-v", vol] - # full_args += ["--entrypoint", entrypoint + ' ' + start] full_args += args print('_docker_compose: {}'.format(' '.join(full_args))) - # os.environ['CURRENT_UID'] = '1000:998' if os.getenv('CI_PIPELINE_ID') is None: print('Setting CI_PIPELINE_ID "latest"') os.environ['CI_PIPELINE_ID'] = 'latest' From 1df25265f1e68a99c185ce39419dde4e83eeed9a Mon Sep 17 00:00:00 2001 From: pablo Date: Wed, 12 Aug 2020 14:01:38 +0200 Subject: [PATCH 19/34] boardfarm-ci: Use relative path Use relative path on docker-compose invocation, not using /usr/local/bin/... Signed-off-by: pablo --- .../boardfarm_prplmesh/devices/prplmesh_compose.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py index 46d374a0e7..7ccd42bda5 100644 --- a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py @@ -82,10 +82,10 @@ def _docker_compose(self, args, parameter=None, start=None): if os.getenv('CI_PIPELINE_ID') is None: print('Setting CI_PIPELINE_ID "latest"') os.environ['CI_PIPELINE_ID'] = 'latest' - self._run_shell_cmd("/usr/local/bin/docker-compose", + self._run_shell_cmd("docker-compose", full_args, env=os.environ) else: - self._run_shell_cmd("/usr/local/bin/docker-compose", full_args) + self._run_shell_cmd("docker-compose", full_args) def __del__(self): self._run_shell_cmd("docker", ["stop", self.docker_name]) From 0042f0ecb26ce86dca55e26846e948af5336931b Mon Sep 17 00:00:00 2001 From: pablo Date: Wed, 12 Aug 2020 14:06:56 +0200 Subject: [PATCH 20/34] boardfarm-ci: Added mutual exclusion in argv This prevents more than one --clean, --test, --build, etc being ran at the same time Signed-off-by: pablo --- dctest.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dctest.py b/dctest.py index 475e1030cb..2e12c1511e 100755 --- a/dctest.py +++ b/dctest.py @@ -156,14 +156,15 @@ def cleanup(rc): if __name__ == '__main__': check_docker_versions() parser = argparse.ArgumentParser(description='Dockerized test launcher') - parser.add_argument('--test', dest='test', type=str, help='Test to be run') - parser.add_argument('--clean', dest='clean', action='store_true', + group = parser.add_mutually_exclusive_group() + group.add_argument('--test', dest='test', type=str, help='Test to be run') + group.add_argument('--clean', dest='clean', action='store_true', help='Clean containers images and networks') - parser.add_argument('--build', dest='build', action='store_true', + group.add_argument('--build', dest='build', action='store_true', help='Rebuild containers') - parser.add_argument('--shell', dest='shell', action='store_true', + group.add_argument('--shell', dest='shell', action='store_true', help='Run a shell on the bf container') - parser.add_argument('--comp', dest='comp', action='store_true', + group.add_argument('--comp', dest='comp', action='store_true', help='Pass the rest of arguments to docker-compose') parser.add_argument('--id', dest='bid', type=str, help='Specify the id to use for build/shell/comp/clean') From e9d90a3027259353518031f2ea64fadb3abcd045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= Date: Wed, 12 Aug 2020 11:25:52 +0200 Subject: [PATCH 21/34] tests: ALEntity: use name in place of device.docker_name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When working on the docker-compose version of the boardfarm tests, we thought the ALEntity names had to be the same as the name boardfarm uses for boardfarm to be able to access them. It turns out that boardfarm only needs PrplMeshCompose to get its name from the boardfarm configuration file, and the ALEntity can use another one. Since test_flows doesn't pass a "device" parameter when constructing an ALEntity, it HAS to use "name" instead of going through the device to access the docker_name. environment.py: - Use the name of the ALEntityDocker and RadioDocker in instead of accessing "device". prplmesh_compose.py: - When creating the ALEntity, use docker_name as the name to make the different docker commands work. This will make the ALEntity usable again regardless of whether the tests runs with boardfarm or test_flows.py. Signed-off-by: Raphaël Mélotte --- .../boardfarm_prplmesh/devices/prplmesh_compose.py | 4 ++-- tests/environment.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py index 7ccd42bda5..83b100c2c6 100644 --- a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py @@ -48,12 +48,12 @@ def __init__(self, *args, **kwargs): "run", "start-controller-agent") time.sleep(self.delay) self.controller_entity = \ - ALEntityDocker(self.name, device=self, is_controller=True, compose=True) + ALEntityDocker(self.docker_name, device=self, is_controller=True, compose=True) else: self._docker_compose(["-d", "--name", self.docker_name, "agent"], "run", "start-agent") time.sleep(self.delay) - self.agent_entity = ALEntityDocker(self.name, device=self, + self.agent_entity = ALEntityDocker(self.docker_name, device=self, is_controller=False, compose=True) self.wired_sniffer = Sniffer(_get_bridge_interface(self.docker_network), diff --git a/tests/environment.py b/tests/environment.py index daa56012a3..5f3bbf3c90 100644 --- a/tests/environment.py +++ b/tests/environment.py @@ -283,7 +283,7 @@ def __init__(self, name: str, device: None = None, is_controller: bool = False, device_ip = re.search( r'inet (?P[0-9.]+)', device_ip_output.decode('utf-8')).group('ip') else: - device_ip = self.device.docker_name + device_ip = self.name ucc_socket = UCCSocket(device_ip, ucc_port) mac = ucc_socket.dev_get_parameter('ALid') @@ -296,12 +296,12 @@ def __init__(self, name: str, device: None = None, is_controller: bool = False, def command(self, *command: str) -> bytes: '''Execute `command` in docker container and return its output.''' - return subprocess.check_output(("docker", "exec", self.device.docker_name) + command) + return subprocess.check_output(("docker", "exec", self.name) + command) def wait_for_log(self, regex: str, start_line: int, timeout: float) -> bool: '''Poll the entity's logfile until it contains "regex" or times out.''' program = "controller" if self.is_controller else "agent" - return _docker_wait_for_log(self.device.docker_name, [program], regex, start_line, timeout) + return _docker_wait_for_log(self.name, [program], regex, start_line, timeout) def prprlmesh_status_check(self): return self.device.prprlmesh_status_check() @@ -323,7 +323,7 @@ def __init__(self, agent: ALEntityDocker, iface_name: str): def wait_for_log(self, regex: str, start_line: int, timeout: float) -> bool: '''Poll the radio's logfile until it contains "regex" or times out.''' programs = ("agent_" + self.iface_name, "ap_manager_" + self.iface_name) - return _docker_wait_for_log(self.agent.device.docker_name, programs, regex, + return _docker_wait_for_log(self.agent.name, programs, regex, start_line, timeout) def send_bwl_event(self, event: str) -> None: From a99970805e1100cdc39b65340643c4af05c34bba Mon Sep 17 00:00:00 2001 From: pablo Date: Wed, 12 Aug 2020 18:13:34 +0200 Subject: [PATCH 22/34] boardfarm-ci: Group all apt-get commands together With apt-get upgrade before Signed-off-by: pablo --- tools/docker/boardfarm-ci/Dockerfile | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/docker/boardfarm-ci/Dockerfile b/tools/docker/boardfarm-ci/Dockerfile index ac996d0da9..abf93a2568 100644 --- a/tools/docker/boardfarm-ci/Dockerfile +++ b/tools/docker/boardfarm-ci/Dockerfile @@ -1,9 +1,11 @@ FROM python:3.8-slim-buster -RUN apt-get update - # Debian dependencies to install docker and docker compose from docker.com -RUN apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common curl -y && apt-get clean +RUN apt-get update \ +&& DEBIAN_FRONTEND=noninteractive apt-get install \ +apt-transport-https ca-certificates curl gnupg-agent \ +software-properties-common curl gcc libsnmp-dev wireshark-common tshark \ +-y && apt-get clean # Install docker and docker-compose from docker.com repositories RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - @@ -19,13 +21,10 @@ RUN git clone https://github.com/mattsm/boardfarm.git \ && git checkout 100521fde1fb67536682cafecc2f91a6e2e8a6f8 \ && python3 setup.py install -# Debian dependencies for installing the Python packages on requirements.txt -RUN apt-get install gcc libsnmp-dev -y && apt-get clean - # Installation of the python packages needed by the tests COPY requirements.txt /app/requirements.txt WORKDIR app RUN pip3 install -r requirements.txt # Installation of Debian dependencies needed by the tests -RUN DEBIAN_FRONTEND=noninteractive apt-get install wireshark-common -y && apt-get clean +# RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install wireshark-common -y && apt-get clean From a0ae26ccb532f7fe3d7662755a35ed17344c9cd0 Mon Sep 17 00:00:00 2001 From: pablo Date: Thu, 13 Aug 2020 12:06:03 +0200 Subject: [PATCH 23/34] boardfarm-ci: Removed unused CURRENT_ID Renamed CURRENT_UID to CURRENT_UID_GID as suggested and removed CURRENT_ID wich was not used by agent/controller images Signed-off-by: pablo --- dctest.py | 4 +--- tools/docker/boardfarm-ci/docker-compose.yml | 5 +---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/dctest.py b/dctest.py index 2e12c1511e..5fc4e9a2e1 100755 --- a/dctest.py +++ b/dctest.py @@ -121,8 +121,7 @@ def dc(self, args, interactive=False): local_env = os.environ local_env['ROOT_DIR'] = self.rootdir docker_gid = grp.getgrnam('docker')[2] - local_env['CURRENT_UID'] = str(os.getuid()) + ':' + str(docker_gid) - local_env['CURRENT_ID'] = str(os.getuid()) + local_env['CURRENT_UID_GID'] = str(os.getuid()) + ':' + str(docker_gid) local_env['RUN_ID'] = self.build_id if os.getenv('CI_PIPELINE_ID') is None: @@ -133,7 +132,6 @@ def dc(self, args, interactive=False): # Running inside gitlab-ci local_env['FINAL_ROOT_DIR'] = '/builds/prpl-foundation/prplMesh' - # local_env['CURRENT_UID']= str(os.getuid()) + ':' + str(os.getgid()) if not interactive: proc = Popen(params, stdout=PIPE, stderr=PIPE) for line in proc.stdout: diff --git a/tools/docker/boardfarm-ci/docker-compose.yml b/tools/docker/boardfarm-ci/docker-compose.yml index 1f50b9cc75..553e14ccf2 100644 --- a/tools/docker/boardfarm-ci/docker-compose.yml +++ b/tools/docker/boardfarm-ci/docker-compose.yml @@ -9,7 +9,6 @@ services: - USER - INSTALL_DIR=${FINAL_ROOT_DIR}/build/install - ROOT_DIR=${FINAL_ROOT_DIR} - - CURRENT_ID - CI_PIPELINE_ID expose: - "5000" @@ -27,7 +26,6 @@ services: - INSTALL_DIR=${FINAL_ROOT_DIR}/build/install - ROOT_DIR=${FINAL_ROOT_DIR} # /builds/prpl-foundation/prplMesh - - CURRENT_ID - CI_PIPELINE_ID expose: - "5000" @@ -45,7 +43,6 @@ services: environment: - USER - ROOT_DIR - - CURRENT_ID - RUN_ID - CI_PIPELINE_ID - FINAL_ROOT_DIR @@ -55,6 +52,6 @@ services: - "$ROOT_DIR:$ROOT_DIR" - "/var/run/docker:/var/run/docker" - "/var/run/docker.sock:/var/run/docker.sock" - user: ${CURRENT_UID} + user: ${CURRENT_UID_GID} working_dir: $ROOT_DIR/tests entrypoint: ["bash", "run_bf_compose.sh"] From 157e5e4afd52a426b4b8aec06850c54bcc6284c4 Mon Sep 17 00:00:00 2001 From: pablo Date: Thu, 13 Aug 2020 12:14:47 +0200 Subject: [PATCH 24/34] boardfarm-ci: Commented on issue PPM-208 As suggested from PR comment. Signed-off-by: pablo --- dctest.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dctest.py b/dctest.py index 5fc4e9a2e1..ce8cf4a903 100755 --- a/dctest.py +++ b/dctest.py @@ -130,6 +130,8 @@ def dc(self, args, interactive=False): local_env['FINAL_ROOT_DIR'] = self.rootdir else: # Running inside gitlab-ci + # Setting a fixed location is needed until + # https://jira.prplfoundation.org/browse/PPM-208 is fixed. local_env['FINAL_ROOT_DIR'] = '/builds/prpl-foundation/prplMesh' if not interactive: From 344ebfeb01b925b597f026207c7de6df7fd45171 Mon Sep 17 00:00:00 2001 From: pablo Date: Thu, 13 Aug 2020 12:18:17 +0200 Subject: [PATCH 25/34] boardfarm-ci: Better error message on _run_cmd Signed-off-by: pablo --- .../boardfarm_prplmesh/devices/prplmesh_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_base.py b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_base.py index c30bf08e28..7bbdde55bf 100644 --- a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_base.py +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_base.py @@ -28,7 +28,7 @@ def _run_shell_cmd(self, cmd: str = "", args: list = None, timeout: int = 30, withexitstatus=1) entry = " ".join((cmd, " ".join(args))) if exitstatus != 0: - raise CommandError("Error executing {}".format(entry)) + raise CommandError("Error executing {}:\{}".format(entry, res)) self.log_calls += entry self.log += "$ " + entry + "\r\n" + res From b4adb53bd4847d754615f66e55321cd986aa06f4 Mon Sep 17 00:00:00 2001 From: pablo Date: Thu, 13 Aug 2020 12:20:07 +0200 Subject: [PATCH 26/34] boardfarm-ci: Fixed check_status Pass self.docker_name instead of fixed "controller-rme" when performing device_get_info, as suggested by PR comment. Signed-off-by: pablo --- .../boardfarm_prplmesh/devices/prplmesh_compose.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py index 83b100c2c6..dd27b9bcf6 100644 --- a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py @@ -98,7 +98,7 @@ def check_status(self): and also after test - to insure that device still operational. """ self._run_shell_cmd("printf", - ["device_get_info", "|", "nc", "-w", "1", "controller-rme", "8002"]) + ["device_get_info", "|", "nc", "-w", "1", self.docker_name, "8002"]) def isalive(self): """Method required by boardfarm. From d0e14154b5a573ba5c83edfe666584385b802149 Mon Sep 17 00:00:00 2001 From: pablo Date: Thu, 13 Aug 2020 12:21:22 +0200 Subject: [PATCH 27/34] boardfarm-ci: Set delay to the default 7 seconds On prplmesh_compose entry of prplmesh_config_compose.json Signed-off-by: pablo --- .../boardfarm_prplmesh/prplmesh_config_compose.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/prplmesh_config_compose.json b/tests/boardfarm_plugins/boardfarm_prplmesh/prplmesh_config_compose.json index 4697ddb022..1f13cbea0e 100644 --- a/tests/boardfarm_plugins/boardfarm_prplmesh/prplmesh_config_compose.json +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/prplmesh_config_compose.json @@ -16,7 +16,7 @@ "name": "lan2", "type": "prplmesh_compose", "role": "agent", - "delay" : 30, + "delay" : 7, "conn_cmd": "" }, { From c34ceebcef0a73bd7dad4edacb4cd41c3640d137 Mon Sep 17 00:00:00 2001 From: pablo Date: Thu, 13 Aug 2020 12:23:31 +0200 Subject: [PATCH 28/34] boardfarm-ci: Restored comment on ALEntityDocker's contructor Was removed but it is still pertinent Signed-off-by: pablo --- tests/environment.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/environment.py b/tests/environment.py index 5f3bbf3c90..5870573a42 100644 --- a/tests/environment.py +++ b/tests/environment.py @@ -252,6 +252,8 @@ class ALEntityDocker(ALEntity): The entity is defined from the name of the container, the rest is derived from that. ''' + # NOTE: name arg can be also extracted from the device class itself, but test_flows.py + # don't have it. We can remove this arg as soon, as we drop test_flows.py def __init__(self, name: str, device: None = None, is_controller: bool = False, compose: bool = False): From 599fc486c756be5d8f4274d3cd21bbc0bd317260 Mon Sep 17 00:00:00 2001 From: pablo Date: Thu, 13 Aug 2020 12:50:58 +0200 Subject: [PATCH 29/34] boardfarm-ci: Added license header to dctest.py Signed-off-by: pablo --- dctest.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dctest.py b/dctest.py index ce8cf4a903..4c86804c4e 100755 --- a/dctest.py +++ b/dctest.py @@ -1,5 +1,13 @@ #!/usr/bin/env python3 # +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# SPDX-FileCopyrightText: 2019-2020 the prplMesh contributors (see AUTHORS.md) +# +# This code is subject to the terms of the BSD+Patent license. +# +# See LICENSE file for more details. +# # Launch the test suite using docker and docker-compose. This script wraps # the creation of the bridge(s) to be able to connect external devices with # the docker network, launching the service for boardfarm. From 356793b16ff60c90abb7fbe5b4fb708cf31628f6 Mon Sep 17 00:00:00 2001 From: pablo Date: Thu, 13 Aug 2020 15:07:17 +0200 Subject: [PATCH 30/34] boardfarm-ci: Reorder lines to improve readability Signed-off-by: pablo --- .../boardfarm_prplmesh/devices/prplmesh_compose.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py index dd27b9bcf6..0400470afe 100644 --- a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_compose.py @@ -34,8 +34,8 @@ def __init__(self, *args, **kwargs): self.unique_id = os.getenv("RUN_ID") self.user_id = os.getenv("SUDO_USER", os.getenv("USER", "")) - self.docker_name = "-".join((config.get("name", "prplmesh_compose"), self.unique_id)) self.name = config.get("name", "prplmesh_compose") + self.docker_name = "-".join((self.name, self.unique_id)) print('config.get("name") {}'.format(config.get("name"))) self.role = config.get("role", "agent") self.cleanup_cmd = config.get("cleanup_cmd", None) From af13310316f08b11dee8daf5f17809bc55d9bb2d Mon Sep 17 00:00:00 2001 From: pablo Date: Fri, 14 Aug 2020 11:57:32 +0200 Subject: [PATCH 31/34] boardfarm-ci: Fixed typo Missing the n when restoring the original format string with \n ... Signed-off-by: pablo --- .../boardfarm_prplmesh/devices/prplmesh_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_base.py b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_base.py index 7bbdde55bf..49e8a83664 100644 --- a/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_base.py +++ b/tests/boardfarm_plugins/boardfarm_prplmesh/devices/prplmesh_base.py @@ -28,7 +28,7 @@ def _run_shell_cmd(self, cmd: str = "", args: list = None, timeout: int = 30, withexitstatus=1) entry = " ".join((cmd, " ".join(args))) if exitstatus != 0: - raise CommandError("Error executing {}:\{}".format(entry, res)) + raise CommandError("Error executing {}:\n{}".format(entry, res)) self.log_calls += entry self.log += "$ " + entry + "\r\n" + res From 09e27fbf7a51029aca9eaf402355b07c9e6cb656 Mon Sep 17 00:00:00 2001 From: pablo Date: Fri, 14 Aug 2020 11:59:00 +0200 Subject: [PATCH 32/34] boardfarm-ci: Aesthetical changes to pass PEP-8 An unused include and some spacess missing for PEP-8 compliance Signed-off-by: pablo --- dctest.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dctest.py b/dctest.py index 4c86804c4e..5329566b47 100755 --- a/dctest.py +++ b/dctest.py @@ -26,7 +26,6 @@ import argparse import os import grp -import shutil import getpass import sys import json @@ -167,13 +166,13 @@ def cleanup(rc): group = parser.add_mutually_exclusive_group() group.add_argument('--test', dest='test', type=str, help='Test to be run') group.add_argument('--clean', dest='clean', action='store_true', - help='Clean containers images and networks') + help='Clean containers images and networks') group.add_argument('--build', dest='build', action='store_true', - help='Rebuild containers') + help='Rebuild containers') group.add_argument('--shell', dest='shell', action='store_true', - help='Run a shell on the bf container') + help='Run a shell on the bf container') group.add_argument('--comp', dest='comp', action='store_true', - help='Pass the rest of arguments to docker-compose') + help='Pass the rest of arguments to docker-compose') parser.add_argument('--id', dest='bid', type=str, help='Specify the id to use for build/shell/comp/clean') args, rest = parser.parse_known_args() From edc4b0a8c554450773f21b59087ac00981f6a4fe Mon Sep 17 00:00:00 2001 From: pablo Date: Fri, 14 Aug 2020 15:08:44 +0200 Subject: [PATCH 33/34] boardfarm-ci: Added missing jq Signed-off-by: pablo --- tools/docker/boardfarm-ci/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/docker/boardfarm-ci/Dockerfile b/tools/docker/boardfarm-ci/Dockerfile index abf93a2568..675d8fedf2 100644 --- a/tools/docker/boardfarm-ci/Dockerfile +++ b/tools/docker/boardfarm-ci/Dockerfile @@ -4,7 +4,7 @@ FROM python:3.8-slim-buster RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install \ apt-transport-https ca-certificates curl gnupg-agent \ -software-properties-common curl gcc libsnmp-dev wireshark-common tshark \ +software-properties-common curl gcc libsnmp-dev jq wireshark-common tshark \ -y && apt-get clean # Install docker and docker-compose from docker.com repositories From df60f7582474a4891217a33fe358ce30709329c6 Mon Sep 17 00:00:00 2001 From: pablo Date: Fri, 14 Aug 2020 15:19:26 +0200 Subject: [PATCH 34/34] boardfarm-ci: Fixes for the new prplmesh/prplmesh URL Signed-off-by: pablo --- dctest.py | 2 +- tools/docker/boardfarm-ci/docker-compose.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dctest.py b/dctest.py index 5329566b47..8f8ab77da5 100755 --- a/dctest.py +++ b/dctest.py @@ -139,7 +139,7 @@ def dc(self, args, interactive=False): # Running inside gitlab-ci # Setting a fixed location is needed until # https://jira.prplfoundation.org/browse/PPM-208 is fixed. - local_env['FINAL_ROOT_DIR'] = '/builds/prpl-foundation/prplMesh' + local_env['FINAL_ROOT_DIR'] = '/builds/prpl-foundation/prplmesh/prplMesh' if not interactive: proc = Popen(params, stdout=PIPE, stderr=PIPE) diff --git a/tools/docker/boardfarm-ci/docker-compose.yml b/tools/docker/boardfarm-ci/docker-compose.yml index 553e14ccf2..354e36dd33 100644 --- a/tools/docker/boardfarm-ci/docker-compose.yml +++ b/tools/docker/boardfarm-ci/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: # Controller and agent are run from inside the boardfarm container controller: - image: registry.gitlab.com/prpl-foundation/prplmesh/prplmesh-runner:${CI_PIPELINE_ID} + image: registry.gitlab.com/prpl-foundation/prplmesh/prplmesh/prplmesh-runner:${CI_PIPELINE_ID} privileged: true # For the creation of the bridge to work container_name: controller environment: @@ -18,7 +18,7 @@ services: entrypoint: ["/root/entrypoint.sh", "/usr/bin/start-controller-agent"] agent: - image: registry.gitlab.com/prpl-foundation/prplmesh/prplmesh-runner:${CI_PIPELINE_ID} + image: registry.gitlab.com/prpl-foundation/prplmesh/prplmesh/prplmesh-runner:${CI_PIPELINE_ID} privileged: true container_name: agent environment: