From b900a6322ae4e68b431f7d65ebfef604657bd030 Mon Sep 17 00:00:00 2001 From: Sahin Yort Date: Wed, 18 Jan 2023 13:50:12 +0300 Subject: [PATCH] refactor: cleanup toolchains (#57) --- .bazelrc | 1 + .github/workflows/ci.bazelrc | 3 + cosign/toolchain.bzl | 4 +- example/attach/BUILD.bazel | 2 +- example/attach/test.bash | 9 +- example/push/BUILD.bazel | 15 ++-- example/push/test.bash | 6 +- example/sign/BUILD.bazel | 2 +- example/sign/test.bash | 8 +- oci/dependencies.bzl | 6 +- oci/private/BUILD.bazel | 3 +- oci/private/image.bzl | 7 +- oci/private/image.sh.tpl | 28 +++--- oci/private/image_index.bzl | 5 +- oci/private/image_index.sh.tpl | 14 +-- oci/private/push.bzl | 2 +- oci/private/structure_test.bzl | 4 +- oci/private/tarball.bzl | 10 +-- oci/private/tarball.sh.tpl | 10 +-- oci/private/zot_launcher.sh.tpl | 34 +++++++ oci/repositories.bzl | 43 +-------- oci/toolchain.bzl | 151 ++++++++------------------------ 22 files changed, 146 insertions(+), 221 deletions(-) create mode 100644 oci/private/zot_launcher.sh.tpl diff --git a/.bazelrc b/.bazelrc index 311a0faa..64984949 100644 --- a/.bazelrc +++ b/.bazelrc @@ -3,6 +3,7 @@ # Settings that apply only to CI are in .github/workflows/ci.bazelrc build --incompatible_strict_action_env +common --nolegacy_external_runfiles # Load any settings specific to the current user. # .bazelrc.user should appear in .gitignore so that settings are not shared with team members diff --git a/.github/workflows/ci.bazelrc b/.github/workflows/ci.bazelrc index e40251cc..bbb1125a 100644 --- a/.github/workflows/ci.bazelrc +++ b/.github/workflows/ci.bazelrc @@ -15,6 +15,9 @@ test --test_env=XDG_CACHE_HOME # Allow DOCKER_HOST to leak into test actions test --test_env=DOCKER_HOST +# Disable legacy external runfiles +common --nolegacy_external_runfiles + # try to import platform specific overrides try-import %workspace%/.github/workflows/darwin.bazelrc diff --git a/cosign/toolchain.bzl b/cosign/toolchain.bzl index 95341111..421ccdf5 100644 --- a/cosign/toolchain.bzl +++ b/cosign/toolchain.bzl @@ -19,9 +19,7 @@ def _cosign_toolchain_impl(ctx): files = depset([binary]), runfiles = ctx.runfiles(files = [binary]), ) - cosign_info = CosignInfo( - binary = binary, - ) + cosign_info = CosignInfo(binary = binary) # Export all the providers inside our ToolchainInfo # so the resolved_toolchain rule can grab and re-export them. diff --git a/example/attach/BUILD.bazel b/example/attach/BUILD.bazel index 27eb934d..52bd664f 100644 --- a/example/attach/BUILD.bazel +++ b/example/attach/BUILD.bazel @@ -22,7 +22,7 @@ sh_test( args = [ "$(COSIGN_BIN)", "$(CRANE_BIN)", - "$(LAUNCHER)", + "$(LAUNCHER_WRAPPER)", "$(location :attach)", "$(location :image)", "$(location sbom.spdx)", diff --git a/example/attach/test.bash b/example/attach/test.bash index ec7e93a2..8f4eeb55 100755 --- a/example/attach/test.bash +++ b/example/attach/test.bash @@ -1,16 +1,17 @@ #!/usr/bin/env bash set -o pipefail -o errexit -o nounset -readonly COSIGN="$1" -readonly CRANE="$2" -readonly REGISTRY_LAUNCHER="$3" +readonly COSIGN="${1/external\//../}" +readonly CRANE="${2/external\//../}" +readonly REGISTRY_LAUNCHER="${3/external\//../}" readonly ATTACHER="$4" readonly IMAGE_PATH="$5" readonly SBOM_PATH="$6" + # Launch a registry instance at a random port source "${REGISTRY_LAUNCHER}" -start_registry $TEST_TMPDIR $TEST_TMPDIR/output.log +REGISTRY=$(start_registry $TEST_TMPDIR $TEST_TMPDIR/output.log) echo "Registry is running at ${REGISTRY}" readonly REPOSITORY="${REGISTRY}/local" diff --git a/example/push/BUILD.bazel b/example/push/BUILD.bazel index 0d74517d..11ec152f 100644 --- a/example/push/BUILD.bazel +++ b/example/push/BUILD.bazel @@ -9,41 +9,40 @@ oci_image( oci_push( name = "push_image", + default_tags = ["latest"], image = ":image", repository = "index.docker.io//image", - default_tags = ["latest"] ) oci_push( name = "push_image_wo_tags", image = ":image", - repository = "index.docker.io//image" + repository = "index.docker.io//image", ) oci_image_index( name = "image_index", images = [ - ":image" - ] + ":image", + ], ) oci_push( name = "push_image_index", + default_tags = ["nightly"], image = ":image_index", repository = "index.docker.io//image", - default_tags = ["nightly"] ) - sh_test( name = "test", srcs = ["test.bash"], args = [ "$(CRANE_BIN)", - "$(LAUNCHER)", + "$(LAUNCHER_WRAPPER)", "$(location :push_image)", "$(location :push_image_index)", - "$(location :push_image_wo_tags)" + "$(location :push_image_wo_tags)", ], data = [ ":push_image", diff --git a/example/push/test.bash b/example/push/test.bash index 1800a8d8..cfbc8de8 100755 --- a/example/push/test.bash +++ b/example/push/test.bash @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -o pipefail -o errexit -o nounset -readonly CRANE="$1" -readonly REGISTRY_LAUNCHER="$2" +readonly CRANE="${1/external\//../}" +readonly REGISTRY_LAUNCHER="${2/external\//../}" # Launch a registry instance at a random port source "${REGISTRY_LAUNCHER}" -start_registry $TEST_TMPDIR $TEST_TMPDIR/output.log +REGISTRY=$(start_registry $TEST_TMPDIR $TEST_TMPDIR/output.log) echo "Registry is running at ${REGISTRY}" diff --git a/example/sign/BUILD.bazel b/example/sign/BUILD.bazel index 42435a09..1f42acdd 100644 --- a/example/sign/BUILD.bazel +++ b/example/sign/BUILD.bazel @@ -31,7 +31,7 @@ sh_test( args = [ "$(CRANE_BIN)", "$(COSIGN_BIN)", - "$(LAUNCHER)", + "$(LAUNCHER_WRAPPER)", "$(location :sign)", "$(location :image)", ], diff --git a/example/sign/test.bash b/example/sign/test.bash index 9c679118..ecabf749 100755 --- a/example/sign/test.bash +++ b/example/sign/test.bash @@ -1,15 +1,15 @@ #!/usr/bin/env bash set -o pipefail -o errexit -o nounset -readonly CRANE="$1" -readonly COSIGN="$2" -readonly REGISTRY_LAUNCHER="$3" +readonly CRANE="${1/external\//../}" +readonly COSIGN="${2/external\//../}" +readonly REGISTRY_LAUNCHER="${3/external\//../}" readonly IMAGE_SIGNER="$4" readonly IMAGE="$5" # Launch a registry instance at a random port source "${REGISTRY_LAUNCHER}" -start_registry $TEST_TMPDIR $TEST_TMPDIR/output.log +REGISTRY=$(start_registry $TEST_TMPDIR $TEST_TMPDIR/output.log) echo "Registry is running at ${REGISTRY}" readonly REPOSITORY="${REGISTRY}/local" diff --git a/oci/dependencies.bzl b/oci/dependencies.bzl index 83e22192..f577531b 100644 --- a/oci/dependencies.bzl +++ b/oci/dependencies.bzl @@ -38,7 +38,7 @@ def rules_oci_dependencies(): http_archive( name = "aspect_bazel_lib", - sha256 = "be236556c7b9c7b91cb370e837fdcec62b6e8893408cd4465ae883c9d7c67024", - strip_prefix = "bazel-lib-1.18.0", - url = "https://github.com/aspect-build/bazel-lib/archive/refs/tags/v1.18.0.tar.gz", + sha256 = "79623d656aa23ad3fd4692ab99786c613cd36e49f5566469ed97bc9b4c655f03", + strip_prefix = "bazel-lib-1.23.3", + url = "https://github.com/aspect-build/bazel-lib/archive/refs/tags/v1.23.3.tar.gz", ) diff --git a/oci/private/BUILD.bazel b/oci/private/BUILD.bazel index 41945a3a..1da2b8cd 100644 --- a/oci/private/BUILD.bazel +++ b/oci/private/BUILD.bazel @@ -9,7 +9,8 @@ exports_files([ "image.sh.tpl", "image_index.sh.tpl", "tarball.sh.tpl", - "push.sh.tpl" + "push.sh.tpl", + "zot_launcher.sh.tpl", ]) filegroup( diff --git a/oci/private/image.bzl b/oci/private/image.bzl index 69031e85..e57378ee 100644 --- a/oci/private/image.bzl +++ b/oci/private/image.bzl @@ -91,8 +91,8 @@ def _oci_image_impl(ctx): output = launcher, is_executable = True, substitutions = { - "{{registry_launcher_path}}": registry.registry_info.launcher_path, - "{{crane_path}}": crane.crane_info.crane_path, + "{{registry_launcher_path}}": registry.registry_info.launcher.path, + "{{crane_path}}": crane.crane_info.binary.path, "{{jq_path}}": jq.jqinfo.bin.path, "{{storage_dir}}": "/".join([ctx.bin_dir.path, ctx.label.package, "storage_%s" % ctx.label.name]), }, @@ -146,7 +146,8 @@ def _oci_image_impl(ctx): arguments = [args], outputs = [output], executable = launcher, - tools = crane.crane_info.crane_files + registry.registry_info.registry_files + [jq.jqinfo.bin], + tools = [crane.crane_info.binary, registry.registry_info.launcher, registry.registry_info.registry, jq.jqinfo.bin], + mnemonic = "OCIImage", progress_message = "OCI Image %{label}", ) diff --git a/oci/private/image.sh.tpl b/oci/private/image.sh.tpl index df4a4e01..c26bb5ef 100644 --- a/oci/private/image.sh.tpl +++ b/oci/private/image.sh.tpl @@ -5,6 +5,11 @@ set -o pipefail -o errexit -o nounset # Then invokes crane with arguments provided after substituting `oci:registry` with REGISTRY variable exported by start_registry. # NB: --output argument is an option only understood by this wrapper and will pull artifact image into a oci layout. +readonly REGISTRY_LAUNCHER="{{registry_launcher_path}}" +readonly CRANE="{{crane_path}}" +readonly JQ="{{jq_path}}" +readonly STORAGE_DIR="{{storage_dir}}" + readonly STDERR=$(mktemp) silent_on_success() { @@ -15,9 +20,6 @@ silent_on_success() { } trap "silent_on_success" EXIT -# this will redirect stderr(2) to stderr file. -{ - function get_option() { local name=$1 shift @@ -30,7 +32,8 @@ function get_option() { function empty_base() { - local ref="$REGISTRY/oci/empty_base:latest" + local registry=$1 + local ref="$registry/oci/empty_base:latest" # TODO: https://github.com/google/go-containerregistry/issues/1513 ref="$("${CRANE}" append --oci-empty-base -t "${ref}" -f <(tar -cf tarfilename.tar -T /dev/null))" ref=$("${CRANE}" config "${ref}" | "${JQ}" ".rootfs.diff_ids = [] | .history = []" | "${CRANE}" edit config "${ref}") @@ -53,18 +56,15 @@ function base_from_layout() { # TODO: https://github.com/google/go-containerregistry/issues/1514 local refs=$(mktemp) local oci_layout_path=$1 - "${CRANE}" push "${oci_layout_path}" "${REGISTRY}/oci/layout:latest" --image-refs "${refs}" + local registry=$2 + "${CRANE}" push "${oci_layout_path}" "${registry}/oci/layout:latest" --image-refs "${refs}" cat "${refs}" } -readonly REGISTRY_LAUNCHER="{{registry_launcher_path}}" -readonly CRANE="{{crane_path}}" -readonly JQ="{{jq_path}}" -readonly STORAGE_DIR="{{storage_dir}}" - +# this will redirect stderr(2) to stderr file. +{ source "${REGISTRY_LAUNCHER}" -mkdir -p "${STORAGE_DIR}" -start_registry "${STORAGE_DIR}" "${STDERR}" +readonly REGISTRY=$(start_registry "${STORAGE_DIR}" "${STDERR}") OUTPUT="" WORKDIR="" @@ -74,8 +74,8 @@ ENV_EXPANSIONS=() for ARG in "$@"; do case "$ARG" in (oci:registry*) FIXED_ARGS+=("${ARG/oci:registry/$REGISTRY}") ;; - (oci:empty_base) FIXED_ARGS+=("$(empty_base $@)") ;; - (oci:layout*) FIXED_ARGS+=("$(base_from_layout ${ARG/oci:layout\/})") ;; + (oci:empty_base) FIXED_ARGS+=("$(empty_base $REGISTRY $@)") ;; + (oci:layout*) FIXED_ARGS+=("$(base_from_layout ${ARG/oci:layout\/} $REGISTRY)") ;; (--env=*\${*}* | --env=*\$*) ENV_EXPANSIONS+=(${ARG#--env=}) ;; (--output=*) OUTPUT="${ARG#--output=}" ;; (--workdir=*) WORKDIR="${ARG#--workdir=}" ;; diff --git a/oci/private/image_index.bzl b/oci/private/image_index.bzl index 8908e3f5..3422a4cc 100644 --- a/oci/private/image_index.bzl +++ b/oci/private/image_index.bzl @@ -41,6 +41,7 @@ def _expand_image_to_args(image, expander): def _oci_image_index_impl(ctx): yq = ctx.toolchains["@aspect_bazel_lib//lib:yq_toolchain_type"] + coreutils = ctx.toolchains["@aspect_bazel_lib//lib:coreutils_toolchain_type"] launcher = ctx.actions.declare_file("image_index_{}.sh".format(ctx.label.name)) ctx.actions.expand_template( @@ -49,6 +50,7 @@ def _oci_image_index_impl(ctx): is_executable = True, substitutions = { "{{yq_path}}": yq.yqinfo.bin.path, + "{{coreutils_path}}": coreutils.coreutils_info.bin.path, }, ) @@ -63,7 +65,7 @@ def _oci_image_index_impl(ctx): arguments = [args], outputs = [output], executable = launcher, - tools = [yq.yqinfo.bin], + tools = [yq.yqinfo.bin, coreutils.coreutils_info.bin], progress_message = "OCI Index %{label}", ) @@ -75,5 +77,6 @@ oci_image_index = rule( doc = _DOC, toolchains = [ "@aspect_bazel_lib//lib:yq_toolchain_type", + "@aspect_bazel_lib//lib:coreutils_toolchain_type", ], ) diff --git a/oci/private/image_index.sh.tpl b/oci/private/image_index.sh.tpl index 7a4957db..93ad14f3 100644 --- a/oci/private/image_index.sh.tpl +++ b/oci/private/image_index.sh.tpl @@ -2,7 +2,7 @@ set -o pipefail -o errexit -o nounset readonly YQ="{{yq_path}}" - +readonly COREUTILS="{{coreutils_path}}" function add_image() { local image_path="$1" @@ -27,13 +27,13 @@ function copy_blob() { local output_path="$2" local blob_image_relative_path="$3" local dest_path="${output_path}/${blob_image_relative_path}" - mkdir -p "$(dirname "${dest_path}")" - cat "${image_path}/${blob_image_relative_path}" > "${dest_path}" + "${COREUTILS}" mkdir -p "$(dirname "${dest_path}")" + "${COREUTILS}" cat "${image_path}/${blob_image_relative_path}" > "${dest_path}" } function create_oci_layout() { local path="$1" - mkdir -p "${path}" + "${COREUTILS}" mkdir -p "${path}" echo '{"imageLayoutVersion": "1.0.0"}' > "${path}/oci-layout" echo '{"schemaVersion": 2, "manifests": []}' > "${path}/index.json" @@ -53,9 +53,9 @@ for ARG in "$@"; do done -export checksum=$(shasum -a 256 "${OUTPUT}/manifest_list.json" | cut -f 1 -d " ") -export size=$(wc -c < "${OUTPUT}/manifest_list.json") +export checksum=$("${COREUTILS}" sha256sum "${OUTPUT}/manifest_list.json" | "${COREUTILS}" cut -f 1 -d " ") +export size=$("${COREUTILS}" wc -c < "${OUTPUT}/manifest_list.json") "${YQ}" --inplace --output-format=json '.manifests += [{"mediaType": "application/vnd.oci.image.index.v1+json", "size": env(size), "digest": "sha256:" + env(checksum)}]' "$OUTPUT/index.json" -mv "${OUTPUT}/manifest_list.json" "$OUTPUT/blobs/sha256/${checksum}" \ No newline at end of file +"${COREUTILS}" mv "${OUTPUT}/manifest_list.json" "$OUTPUT/blobs/sha256/${checksum}" \ No newline at end of file diff --git a/oci/private/push.bzl b/oci/private/push.bzl index c96710ee..fb6fc510 100644 --- a/oci/private/push.bzl +++ b/oci/private/push.bzl @@ -88,7 +88,7 @@ def _impl(ctx): output = executable, is_executable = True, substitutions = { - "{{crane_path}}": crane.crane_info.crane_path, + "{{crane_path}}": crane.crane_info.binary.short_path, "{{yq_path}}": jq.yqinfo.bin.short_path, "{{image_dir}}": ctx.file.image.short_path, "{{fixed_args}}": " ".join(_quote_args(fixed_args)), diff --git a/oci/private/structure_test.bzl b/oci/private/structure_test.bzl index 4a2d4476..85195a48 100644 --- a/oci/private/structure_test.bzl +++ b/oci/private/structure_test.bzl @@ -44,13 +44,13 @@ def _structure_test_impl(ctx): ctx.actions.write( launcher, content = CMD.format( - st_path = st_info.structure_test_path, + st_path = st_info.binary.short_path, fixed_args = " ".join(fixed_args), ), is_executable = True, ) - runfiles = ctx.runfiles(files = ctx.files.image + ctx.files.config + st_info.structure_test_files) + runfiles = ctx.runfiles(files = ctx.files.image + ctx.files.config + [st_info.binary]) return DefaultInfo(runfiles = runfiles, executable = launcher) diff --git a/oci/private/tarball.bzl b/oci/private/tarball.bzl index b662aa8d..a1e2992b 100644 --- a/oci/private/tarball.bzl +++ b/oci/private/tarball.bzl @@ -68,11 +68,11 @@ def _tarball_impl(ctx): output = executable, is_executable = True, substitutions = { - "%yq%": yq_bin.path, - "%image_dir%": image.path, - "%blobs_dir%": blobs.path, - "%manifest_path%": manifest.path, - "%repotags%": json.encode(ctx.attr.repotags), + "{{yq}}": yq_bin.path, + "{{image_dir}}": image.path, + "{{blobs_dir}}": blobs.path, + "{{manifest_path}}": manifest.path, + "{{repotags}}": json.encode(ctx.attr.repotags), }, ) diff --git a/oci/private/tarball.sh.tpl b/oci/private/tarball.sh.tpl index d8232236..515e8e79 100644 --- a/oci/private/tarball.sh.tpl +++ b/oci/private/tarball.sh.tpl @@ -1,11 +1,11 @@ #!/usr/bin/env bash set -o pipefail -o errexit -o nounset -readonly YQ="%yq%" -readonly IMAGE_DIR="%image_dir%" -readonly BLOBS_DIR="%blobs_dir%" -readonly REPOTAGS='%repotags%' -readonly TARBALL_MANIFEST_PATH="%manifest_path%" +readonly YQ="{{yq}}" +readonly IMAGE_DIR="{{image_dir}}" +readonly BLOBS_DIR="{{blobs_dir}}" +readonly REPOTAGS='{{repotags}}' +readonly TARBALL_MANIFEST_PATH="{{manifest_path}}" MANIFEST_DIGEST=$(${YQ} eval '.manifests[0].digest | sub(":"; "/")' "${IMAGE_DIR}/index.json") MANIFEST_BLOB_PATH="${IMAGE_DIR}/blobs/${MANIFEST_DIGEST}" diff --git a/oci/private/zot_launcher.sh.tpl b/oci/private/zot_launcher.sh.tpl new file mode 100644 index 00000000..97daffeb --- /dev/null +++ b/oci/private/zot_launcher.sh.tpl @@ -0,0 +1,34 @@ +readonly SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" +readonly ZOT="${SCRIPT_DIR}/zot" + +function start_registry() { + local storage_dir="$1" + local output="$2" + local deadline="${3:-5}" + local config_path="$1/config.json" + + mkdir -p "${storage_dir}" + cat > "${config_path}" <> $output 2>&1 & + + local timeout=$((SECONDS+${deadline})) + + while [ "${SECONDS}" -lt "${timeout}" ]; do + local port=$(cat $output | sed -nr 's/.+"port":([0-9]+),.+/\1/p') + if [ -n "${port}" ]; then + break + fi + done + if [ -z "${port}" ]; then + echo "registry didn't become ready within ${deadline}s." + exit 1 + fi + echo "127.0.0.1:${port}" +} \ No newline at end of file diff --git a/oci/repositories.bzl b/oci/repositories.bzl index 6884fe32..b4c61ac7 100644 --- a/oci/repositories.bzl +++ b/oci/repositories.bzl @@ -1,6 +1,6 @@ """Repository rules for fetching external tools""" -load("@aspect_bazel_lib//lib:repositories.bzl", "register_jq_toolchains", "register_yq_toolchains") +load("@aspect_bazel_lib//lib:repositories.bzl", "register_coreutils_toolchains", "register_jq_toolchains", "register_yq_toolchains") load("//oci/private:toolchains_repo.bzl", "PLATFORMS", "toolchains_repo") load("//oci/private:versions.bzl", "CRANE_VERSIONS", "ST_VERSIONS", "ZOT_VERSIONS") @@ -49,43 +49,6 @@ registry_toolchain( ) """ -ZOT_LAUNCHER_TMPL = """\ -#!/usr/bin/env bash -set -o errexit -o nounset -o pipefail - -SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" -ZOT="${SCRIPT_DIR}/zot" - -function start_registry() { - local CONFIG_PATH="$1/config.json" - cat > "${CONFIG_PATH}" <&1 >> "${OUTPUT}" & - - local DEADLINE=5 - local TIMEOUT=$((SECONDS+${DEADLINE})) - - while [ "${SECONDS}" -lt "${TIMEOUT}" ]; do - PORT=$(cat $OUTPUT | sed -nr 's/.+"port":([0-9]+),.+/\\1/p') - if [ -n "${PORT}" ]; then - break - fi - done - if [ -z "${PORT}" ]; then - echo "Exhausted: registry couldn't become ready within ${DEADLINE}s." >> "${OUTPUT}" - fi - REGISTRY="127.0.0.1:${PORT}" -} -""" - def _zot_repo_impl(repository_ctx): platform = repository_ctx.attr.platform.replace("x86_64", "amd64").replace("_", "-") url = "https://github.com/project-zot/zot/releases/download/{version}/zot-{platform}".format( @@ -98,7 +61,7 @@ def _zot_repo_impl(repository_ctx): executable = True, integrity = ZOT_VERSIONS[repository_ctx.attr.zot_version][platform], ) - repository_ctx.file("launcher.sh", ZOT_LAUNCHER_TMPL) + repository_ctx.template("launcher.sh", repository_ctx.attr._launcher_tpl) repository_ctx.file("BUILD.bazel", ZOT_BUILD_TMPL) zot_repositories = repository_rule( @@ -107,6 +70,7 @@ zot_repositories = repository_rule( attrs = { "zot_version": attr.string(mandatory = True, values = ZOT_VERSIONS.keys()), "platform": attr.string(mandatory = True, values = PLATFORMS.keys()), + "_launcher_tpl": attr.label(default = "//oci/private:zot_launcher.sh.tpl"), }, ) @@ -164,6 +128,7 @@ def oci_register_toolchains(name, crane_version, zot_version): register_yq_toolchains() register_jq_toolchains() + register_coreutils_toolchains() crane_toolchain_name = "{name}_crane_toolchains".format(name = name) zot_toolchain_name = "{name}_zot_toolchains".format(name = name) diff --git a/oci/toolchain.bzl b/oci/toolchain.bzl index 1efcfd6a..f032ec64 100644 --- a/oci/toolchain.bzl +++ b/oci/toolchain.bzl @@ -1,50 +1,22 @@ """This module implements the language-specific toolchain rule.""" -def _to_manifest_path(ctx, file): - if file.short_path.startswith("../"): - return "external/" + file.short_path[3:] - else: - return ctx.workspace_name + "/" + file.short_path - CraneInfo = provider( doc = "Information about how to invoke the crane executable.", fields = { - "crane_path": "Path to the crane executable for the target platform.", - "crane_files": """Files required in runfiles to make the crane executable available. - -May be empty if the crane_path points to a locally installed tool binary.""", + "binary": "Executable crane binary", }, ) def _crane_toolchain_impl(ctx): - if ctx.attr.crane and ctx.attr.crane_path: - fail("Can only set one of crane or crane_path but both were set.") - if not ctx.attr.crane and not ctx.attr.crane_path: - fail("Must set one of crane or crane_path.") - - crane_files = [] - crane_path = ctx.attr.crane_path - - if ctx.attr.crane: - crane_files = ctx.attr.crane.files.to_list() - crane_path = _to_manifest_path(ctx, crane_files[0]) - - # Make the $(CRANE_BIN) variable available in places like genrules. - # See https://docs.bazel.build/versions/main/be/make-variables.html#custom_variables + binary = ctx.executable.crane template_variables = platform_common.TemplateVariableInfo({ - "CRANE_BIN": crane_path, + "CRANE_BIN": binary.path, }) default = DefaultInfo( - files = depset(crane_files), - runfiles = ctx.runfiles(files = crane_files), - ) - crane_info = CraneInfo( - crane_path = crane_path, - crane_files = crane_files, + files = depset([binary]), + runfiles = ctx.runfiles(files = [binary]), ) - - # Export all the providers inside our ToolchainInfo - # so the resolved_toolchain rule can grab and re-export them. + crane_info = CraneInfo(binary = binary) toolchain_info = platform_common.ToolchainInfo( crane_info = crane_info, template_variables = template_variables, @@ -61,65 +33,40 @@ crane_toolchain = rule( attrs = { "crane": attr.label( doc = "A hermetically downloaded executable target for the target platform.", - mandatory = False, + mandatory = True, allow_single_file = True, executable = True, cfg = "exec", ), - "crane_path": attr.string( - doc = "Path to an existing executable for the target platform.", - mandatory = False, - ), }, - doc = """Defines a container compiler/runtime toolchain. - -For usage see https://docs.bazel.build/versions/main/toolchains.html#defining-toolchains. -""", + doc = "Defines a crane toolchain. See: https://docs.bazel.build/versions/main/toolchains.html#defining-toolchains.", ) RegistryInfo = provider( doc = "Information about how to invoke the registry executable.", fields = { - "launcher_path": "Path to the launcher script exporting a bash function named start_registry taking storage dir as the only argument.", - "registry_path": "Path to the registry executable for the target platform.", - "registry_files": """Files required in runfiles to make the registry executable available. - -May be empty if the registry_path points to a locally installed tool binary.""", + "launcher": "Executable launcher wrapper", + "registry": "Executable registry binary", }, ) def _registry_toolchain_impl(ctx): - if ctx.attr.registry and ctx.attr.registry_path: - fail("Only one of 'registry' or 'registry_path' attributes can be set.") - if not ctx.attr.registry and not ctx.attr.registry_path: - fail("One of 'registry' or 'registry_path' attributes must be set.") - - registry_files = [ctx.file.launcher] - registry_path = ctx.attr.registry_path - launcher_path = _to_manifest_path(ctx, ctx.file.launcher) + registry = ctx.executable.registry + launcher = ctx.executable.launcher - if ctx.attr.registry: - registry_files.append(ctx.file.registry) - registry_path = _to_manifest_path(ctx, ctx.file.registry) - - # Make the $(REGISTRY_BIN) variable available in places like genrules. - # See https://docs.bazel.build/versions/main/be/make-variables.html#custom_variables template_variables = platform_common.TemplateVariableInfo({ - "REGISTRY_BIN": registry_path, - "LAUNCHER": launcher_path, + "REGISTRY_BIN": registry.path, + "LAUNCHER_WRAPPER": launcher.path, }) default = DefaultInfo( - files = depset(registry_files), - runfiles = ctx.runfiles(files = registry_files), + files = depset([registry, launcher]), + runfiles = ctx.runfiles(files = [registry, launcher]), ) registry_info = RegistryInfo( - registry_path = registry_path, - registry_files = registry_files, - launcher_path = launcher_path, + registry = registry, + launcher = launcher, ) - # Export all the providers inside our ToolchainInfo - # so the resolved_toolchain rule can grab and re-export them. toolchain_info = platform_common.ToolchainInfo( registry_info = registry_info, template_variables = template_variables, @@ -135,65 +82,42 @@ registry_toolchain = rule( implementation = _registry_toolchain_impl, attrs = { "launcher": attr.label( - doc = "Launcher script exporting a bash function named start_registry taking storage dir as the only argument.", + doc = "Launcher script defining a bash function `start_registry` that conforms to `start_registry(storage_dir, output, deadline)`", allow_single_file = True, + executable = True, + cfg = "exec", mandatory = True, ), "registry": attr.label( doc = "A hermetically downloaded registry executable for the target platform.", - mandatory = False, + mandatory = True, + executable = True, + cfg = "exec", allow_single_file = True, ), - "registry_path": attr.string( - doc = "Path to an existing registry executable for the target platform.", - mandatory = False, - ), }, - doc = """Defines a registry toolchain. - -For usage see https://docs.bazel.build/versions/main/toolchains.html#defining-toolchains. -""", + doc = "Defines a registry toolchain. See: https://docs.bazel.build/versions/main/toolchains.html#defining-toolchains.", ) StructureTestInfo = provider( doc = "Information about how to invoke the container-structure-test executable.", fields = { - "structure_test_path": "Path to the container-structure-test executable for the target platform.", - "structure_test_files": """Files required in runfiles to make the structure_test executable available. - -May be empty if the structure_test_path points to a locally installed tool binary.""", + "binary": "Executable container-structure-test binary", }, ) def _structure_test_toolchain_impl(ctx): - if ctx.attr.structure_test and ctx.attr.structure_test_path: - fail("Can only set one of structure_test or structure_test_path but both were set.") - if not ctx.attr.structure_test and not ctx.attr.structure_test_path: - fail("Must set one of structure_test or structure_test_path.") - - structure_test_files = [] - structure_test_path = ctx.attr.structure_test_path + binary = ctx.executable.structure_test - if ctx.attr.structure_test: - structure_test_files.append(ctx.file.structure_test) - structure_test_path = _to_manifest_path(ctx, ctx.file.structure_test) - - # Make the $(REGISTRY_BIN) variable available in places like genrules. - # See https://docs.bazel.build/versions/main/be/make-variables.html#custom_variables template_variables = platform_common.TemplateVariableInfo({ - "STRUCTURE_TEST_BIN": structure_test_path, + "STRUCTURE_TEST_BIN": binary.path, }) default = DefaultInfo( - files = depset(structure_test_files), - runfiles = ctx.runfiles(files = structure_test_files), - ) - st_info = StructureTestInfo( - structure_test_path = structure_test_path, - structure_test_files = structure_test_files, + files = depset([binary]), + runfiles = ctx.runfiles(files = [binary]), ) + st_info = StructureTestInfo(binary = binary) - # Export all the providers inside our ToolchainInfo - # so the resolved_toolchain rule can grab and re-export them. toolchain_info = platform_common.ToolchainInfo( st_info = st_info, template_variables = template_variables, @@ -210,16 +134,11 @@ structure_test_toolchain = rule( attrs = { "structure_test": attr.label( doc = "A hermetically downloaded structure_test executable for the target platform.", - mandatory = False, + mandatory = True, + executable = True, + cfg = "exec", allow_single_file = True, ), - "structure_test_path": attr.string( - doc = "Path to an existing structure_test executable for the target platform.", - mandatory = False, - ), }, - doc = """Defines a structure_test structure_test toolchain. - -For usage see https://docs.bazel.build/versions/main/toolchains.html#defining-toolchains. -""", + doc = "Defines a structure_test toolchain. See: https://docs.bazel.build/versions/main/toolchains.html#defining-toolchains.", )