diff --git a/bazel/labgrid/strategy/qemu/strategy.py b/bazel/labgrid/strategy/qemu/strategy.py index 28b071fa1ca22c6395fad461f5cb703d44ec7b19..b9296e2c96c5cd1ba2a1e8f34e7987187c6087ac 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) diff --git a/e2e/docker/BUILD.bazel b/e2e/docker/BUILD.bazel index 802fd8e7e36824ca29b6e317dda386d2306ec641..84bcd3ebd50b3f1f2b4fc5a4f364b038089167f3 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/e2e/qemu/BUILD.bazel b/e2e/qemu/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..69a6e7a2d09da0ce191e655ed0c60afda7385469 --- /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//ape:cat"], + outs = ["stdout.log"], + cmd = "$(location @ape//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 0000000000000000000000000000000000000000..3320862178e5a63681c384aa77ab6998f5655b1c --- /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/config/data.bzl b/labgrid/config/data.bzl index b51aaf69c2e72d2c246e45b913f3f797214b8358..553918b8cbf21c821d984d8ce0c6f296fd4e3624 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 97733b1ae865ebf9eca4847fcbced2f285ef5601..83eb2f1d867e1b766b18bf3b9a9ddc32985eb096 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), ) diff --git a/labgrid/config/toolchain/macro.bzl b/labgrid/config/toolchain/macro.bzl index 3928a6777f09ff4e18816f1cdf0e4fa155e8c804..fa40645f593e0c8483991547a8492e82314ac739 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 44e157bb68c9a2c237ad7fe4f49a9e117a7fbb3f..aff284bd1165096dfc590b6e6c3782ecac151483 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): @@ -35,9 +37,17 @@ 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: + # 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." ) @@ -46,34 +56,45 @@ 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() 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}") + 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 diff --git a/labgrid/toolchain/config/qemu/amd64/BUILD.bazel b/labgrid/toolchain/config/qemu/amd64/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..7b326cd4dd653b8ae3351d710b813c98d85bf5cf --- /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 0000000000000000000000000000000000000000..9f8b97931b57319bd0620e35176d1ff63c30f3c6 --- /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 diff --git a/labgrid/toolchain/qemu-system/BUILD.bazel b/labgrid/toolchain/qemu-system/BUILD.bazel index 354522b952161827809d6b38f8c586c8088ec67f..d1e160d42ae3ece21d850668e5415ba3d627561e 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), 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 589a0dbedb4dbf3cfc0f13392276a91efca5ac91..81e0b2c3c326a7f26441481fea12f554ffa7be0b 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(