diff --git a/client/Dockerfile b/client/Dockerfile index 6b1cac29c..c007c6eed 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -1,6 +1,4 @@ -ARG BALENA_ARCH=%%BALENA_ARCH%% - -FROM balenalib/armv7hf-alpine-node:16-run +FROM node:18.16.0-alpine3.16 WORKDIR /usr/src/app # hadolint ignore=DL3018 diff --git a/core/Dockerfile b/core/Dockerfile index c892fdb10..5bbaacd27 100644 --- a/core/Dockerfile +++ b/core/Dockerfile @@ -1,6 +1,4 @@ -ARG BALENA_ARCH=%%BALENA_ARCH%% - -FROM balenalib/armv7hf-node:16-bullseye as base +FROM node:16-bullseye-slim as base WORKDIR /usr/app @@ -12,16 +10,13 @@ ENV DEBIAN_FRONTEND noninteractive # hadolint ignore=DL3008 RUN apt-get update && apt-get install --no-install-recommends -y \ - bind9-dnsutils \ ca-certificates \ + wget \ + bind9-dnsutils \ docker.io \ - git \ iproute2 \ - jq \ openssh-client \ - socat \ - libudev-dev \ - rsync \ + libudev-dev \ unzip \ util-linux \ build-essential \ @@ -42,7 +37,8 @@ RUN if [ "$(uname -m)" = "arm64" ] || [ "$(uname -m)" = "aarch64" ] ; \ then \ npm i balena-cli@latest ; \ mkdir /usr/app/cli/ ; \ - cp -R /usr/app/node_modules/balena-cli/ /usr/app ; \ + mv /usr/app/node_modules/balena-cli/ /usr/app ; \ + rm -rf /usr/app/node_modules/ ; \ else \ wget -q -O balena-cli.zip "https://github.com/balena-io/balena-cli/releases/download/${BALENA_CLI_REF}/balena-cli-v${BALENA_CLI_VERSION}-linux-x64-standalone.zip" && \ unzip balena-cli.zip && rm balena-cli.zip ; \ @@ -50,8 +46,7 @@ RUN if [ "$(uname -m)" = "arm64" ] || [ "$(uname -m)" = "aarch64" ] ; \ # Add balena-cli to PATH ENV PATH /usr/app/balena-cli:$PATH -RUN ls /usr/app/balena-cli && ls /usr/app/balena-cli/bin -ENV PATH $PATH:/usr/app/balena-cli/bin +# ENV PATH $PATH:/usr/app/balena-cli/bin RUN balena version diff --git a/core/lib/common/worker.js b/core/lib/common/worker.js index 8d8ec2bed..559b2e0f1 100644 --- a/core/lib/common/worker.js +++ b/core/lib/common/worker.js @@ -131,62 +131,6 @@ module.exports = class Worker { }, json: true, }); - // await new Promise(async (resolve, reject) => { - // const req = rp.post({ - // uri: `${this.url}/dut/flash`, - // body: { - // path: imagePath - // }, - // json: true - // }); - - // req.catch((error) => { - // reject(error); - // }); - // req.finally(() => { - // if (lastStatus !== 'done') { - // reject(new Error('Unexpected end of TCP connection')); - // } - - // resolve(); - // }); - - // let lastStatus; - // req.on('data', (data) => { - // const computedLine = RegExp('(.+?): (.*)').exec(data.toString()); - - // if (computedLine) { - // if (computedLine[1] === 'error') { - // req.cancel(); - // reject(new Error(computedLine[2])); - // } - - // if (computedLine[1] === 'progress') { - // once(() => { - // this.logger.log('Flashing'); - // }); - // // Hide any errors as the lines we get can be half written - // const state = JSON.parse(computedLine[2]); - // if (state != null && isNumber(state.percentage)) { - // this.logger.status({ - // message: 'Flashing', - // percentage: state.percentage, - // }); - // } - // } - - // if (computedLine[1] === 'status') { - // lastStatus = computedLine[2]; - // } - // } - // }); - - // pipeline( - // fs.createReadStream(imagePath), - // createGzip({ level: 6 }), - // req, - // ); - // }); this.logger.log('Flash completed'); }, { @@ -431,12 +375,6 @@ module.exports = class Worker { async executeCommandInWorker(command, retryOptions={}) { return retry( async () => { - // let containerId = await this.executeCommandInWorkerHost( - // `balena ps | grep worker | awk '{print $1}'`, - // ); - // let result = await this.executeCommandInWorkerHost( - // `balena exec ${containerId} ${command}`, - // ); let result = await exec(command); console.log(`Exec call: ${command}, Result: ${result}`) return result; diff --git a/core/lib/config.js b/core/lib/config.js index d5790197c..ed7ceb187 100644 --- a/core/lib/config.js +++ b/core/lib/config.js @@ -1,12 +1,12 @@ module.exports = { leviathan: { artifacts: '/tmp/artifacts', // To store artifacts meant to be reported as results at the end of the suite - downloads: '/data/downloads', // To store/download assets needed for the suite (non-persistent) + downloads: '/data/workspace/downloads', // To store/download assets needed for the suite (non-persistent) reports: '/reports/', // To store/download reports generated from the suite (non-persistent) workdir: '/data', uploads: { - config: '/data/workspace/config.js', - suite: '/data/suites' + config:'/data/config.json', + suite: '/data/suite' } } }; diff --git a/core/lib/main-standalone.js b/core/lib/main-standalone.js deleted file mode 100644 index b962e6c87..000000000 --- a/core/lib/main-standalone.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2017 balena - * - * 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const { fork } = require('child_process'); - -(async function main() { - // The reason we need to fork is because many 3rd party libariers output to stdout - // so we need to capture that - suite = fork('./lib/common/suiteSubprocess', { - stdio: ['pipe', 'pipe', 'pipe', 'ipc'], - }); - - suite.stdout.on('data', (data) =>{ - console.log(data) - }); - suite.stderr.on('data', (data) => { - console.log(data) - }); - suite.on('message', (message) => { - console.log(`Message: ${message}`) - }); - - - try{ - const suiteExitCode = await new Promise((resolve, reject) => { - suite.on('error', reject); - suite.on('exit', code => { - console.log(`exiting suite...`); - resolve(code); - }); - }); - - console.log(`Suite exit code is: ${suiteExitCode}`); - const success = suiteExitCode === 0; - if(success){ - console.log(`Test result: PASS`) - process.exit(0) - } else { - console.log(`Test result: FAIL`) - process.exit(suiteExitCode) - } - } catch (e) { - console.log(`Error while runnign test suite... exiting`) - process.exit(127) - } -})(); diff --git a/docker-compose.worker.yml b/docker-compose.worker.yml index 7d435f267..844c8ed2b 100644 --- a/docker-compose.worker.yml +++ b/docker-compose.worker.yml @@ -1,25 +1,25 @@ version: "2" services: - # client: - # build: ./client - # network_mode: host - # volumes: - # # - "${WORKSPACE:-./workspace}:/usr/src/app/workspace:ro" - # # - "${REPORTS:-./workspace/reports}:/usr/src/app/reports:rw" - # # - "${SUITES:-./suites}:/usr/src/app/suites:ro" - # - "${SUITES:-./suites}:/data/suites" - # - "${REPORTS:-./workspace/reports}:/data/reports" - # - "${WORKSPACE:-./workspace}:/data/workspace" - # environment: - # - WORKER_TYPE=${WORKER_TYPE} - # - DEVICE_TYPE=${DEVICE_TYPE} - # - BALENACLOUD_API_KEY=${BALENACLOUD_API_KEY} - # - BALENACLOUD_ORG=${BALENACLOUD_ORG} - # - BALENACLOUD_APP_NAME=${BALENACLOUD_APP_NAME} - # - CORE_HOST=localhost - # depends_on: - # - core + client: + build: ./client + network_mode: host + volumes: + # - "${WORKSPACE:-./workspace}:/usr/src/app/workspace:ro" + # - "${REPORTS:-./workspace/reports}:/usr/src/app/reports:rw" + # - "${SUITES:-./suites}:/usr/src/app/suites:ro" + - "${SUITES:-./suites}:/data/suites" + - "${REPORTS:-./workspace/reports}:/data/reports" + - "${WORKSPACE:-./workspace}:/data/workspace" + environment: + - WORKER_TYPE=${WORKER_TYPE} + - DEVICE_TYPE=${DEVICE_TYPE} + - BALENACLOUD_API_KEY=${BALENACLOUD_API_KEY} + - BALENACLOUD_ORG=${BALENACLOUD_ORG} + - BALENACLOUD_APP_NAME=${BALENACLOUD_APP_NAME} + - CORE_HOST=localhost + depends_on: + - core core: privileged: true # preload requires docker-in-docker diff --git a/suites/e2e/suite.js b/suites/e2e/suite.js index 439148866..5dcd46647 100644 --- a/suites/e2e/suite.js +++ b/suites/e2e/suite.js @@ -119,7 +119,7 @@ module.exports = { .sdk.fetchOS( this.suite.options.balenaOS.download.version, this.suite.deviceType.slug, - )}` + )}` : undefined, configJson: { uuid: this.suite.options.balenaOS.config.uuid, diff --git a/suites/e2e/tests/flash/index.js b/suites/e2e/tests/flash/index.js index 15218804f..ee4b65f5e 100644 --- a/suites/e2e/tests/flash/index.js +++ b/suites/e2e/tests/flash/index.js @@ -22,7 +22,6 @@ module.exports = { run: async function (test) { try { await this.worker.off(); // Ensure DUT is off before starting tests - console.log(`suite image path: ${this.os.image.path}`) await this.worker.flash(this.os.image.path); } catch (err) { throw new Error(`Flashing failed with error: ${err}`); diff --git a/testrunner/Dockerfile b/testrunner/Dockerfile index 2931cbc45..424f7ca65 100644 --- a/testrunner/Dockerfile +++ b/testrunner/Dockerfile @@ -1,12 +1,12 @@ # avoid alpine 3.13 or later due to this issue on armv7 # https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0#time64_requirements -FROM alpine:3.12 + +FROM balenalib/armv7hf-alpine:3.15-run WORKDIR /usr/src/app -# https://github.com/balena-io/balena-cli/blob/master/INSTALL-LINUX.md#additional-dependencies # hadolint ignore=DL3018 -RUN apk add --no-cache bash git ca-certificates docker nano make curl +RUN apk add --no-cache git ca-certificates docker nano make curl # fail if binaries are missing or won't run RUN dockerd --version && docker --version diff --git a/testrunner/config.js b/testrunner/config.js deleted file mode 100644 index 2e397d47c..000000000 --- a/testrunner/config.js +++ /dev/null @@ -1,94 +0,0 @@ -module.exports = [ - { - // Device under test (DUT) name goes here - deviceType: "raspberrypi4-64", - - // Suite name goes here - suite: `/data/suites/e2e`, - config: { - - // Network configuration for the DUT - networkWired: false, - networkWireless: true, - - // For tests that need a specific balenaOS version to be downloaded. Default: latest - downloadVersion: 'latest', - - // Needed the provision the DUT to a balenaCloud fleet - balenaApiKey: '', - balenaApiUrl: 'balena-cloud.com', - organization: 'gh_rcooke_warwick', - }, - - // Path to the gzipped image to be tested goes here. This image is used to provision the DUT - image: `/data/workspace/os.img`, - - // Worker configuration: Pointing to a Fleet - // https://balena-os.github.io/leviathan/pages/Getting-Started/config-reference.html#different-workers-configurations-available - workers:['http://localhost:80'], - - debug: { - // Exit the ongoing test suite if a test fails - failFast: false, - // Exit the ongoing test run if a test fails - globalFailFast: false, - // Persist downloadeded artifacts - preserveDownloads: false, - // Mark unstable tests to be skipped - unstable: ["Kill the device under test"], - }, - }, - // - // { - // deviceType: "raspberrypi3", - // suite: `${__dirname}/../suites/os`, - // config: { - // networkWired: false, - // networkWireless: true, - // balenaApiKey: process.env.BALENACLOUD_API_KEY, - // balenaApiUrl: 'balena-cloud.com', - // organization: 'BALENACLOUD_ORG_GOES_HERE' - // }, - // image: `${__dirname}/balena.img.gz`, - // // https://balena-os.github.io/leviathan/pages/Getting-Started/config-reference.html#different-workers-configurations-available - // workers: { - // balenaApplication: 'testbot-personal', - // apiKey: process.env.BALENACLOUD_API_KEY - // } - // }, - // - // - // { - // deviceType: "raspberrypi3", - // suite: `${__dirname}/../suites/hup`, - // config: { - // networkWired: false, - // networkWireless: true, - // balenaApiKey: process.env.BALENACLOUD_API_KEY, - // balenaApiUrl: 'balena-cloud.com', - // organization: 'BALENACLOUD_ORG_GOES_HERE' - // }, - // image: `${__dirname}/balena.img.gz`, - // // Worker configuration: Public URL's - // // https://balena-os.github.io/leviathan/pages/Getting-Started/config-reference.html#different-workers-configurations-available - // workers: ['https://123213bda32048sgd5dfw223423723324.balena-devices.com/'] - // }, - // - // - // { - // deviceType: "genericx86-64-ext", - // suite: `${__dirname}/../suites/os`, - // config: { - // networkWired: false, - // networkWireless: true, - // balenaApiKey: process.env.BALENACLOUD_API_KEY, - // balenaApiUrl: 'balena-cloud.com', - // organization: 'BALENACLOUD_ORG_GOES_HERE' - // }, - // // balenaOS image that is uploaded to the testbot - // image: `${__dirname}/balena.img.gz`, - // // Worker configuration to run the QEMU worker - // // https://balena-os.github.io/leviathan/pages/Getting-Started/config-reference.html#different-workers-configurations-available - // workers: ['http://worker'] - // } -]; \ No newline at end of file diff --git a/testrunner/entry.sh b/testrunner/entry.sh index d5dfc47aa..933da2920 100644 --- a/testrunner/entry.sh +++ b/testrunner/entry.sh @@ -1,5 +1,8 @@ #!/bin/bash +# Clone Leviathan +https://github.com/balena-os/Leviathan + rm -rf /var/run/docker 2>/dev/null || true rm -f /var/run/docker.sock 2>/dev/null || true rm -f /var/run/docker.pid 2>/dev/null || true