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..60476d550d56679c237a6a1d19945770d8be9146 100644 --- a/e2e/docker/BUILD.bazel +++ b/e2e/docker/BUILD.bazel @@ -25,6 +25,7 @@ platform( labgrid_config_toolchain( name = "config", src = "local-ubuntu.16.04-gnu.yaml", + final_state = "gone", state = "accessible", target_compatible_with = [ ":constraint", 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/BUILD.bazel b/labgrid/config/BUILD.bazel index 36c525c32cce5d28d7e0aef349340b4167d6e680..3d90adba747e7e7f4a593ac4fd08c328ca9fefd0 100644 --- a/labgrid/config/BUILD.bazel +++ b/labgrid/config/BUILD.bazel @@ -2,6 +2,7 @@ load(":data.bzl", "data") load(":deps.bzl", "deps") load(":env.bzl", "env") load(":managers.bzl", "managers") +load(":tools.bzl", "tools") env( name = "env", @@ -13,6 +14,11 @@ data( visibility = ["//:__subpackages__"], ) +tools( + name = "tools", + visibility = ["//:__subpackages__"], +) + managers( name = "managers", visibility = ["//:__subpackages__"], 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 35d8aea9541dfd1133090907e868ddd6865f1e6f..d02e5bfce495ab63e5aed813d8da4efd3ad8b672 100644 --- a/labgrid/config/rule.bzl +++ b/labgrid/config/rule.bzl @@ -67,6 +67,12 @@ ATTRS = { allow_files = True, doc = "The data files to use.", providers = [DefaultInfo], + cfg = "target", + ), + "tools": attr.label_list( + allow_files = True, + doc = "The tools to use.", + providers = [DefaultInfo], cfg = "exec", ), "managers": attr.label_list( @@ -113,15 +119,23 @@ def _merge_default_info(ctx, targets): runfiles = runfiles, ) +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 + data = ctx.attr.data + [ctx.attr.src] + tools = ctx.attr.tools + ctx.attr.toolchains env = {k: _expand(ctx, data, v) for k, v in ctx.attr.env.items()} default = DefaultInfo(files = depset([ctx.file.src])) toolchain = platform_common.ToolchainInfo( src = ctx.file.src, deps = [_merge_default_info(ctx, ctx.attr.deps), _merge_py_info(ctx.attr.deps)], env = env, - data = depset(transitive = [d.files for d in data]), + data = _forward_runfiles(ctx, data), + tools = _forward_runfiles(ctx, tools), managers = [_merge_default_info(ctx, ctx.attr.managers), _merge_py_info(ctx.attr.managers)], ) diff --git a/labgrid/config/toolchain/macro.bzl b/labgrid/config/toolchain/macro.bzl index 13c015d8ac87059db442f97c517fac4fd7d6c171..82b5d0d387fef54fb442588099c0db105ab59ce6 100644 --- a/labgrid/config/toolchain/macro.bzl +++ b/labgrid/config/toolchain/macro.bzl @@ -2,7 +2,7 @@ load("@rules_labgrid//labgrid/config:defs.bzl", "labgrid_config") visibility("//...") -def labgrid_config_toolchain(*, name, src, state, target_compatible_with, managers = [], deps = [], env = {}, data = [], toolchains = []): +def labgrid_config_toolchain(*, name, src, target_compatible_with, state = "shell", final_state = "off", managers = [], deps = [], env = {}, data = [], tools = [], toolchains = []): src = native.package_relative_label(src) labgrid_config( name = "{}-config".format(name), @@ -11,8 +11,10 @@ def labgrid_config_toolchain(*, name, src, state, target_compatible_with, manage env = env | { "LG_ENV": "$(location {})".format(src), "LG_STATE": state, + "BZL_LG_FINAL_STATE": final_state, }, data = data, + tools = tools, toolchains = toolchains, managers = [native.package_relative_label(m) for m in managers], ) diff --git a/labgrid/config/tools.bzl b/labgrid/config/tools.bzl new file mode 100644 index 0000000000000000000000000000000000000000..009f2c7c667ba0bc66ff71a5bb48641ba4c55395 --- /dev/null +++ b/labgrid/config/tools.bzl @@ -0,0 +1,20 @@ +load("//labgrid/cfg:unstore.bzl", _cfg = "unstore") + +visibility("//labgrid/config/...") + +DOC = "Unpacks the `tools` from the `//labgrid/toolchain/config:type` toolchain" + +ATTRS = {} + +def implementation(ctx): + toolchain = ctx.toolchains["//labgrid/toolchain/config:type"] + return toolchain.tools + +tools = rule( + doc = DOC, + attrs = ATTRS, + implementation = implementation, + provides = [DefaultInfo], + toolchains = ["//labgrid/toolchain/config:type"], + cfg = _cfg, +) diff --git a/labgrid/executor/BUILD.bazel b/labgrid/executor/BUILD.bazel index db6fcbecec62c9487ef1916967637ac914c23afd..6ead04d607d94f21766c0f1c4331eac9c71e164f 100644 --- a/labgrid/executor/BUILD.bazel +++ b/labgrid/executor/BUILD.bazel @@ -9,7 +9,10 @@ args( py_binary( name = "executor", srcs = ["executor.py"], - data = ["//labgrid/config:data"], + data = [ + "//labgrid/config:data", + "//labgrid/config:tools", + ], tags = ["manual"], visibility = ["//:__subpackages__"], deps = [ diff --git a/labgrid/run/run.py b/labgrid/run/run.py index 44e157bb68c9a2c237ad7fe4f49a9e117a7fbb3f..5d0a236b6294d01273e5eb8d5bc4f48693842081 100644 --- a/labgrid/run/run.py +++ b/labgrid/run/run.py @@ -35,9 +35,17 @@ def arguments(prsr: ArgumentParser) -> None: help="The state to transition the LabGrid strategy to", default=environ["LG_STATE"], ) + prsr.add_argument( + "--final-state", + help="The state to transition the LabGrid strategy to at the end", + default=environ["BZL_LG_FINAL_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." ) @@ -50,30 +58,35 @@ 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}") + 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.final_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..a8377ee4d374f207a889f2eb82fa638582c1ccc8 --- /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: 600 + 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(