From 282fad2538c0bc50d3828233c7e8f61c88afe40c Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Wed, 23 Oct 2024 17:32:03 +0100 Subject: [PATCH 1/4] feat(debian/launcher): bake environment variables Allows the environment variables to propagate through Bazel run targets. --- debian/launcher/launch.py | 29 +++++++++++++++++++++++++++-- debian/launcher/rule.bzl | 6 ++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/debian/launcher/launch.py b/debian/launcher/launch.py index 9011b781..f020ef75 100644 --- a/debian/launcher/launch.py +++ b/debian/launcher/launch.py @@ -26,6 +26,17 @@ def runfile(path: Path) -> Path: return resolved +def resolve(value: str) -> str: + runfiles = Runfiles.Create() + try: + resolved = runfiles.Rlocation(value) + except ValueError: + return value + if not Path(resolved).exists(): + return value + return resolved + + def quoted(value: str) -> str: return value.removeprefix("'").removesuffix("'") @@ -60,6 +71,14 @@ def arguments(prsr: ArgumentParser) -> None: help="The root of the unpacked Debian archives.", type=runfile, ) + prsr.add_argument( + "--env", + action="append", + metavar=("NAME", "VALUE"), + nargs=2, + help="A environment variable pairing to enforce into the subprocess.", + default=[], + ) prsr.add_argument( "executable", metavar="EXECUTABLE", @@ -94,8 +113,13 @@ def execute( return process.returncode +class BazelArgumentParser(ArgumentParser): + def convert_arg_line_to_args(self, line): + return (line.removeprefix("'").removesuffix("'"),) + + def main(exe: Path, *args: str) -> int: - prsr = ArgumentParser( + prsr = BazelArgumentParser( prog=str(exe), description="Launches a Debian ELF interpreter patched executable.", fromfile_prefix_chars="@", @@ -119,7 +143,8 @@ def main(exe: Path, *args: str) -> int: interpreter=parsed.root / parsed.interpreter, symlink=parsed.symlink, env=environ - | {"LD_LIBRARY_PATH": parsed.llp.removeprefix("'").removesuffix("'")}, + | {k: resolve(v) for k, v in parsed.env} + | {"LD_LIBRARY_PATH": parsed.llp}, ) except CalledProcessError as e: return e.returncode diff --git a/debian/launcher/rule.bzl b/debian/launcher/rule.bzl index ad061241..caa1919f 100644 --- a/debian/launcher/rule.bzl +++ b/debian/launcher/rule.bzl @@ -47,6 +47,10 @@ def _runfile(label, file): return path.removeprefix("../") return "{}/{}".format(label.workspace_name or "_main", path) +def _env(pair): + key, value = pair + return ["--env", key, value] + def implementation(ctx): if not ctx.file.src.is_directory: fail("`src` must be a directory") @@ -64,6 +68,8 @@ def implementation(ctx): args.add("--interpreter", interpreter) args.add("--symlink", symlink) args.add("--root", _runfile(ctx.attr.src.label, ctx.file.src)) + args.add_all(ctx.attr.env.items(), map_each = _env) + args.add("--") args.add(relative) ctx.actions.write(output = arguments, content = args) -- GitLab From e05a1dd96b602ea715191f7574abe0978cc17d1a Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Fri, 25 Oct 2024 15:12:09 +0100 Subject: [PATCH 2/4] feat(debian/launcher): create temporary directory If the user provides `TMPDIR`, make sure it is created. --- debian/launcher/launch.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debian/launcher/launch.py b/debian/launcher/launch.py index f020ef75..6aa5b7d4 100644 --- a/debian/launcher/launch.py +++ b/debian/launcher/launch.py @@ -107,6 +107,13 @@ def execute( tmp.symlink_to(interpreter) move(tmp, symlink) + try: + tmpdir = env["TMPDIR"] + except KeyError: + pass + else: + Path(tmpdir).mkdir(parents=True, exist_ok=True) + assert executable.exists() cmd = (f"{executable}", *arguments) process = run(cmd, env=env) -- GitLab From 1ea663734dc3d795efbca6e62cb318c3d8319b43 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Thu, 24 Oct 2024 16:34:48 +0100 Subject: [PATCH 3/4] fix(debian/launcher): return `RunEnvironmentInfo` Needed for `bazelisk run` to respect `env`. --- debian/launcher/rule.bzl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/debian/launcher/rule.bzl b/debian/launcher/rule.bzl index caa1919f..b84f5026 100644 --- a/debian/launcher/rule.bzl +++ b/debian/launcher/rule.bzl @@ -88,7 +88,10 @@ def implementation(ctx): runfiles = runfiles.merge(ctx.attr.src.default_runfiles) runfiles = runfiles.merge_all([d.default_runfiles for d in ctx.attr.data]) - return DefaultInfo(executable = executable, files = files, runfiles = runfiles) + default = DefaultInfo(executable = executable, files = files, runfiles = runfiles) + env = RunEnvironmentInfo(environment = ctx.attr.env) + + return default, env debian_launcher = rule( doc = DOC, -- GitLab From 1062f66ff968a7aaf88970137441eb5c4d6a8e54 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Thu, 24 Oct 2024 17:25:19 +0100 Subject: [PATCH 4/4] fix(qemu): set `TMPDIR` to writeable directory QEMU attempts to write copy-on-write snapshots to `/var/tmp` because they can be become large and `/tmp` is often `tmpfs` which may not have enough space. `/var/tmp` in a sandbox is read-only. This changes QEMU to write into `./tmp` which is relative to the sandbox root. --- debian/amd64/qemu-system-arm/BUILD.bazel | 6 ++++++ debian/amd64/qemu-system-x86/BUILD.bazel | 6 ++++++ debian/arm64/qemu-system-arm/BUILD.bazel | 6 ++++++ debian/arm64/qemu-system-x86/BUILD.bazel | 6 ++++++ 4 files changed, 24 insertions(+) diff --git a/debian/amd64/qemu-system-arm/BUILD.bazel b/debian/amd64/qemu-system-arm/BUILD.bazel index 0a7d8329..184f32df 100644 --- a/debian/amd64/qemu-system-arm/BUILD.bazel +++ b/debian/amd64/qemu-system-arm/BUILD.bazel @@ -10,11 +10,17 @@ debian_patchelf( debian_launcher( name = "qemu-system-arm", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) debian_launcher( name = "qemu-system-aarch64", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) diff --git a/debian/amd64/qemu-system-x86/BUILD.bazel b/debian/amd64/qemu-system-x86/BUILD.bazel index 928b882e..1fda05ff 100644 --- a/debian/amd64/qemu-system-x86/BUILD.bazel +++ b/debian/amd64/qemu-system-x86/BUILD.bazel @@ -10,11 +10,17 @@ debian_patchelf( debian_launcher( name = "qemu-system-i386", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) debian_launcher( name = "qemu-system-x86_64", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) diff --git a/debian/arm64/qemu-system-arm/BUILD.bazel b/debian/arm64/qemu-system-arm/BUILD.bazel index 0a7d8329..184f32df 100644 --- a/debian/arm64/qemu-system-arm/BUILD.bazel +++ b/debian/arm64/qemu-system-arm/BUILD.bazel @@ -10,11 +10,17 @@ debian_patchelf( debian_launcher( name = "qemu-system-arm", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) debian_launcher( name = "qemu-system-aarch64", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) diff --git a/debian/arm64/qemu-system-x86/BUILD.bazel b/debian/arm64/qemu-system-x86/BUILD.bazel index 928b882e..1fda05ff 100644 --- a/debian/arm64/qemu-system-x86/BUILD.bazel +++ b/debian/arm64/qemu-system-x86/BUILD.bazel @@ -10,11 +10,17 @@ debian_patchelf( debian_launcher( name = "qemu-system-i386", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) debian_launcher( name = "qemu-system-x86_64", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) -- GitLab