From f9052205ce21bd9436e64874e494212f212afe0f Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Thu, 10 Oct 2024 09:37:59 +0100 Subject: [PATCH 01/10] feat(qemu-system): use consistent "Make" variable name This will allow us to use `$(QEMU_SYSTEM)` in env var substitutions when passing `//labgrid/toolchain/qemu-system:resolved` to `toolchains`. --- labgrid/toolchain/qemu-system/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/labgrid/toolchain/qemu-system/BUILD.bazel b/labgrid/toolchain/qemu-system/BUILD.bazel index 354522b9..d1e160d4 100644 --- a/labgrid/toolchain/qemu-system/BUILD.bazel +++ b/labgrid/toolchain/qemu-system/BUILD.bazel @@ -11,6 +11,7 @@ toolchain_type( toolchain_info( name = "{}-{}-qemu-system-{}".format(cpu, os, bin), target = "//debian/{}/qemu-system-{}:qemu-system-{}".format(cpu, pkg, bin), + variable = "QEMU_SYSTEM", ), toolchain( name = "{}-{}-qemu-system-{}-toolchain".format(cpu, os, bin), -- GitLab From 0acefaaa4f5052ccd1f027bea2dcd92311fd2051 Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Fri, 11 Oct 2024 09:27:15 +0100 Subject: [PATCH 02/10] fix(config): forward data runfiles --- labgrid/config/data.bzl | 2 +- labgrid/config/rule.bzl | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/labgrid/config/data.bzl b/labgrid/config/data.bzl index b51aaf69..553918b8 100644 --- a/labgrid/config/data.bzl +++ b/labgrid/config/data.bzl @@ -8,7 +8,7 @@ ATTRS = {} def implementation(ctx): toolchain = ctx.toolchains["//labgrid/toolchain/config:type"] - return DefaultInfo(files = toolchain.data) + return toolchain.data data = rule( doc = DOC, diff --git a/labgrid/config/rule.bzl b/labgrid/config/rule.bzl index 97733b1a..83eb2f1d 100644 --- a/labgrid/config/rule.bzl +++ b/labgrid/config/rule.bzl @@ -104,6 +104,12 @@ def _runfile(value, separator = "~"): return value +def _forward_runfiles(ctx, targets): + files = depset(transitive = [d.files for d in targets]) + runfiles = ctx.runfiles() + runfiles = runfiles.merge_all([d.default_runfiles for d in targets]) + return DefaultInfo(files = files, runfiles = runfiles) + def implementation(ctx): data = ctx.attr.data + [ctx.attr.src] + ctx.attr.toolchains env = {k: _expand(ctx, data, v) for k, v in ctx.attr.env.items()} @@ -112,7 +118,7 @@ def implementation(ctx): src = ctx.file.src, deps = _flatten([_forward(d) for d in ctx.attr.deps]), env = env, - data = depset(transitive = [d.files for d in data]), + data = _forward_runfiles(ctx, data), manager = _forward(ctx.attr.manager), ) -- GitLab From cf0371f72474ce8600bafba358302c892669d2aa Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Fri, 11 Oct 2024 20:46:42 +0100 Subject: [PATCH 03/10] fix(run): allow subprocesses to have their own runfiles Without this, QEMU won't work, as the `debian_launcher` will look for runfiles under `run`. --- labgrid/run/run.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/labgrid/run/run.py b/labgrid/run/run.py index 44e157bb..996557e6 100644 --- a/labgrid/run/run.py +++ b/labgrid/run/run.py @@ -38,6 +38,9 @@ def arguments(prsr: ArgumentParser) -> None: def main(exe: Path, *args: str) -> int: + # Allow subprocesses to have their own runfiles + del environ["RUNFILES_DIR"] + prsr = ArgumentParser( prog=str(exe), description="Runs a command over SSH to a LabGrid Docker device." ) -- GitLab From 6494abdcdc7fc7110fd7204a73837ee83ea25846 Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Tue, 15 Oct 2024 17:17:31 +0100 Subject: [PATCH 04/10] feat(run): do strategy clean-up at the end BREAKING CHANGE: `state` is now `states` in `labgrid_config_toolchain` We now accept a 2-item string tuple representing the states to transition to before and after command execution. The default of `("shell", "off")` serves most built-in Labgrid strategies. --- e2e/docker/BUILD.bazel | 2 +- labgrid/config/toolchain/macro.bzl | 4 +++- labgrid/run/run.py | 8 ++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/e2e/docker/BUILD.bazel b/e2e/docker/BUILD.bazel index 802fd8e7..84bcd3eb 100644 --- a/e2e/docker/BUILD.bazel +++ b/e2e/docker/BUILD.bazel @@ -25,7 +25,7 @@ platform( labgrid_config_toolchain( name = "config", src = "local-ubuntu.16.04-gnu.yaml", - state = "accessible", + states = ("accessible", "gone"), target_compatible_with = [ ":constraint", "@toolchain_utils//toolchain/constraint/os:linux", diff --git a/labgrid/config/toolchain/macro.bzl b/labgrid/config/toolchain/macro.bzl index 3928a677..fa40645f 100644 --- a/labgrid/config/toolchain/macro.bzl +++ b/labgrid/config/toolchain/macro.bzl @@ -2,7 +2,8 @@ load("@rules_labgrid//labgrid/config:defs.bzl", "labgrid_config") visibility("//...") -def labgrid_config_toolchain(*, name, src, state, target_compatible_with, manager = "@rules_labgrid//labgrid/manager:passthrough", deps = (), env = {}, data = [], toolchains = []): +def labgrid_config_toolchain(*, name, src, target_compatible_with, states = ("shell", "off"), manager = "@rules_labgrid//labgrid/manager:passthrough", deps = (), env = {}, data = [], toolchains = []): + state, end_state = states # TODO: add proper validation src = native.package_relative_label(src) labgrid_config( name = "{}-config".format(name), @@ -11,6 +12,7 @@ def labgrid_config_toolchain(*, name, src, state, target_compatible_with, manage env = env | { "LG_ENV": "$(location {})".format(src), "LG_STATE": state, + "BZL_LG_END_STATE": end_state, }, data = data, toolchains = toolchains, diff --git a/labgrid/run/run.py b/labgrid/run/run.py index 996557e6..a5e295b7 100644 --- a/labgrid/run/run.py +++ b/labgrid/run/run.py @@ -35,6 +35,11 @@ def arguments(prsr: ArgumentParser) -> None: help="The state to transition the LabGrid strategy to", default=environ["LG_STATE"], ) + prsr.add_argument( + "--end_state", + help="The state to transition the LabGrid strategy to at the end", + default=environ["BZL_LG_END_STATE"], + ) def main(exe: Path, *args: str) -> int: @@ -77,6 +82,9 @@ def main(exe: Path, *args: str) -> int: stdout.write(f"{line}{linesep}") for line in err: stderr.write(f"{line}{linesep}") + + strategy.transition(parsed.end_state) + return code -- GitLab From 9a2e9394940fc33b938a3fc2d54d07f577c80200 Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Tue, 15 Oct 2024 17:21:16 +0100 Subject: [PATCH 05/10] feat(QEMUStrategy): replace `accessible` with `shell` By adopting the "default", we can omit `states` when using `labgrid_config_toolchain`. Also, semantically it probably makes sense to call it `shell`, as we wait for the shell to be activated. --- bazel/labgrid/strategy/qemu/strategy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bazel/labgrid/strategy/qemu/strategy.py b/bazel/labgrid/strategy/qemu/strategy.py index 28b071fa..b9296e2c 100644 --- a/bazel/labgrid/strategy/qemu/strategy.py +++ b/bazel/labgrid/strategy/qemu/strategy.py @@ -12,7 +12,7 @@ from labgrid.strategy import Strategy, StrategyError class Status(enum.Enum): unknown = 0 off = 1 - accessible = 2 + shell = 2 @target_factory.reg_driver @@ -37,7 +37,7 @@ class QEMUStrategy(Strategy): self.target.activate(self.qemu) # Stop the QEMU instance self.qemu.off() - elif status == Status.accessible: + elif status == Status.shell: # Resets shell drivers status self.target.deactivate(self.shell) self.target.activate(self.qemu) -- GitLab From c33c669cd87b25cf80e5cfdd51b059a64d11e55f Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Wed, 16 Oct 2024 09:00:25 +0100 Subject: [PATCH 06/10] style: move debian image to match seed image --- qemu/debian/{ => image}/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) rename qemu/debian/{ => image}/BUILD.bazel (91%) diff --git a/qemu/debian/BUILD.bazel b/qemu/debian/image/BUILD.bazel similarity index 91% rename from qemu/debian/BUILD.bazel rename to qemu/debian/image/BUILD.bazel index 589a0dbe..81e0b2c3 100644 --- a/qemu/debian/BUILD.bazel +++ b/qemu/debian/image/BUILD.bazel @@ -9,6 +9,7 @@ alias( }, no_match_error = "No QEMU Debian image for platform.", ), + visibility = ["//:__subpackages__"], ) build_test( -- GitLab From f494cc57c7b9e987d32f5a9ff4728e924f5f6459 Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Wed, 16 Oct 2024 09:05:07 +0100 Subject: [PATCH 07/10] feat(e2e): add QEMU test --- e2e/qemu/BUILD.bazel | 25 +++++++++++++++++ e2e/qemu/stdout.log.expected | 9 +++++++ .../toolchain/config/qemu/amd64/BUILD.bazel | 21 +++++++++++++++ .../toolchain/config/qemu/amd64/config.yaml | 27 +++++++++++++++++++ 4 files changed, 82 insertions(+) create mode 100644 e2e/qemu/BUILD.bazel create mode 100644 e2e/qemu/stdout.log.expected create mode 100644 labgrid/toolchain/config/qemu/amd64/BUILD.bazel create mode 100644 labgrid/toolchain/config/qemu/amd64/config.yaml diff --git a/e2e/qemu/BUILD.bazel b/e2e/qemu/BUILD.bazel new file mode 100644 index 00000000..3c9bbe29 --- /dev/null +++ b/e2e/qemu/BUILD.bazel @@ -0,0 +1,25 @@ +load("@rules_diff//diff/file/test:defs.bzl", "diff_file_test") +load("@rules_labgrid//labgrid/run:defs.bzl", "labgrid_run") + +platform( + name = "platform", + constraint_values = [ + "@toolchain_utils//toolchain/constraint/os:linux", + "@toolchain_utils//toolchain/constraint/cpu:amd64", + ], +) + +labgrid_run( + name = "cat", + srcs = ["@ape//:cat"], + outs = ["stdout.log"], + cmd = "$(location @ape//:cat) /etc/os-release > $@", + platform = ":platform", +) + +diff_file_test( + name = "test", + size = "small", + a = ":stdout.log.expected", + b = ":stdout.log", +) diff --git a/e2e/qemu/stdout.log.expected b/e2e/qemu/stdout.log.expected new file mode 100644 index 00000000..33208621 --- /dev/null +++ b/e2e/qemu/stdout.log.expected @@ -0,0 +1,9 @@ +PRETTY_NAME="Debian GNU/Linux 12 (bookworm)" +NAME="Debian GNU/Linux" +VERSION_ID="12" +VERSION="12 (bookworm)" +VERSION_CODENAME=bookworm +ID=debian +HOME_URL="https://www.debian.org/" +SUPPORT_URL="https://www.debian.org/support" +BUG_REPORT_URL="https://bugs.debian.org/" diff --git a/labgrid/toolchain/config/qemu/amd64/BUILD.bazel b/labgrid/toolchain/config/qemu/amd64/BUILD.bazel new file mode 100644 index 00000000..7b326cd4 --- /dev/null +++ b/labgrid/toolchain/config/qemu/amd64/BUILD.bazel @@ -0,0 +1,21 @@ +load("//labgrid/config/toolchain:defs.bzl", "labgrid_config_toolchain") + +labgrid_config_toolchain( + name = "amd64", + src = "config.yaml", + data = [ + "//qemu/debian/image", + "//qemu/seed/image", + ], + env = { + "LG_QEMU_SYSTEM_BIN": "$(QEMU_SYSTEM)", + "LG_QEMU_QCOW2_IMAGE": "$(location //qemu/debian/image)", + "LG_QEMU_VIRT_IMAGE": "$(location //qemu/seed/image)", + }, + target_compatible_with = [ + "@toolchain_utils//toolchain/constraint/os:linux", + "@toolchain_utils//toolchain/constraint/cpu:amd64", + ], + toolchains = ["//labgrid/toolchain/qemu-system:resolved"], + deps = ["//bazel/labgrid/strategy"], +) diff --git a/labgrid/toolchain/config/qemu/amd64/config.yaml b/labgrid/toolchain/config/qemu/amd64/config.yaml new file mode 100644 index 00000000..9f8b9793 --- /dev/null +++ b/labgrid/toolchain/config/qemu/amd64/config.yaml @@ -0,0 +1,27 @@ +targets: + main: + resources: + NetworkService: + address: "localhost" + port: 2222 + username: "labgrid-user" + password: "labgrid" + drivers: + QEMUDriver: + qemu_bin: "qemu" + machine: "pc" + cpu: "max" + memory: "2G" + nic: "user,model=e1000,hostfwd=tcp::2222-:22" + extra_args: !template "-snapshot -drive file=$LG_QEMU_QCOW2_IMAGE,format=qcow2 -cdrom $LG_QEMU_VIRT_IMAGE" + ShellDriver: + prompt: " login: " + login_prompt: " login: " + username: "labgrid-user" + login_timeout: 200 + SSHDriver: {} + QEMUStrategy: {} +tools: + qemu: !template "$LG_QEMU_SYSTEM_BIN" +imports: + - bazel.labgrid.strategy -- GitLab From 7b8b26ce3a0e870eb604afbbdf6c52fd74384ac9 Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Wed, 16 Oct 2024 15:03:30 +0100 Subject: [PATCH 08/10] fix: try-finally --- labgrid/run/run.py | 54 ++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/labgrid/run/run.py b/labgrid/run/run.py index a5e295b7..cfdebfd2 100644 --- a/labgrid/run/run.py +++ b/labgrid/run/run.py @@ -58,32 +58,34 @@ def main(exe: Path, *args: str) -> int: env = Environment(str(parsed.config)) target = env.get_target() strategy = target.get_driver("Strategy") - strategy.transition(parsed.state) - - # Retrieve the communication protocols - shell = target.get_driver("CommandProtocol") - transfer = target.get_driver("FileTransferProtocol") - - # Transfer the provided program over to the Docker image - # TODO: this should be a context manager that removes it later - # TODO: this should use a unique remote name/directory - program = "/tmp/{}".format(parsed.program.name) - transfer.put(parsed.program, program) - - # Transfer runfiles - src_runfiles = parsed.program.with_suffix(".runfiles") - dest_runfiles = Path(program).with_suffix(".runfiles") - if src_runfiles.exists(): - transfer.put(src_runfiles, dest_runfiles) - - # Run the transferred program - out, err, code = shell.run(join((program, *parsed.arguments))) - for line in out: - stdout.write(f"{line}{linesep}") - for line in err: - stderr.write(f"{line}{linesep}") - - strategy.transition(parsed.end_state) + try: + strategy.transition(parsed.state) + + # Retrieve the communication protocols + shell = target.get_driver("CommandProtocol") + transfer = target.get_driver("FileTransferProtocol") + + # Transfer the provided program over to the Docker image + # TODO: this should be a context manager that removes it later + # TODO: this should use a unique remote name/directory + program = "/tmp/{}".format(parsed.program.name) + transfer.put(parsed.program, program) + + # Transfer runfiles + src_runfiles = parsed.program.with_suffix(".runfiles") + dest_runfiles = Path(program).with_suffix(".runfiles") + if src_runfiles.exists(): + transfer.put(src_runfiles, dest_runfiles) + + # Run the transferred program + out, err, code = shell.run(join((program, *parsed.arguments))) + for line in out: + stdout.write(f"{line}{linesep}") + for line in err: + stderr.write(f"{line}{linesep}") + + finally: + strategy.transition(parsed.end_state) return code -- GitLab From 9470bae7f75b47b550c2957731637bbf036be8c6 Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Thu, 17 Oct 2024 10:24:49 +0000 Subject: [PATCH 09/10] feat(run): Added labgrid DEBUG and Step logging (cherry picked from commit c30d0021f67e23fc1b1deac6ba85c3d91aa1d01f) Co-authored-by: David Brown --- labgrid/run/run.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/labgrid/run/run.py b/labgrid/run/run.py index cfdebfd2..aff284bd 100644 --- a/labgrid/run/run.py +++ b/labgrid/run/run.py @@ -1,5 +1,6 @@ #! /usr/bin/env python3 +import logging from argparse import ArgumentParser from os import environ, linesep from pathlib import Path, PurePath @@ -8,6 +9,7 @@ from sys import argv, stderr, stdout from typing import Collection, Protocol, Tuple from labgrid import Environment +from labgrid.logging import basicConfig, StepLogger class Shell(Protocol): @@ -54,6 +56,12 @@ def main(exe: Path, *args: str) -> int: parsed = prsr.parse_args(args) + # enable info logging + basicConfig(level=logging.DEBUG) + + # show labgrid steps on the console + StepLogger.start() + # Start up Docker container with LabGrid env = Environment(str(parsed.config)) target = env.get_target() -- GitLab From fd9ac8a3d532bac034c578902f4749f2a45dc7ea Mon Sep 17 00:00:00 2001 From: David Brown Date: Thu, 17 Oct 2024 13:37:41 +0000 Subject: [PATCH 10/10] fix(e2e): use the APE target that uses the configuration --- e2e/qemu/BUILD.bazel | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/qemu/BUILD.bazel b/e2e/qemu/BUILD.bazel index 3c9bbe29..69a6e7a2 100644 --- a/e2e/qemu/BUILD.bazel +++ b/e2e/qemu/BUILD.bazel @@ -11,9 +11,9 @@ platform( labgrid_run( name = "cat", - srcs = ["@ape//:cat"], + srcs = ["@ape//ape:cat"], outs = ["stdout.log"], - cmd = "$(location @ape//:cat) /etc/os-release > $@", + cmd = "$(location @ape//ape:cat) /etc/os-release > $@", platform = ":platform", ) -- GitLab