From d789ed70ceff0c26a122712d8e1bc774bd393357 Mon Sep 17 00:00:00 2001 From: Jochen Hoenle Date: Wed, 12 Aug 2026 11:17:32 +0200 Subject: [PATCH] [rules score] drop dependency to rules_distroless fork --- MODULE.bazel | 87 ++++--------- .../examples/integrator/MODULE.bazel | 15 --- .../rules_score/examples/minimal/MODULE.bazel | 15 --- .../rules_score/examples/seooc/MODULE.bazel | 15 --- .../examples/some_other_library/MODULE.bazel | 15 --- bazel/rules/rules_score/test/MODULE.bazel | 15 --- bazel/rules/sysroot_from_lock/BUILD | 14 +++ .../sysroot_from_lock/sysroot_from_lock.bzl | 117 ++++++++++++++++++ third_party/docs_runtime/BUILD | 4 +- third_party/docs_runtime/README.md | 12 +- third_party/docs_runtime/manifest.yaml | 26 ++++ third_party/tooling_sysroot/BUILD | 18 +++ third_party/tooling_sysroot/manifest.yaml | 31 +++++ 13 files changed, 239 insertions(+), 145 deletions(-) create mode 100644 bazel/rules/sysroot_from_lock/BUILD create mode 100644 bazel/rules/sysroot_from_lock/sysroot_from_lock.bzl create mode 100644 third_party/docs_runtime/manifest.yaml create mode 100644 third_party/tooling_sysroot/BUILD create mode 100644 third_party/tooling_sysroot/manifest.yaml diff --git a/MODULE.bazel b/MODULE.bazel index 6121d59e..f83c88f6 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -35,23 +35,9 @@ bazel_dep(name = "score_rust_policies", version = "0.0.2") bazel_dep(name = "bazel_skylib", version = "1.7.1") bazel_dep(name = "flatbuffers", version = "25.9.23") bazel_dep(name = "download_utils", version = "1.2.2") -bazel_dep(name = "trlc", version = "3.0.0") +bazel_dep(name = "trlc", version = "3.0.1") bazel_dep(name = "lobster", version = "1.0.6") bazel_dep(name = "rules_distroless", version = "0.8.0") - -# The released 0.8.0 only supports the old manifest/lock apt.install() API. -# apt.sysroot() (needed for the hermetic libclang sysroot below, and for the -# docs_runtime dependency_set API) is only available on this fork, which is -# also what eclipse-score-communication2 overrides to (see its -# third_party/score_tooling/bump_rules_distroless_api.patch, which exists -# specifically to migrate *this* module's old-API usage to match this fork -# when score_tooling is a non-root dependency). -git_override( - module_name = "rules_distroless", - commit = "e1df344fde5adaef7397c34076b56f27771d08b8", - remote = "https://github.com/LittleHuba/rules_distroless.git", -) - bazel_dep(name = "googletest", version = "1.17.0.bcr.2") bazel_dep(name = "toolchains_llvm", version = "1.8.0", dev_dependency = True) # Libclang Tooling @@ -299,7 +285,7 @@ multitool.hub( hub_name = "actionlint_hub", lockfile = "tools/actionlint.lock.json", ) -use_repo(multitool, "actionlint_hub") +use_repo(multitool, "actionlint_hub", "multitool") register_toolchains("@actionlint_hub//toolchains:all") @@ -317,72 +303,49 @@ deb( ############################################################################### # Hermetic apt packages (docs_runtime sysroot + LLVM toolchain sysroot) # -# Pinned to the Ubuntu 24.04 (noble) snapshot so the package closure is -# reproducible. Both dependency sets below share this one sources_list. +# Both use the upstream (BCR-published) rules_distroless manifest/lock API -- +# no fork/override needed. Pinned to the Ubuntu 24.04 (noble) snapshot in each +# manifest.yaml so the package closure is reproducible. ############################################################################### # bsdtar (used by //bazel/rules/exec_in_sysroot to extract sysroot archives). bazel_dep(name = "tar.bzl", version = "0.6.0") apt = use_extension("@rules_distroless//apt:extensions.bzl", "apt") -apt.sources_list( - architectures = ["amd64"], - components = [ - "main", - "universe", - ], - suites = [ - "noble", - "noble-security", - "noble-updates", - ], - types = ["deb"], - uris = ["https://snapshot.ubuntu.com/ubuntu/20260401T104001Z"], -) # Distroless rootfs providing graphviz + fakechroot for hermetic dot execution # via //third_party/docs_runtime:dot (exec_in_sysroot). apt.install( - dependency_set = "docs_runtime", - packages = [ - "base-files", - "fakechroot", # /usr/bin/fakechroot + libfakechroot.so for exec_in_sysroot - "graphviz", # /usr/bin/dot and plugins used by Sphinx + PlantUML - ], - suites = [ - "noble", - "noble-security", - "noble-updates", - ], + name = "docs_runtime", + manifest = "//third_party/docs_runtime:manifest.yaml", + nolock = True, ) +use_repo(apt, "docs_runtime") # Hermetic sysroot for the LLVM toolchain (see cpp/libclang), so that # cpp_parser's cc_common-derived flags (and any normal C++ compile using this # toolchain) resolve libc/libstdc++ headers from a pinned rootfs instead of the # build host, matching eclipse-score-communication2's ubuntu24_04_sysroot setup. apt.install( - dependency_set = "tooling_sysroot", - packages = [ - "base-files", - "libatomic1", # Non-lock-free atomics support - "libc6", # Core C/POSIX - "libc6-dev", # Core C/POSIX - "libgcc-s1", # Exception unwinding - "libstdc++-13-dev", # C++ standard library headers - "libstdc++6", # C++ standard library runtime - "linux-libc-dev", # Core C/POSIX - ], - suites = [ - "noble", - "noble-security", - "noble-updates", - ], + name = "tooling_sysroot", + manifest = "//third_party/tooling_sysroot:manifest.yaml", + nolock = True, ) -apt.sysroot( +use_repo(apt, "tooling_sysroot", "tooling_sysroot_resolve") + +# Unpacks the tooling_sysroot lockfile's packages into a flat, fetch-time +# sysroot directory -- our own replacement for the LittleHuba fork's fork-only +# apt.sysroot(), so no rules_distroless override is needed (see +# //bazel/rules/sysroot_from_lock:sysroot_from_lock.bzl for attribution). +sysroot_from_lock = use_repo_rule( + "//bazel/rules/sysroot_from_lock:sysroot_from_lock.bzl", + "sysroot_from_lock", +) + +sysroot_from_lock( name = "tooling_sysroot_amd64", architecture = "amd64", - dependency_set = "tooling_sysroot", + lock = "@tooling_sysroot_resolve//:lock.json", ) -use_repo(apt, "docs_runtime", "tooling_sysroot_amd64") register_toolchains( "//bazel/rules/rules_score:sphinx_default_toolchain", diff --git a/bazel/rules/rules_score/examples/integrator/MODULE.bazel b/bazel/rules/rules_score/examples/integrator/MODULE.bazel index 1ccd0c0d..5b3c1b28 100644 --- a/bazel/rules/rules_score/examples/integrator/MODULE.bazel +++ b/bazel/rules/rules_score/examples/integrator/MODULE.bazel @@ -40,21 +40,6 @@ local_path_override( path = "../some_other_library", ) -# score_tooling's own git_override for rules_distroless (needed for -# apt.sources_list()/apt.sysroot()/dependency_set, used by its hermetic -# libclang sysroot) is only honored when score_tooling is the root module. -# Since score_tooling is merely a transitive dependency here, this module -# must repeat the override, or the registry rules_distroless 0.8.0 (which -# lacks those tag classes) is used instead and score_tooling's own -# MODULE.bazel fails to load with "does not have a tag class named -# sources_list". -bazel_dep(name = "rules_distroless", version = "0.8.0") -git_override( - module_name = "rules_distroless", - commit = "e1df344fde5adaef7397c34076b56f27771d08b8", - remote = "https://github.com/LittleHuba/rules_distroless.git", -) - bazel_dep(name = "trlc", version = "3.0.0") bazel_dep(name = "googletest", version = "1.17.0.bcr.2") bazel_dep(name = "lobster", version = "1.0.4") diff --git a/bazel/rules/rules_score/examples/minimal/MODULE.bazel b/bazel/rules/rules_score/examples/minimal/MODULE.bazel index 13627b32..15f7f113 100644 --- a/bazel/rules/rules_score/examples/minimal/MODULE.bazel +++ b/bazel/rules/rules_score/examples/minimal/MODULE.bazel @@ -22,21 +22,6 @@ local_path_override( path = "../../../../..", ) -# score_tooling's own git_override for rules_distroless (needed for -# apt.sources_list()/apt.sysroot()/dependency_set, used by its hermetic -# libclang sysroot) is only honored when score_tooling is the root module. -# Since score_tooling is merely a transitive dependency here, this module -# must repeat the override, or the registry rules_distroless 0.8.0 (which -# lacks those tag classes) is used instead and score_tooling's own -# MODULE.bazel fails to load with "does not have a tag class named -# sources_list". -bazel_dep(name = "rules_distroless", version = "0.8.0") -git_override( - module_name = "rules_distroless", - commit = "e1df344fde5adaef7397c34076b56f27771d08b8", - remote = "https://github.com/LittleHuba/rules_distroless.git", -) - bazel_dep(name = "toolchains_llvm", version = "1.6.0", dev_dependency = True) llvm = use_extension( diff --git a/bazel/rules/rules_score/examples/seooc/MODULE.bazel b/bazel/rules/rules_score/examples/seooc/MODULE.bazel index 624c9f1d..8fa6c228 100644 --- a/bazel/rules/rules_score/examples/seooc/MODULE.bazel +++ b/bazel/rules/rules_score/examples/seooc/MODULE.bazel @@ -29,21 +29,6 @@ local_path_override( path = "../some_other_library", ) -# score_tooling's own git_override for rules_distroless (needed for -# apt.sources_list()/apt.sysroot()/dependency_set, used by its hermetic -# libclang sysroot) is only honored when score_tooling is the root module. -# Since score_tooling is merely a transitive dependency here, this module -# must repeat the override, or the registry rules_distroless 0.8.0 (which -# lacks those tag classes) is used instead and score_tooling's own -# MODULE.bazel fails to load with "does not have a tag class named -# sources_list". -bazel_dep(name = "rules_distroless", version = "0.8.0") -git_override( - module_name = "rules_distroless", - commit = "e1df344fde5adaef7397c34076b56f27771d08b8", - remote = "https://github.com/LittleHuba/rules_distroless.git", -) - # Some other llvm toolchain bazel_dep(name = "toolchains_llvm", version = "1.6.0", dev_dependency = True) diff --git a/bazel/rules/rules_score/examples/some_other_library/MODULE.bazel b/bazel/rules/rules_score/examples/some_other_library/MODULE.bazel index d90e6088..d44fe4bf 100644 --- a/bazel/rules/rules_score/examples/some_other_library/MODULE.bazel +++ b/bazel/rules/rules_score/examples/some_other_library/MODULE.bazel @@ -23,21 +23,6 @@ local_path_override( path = "../../../../../", ) -# score_tooling's own git_override for rules_distroless (needed for -# apt.sources_list()/apt.sysroot()/dependency_set, used by its hermetic -# libclang sysroot) is only honored when score_tooling is the root module. -# Since score_tooling is merely a transitive dependency here, this module -# must repeat the override, or the registry rules_distroless 0.8.0 (which -# lacks those tag classes) is used instead and score_tooling's own -# MODULE.bazel fails to load with "does not have a tag class named -# sources_list". -bazel_dep(name = "rules_distroless", version = "0.8.0") -git_override( - module_name = "rules_distroless", - commit = "e1df344fde5adaef7397c34076b56f27771d08b8", - remote = "https://github.com/LittleHuba/rules_distroless.git", -) - # Some other llvm toolchain bazel_dep(name = "toolchains_llvm", version = "1.6.0", dev_dependency = True) diff --git a/bazel/rules/rules_score/test/MODULE.bazel b/bazel/rules/rules_score/test/MODULE.bazel index 07bcb491..7ff05d0e 100644 --- a/bazel/rules/rules_score/test/MODULE.bazel +++ b/bazel/rules/rules_score/test/MODULE.bazel @@ -73,21 +73,6 @@ local_path_override( path = "../../../..", ) -# score_tooling's own git_override for rules_distroless (needed for -# apt.sources_list()/apt.sysroot()/dependency_set, used by its hermetic -# libclang sysroot) is only honored when score_tooling is the root module. -# Since score_tooling is merely a transitive dependency here, this module -# must repeat the override, or the registry rules_distroless 0.8.0 (which -# lacks those tag classes) is used instead and score_tooling's own -# MODULE.bazel fails to load with "does not have a tag class named -# sources_list". -bazel_dep(name = "rules_distroless", version = "0.8.0") -git_override( - module_name = "rules_distroless", - commit = "e1df344fde5adaef7397c34076b56f27771d08b8", - remote = "https://github.com/LittleHuba/rules_distroless.git", -) - register_toolchains( "//:score_toolchain", ) diff --git a/bazel/rules/sysroot_from_lock/BUILD b/bazel/rules/sysroot_from_lock/BUILD new file mode 100644 index 00000000..53ffb985 --- /dev/null +++ b/bazel/rules/sysroot_from_lock/BUILD @@ -0,0 +1,14 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +exports_files(["sysroot_from_lock.bzl"]) diff --git a/bazel/rules/sysroot_from_lock/sysroot_from_lock.bzl b/bazel/rules/sysroot_from_lock/sysroot_from_lock.bzl new file mode 100644 index 00000000..f0e82bff --- /dev/null +++ b/bazel/rules/sysroot_from_lock/sysroot_from_lock.bzl @@ -0,0 +1,117 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# The unpack logic in this file (_materialize_deb_data_into_root, _unpack) is +# adapted from `apt/private/sysroot_repository.bzl` in +# https://github.com/LittleHuba/rules_distroless (commit +# e1df344fde5adaef7397c34076b56f27771d08b8), which is licensed under the +# Apache License, Version 2.0 (https://github.com/LittleHuba/rules_distroless +# has no per-file copyright headers; the repository's LICENSE file is +# Apache-2.0). It has been reworked to consume a plain rules_distroless +# `apt.install()` lockfile (as produced by the upstream, BCR-published +# rules_distroless, without requiring that fork's fork-only `apt.sysroot()` +# extension or its `dependency_set`-keyed lockfile format), so this repo needs +# no `rules_distroless` override. + +"""Repository rule that unpacks a rules_distroless apt.install() lockfile's +packages into a flat, fetch-time sysroot directory, for use as a C/C++ +toolchain sysroot (e.g. toolchains_llvm's `llvm.sysroot(label = ...)`).""" + +_BUILD_TMPL = """\ +"Generated by sysroot_from_lock. DO NOT EDIT." + +filegroup( + name = "sysroot", + srcs = ["."], + visibility = ["//visibility:public"], +) +""" + +def _materialize_deb_data_into_root(rctx, deb_path, ar_dir, unpack_dir): + """Unpacks the data.tar.* payload of a .deb archive into unpack_dir. + + This relies exclusively on Bazel's built-in support for extracting the + `ar` container format used by .deb files, and the nested `tar.*` payload, + via repository_ctx.extract(). + """ + + # .deb files are `ar` archives containing debian-binary, control.tar.* and + # data.tar.* members. Extracting unpacks those members as plain, + # uncompressed files (the ".deb" extension is auto-detected as ar). + rctx.extract(archive = deb_path, output = ar_dir) + + data_member = None + for entry in rctx.path(ar_dir).readdir(): + if entry.basename.startswith("data.tar"): + data_member = entry + break + + if data_member == None: + fail("No data archive found in {}".format(deb_path)) + + # The archive type (tar.gz/tar.xz/tar.zst/...) is auto-detected from the + # data_member's file extension. + rctx.extract(archive = data_member, output = unpack_dir) + +def _unpack(rctx, packages, architecture): + unpack_dir = "sysroot" + work_dir = ".unpack_work" + + for package in packages: + if package["arch"] not in (architecture, "all"): + continue + + key = package["key"] + deb_path = "{}/{}.deb".format(work_dir, key) + ar_dir = "{}/{}.ar".format(work_dir, key) + + rctx.download( + output = deb_path, + sha256 = package["sha256"], + url = package["urls"], + ) + + _materialize_deb_data_into_root(rctx, deb_path, ar_dir, unpack_dir) + + rctx.delete(work_dir) + +def _sysroot_from_lock_impl(rctx): + lock = json.decode(rctx.read(rctx.attr.lock)) + if lock["version"] != 1: + fail("invalid lockfile version") + + _unpack(rctx, lock["packages"], rctx.attr.architecture) + + rctx.file("sysroot/BUILD.bazel", _BUILD_TMPL) + +sysroot_from_lock = repository_rule( + implementation = _sysroot_from_lock_impl, + attrs = { + "lock": attr.label( + mandatory = True, + doc = "Label of a rules_distroless apt.install() lockfile's " + + "generated lock.json file, e.g. " + + "'@_resolve//:lock.json'.", + ), + "architecture": attr.string( + mandatory = True, + doc = "Debian architecture (e.g. 'amd64') to unpack packages " + + "for; packages for other architectures in the lockfile " + + "are skipped. Packages with arch 'all' are always " + + "included.", + ), + }, + doc = "Unpacks a rules_distroless apt.install() lockfile's packages " + + "for a single architecture into a flat, fetch-time sysroot " + + "directory, exposed as a `:sysroot` filegroup.", +) diff --git a/third_party/docs_runtime/BUILD b/third_party/docs_runtime/BUILD index 7b31b38e..028ac5e6 100644 --- a/third_party/docs_runtime/BUILD +++ b/third_party/docs_runtime/BUILD @@ -12,8 +12,8 @@ # ******************************************************************************* # Hermetic doc-tool runtime rootfs. The @docs_runtime repo (rules_distroless -# apt.install(dependency_set = "docs_runtime", ...)) is defined in -# //MODULE.bazel, which lists the pinned packages directly. +# apt.install(name = "docs_runtime", ...)) is defined in //MODULE.bazel; +# pinned packages are listed in manifest.yaml in this package. load("//bazel/rules/exec_in_sysroot:exec_in_sysroot.bzl", "exec_in_sysroot", "prepare_sysroot") diff --git a/third_party/docs_runtime/README.md b/third_party/docs_runtime/README.md index 75152d7b..7c68feeb 100644 --- a/third_party/docs_runtime/README.md +++ b/third_party/docs_runtime/README.md @@ -17,8 +17,8 @@ The docs build needs Graphviz `dot` at action runtime (Sphinx graphviz extension and PlantUML `-graphvizdot`). This package makes that use hermetic: 1. `@docs_runtime//:flat` provides a distroless rootfs tar (from the - `apt.install(dependency_set = "docs_runtime", ...)` tag in `//MODULE.bazel`) - containing `graphviz` and `fakechroot`. + `apt.install(name = "docs_runtime", manifest = "//third_party/docs_runtime:manifest.yaml", ...)` + tag in `//MODULE.bazel`) containing `graphviz` and `fakechroot`. 2. `//third_party/docs_runtime:dot_sysroot` (a `prepare_sysroot` rule) unpacks that tar, prunes plugins with missing host dependencies, runs `dot -c` to generate the plugin manifest, and repackages the result as a single cached @@ -49,10 +49,10 @@ remain: ## Updating packages -Edit the `packages` list of the `dependency_set = "docs_runtime"` `apt.install(...)` -tag in `//MODULE.bazel`, then re-run any build that depends on `@docs_runtime` -(rules_distroless resolves and re-locks the closure automatically via Bazel's -module extension facts — no separate lock file to regenerate/commit). +Edit the `packages` list in `manifest.yaml`, then re-run any build that +depends on `@docs_runtime` (rules_distroless resolves and re-locks the +closure automatically since `nolock = True` is set on the `apt.install(...)` +tag -- no separate lock file to regenerate/commit). ## Targets in this package diff --git a/third_party/docs_runtime/manifest.yaml b/third_party/docs_runtime/manifest.yaml new file mode 100644 index 00000000..c5c7e630 --- /dev/null +++ b/third_party/docs_runtime/manifest.yaml @@ -0,0 +1,26 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +version: 1 +sources: + - channel: noble main universe + url: https://snapshot.ubuntu.com/ubuntu/20260401T104001Z + - channel: noble-security main universe + url: https://snapshot.ubuntu.com/ubuntu/20260401T104001Z + - channel: noble-updates main universe + url: https://snapshot.ubuntu.com/ubuntu/20260401T104001Z +archs: + - amd64 +packages: + - base-files + - fakechroot + - graphviz diff --git a/third_party/tooling_sysroot/BUILD b/third_party/tooling_sysroot/BUILD new file mode 100644 index 00000000..3777f094 --- /dev/null +++ b/third_party/tooling_sysroot/BUILD @@ -0,0 +1,18 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# Hermetic LLVM toolchain sysroot packages, resolved by the `apt.install(name +# = "tooling_sysroot", ...)` tag in //MODULE.bazel and unpacked via +# //bazel/rules/sysroot_from_lock into @tooling_sysroot_amd64//sysroot. + +exports_files(["manifest.yaml"]) diff --git a/third_party/tooling_sysroot/manifest.yaml b/third_party/tooling_sysroot/manifest.yaml new file mode 100644 index 00000000..f80550a1 --- /dev/null +++ b/third_party/tooling_sysroot/manifest.yaml @@ -0,0 +1,31 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +version: 1 +sources: + - channel: noble main universe + url: https://snapshot.ubuntu.com/ubuntu/20260401T104001Z + - channel: noble-security main universe + url: https://snapshot.ubuntu.com/ubuntu/20260401T104001Z + - channel: noble-updates main universe + url: https://snapshot.ubuntu.com/ubuntu/20260401T104001Z +archs: + - amd64 +packages: + - base-files + - libatomic1 + - libc6 + - libc6-dev + - libgcc-s1 + - libstdc++-13-dev + - libstdc++6 + - linux-libc-dev