mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-01-24 14:22:14 -05:00
bazel: rules to handle container images
This commit is contained in:
parent
9dfad32e33
commit
daf18052f9
@ -26,6 +26,11 @@ alias(
|
||||
actual = "//bazel/devbuild:devbuild",
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "push",
|
||||
actual = "//bazel/release:push",
|
||||
)
|
||||
|
||||
# These magic Gazelle commands need to be in the top-level BUILD file.
|
||||
# gazelle:map_kind go_test go_test //bazel/go:go_test.bzl
|
||||
# gazelle:prefix github.com/edgelesssys/constellation/v2
|
||||
|
@ -3,6 +3,7 @@ load("//bazel/sh:def.bzl", "sh_template")
|
||||
sh_template(
|
||||
name = "devbuild",
|
||||
data = [
|
||||
"//bazel/release:container_sums",
|
||||
"//bootstrapper/cmd/bootstrapper:bootstrapper_linux_amd64",
|
||||
"//cli:cli_oss_host",
|
||||
"//debugd/cmd/cdbg:cdbg_host",
|
||||
@ -12,6 +13,7 @@ sh_template(
|
||||
"@@BOOTSTRAPPER@@": "$(rootpath //bootstrapper/cmd/bootstrapper:bootstrapper_linux_amd64)",
|
||||
"@@CDBG@@": "$(rootpath //debugd/cmd/cdbg:cdbg_host)",
|
||||
"@@CLI@@": "$(rootpath //cli:cli_oss_host)",
|
||||
"@@CONTAINER_SUMS@@": "$(rootpath //bazel/release:container_sums)",
|
||||
"@@UPGRADE_AGENT@@": "$(rootpath //upgrade-agent/cmd:upgrade_agent_linux_amd64)",
|
||||
},
|
||||
template = "prepare_developer_workspace.sh.in",
|
||||
|
@ -22,6 +22,8 @@ cli=$(realpath @@CLI@@)
|
||||
stat "${cli}" >> /dev/null
|
||||
cdbg=$(realpath @@CDBG@@)
|
||||
stat "${cdbg}" >> /dev/null
|
||||
container_sums=$(realpath @@CONTAINER_SUMS@@)
|
||||
stat "${container_sums}" >> /dev/null
|
||||
|
||||
cd "${BUILD_WORKING_DIRECTORY}"
|
||||
|
||||
@ -53,3 +55,4 @@ ln -sf "$(replace_prefix "${host_cache}" "${builder_cache}" "${bootstrapper}")"
|
||||
ln -sf "$(replace_prefix "${host_cache}" "${builder_cache}" "${upgrade_agent}")" "${workdir}/upgrade-agent"
|
||||
ln -sf "$(replace_prefix "${host_cache}" "${builder_cache}" "${cli}")" "${workdir}/constellation"
|
||||
ln -sf "$(replace_prefix "${host_cache}" "${builder_cache}" "${cdbg}")" "${workdir}/cdbg"
|
||||
ln -sf "$(replace_prefix "${host_cache}" "${builder_cache}" "${container_sums}")" "${workdir}/container_sums.sha256"
|
||||
|
0
bazel/oci/BUILD.bazel
Normal file
0
bazel/oci/BUILD.bazel
Normal file
135
bazel/oci/containers.bzl
Normal file
135
bazel/oci/containers.bzl
Normal file
@ -0,0 +1,135 @@
|
||||
"""
|
||||
This module holds the definitions of the containers that are built.
|
||||
"""
|
||||
|
||||
load("@rules_oci//oci:defs.bzl", _oci_push = "oci_push", _oci_tarball = "oci_tarball")
|
||||
load("//bazel/oci:pin.bzl", "oci_sum")
|
||||
|
||||
_default_registry = "ghcr.io"
|
||||
_default_prefix = "edgelesssys/constellation"
|
||||
|
||||
def containers():
|
||||
return [
|
||||
{
|
||||
"identifier": "joinService",
|
||||
"image_name": "join-service",
|
||||
"name": "joinservice",
|
||||
"oci": "//joinservice/cmd:joinservice",
|
||||
"prefix": _default_prefix,
|
||||
"registry": _default_registry,
|
||||
"tag_file": "//bazel/settings:tag",
|
||||
"used_by": ["helm"],
|
||||
},
|
||||
{
|
||||
"identifier": "keyService",
|
||||
"image_name": "key-service",
|
||||
"name": "keyservice",
|
||||
"oci": "//keyservice/cmd:keyservice",
|
||||
"prefix": _default_prefix,
|
||||
"registry": _default_registry,
|
||||
"tag_file": "//bazel/settings:tag",
|
||||
"used_by": ["helm"],
|
||||
},
|
||||
{
|
||||
"identifier": "verificationService",
|
||||
"image_name": "verification-service",
|
||||
"name": "verificationservice",
|
||||
"oci": "//verify/cmd:verificationservice",
|
||||
"prefix": _default_prefix,
|
||||
"registry": _default_registry,
|
||||
"tag_file": "//bazel/settings:tag",
|
||||
"used_by": ["helm"],
|
||||
},
|
||||
{
|
||||
"identifier": "constellationNodeOperator",
|
||||
"image_name": "node-operator",
|
||||
"name": "nodeoperator",
|
||||
"oci": "//operators/constellation-node-operator:node_operator",
|
||||
"prefix": _default_prefix,
|
||||
"registry": _default_registry,
|
||||
"tag_file": "//bazel/settings:tag",
|
||||
"used_by": ["helm"],
|
||||
},
|
||||
{
|
||||
"identifier": "qemuMetadata",
|
||||
"image_name": "qemu-metadata-api",
|
||||
"name": "qemumetadata",
|
||||
"oci": "//hack/qemu-metadata-api:qemumetadata",
|
||||
"prefix": _default_prefix,
|
||||
"registry": _default_registry,
|
||||
"tag_file": "//bazel/settings:tag",
|
||||
"used_by": ["config"],
|
||||
},
|
||||
{
|
||||
"identifier": "libvirt",
|
||||
"image_name": "libvirt",
|
||||
"name": "libvirt",
|
||||
"oci": "//cli/internal/libvirt:constellation_libvirt",
|
||||
"prefix": _default_prefix,
|
||||
"registry": _default_registry,
|
||||
"tag_file": "//bazel/settings:tag",
|
||||
"used_by": ["config"],
|
||||
},
|
||||
]
|
||||
|
||||
def helm_containers():
|
||||
return [container for container in containers() if "helm" in container["used_by"]]
|
||||
|
||||
def config_containers():
|
||||
return [container for container in containers() if "config" in container["used_by"]]
|
||||
|
||||
def container_sum(name, oci, registry, prefix, image_name, **kwargs):
|
||||
tag = kwargs.get("tag", None)
|
||||
tag_file = kwargs.get("tag_file", None)
|
||||
oci_sum(
|
||||
name = name + "_sum",
|
||||
oci = oci,
|
||||
registry = registry,
|
||||
prefix = prefix,
|
||||
image_name = image_name,
|
||||
tag = tag,
|
||||
tag_file = tag_file,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
def oci_push(name, image, registry, image_name, **kwargs):
|
||||
"""oci_push pushes an OCI image to a registry.
|
||||
|
||||
Args:
|
||||
name: The name of the target.
|
||||
image: The OCI image to push.
|
||||
registry: The registry to push to.
|
||||
image_name: The name of the image.
|
||||
**kwargs: Additional arguments to pass to oci_push.
|
||||
"""
|
||||
prefix = kwargs.pop("prefix", None)
|
||||
tag = kwargs.pop("tag", None)
|
||||
tag_file = kwargs.pop("tag_file", None)
|
||||
if prefix == None:
|
||||
repository = registry + "/" + image_name
|
||||
else:
|
||||
repository = registry + "/" + prefix + "/" + image_name
|
||||
_oci_push(
|
||||
name = name,
|
||||
image = image,
|
||||
repository = repository,
|
||||
tag = tag,
|
||||
tag_file = tag_file,
|
||||
visibility = ["//visibility:public"],
|
||||
**kwargs
|
||||
)
|
||||
|
||||
# TODO(malt3): allow repotags (registry + tag) to be read from a file.
|
||||
def oci_tarball(name, image):
|
||||
"""oci_tarball creates a tarball of an OCI image.
|
||||
|
||||
Args:
|
||||
name: The name of the target.
|
||||
image: The OCI image to create a tarball of.
|
||||
"""
|
||||
_oci_tarball(
|
||||
name = name,
|
||||
image = image,
|
||||
repotags = [],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
230
bazel/oci/pin.bzl
Normal file
230
bazel/oci/pin.bzl
Normal file
@ -0,0 +1,230 @@
|
||||
"""
|
||||
This module contains rules and macros for pinning oci images.
|
||||
"""
|
||||
|
||||
load("@aspect_bazel_lib//lib:jq.bzl", "jq")
|
||||
load("@bazel_skylib//lib:types.bzl", "types")
|
||||
|
||||
def stamp_tags(name, repotags, **kwargs):
|
||||
if not types.is_list(repotags):
|
||||
fail("repotags should be a list")
|
||||
_maybe_quote = lambda x: x if "\"" in x else "\"{}\"".format(x)
|
||||
jq(
|
||||
name = name,
|
||||
srcs = [],
|
||||
out = "_{}.tags.txt".format(name),
|
||||
args = ["--raw-output"],
|
||||
filter = "|".join([
|
||||
"$ARGS.named.STAMP as $stamp",
|
||||
",".join([_maybe_quote(t) for t in repotags]),
|
||||
]),
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def _oci_go_source_impl(ctx):
|
||||
oci = ctx.file.oci
|
||||
inputs = [oci]
|
||||
if ctx.attr.tag_file:
|
||||
inputs.append(ctx.file.tag_file)
|
||||
output = ctx.actions.declare_file(ctx.label.name + ".go")
|
||||
args = [
|
||||
"codegen",
|
||||
"--image-registry",
|
||||
ctx.attr.registry,
|
||||
"--image-prefix",
|
||||
ctx.attr.prefix,
|
||||
"--image-name",
|
||||
ctx.attr.image_name,
|
||||
"--oci-path",
|
||||
oci.path,
|
||||
"--package",
|
||||
ctx.attr.package,
|
||||
"--identifier",
|
||||
ctx.attr.identifier,
|
||||
"--output",
|
||||
output.path,
|
||||
]
|
||||
if ctx.attr.tag:
|
||||
args.append("--image-tag")
|
||||
args.append(ctx.attr.tag)
|
||||
if ctx.attr.tag_file:
|
||||
args.append("--image-tag-file")
|
||||
args.append(ctx.file.tag_file.path)
|
||||
|
||||
ctx.actions.run(
|
||||
inputs = inputs,
|
||||
arguments = args,
|
||||
outputs = [output],
|
||||
executable = ctx.executable._oci_pin,
|
||||
mnemonic = "OCIPin",
|
||||
progress_message = "Generating OCI pin Go source %{label}",
|
||||
)
|
||||
|
||||
return [DefaultInfo(
|
||||
files = depset([output]),
|
||||
)]
|
||||
|
||||
_go_source_attrs = {
|
||||
"identifier": attr.string(
|
||||
mandatory = True,
|
||||
doc = "Identifier to use for the generated Go source.",
|
||||
),
|
||||
"image_name": attr.string(
|
||||
mandatory = True,
|
||||
doc = "Image name to use for the generated Go source.",
|
||||
),
|
||||
"oci": attr.label(
|
||||
mandatory = True,
|
||||
allow_single_file = True,
|
||||
doc = "OCI image to extract the digest from.",
|
||||
),
|
||||
"package": attr.string(
|
||||
mandatory = True,
|
||||
doc = "Package to use for the generated Go source.",
|
||||
),
|
||||
"prefix": attr.string(
|
||||
doc = "Prefix to use for the generated Go source.",
|
||||
),
|
||||
"registry": attr.string(
|
||||
mandatory = True,
|
||||
doc = "Registry to use for the generated Go source.",
|
||||
),
|
||||
"tag": attr.string(
|
||||
doc = "OCI image tag to use for the generated Go source.",
|
||||
),
|
||||
"tag_file": attr.label(
|
||||
allow_single_file = True,
|
||||
doc = "OCI image tag file to use for the generated Go source.",
|
||||
),
|
||||
"_oci_pin": attr.label(
|
||||
allow_single_file = True,
|
||||
executable = True,
|
||||
cfg = "exec",
|
||||
default = Label("//hack/oci-pin"),
|
||||
),
|
||||
}
|
||||
|
||||
oci_go_source = rule(
|
||||
implementation = _oci_go_source_impl,
|
||||
attrs = _go_source_attrs,
|
||||
)
|
||||
|
||||
def _oci_sum_impl(ctx):
|
||||
oci = ctx.file.oci
|
||||
inputs = [oci]
|
||||
if ctx.attr.tag_file:
|
||||
inputs.append(ctx.file.tag_file)
|
||||
output = ctx.actions.declare_file(ctx.label.name + ".sha256")
|
||||
args = [
|
||||
"sum",
|
||||
"--image-name",
|
||||
ctx.attr.image_name,
|
||||
"--oci-path",
|
||||
oci.path,
|
||||
"--output",
|
||||
output.path,
|
||||
"--registry",
|
||||
ctx.attr.registry,
|
||||
]
|
||||
if ctx.attr.prefix:
|
||||
args.append("--prefix")
|
||||
args.append(ctx.attr.prefix)
|
||||
if ctx.attr.tag:
|
||||
args.append("--image-tag")
|
||||
args.append(ctx.attr.tag)
|
||||
if ctx.attr.tag_file:
|
||||
args.append("--image-tag-file")
|
||||
args.append(ctx.file.tag_file.path)
|
||||
|
||||
ctx.actions.run(
|
||||
inputs = inputs,
|
||||
arguments = args,
|
||||
outputs = [output],
|
||||
executable = ctx.executable._oci_pin,
|
||||
mnemonic = "OCISum",
|
||||
progress_message = "Generating OCI sum file %{label}",
|
||||
)
|
||||
|
||||
return [DefaultInfo(
|
||||
files = depset([output]),
|
||||
)]
|
||||
|
||||
_sum_attrs = {
|
||||
"image_name": attr.string(
|
||||
mandatory = True,
|
||||
doc = "Image name to use for the sum entry.",
|
||||
),
|
||||
"oci": attr.label(
|
||||
mandatory = True,
|
||||
allow_single_file = True,
|
||||
doc = "OCI image to extract the digest from.",
|
||||
),
|
||||
"prefix": attr.string(
|
||||
doc = "Prefix to use for the sum entry.",
|
||||
),
|
||||
"registry": attr.string(
|
||||
mandatory = True,
|
||||
doc = "Registry to use for the sum entry.",
|
||||
),
|
||||
"tag": attr.string(
|
||||
doc = "OCI image tag to use for the sum entry.",
|
||||
),
|
||||
"tag_file": attr.label(
|
||||
allow_single_file = True,
|
||||
doc = "OCI image tag file to use for the sum entry.",
|
||||
),
|
||||
"_oci_pin": attr.label(
|
||||
allow_single_file = True,
|
||||
executable = True,
|
||||
cfg = "exec",
|
||||
default = Label("//hack/oci-pin"),
|
||||
),
|
||||
}
|
||||
|
||||
oci_sum = rule(
|
||||
implementation = _oci_sum_impl,
|
||||
attrs = _sum_attrs,
|
||||
)
|
||||
|
||||
def _oci_sum_merge_impl(ctx):
|
||||
# TODO: select list of labels
|
||||
inputs = ctx.files.sums
|
||||
output = ctx.actions.declare_file(ctx.label.name + ".sha256")
|
||||
args = [
|
||||
"merge",
|
||||
"--output",
|
||||
output.path,
|
||||
]
|
||||
for sum in ctx.files.sums:
|
||||
args.append("--input")
|
||||
args.append(sum.path)
|
||||
|
||||
ctx.actions.run(
|
||||
inputs = inputs,
|
||||
arguments = args,
|
||||
outputs = [output],
|
||||
executable = ctx.executable._oci_pin,
|
||||
mnemonic = "OCISumMerge",
|
||||
progress_message = "Merging OCI sum files %{label}",
|
||||
)
|
||||
|
||||
return [DefaultInfo(
|
||||
files = depset([output]),
|
||||
)]
|
||||
|
||||
_sum_merge_attrs = {
|
||||
"sums": attr.label_list(
|
||||
doc = "Sum files to merge for the combined sum entry.",
|
||||
),
|
||||
"_oci_pin": attr.label(
|
||||
allow_single_file = True,
|
||||
executable = True,
|
||||
cfg = "exec",
|
||||
default = Label("//hack/oci-pin"),
|
||||
),
|
||||
}
|
||||
|
||||
oci_sum_merge = rule(
|
||||
implementation = _oci_sum_merge_impl,
|
||||
attrs = _sum_merge_attrs,
|
||||
)
|
60
bazel/release/BUILD.bazel
Normal file
60
bazel/release/BUILD.bazel
Normal file
@ -0,0 +1,60 @@
|
||||
"""
|
||||
This folder contains labels used to collect release artifacts.
|
||||
"""
|
||||
|
||||
load("@com_github_ash2k_bazel_tools//multirun:def.bzl", "multirun")
|
||||
load("//bazel/oci:containers.bzl", "container_sum", "containers", "oci_push", "oci_tarball")
|
||||
load("//bazel/oci:pin.bzl", "oci_sum_merge")
|
||||
|
||||
[
|
||||
oci_tarball(
|
||||
name = container["name"] + "_tar",
|
||||
image = container["oci"],
|
||||
)
|
||||
for container in containers()
|
||||
]
|
||||
|
||||
[
|
||||
container_sum(
|
||||
name = container["name"],
|
||||
image_name = container["image_name"],
|
||||
oci = container["oci"],
|
||||
prefix = container["prefix"],
|
||||
registry = container["registry"],
|
||||
tag_file = container["tag_file"],
|
||||
)
|
||||
for container in containers()
|
||||
]
|
||||
|
||||
oci_sum_merge(
|
||||
name = "container_sums",
|
||||
sums = [
|
||||
":%s_sum" % container["name"]
|
||||
for container in containers()
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
# TODO(malt3): use config setting to allow devs the use of custom registries
|
||||
# https://www.grahambrooks.com/software-development/2021/08/30/user-defined-bazel-arguments.html
|
||||
[
|
||||
oci_push(
|
||||
name = container["name"] + "_push",
|
||||
image = container["oci"],
|
||||
image_name = container["image_name"],
|
||||
prefix = container["prefix"],
|
||||
registry = container["registry"],
|
||||
repotags = container["tag_file"],
|
||||
)
|
||||
for container in containers()
|
||||
]
|
||||
|
||||
multirun(
|
||||
name = "push",
|
||||
commands = [
|
||||
":" + container["name"] + "_push"
|
||||
for container in containers()
|
||||
],
|
||||
jobs = 0, # execute in parallel
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
@ -1,4 +1,5 @@
|
||||
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "string_flag")
|
||||
load("//bazel/oci:pin.bzl", "stamp_tags")
|
||||
|
||||
bool_flag(
|
||||
# tpm_simulator is used to decide if the TPM simulator should be enabled
|
||||
@ -44,3 +45,10 @@ config_setting(
|
||||
flag_values = {":select_never": "True"},
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
stamp_tags(
|
||||
# generates a container image version tag based on the version stamp
|
||||
name = "tag",
|
||||
repotags = [""""v"+($stamp.STABLE_STAMP_VERSION // "0.0.0")"""],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
16
bazel/toolchains/container_images.bzl
Normal file
16
bazel/toolchains/container_images.bzl
Normal file
@ -0,0 +1,16 @@
|
||||
"""
|
||||
This file contains external container images used by the project.
|
||||
"""
|
||||
|
||||
load("@rules_oci//oci:pull.bzl", "oci_pull")
|
||||
|
||||
def containter_image_deps():
|
||||
oci_pull(
|
||||
name = "distroless_static",
|
||||
digest = "sha256:c3c3d0230d487c0ad3a0d87ad03ee02ea2ff0b3dcce91ca06a1019e07de05f12",
|
||||
image = "gcr.io/distroless/static",
|
||||
platforms = [
|
||||
"linux/amd64",
|
||||
"linux/arm64",
|
||||
],
|
||||
)
|
Loading…
Reference in New Issue
Block a user