Skip to content

Commit

Permalink
Allow users to provide the versions of apko binaries not listed in ve…
Browse files Browse the repository at this point in the history
…rsions.bzl (#78)

The motivation here is to be able to use newest apko releases without
updating rules_apko as an intermediate step.

It offloads some complexity (specifying hash, prefix to strip and url to
the user), but if one just wants to use default apko version, they don't
need to do it.

---------

Signed-off-by: Mateusz Hazy <mateusz.hazy@snowflake.com>
  • Loading branch information
sfc-gh-mhazy authored Jun 18, 2024
1 parent 5d30a2d commit 4df2175
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 169 deletions.
1 change: 1 addition & 0 deletions apko/private/toolchains_repo.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,6 @@ toolchains_repo = repository_rule(
which can be registered or selected.""",
attrs = {
"user_repository_name": attr.string(doc = "what the user chose for the base name"),
"platforms": attr.string_list(default = PLATFORMS.keys()),
},
)
68 changes: 51 additions & 17 deletions apko/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,18 @@ def rules_apko_dependencies():
########
_DOC = "Fetch external tools needed for apko toolchain"
_ATTRS = {
"apko_version": attr.string(mandatory = True, values = APKO_VERSIONS.keys()),
"platform": attr.string(mandatory = True, values = PLATFORMS.keys()),
"apko_version": attr.string(mandatory = True),
"platform": attr.string(mandatory = True),
"sha256": attr.string(mandatory = True),
"url": attr.string(mandatory = True),
"strip_prefix": attr.string(mandatory = False, default = ""),
}

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 = version,
platform = repository_ctx.attr.platform,
)
repository_ctx.download_and_extract(
integrity = APKO_VERSIONS[repository_ctx.attr.apko_version][repository_ctx.attr.platform],
stripPrefix = "apko_{}_{}".format(
repository_ctx.attr.apko_version.lstrip("v"),
repository_ctx.attr.platform,
),
url = url,
integrity = repository_ctx.attr.sha256,
stripPrefix = repository_ctx.attr.strip_prefix,
url = repository_ctx.attr.url,
)
repository_ctx.file(
"BUILD.bazel",
Expand All @@ -74,7 +69,7 @@ apko_toolchain(
apko = "apko",
version = "{version}",
)
""".format(version = version),
""".format(version = repository_ctx.attr.apko_version),
)

apko_repositories = repository_rule(
Expand All @@ -83,8 +78,32 @@ apko_repositories = repository_rule(
attrs = _ATTRS,
)

def apko_binary_spec(url, sha256, version, strip_prefix):
return struct(url = url, sha256 = sha256, version = version, strip_prefix = strip_prefix)

def _build_platform_to_apko_binary_map(apko_version):
version = apko_version.lstrip("v")
result = {}
for platform in PLATFORMS.keys():
url = "https://github.com/chainguard-dev/apko/releases/download/v{version}/apko_{version}_{platform}.tar.gz".format(
version = version,
platform = platform,
)
sha256 = APKO_VERSIONS[apko_version][platform]
strip_prefix = "apko_{}_{}".format(
version,
platform,
)
result[platform] = apko_binary_spec(
url = url,
sha256 = sha256,
version = version,
strip_prefix = strip_prefix,
)
return result

# Wrapper macro around everything above, this is the primary API
def apko_register_toolchains(name, apko_version = LATEST_APKO_VERSION, register = True):
def apko_register_toolchains(name, apko_version = LATEST_APKO_VERSION, platform_to_apko_binary_map = None, register = True):
"""Convenience macro for users which does typical setup.
- create a repository for each built-in platform like "apko_linux_amd64" -
Expand All @@ -97,17 +116,32 @@ def apko_register_toolchains(name, apko_version = LATEST_APKO_VERSION, register
register: whether to call through to native.register_toolchains.
Should be True for WORKSPACE users, but false when used under bzlmod extension
apko_version: version of apko
platform_to_apko_binary_map: specialized way of providing urls of apko binaries for the toolchains.
If specified, apko_version is ignored. It is a dict of platform string to struct produced by
apko_binary_spec macro that consists of url to the archive with apko binary, it's sha256, version
of apko and prefix that should be stripped after unpacking the archive. The prefix
should specified, so that apko binary lands in top level directory after stripping.
The intention here is to allow using apko versions that are not included in versions.bzl.
"""
for platform in PLATFORMS.keys():
map = platform_to_apko_binary_map
if map == None:
map = _build_platform_to_apko_binary_map(apko_version)
for platform, apko_spec in map.items():
if platform not in PLATFORMS.keys():
fail("Unsupported platform: {}".format(platform))
apko_repositories(
name = name + "_" + platform,
platform = platform,
apko_version = apko_version,
sha256 = apko_spec.sha256,
url = apko_spec.url,
apko_version = apko_spec.version,
strip_prefix = apko_spec.strip_prefix,
)
if register:
native.register_toolchains("@%s_toolchains//:%s_toolchain" % (name, platform))

toolchains_repo(
name = name + "_toolchains",
user_repository_name = name,
platforms = map.keys(),
)
18 changes: 9 additions & 9 deletions e2e/smoke/apko.lock.json

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

24 changes: 14 additions & 10 deletions e2e/smoke/multifile_config/apko.generated.lock.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"version": "v1",
"config": {
"name": "multifile_config/final_config",
"checksum": "sha256-MSnniHz70jvjVUCXoODhAlzNWxY5Vdjb8UOK8gFF0bk="
},
"contents": {
"keyring": [],
"repositories": [
Expand Down Expand Up @@ -31,23 +35,23 @@
},
{
"name": "busybox",
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.18/main/x86_64/busybox-1.36.1-r5.apk",
"version": "1.36.1-r5",
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.18/main/x86_64/busybox-1.36.1-r7.apk",
"version": "1.36.1-r7",
"architecture": "x86_64",
"signature": {
"range": "bytes=0-665",
"checksum": "sha1-oXF25kDE6Jja1iQ2psyt9nV+ddE="
"range": "bytes=0-666",
"checksum": "sha1-a//l3+A49R6SnnktH1+pQuZE2qI="
},
"control": {
"range": "bytes=666-2301",
"checksum": "sha1-aBWv1Kn2ASOLShUeDPoSLaozuMs="
"range": "bytes=667-2300",
"checksum": "sha1-ierGKl33AY17yZdo8YN+z8NeMPg="
},
"data": {
"range": "bytes=2302-946176",
"checksum": "sha256-pDdzepugl8LYISmpJ2wGr885gfpwo2hi9ZMf4dQTi5s="
"range": "bytes=2301-946176",
"checksum": "sha256-FzlpW4Mq56716OmdQnwYlES9hohBM0ouq62EWds3kDI="
},
"checksum": "Q1aBWv1Kn2ASOLShUeDPoSLaozuMs="
"checksum": "Q1ierGKl33AY17yZdo8YN+z8NeMPg="
}
]
}
}
}
18 changes: 9 additions & 9 deletions examples/lock/apko.lock.json

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

Loading

0 comments on commit 4df2175

Please sign in to comment.