Skip to content

Commit

Permalink
reimplement image aliases (#28)
Browse files Browse the repository at this point in the history
* wip

* update tests

* wip

* reimplement image aliases

* update aspect_bazel_lib
  • Loading branch information
apesternikov authored Apr 23, 2024
1 parent 16bd84e commit 29dc880
Show file tree
Hide file tree
Showing 18 changed files with 153 additions and 35 deletions.
2 changes: 1 addition & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module(
version = "0.50.0",
)

bazel_dep(name = "aspect_bazel_lib", version = "2.4.1")
bazel_dep(name = "aspect_bazel_lib", version = "2.7.1")
bazel_dep(name = "bazel_skylib", version = "1.5.0")
bazel_dep(name = "platforms", version = "0.0.8")
bazel_dep(name = "rules_oci", version = "1.7.2")
Expand Down
2 changes: 1 addition & 1 deletion MODULE.bazel.lock

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

6 changes: 3 additions & 3 deletions gitops/deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ def rules_gitops_dependencies():
maybe(
http_archive,
name = "aspect_bazel_lib",
sha256 = "979667bb7276ee8fcf2c114c9be9932b9a3052a64a647e0dcaacfb9c0016f0a3",
strip_prefix = "bazel-lib-2.4.1",
url = "https://github.com/aspect-build/bazel-lib/releases/download/v2.4.1/bazel-lib-v2.4.1.tar.gz",
sha256 = "b554eb7942a5ab44c90077df6a0c76fc67c5874c9446a007e9ba68be82bd4796",
strip_prefix = "bazel-lib-2.7.1",
url = "https://github.com/aspect-build/bazel-lib/releases/download/v2.4.1/bazel-lib-v2.7.1.tar.gz",
)

maybe(
Expand Down
7 changes: 7 additions & 0 deletions gitops/provider.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,10 @@ GitopsArtifactsInfo = provider(
"deployment_branch": "Branch to merge manifests into and create a PR from.",
},
)

AliasInfo = provider(
"Alias for an image to be used in a manifest",
fields = {
"alias": "Alias for a target",
},
)
12 changes: 6 additions & 6 deletions gitops/testing/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ k8s_deploy(
cluster = "testcluster",
deployment_branch = "test1",
gitops = 1,
images = [
"//skylib/kustomize/tests:image",
],
images = {
"testimage": "//skylib/kustomize/tests:image",
},
manifests = [
":deployment_legacy.yaml",
],
Expand Down Expand Up @@ -98,9 +98,9 @@ k8s_deploy(
cluster = "testcluster",
deployment_branch = "test1",
gitops = 1,
images = [
":pushed_image",
],
images = {
"testimage": ":pushed_image",
},
manifests = [
":deployment_legacy.yaml",
],
Expand Down
2 changes: 1 addition & 1 deletion gitops/testing/deployment_legacy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ spec:
spec:
containers:
- name: myapp
image: //skylib/kustomize/tests:image
image: testimage

2 changes: 1 addition & 1 deletion gitops/testing/legacy_alias_expected.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ spec:
app: myapp
spec:
containers:
- image: docker.io/skylib/kustomize/tests/image@sha256:1fa852d8eaf0f0a491713fb8c62c13ab8d25e2d6b32f024e49513f12a2e57b7a
- image: docker.io/skylib/kustomize/tests/image@sha256:1abae145a9069d0f4fdf9a0527ff5aec503ec02c3df783e25172895745dd2172
name: myapp
2 changes: 1 addition & 1 deletion gitops/testing/legacy_label_expected.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ spec:
app: myapp
spec:
containers:
- image: docker.io/skylib/kustomize/tests/image@sha256:1fa852d8eaf0f0a491713fb8c62c13ab8d25e2d6b32f024e49513f12a2e57b7a
- image: docker.io/skylib/kustomize/tests/image@sha256:1abae145a9069d0f4fdf9a0527ff5aec503ec02c3df783e25172895745dd2172
name: myapp
2 changes: 1 addition & 1 deletion gitops/testing/legacy_renamed_alias_expected.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ spec:
app: myapp
spec:
containers:
- image: gcr.io/repo/imagethere@sha256:1fa852d8eaf0f0a491713fb8c62c13ab8d25e2d6b32f024e49513f12a2e57b7a
- image: gcr.io/repo/imagethere@sha256:1abae145a9069d0f4fdf9a0527ff5aec503ec02c3df783e25172895745dd2172
name: myapp
4 changes: 2 additions & 2 deletions push_oci/tests/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
load("@rules_oci//oci:defs.bzl", "oci_image")
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load("@aspect_bazel_lib//lib:tar.bzl", "tar")
load("//push_oci:push_oci.bzl", "push_oci")

pkg_tar(
tar(
name = "image_tar",
srcs = [":container_content.txt"],
)
Expand Down
29 changes: 25 additions & 4 deletions skylib/k8s.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
load("//gitops:provider.bzl", "GitopsArtifactsInfo")
load("//push_oci:push_oci.bzl", "push_oci")
load("//skylib:runfile.bzl", "get_runfile_path")
load("//skylib:push_alias.bzl", "pushed_image_alias")
load(
"//skylib/kustomize:kustomize.bzl",
"imagePushStatements",
Expand Down Expand Up @@ -67,7 +68,7 @@ show = rule(
def _image_pushes(name_suffix, images, image_registry, image_repository, image_digest_tag):
image_pushes = []

def process_image(image_label):
def process_image(image_label, image_alias = None):
rule_name_parts = [image_label, image_registry, image_repository]
rule_name_parts = [p for p in rule_name_parts if p]
rule_name = "_".join(rule_name_parts)
Expand All @@ -80,9 +81,31 @@ def _image_pushes(name_suffix, images, image_registry, image_repository, image_d
image_digest_tag = image_digest_tag,
registry = image_registry,
repository = image_repository,
visibility = ["//visibility:public"],
)
return rule_name + name_suffix
if not image_alias:
return rule_name + name_suffix

#
if not native.existing_rule(rule_name + "_alias_" + name_suffix):
pushed_image_alias(
name = rule_name + "_alias_" + name_suffix,
alias = image_alias,
pushed_image = rule_name + name_suffix,
visibility = ["//visibility:public"],
)
return rule_name + "_alias_" + name_suffix

if type(images) == "dict":
for image_alias in images:
image = images[image_alias]
push = process_image(image, image_alias)
image_pushes.append(push)
else:
for image in images:
push = process_image(image)
image_pushes.append(push)
return image_pushes
for image in images:
image_push = process_image(image)
image_pushes.append(image_push)
Expand Down Expand Up @@ -125,8 +148,6 @@ def k8s_deploy(
""" k8s_deploy
"""

if type(images) == "dict":
fail("image_pushes: dict type is deprecated. Use list instead.")
if not manifests:
manifests = native.glob(["*.yaml", "*.yaml.tpl"])
if prefix_suffix_app_labels:
Expand Down
14 changes: 4 additions & 10 deletions skylib/kustomize/kustomize.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# OF ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.

load("//gitops:provider.bzl", "GitopsArtifactsInfo", "GitopsPushInfo")
load("//gitops:provider.bzl", "AliasInfo", "GitopsArtifactsInfo", "GitopsPushInfo")
load("//skylib:runfile.bzl", "get_runfile_path")
load("//skylib:stamp.bzl", "stamp")

Expand Down Expand Up @@ -71,15 +71,6 @@ set -euo pipefail
{kustomize} build --load-restrictor LoadRestrictionsNone --reorder legacy {kustomize_dir} {template_part} {resolver_part} >{out}
"""

def _no_at_str(label):
"""Strips any leading '@'s for labels in the main repo."""
s = str(label)
if s.startswith("@@//"):
return s[2:]
if s.startswith("@//"):
return s[1:]
return s

def _kustomize_impl(ctx):
kustomize_bin = ctx.toolchains["@rules_gitops//gitops:kustomize_toolchain_type"].kustomizeinfo.bin
kustomization_yaml_file = ctx.actions.declare_file(ctx.attr.name + "/kustomization.yaml")
Expand Down Expand Up @@ -206,6 +197,9 @@ def _kustomize_impl(ctx):
resolver_part += " --image {}={}@$(cat {})".format(label_str, regrepo, kpi.digestfile.path)
tmpfiles.append(kpi.digestfile)
transitive_runfiles.append(img[DefaultInfo].default_runfiles)
if AliasInfo in img:
alias = img[AliasInfo].alias
resolver_part += " --image {}={}@$(cat {})".format(alias, regrepo, kpi.digestfile.path)

template_part = ""
if ctx.attr.substitutions or ctx.attr.deps:
Expand Down
23 changes: 21 additions & 2 deletions skylib/kustomize/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@

load("@bazel_tools//tools/build_rules:test_rules.bzl", "file_test")
load("@rules_oci//oci:defs.bzl", "oci_image")
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load("//push_oci:push_oci.bzl", "push_oci_rule")
load("//skylib/kustomize:kustomize.bzl", "gitops", "kubectl", "kustomize", "push_all")
load("//skylib:push_alias.bzl", "pushed_image_alias")
load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_files")
load("@aspect_bazel_lib//lib:tar.bzl", "tar")

# to generate new test data if needed:
# bazel run //skylib/kustomize:set_namespace newnamespace-1 <test.yaml >test_expected.yaml
Expand Down Expand Up @@ -73,7 +74,7 @@ kustomize(
namespace = "",
)

pkg_tar(
tar(
name = "image_tar",
srcs = [":container_content.txt"],
)
Expand All @@ -93,6 +94,12 @@ push_oci_rule(
visibility = ["//visibility:public"],
)

pushed_image_alias(
name = "image_alias",
alias = "testimage",
pushed_image = ":image_push",
)

kustomize(
name = "image_test",
images = [
Expand All @@ -106,6 +113,17 @@ kustomize(
namespace = "",
)

kustomize(
name = "alias_test",
images = [
":image_alias",
],
manifests = [
"deployment_with_alias.yaml",
],
namespace = "",
)

kustomize(
name = "configmap_test",
configmaps_srcs = glob(["configmaps/**/*"]),
Expand Down Expand Up @@ -255,6 +273,7 @@ write_source_files(
"expected_raw_test.yaml": ":raw_test",
"expected_raw2_test.yaml": ":raw2_test",
"expected_image_resolved_test.yaml": ":image_test",
"expected_alias_test.yaml": ":alias_test",
"expected_configmap_test.yaml": ":configmap_test",
"expected_secret_test.yaml": ":secret_test",
"expected_patch_test.yaml": ":patch",
Expand Down
16 changes: 16 additions & 0 deletions skylib/kustomize/tests/deployment_with_alias.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: //skylib/kustomize/tests:image
16 changes: 16 additions & 0 deletions skylib/kustomize/tests/expected_alias_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- image: gcr.io/bs-dev/test_image@sha256:1abae145a9069d0f4fdf9a0527ff5aec503ec02c3df783e25172895745dd2172
name: myapp
2 changes: 1 addition & 1 deletion skylib/kustomize/tests/expected_image_resolved_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ spec:
app: myapp
spec:
containers:
- image: gcr.io/bs-dev/test_image@sha256:1fa852d8eaf0f0a491713fb8c62c13ab8d25e2d6b32f024e49513f12a2e57b7a
- image: gcr.io/bs-dev/test_image@sha256:1abae145a9069d0f4fdf9a0527ff5aec503ec02c3df783e25172895745dd2172
name: myapp
2 changes: 1 addition & 1 deletion skylib/kustomize/tests/expected_patch_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ spec:
app: myapp
spec:
containers:
- image: gcr.io/bs-dev/test_image@sha256:1fa852d8eaf0f0a491713fb8c62c13ab8d25e2d6b32f024e49513f12a2e57b7a
- image: gcr.io/bs-dev/test_image@sha256:1abae145a9069d0f4fdf9a0527ff5aec503ec02c3df783e25172895745dd2172
name: myapp
resources:
limits:
Expand Down
45 changes: 45 additions & 0 deletions skylib/push_alias.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""
Implementation of the wrapper that would add an alias to a pushed image.
Provides a legacy interface for using short aliases for images instead of the full bazel target path.
Using aliases in new code is not recommended, as it creates a unnecessary level of indirection.
"""

load("//gitops:provider.bzl", "AliasInfo", "GitopsPushInfo")

def _push_alias_impl(ctx):
default_info = ctx.attr.pushed_image[DefaultInfo]
files = default_info.files
new_executable = None
original_executable = default_info.files_to_run.executable
runfiles = default_info.default_runfiles

new_executable = ctx.outputs.executable

ctx.actions.symlink(
output = new_executable,
target_file = original_executable,
is_executable = True,
)
files = depset(direct = [new_executable], transitive = [files])
runfiles = runfiles.merge(ctx.runfiles([new_executable]))

return [
DefaultInfo(
files = files,
runfiles = runfiles,
executable = new_executable,
),
ctx.attr.pushed_image[GitopsPushInfo],
AliasInfo(
alias = ctx.attr.alias,
),
]

pushed_image_alias = rule(
implementation = _push_alias_impl,
attrs = {
"pushed_image": attr.label(mandatory = True, providers = (GitopsPushInfo,), doc = "The pushed image like k8s_image_push"),
"alias": attr.string(mandatory = True, doc = "The alias to be added to the pushed image"),
},
executable = True,
)

0 comments on commit 29dc880

Please sign in to comment.