Skip to content

Commit

Permalink
Integrate with apko-0.13+ . Pass --lockfile to apko to get hermetic…
Browse files Browse the repository at this point in the history
… (re)builds. (#41)

Integrate with apko-0.12+ . Pass `--lockfile` to apko to get hermetic
(re)builds.

This is `rules_apko` part of:
#13
that integrates: 
 - go-apk change: chainguard-dev/go-apk#172
 - apko change: chainguard-dev/apko#979

---------

Signed-off-by: Piotr Tabor <piotr.tabor@snowflake.com>
  • Loading branch information
sfc-gh-ptabor authored Dec 31, 2023
1 parent d8f33ae commit 620fba9
Show file tree
Hide file tree
Showing 15 changed files with 936 additions and 731 deletions.
2 changes: 1 addition & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ bazel_dep(name = "bazel_skylib_gazelle_plugin", version = "1.4.1", dev_dependenc
bazel_dep(name = "buildifier_prebuilt", version = "6.1.0", dev_dependency = True)

toolchain = use_extension("//apko:extensions.bzl", "apko")
toolchain.toolchain(apko_version = "v0.11.0")
toolchain.toolchain(apko_version = "v0.13.1")
use_repo(toolchain, "apko_toolchains")

register_toolchains("@apko_toolchains//:all")
Expand Down
3 changes: 2 additions & 1 deletion apko/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ bzl_library(
visibility = ["//apko:__subpackages__"],
deps = [
"apko_run",
"@bazel_skylib//:lib",
"@bazel_skylib//lib:paths",
"@bazel_skylib//lib:versions",
],
)

Expand Down
25 changes: 25 additions & 0 deletions apko/private/apk.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,28 @@ apk_keyring = repository_rule(
"url": attr.string(mandatory = True),
},
)

def _apk_filegroup_impl(ctx):
lockfile = depset([ctx.file.lockfile])
apks = depset(ctx.files.apks)
indexes = depset(ctx.files.indexes)
keyrings = depset(ctx.files.keyrings)
return [
DefaultInfo(files = depset(transitive = [lockfile, apks, indexes, keyrings])),
OutputGroupInfo(
lockfile = lockfile,
apks = apks,
indexes = indexes,
keyrings = keyrings,
),
]

apk_filegroup = rule(
implementation = _apk_filegroup_impl,
attrs = {
"lockfile": attr.label(doc = "Label to the `apko.resolved.json` file.", allow_single_file = True, mandatory = True),
"keyrings": attr.label_list(doc = "Labels of the keyring (public key) files.", allow_files = True, mandatory = True),
"apks": attr.label_list(doc = "Labels of the package (apk) files.", allow_files = True, mandatory = True),
"indexes": attr.label_list(doc = "Labels of the APKINDEX files.", allow_files = True, mandatory = True),
},
)
22 changes: 18 additions & 4 deletions apko/private/apko_image.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

load("//apko/private:apko_run.bzl", "apko_run")
load("@bazel_skylib//lib:paths.bzl", "paths")
load("@bazel_skylib//lib:versions.bzl", "versions")

_ATTRS = {
"contents": attr.label(doc = "Label to the contents repository generated by translate_lock. See [apko-cache](./apko-cache.md) documentation.", mandatory = True),
"contents": attr.label(doc = "Label to the contents repository generated by translate_lock. See [apko-cache](./apko-cache.md) documentation.", mandatory = True, providers = [OutputGroupInfo]),
"config": attr.label(doc = "Label to the `apko.yaml` file.", allow_single_file = True, mandatory = True),
"output": attr.string(default = "oci", values = ["oci", "docker"]),
"architecture": attr.string(doc = "the CPU architecture which this image should be built to run on. See https://github.com/chainguard-dev/apko/blob/main/docs/apko_file.md#archs-top-level-element"),
Expand Down Expand Up @@ -32,16 +33,29 @@ def _impl(ctx):

args.add_all(ctx.attr.args)

lockfile = ctx.attr.contents[OutputGroupInfo].lockfile.to_list()[0]
apks = ctx.attr.contents[OutputGroupInfo].apks
indexes = ctx.attr.contents[OutputGroupInfo].indexes
keyrings = ctx.attr.contents[OutputGroupInfo].keyrings

inputs = [ctx.file.config]
deps = [apks, keyrings]

supports_lockfile = versions.is_at_least("0.13.0", apko_info.version)
if supports_lockfile:
inputs.append(lockfile)
args.add("--lockfile={}".format(lockfile.path))
else:
deps.append(indexes)

args.add("--cache-dir={}".format(paths.join(ctx.bin_dir.path, ctx.label.workspace_root, ctx.label.package, cache_name)))
args.add("--offline")

if ctx.attr.architecture:
args.add("--arch")
args.add(ctx.attr.architecture)

inputs = [ctx.file.config] + ctx.files.contents

for content in ctx.files.contents:
for content in depset(transitive = deps).to_list():
content_owner = content.owner.workspace_name
content_cache_entry_key = content.path[content.path.find(content_owner) + len(content_owner) + 1:]
content_entry = ctx.actions.declare_file("/".join([cache_name, content_cache_entry_key]))
Expand Down
12 changes: 6 additions & 6 deletions apko/private/versions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
# Add new versions by running
# ./scripts/mirror_apko.sh
APKO_VERSIONS = {
"v0.11.0": {
"darwin_amd64": "sha256-u7OtDCR+RRm1H60gz5n12wV0HFjVF5ZLxOh8cWj/a4g=",
"darwin_arm64": "sha256-TwZIc/Au3HiZGFtSu6+jAPjGb1tgf3SLR7Brgx9NAnU=",
"linux_386": "sha256-l+CqC0kTOib9POfYvEQHE/6UPvRvgBlsEwD5VOiVfQM=",
"linux_amd64": "sha256-3bNyYPKFjoyrUCuTRS1ylfwmywioOeroc0hfcoGpKHw=",
"linux_arm64": "sha256-WAJItgSMVFBLr3M2iSn+wXatYG+YCcE6hyEupRxhRA4=",
"v0.13.1": {
"darwin_amd64": "sha256-4TR9HqR3vgRauBrgWZdfa5e37JTJJr9N6jppJptJHvs=",
"darwin_arm64": "sha256-DzE17CSC+5Vm3HVPKoUy09Jgyg5e4Wh6Cxe97ryGb2A=",
"linux_386": "sha256-TykjzvWJZ0squJ3KpQ04zFv1JoNkyVrlXZIwDfuobfM=",
"linux_amd64": "sha256-oODdjPPU846ArFM6M3Crnx0H2aOBanL3QhVh6NoLFWA=",
"linux_arm64": "sha256-CQ/OBkp99hmIaVlb5XhA1WJuRt9mbQtUjOh3q8k11uI=",
},
}
8 changes: 5 additions & 3 deletions apko/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ _ATTRS = {
}

def _apko_repo_impl(repository_ctx):
version = repository_ctx.attr.apko_version.lstrip("v")
url = "https://github.com/chainguard-dev/apko/releases/download/v{version}/apko_{version}_{platform}.tar.gz".format(
version = repository_ctx.attr.apko_version.lstrip("v"),
version = version,
platform = repository_ctx.attr.platform,
)
repository_ctx.download_and_extract(
Expand All @@ -70,9 +71,10 @@ apko_toolchain(
name = "apko_toolchain",
# After https://github.com/chainguard-dev/apko/issues/827 is fixed,
# this may need to be conditional so it's "apko.exe" on Windows.
apko = "apko"
apko = "apko",
version = "{version}",
)
""",
""".format(version = version),
)

apko_repositories = repository_rule(
Expand Down
2 changes: 1 addition & 1 deletion apko/tests/versions_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ load("//apko/private:versions.bzl", "APKO_VERSIONS")

def _smoke_test_impl(ctx):
env = unittest.begin(ctx)
asserts.equals(env, "v0.11.0", APKO_VERSIONS.keys()[0])
asserts.equals(env, "v0.13.1", APKO_VERSIONS.keys()[0])
return unittest.end(env)

# The unittest library requires that we export the test cases as named test rules,
Expand Down
11 changes: 10 additions & 1 deletion apko/toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ ApkoInfo = provider(
doc = "Information about how to invoke the apko executable.",
fields = {
"binary": "Path to an apko binary",
"version": "Version of the apko binary, e.g (0.12.3-foo)",
},
)

Expand All @@ -16,7 +17,11 @@ def _apko_toolchain_impl(ctx):
files = depset([binary]),
runfiles = ctx.runfiles(files = [binary]),
)
apko_info = ApkoInfo(binary = binary)
version = ctx.attr.version
apko_info = ApkoInfo(
binary = binary,
version = version,
)
toolchain_info = platform_common.ToolchainInfo(
apko_info = apko_info,
template_variables = template_variables,
Expand All @@ -38,6 +43,10 @@ apko_toolchain = rule(
executable = True,
cfg = "exec",
),
"version": attr.string(
doc = "A version of the apko binary.",
mandatory = True,
),
},
doc = "Defines an apko toolchain. See: https://docs.bazel.build/versions/main/toolchains.html#defining-toolchains.",
)
26 changes: 19 additions & 7 deletions apko/translate_lock.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@ See [apko-cache.md](./apko-cache.md) documentation.
"""

BUILD_TMPL = """\
load("@rules_apko//apko/private:apk.bzl", "apk_filegroup")
# Generated by apko_translate_lock. DO NOT EDIT.
filegroup(
apk_filegroup(
name = "contents",
srcs = {targets},
lockfile = "{lockfile}",
apks = {apks},
indexes = {indexes},
keyrings = {keyrings},
visibility = ["//visibility:public"]
)
"""
Expand Down Expand Up @@ -58,23 +63,30 @@ APK_KEYRING_TMPL = """\

def _translate_apko_lock_impl(rctx):
lock_file = util.parse_lock(rctx.read(rctx.attr.lock))
targets = []

# We copy the lockfile (.resolved.json) to avoid visibility problems when we reference it from another module.
lock_file_local = "lockfile_copy"
rctx.symlink(rctx.attr.lock, lock_file_local)

apks = []
indexes = []
keyrings = []
defs = []

target_name = rctx.attr.target_name if rctx.attr.target_name else rctx.name

if "keyring" in lock_file["contents"]:
for keyring in lock_file["contents"]["keyring"]:
name = util.sanitize_string("{}_{}".format(target_name, keyring["name"]))
targets.append("@{}//:keyring".format(name))
keyrings.append("@{}//:keyring".format(name))
defs.append(APK_KEYRING_TMPL.format(
name = name,
url = keyring["url"],
))

for package in lock_file["contents"]["packages"]:
name = util.sanitize_string("{}_{}_{}_{}".format(target_name, package["name"], package["architecture"], package["version"]))
targets.append("@{}//:all".format(name))
apks.append("@{}//:all".format(name))

defs.append(APK_IMPORT_TMPL.format(
name = name,
Expand All @@ -92,7 +104,7 @@ def _translate_apko_lock_impl(rctx):

for repository in lock_file["contents"]["repositories"]:
name = util.sanitize_string("{}_{}_{}".format(target_name, repository["name"], repository["architecture"]))
targets.append("@{}//:index".format(name))
indexes.append("@{}//:index".format(name))
defs.append(APK_REPOSITORY_TMPL.format(
name = name,
url = repository["url"],
Expand All @@ -106,7 +118,7 @@ def _translate_apko_lock_impl(rctx):

rctx.file(
"BUILD.bazel",
BUILD_TMPL.format(targets = targets),
BUILD_TMPL.format(apks = apks, keyrings = keyrings, indexes = indexes, lockfile = lock_file_local),
)

translate_apko_lock = repository_rule(
Expand Down
6 changes: 4 additions & 2 deletions e2e/smoke/apko.resolved.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions examples/lock/apko.resolved.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 620fba9

Please sign in to comment.