From 79cdc2cda6e326142c3fc8282d7f6f9d84e8e120 Mon Sep 17 00:00:00 2001 From: Ethan Mosbaugh Date: Mon, 29 Jul 2024 06:42:37 -0700 Subject: [PATCH] feat: remove kube-rbac-proxy image (#863) * feat: remove kube-rbac-proxy image * f * f * f * f * f --- .github/workflows/ci.yaml | 14 -- .github/workflows/image-deps-updater.yaml | 1 + Makefile | 16 -- cmd/buildtools/addon.go | 4 +- cmd/buildtools/embeddedclusteroperator.go | 191 ++++++++++++++---- cmd/buildtools/update.go | 1 + .../embeddedclusteroperator.go | 31 ++- .../static/metadata.yaml | 7 +- .../static/values.tpl.yaml | 3 +- .../static/values.yaml | 5 +- pkg/release/addon.go | 20 +- 11 files changed, 193 insertions(+), 100 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 878380737..5528ecfea 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -71,18 +71,6 @@ jobs: make build-and-push-local-artifact-mirror-image VERSION="${SHORT_SHA}-previous-k0s" make build-and-push-local-artifact-mirror-image VERSION="${SHORT_SHA}-upgrade" - - name: Build and push utils image - run: | - export SHORT_SHA=dev-${GITHUB_SHA::7} - export EMBEDDED_OPERATOR_UTILS_IMAGE=replicated/embedded-cluster-utils-staging - export REGISTRY=docker.io - export USERNAME=${{ secrets.DOCKERHUB_USER }} - export PASSWORD=${{ secrets.DOCKERHUB_PASSWORD }} - make apko - make build-and-push-utils-image VERSION="${SHORT_SHA}" - make build-and-push-utils-image VERSION="${SHORT_SHA}-previous-k0s" - make build-and-push-utils-image VERSION="${SHORT_SHA}-upgrade" - buildtools: name: Build Buildtools runs-on: ubuntu-latest @@ -119,7 +107,6 @@ jobs: run: | export SHORT_SHA=dev-${GITHUB_SHA::7} export LOCAL_ARTIFACT_MIRROR_IMAGE=replicated/embedded-cluster-local-artifact-mirror-staging - export EMBEDDED_OPERATOR_UTILS_IMAGE=replicated/embedded-cluster-utils-staging make -B embedded-cluster-linux-amd64 K0S_VERSION=$(make print-PREVIOUS_K0S_VERSION) K0S_BINARY_SOURCE_OVERRIDE=$(make print-PREVIOUS_K0S_BINARY_SOURCE_OVERRIDE) VERSION="${SHORT_SHA}-previous-k0s" tar -C output/bin -czvf embedded-cluster-linux-amd64-previous-k0s.tgz embedded-cluster ./output/bin/embedded-cluster version metadata > metadata-previous-k0s.json @@ -150,7 +137,6 @@ jobs: run: | export SHORT_SHA=dev-${GITHUB_SHA::7} export LOCAL_ARTIFACT_MIRROR_IMAGE=replicated/embedded-cluster-local-artifact-mirror-staging - export EMBEDDED_OPERATOR_UTILS_IMAGE=replicated/embedded-cluster-utils-staging echo "# channel release object" > e2e/kots-release-install/release.yaml echo 'channelID: "2cHXb1RCttzpR0xvnNWyaZCgDBP"' >> e2e/kots-release-install/release.yaml echo 'channelSlug: "ci"' >> e2e/kots-release-install/release.yaml diff --git a/.github/workflows/image-deps-updater.yaml b/.github/workflows/image-deps-updater.yaml index 80cda5dca..b588c8a47 100644 --- a/.github/workflows/image-deps-updater.yaml +++ b/.github/workflows/image-deps-updater.yaml @@ -56,6 +56,7 @@ jobs: - k0s - openebs - velero + - embeddedclusteroperator - seaweedfs steps: - name: Checkout diff --git a/Makefile b/Makefile index e60f8a779..dfda3d52a 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,6 @@ ADMIN_CONSOLE_MIGRATIONS_IMAGE_OVERRIDE = ADMIN_CONSOLE_KURL_PROXY_IMAGE_OVERRIDE = EMBEDDED_OPERATOR_IMAGE_OVERRIDE = EMBEDDED_OPERATOR_BINARY_URL_OVERRIDE = -EMBEDDED_OPERATOR_UTILS_IMAGE ?= replicated/embedded-cluster-utils -EMBEDDED_OPERATOR_UTILS_IMAGE_VERSION ?= $(subst +,-,$(VERSION)) -EMBEDDED_OPERATOR_UTILS_IMAGE_LOCATION = proxy.replicated.com/anonymous/$(EMBEDDED_OPERATOR_UTILS_IMAGE):$(EMBEDDED_OPERATOR_UTILS_IMAGE_VERSION) KUBECTL_VERSION = v1.30.1 K0S_VERSION = v1.29.6+k0s.0 K0S_GO_VERSION = v1.29.6+k0s.0 @@ -36,7 +33,6 @@ LD_FLAGS = \ -X github.com/replicatedhq/embedded-cluster/pkg/addons/adminconsole.AdminConsoleImageOverride=$(ADMIN_CONSOLE_IMAGE_OVERRIDE) \ -X github.com/replicatedhq/embedded-cluster/pkg/addons/adminconsole.AdminConsoleMigrationsImageOverride=$(ADMIN_CONSOLE_MIGRATIONS_IMAGE_OVERRIDE) \ -X github.com/replicatedhq/embedded-cluster/pkg/addons/adminconsole.AdminConsoleKurlProxyImageOverride=$(ADMIN_CONSOLE_KURL_PROXY_IMAGE_OVERRIDE) \ - -X github.com/replicatedhq/embedded-cluster/pkg/addons/embeddedclusteroperator.UtilsImage=$(EMBEDDED_OPERATOR_UTILS_IMAGE_LOCATION) \ -X github.com/replicatedhq/embedded-cluster/pkg/addons/embeddedclusteroperator.EmbeddedOperatorImageOverride=$(EMBEDDED_OPERATOR_IMAGE_OVERRIDE) export PATH := $(shell pwd)/bin:$(PATH) @@ -187,18 +183,6 @@ scan: --ignore-unfixed \ ./ -.PHONY: build-utils-image -build-utils-image: export IMAGE ?= $(EMBEDDED_OPERATOR_UTILS_IMAGE):$(EMBEDDED_OPERATOR_UTILS_IMAGE_VERSION) -build-utils-image: export PACKAGE_VERSION ?= $(EMBEDDED_OPERATOR_UTILS_IMAGE_VERSION) -build-utils-image: export APKO_CONFIG = deploy/images/utils/apko.tmpl.yaml -build-utils-image: apko-build - -.PHONY: build-and-push-utils-image -build-and-push-utils-image: export IMAGE ?= $(EMBEDDED_OPERATOR_UTILS_IMAGE):$(EMBEDDED_OPERATOR_UTILS_IMAGE_VERSION) -build-and-push-utils-image: export PACKAGE_VERSION ?= $(EMBEDDED_OPERATOR_UTILS_IMAGE_VERSION) -build-and-push-utils-image: export APKO_CONFIG = deploy/images/utils/apko.tmpl.yaml -build-and-push-utils-image: apko-login apko-build-and-publish - .PHONY: build-local-artifact-mirror-image build-local-artifact-mirror-image: export IMAGE ?= $(LOCAL_ARTIFACT_MIRROR_IMAGE):$(LOCAL_ARTIFACT_MIRROR_IMAGE_VERSION) build-local-artifact-mirror-image: export PACKAGE_VERSION ?= $(LOCAL_ARTIFACT_MIRROR_IMAGE_VERSION) diff --git a/cmd/buildtools/addon.go b/cmd/buildtools/addon.go index 83cc2a124..ca5f8c68c 100644 --- a/cmd/buildtools/addon.go +++ b/cmd/buildtools/addon.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "strings" "github.com/Masterminds/semver/v3" ) @@ -10,6 +11,7 @@ type addonComponent struct { getWolfiPackageName func(opts addonComponentOptions) string getWolfiPackageVersionComparison func(opts addonComponentOptions) string upstreamVersionInputOverride string + useUpstreamImage bool } type addonComponentOptions struct { @@ -21,7 +23,7 @@ type addonComponentOptions struct { func (c *addonComponent) getPackageNameAndVersion(wolfiAPKIndex []byte, upstreamVersion string) (string, string, error) { packageName := "" if c.getWolfiPackageName == nil { - return packageName, upstreamVersion, nil + return packageName, strings.TrimPrefix(upstreamVersion, "v"), nil } k0sVersion, err := getK0sVersion() diff --git a/cmd/buildtools/embeddedclusteroperator.go b/cmd/buildtools/embeddedclusteroperator.go index f5f38502d..18a9b8f15 100644 --- a/cmd/buildtools/embeddedclusteroperator.go +++ b/cmd/buildtools/embeddedclusteroperator.go @@ -1,7 +1,10 @@ package main import ( + "context" "fmt" + "os" + "os/exec" "strings" "github.com/replicatedhq/embedded-cluster/pkg/addons/embeddedclusteroperator" @@ -10,58 +13,131 @@ import ( "github.com/urfave/cli/v2" ) +var operatorImageComponents = map[string]string{ + "docker.io/replicated/embedded-cluster-operator-image": "embedded-cluster-operator", + "docker.io/library/busybox": "utils", +} + +var operatorComponents = map[string]addonComponent{ + "embedded-cluster-operator": { + useUpstreamImage: true, + }, + "utils": {}, +} + var updateOperatorAddonCommand = &cli.Command{ Name: "embeddedclusteroperator", Usage: "Updates the Embedded Cluster Operator addon", UsageText: environmentUsageText, Action: func(c *cli.Context) error { - logrus.Infof("updating operator addon") - - logrus.Infof("getting embedded cluster operator release") - latest, err := GetGitHubRelease( - c.Context, "replicatedhq", "embedded-cluster-operator", - func(tag string) bool { - return !strings.Contains(tag, "build") - }, - ) - if err != nil { - return fmt.Errorf("failed to get embedded cluster operator release: %w", err) - } - latest = strings.TrimPrefix(latest, "v") - logrus.Infof("embedded cluster operator release found: %s", latest) + logrus.Infof("updating embedded cluster operator addon") - current := embeddedclusteroperator.Metadata - if current.Version == latest && !c.Bool("force") { - logrus.Infof("operator chart version is already up-to-date") - return nil + nextChartVersion := os.Getenv("INPUT_OPERATOR_CHART_VERSION") + if nextChartVersion != "" { + logrus.Infof("using input override from INPUT_OPERATOR_CHART_VERSION: %s", nextChartVersion) + } else { + logrus.Infof("fetching the latest embedded cluster operator release") + latest, err := GetGitHubRelease( + c.Context, "replicatedhq", "embedded-cluster-operator", + func(tag string) bool { + return !strings.Contains(tag, "build") + }, + ) + if err != nil { + return fmt.Errorf("failed to get embedded cluster operator release: %w", err) + } + nextChartVersion = strings.TrimPrefix(latest, "v") + logrus.Printf("latest embedded cluster operator release: %s", latest) } + nextChartVersion = strings.TrimPrefix(nextChartVersion, "v") upstream := "registry.replicated.com/library/embedded-cluster-operator" - newmeta := release.AddonMetadata{ - Version: latest, - Location: fmt.Sprintf("oci://proxy.replicated.com/anonymous/%s", upstream), - Images: make(map[string]string), - } + withproto := fmt.Sprintf("oci://proxy.replicated.com/anonymous/%s", upstream) - values, err := release.GetValuesWithOriginalImages("embeddedclusteroperator") + logrus.Infof("updating embedded cluster operator images") + + err := updateOperatorAddonImages(c.Context, withproto, nextChartVersion) if err != nil { - return fmt.Errorf("unable to get openebs values: %v", err) + return fmt.Errorf("failed to update embedded cluster operator images: %w", err) } - logrus.Infof("extracting images from chart") - withproto := fmt.Sprintf("oci://%s", upstream) - images, err := GetImagesFromOCIChart(withproto, "embeddedclusteroperator", latest, values) + logrus.Infof("successfully updated embedded cluster operator addon") + + return nil + }, +} + +var updateOperatorImagesCommand = &cli.Command{ + Name: "embeddedclusteroperator", + Usage: "Updates the embedded cluster operator images", + UsageText: environmentUsageText, + Action: func(c *cli.Context) error { + logrus.Infof("updating embedded cluster operator images") + + current := embeddedclusteroperator.Metadata + + err := updateOperatorAddonImages(c.Context, current.Location, current.Version) if err != nil { - return fmt.Errorf("failed to get images from embedded cluster operator chart: %w", err) + return fmt.Errorf("failed to update embedded cluster operator images: %w", err) + } + + logrus.Infof("successfully updated embedded cluster operator images") + + return nil + }, +} + +func updateOperatorAddonImages(ctx context.Context, chartURL string, chartVersion string) error { + newmeta := release.AddonMetadata{ + Version: chartVersion, + Location: chartURL, + Images: make(map[string]string), + } + + logrus.Infof("fetching wolfi apk index") + wolfiAPKIndex, err := GetWolfiAPKIndex() + if err != nil { + return fmt.Errorf("failed to get APK index: %w", err) + } + + values, err := release.GetValuesWithOriginalImages("embeddedclusteroperator") + if err != nil { + return fmt.Errorf("failed to get embedded cluster operator values: %v", err) + } + + logrus.Infof("extracting images from chart version %s", chartVersion) + images, err := GetImagesFromOCIChart(chartURL, "embeddedclusteroperator", chartVersion, values) + if err != nil { + return fmt.Errorf("failed to get images from embedded cluster operator chart: %w", err) + } + + // make sure we include the operator util image as it does not show up when rendering the helm + // chart. + images = append(images, "docker.io/library/busybox:latest") + + if err := ApkoLogin(); err != nil { + return fmt.Errorf("failed to apko login: %w", err) + } + + for _, image := range images { + logrus.Infof("updating image %s", image) + + upstreamVersion := TagFromImage(image) + imageNoTag := RemoveTagFromImage(image) + + componentName, ok := operatorImageComponents[imageNoTag] + if !ok { + return fmt.Errorf("no component found for image %s", imageNoTag) } - // make sure we include the operator util image as it does not show up - // when rendering the helm chart. - images = append(images, "docker.io/library/busybox:1.36") + component, ok := operatorComponents[componentName] + if !ok { + return fmt.Errorf("no component found for component name %s", componentName) + } - logrus.Infof("fetching digest for images") - for _, image := range images { - sha, err := GetImageDigest(c.Context, image) + if component.useUpstreamImage { + logrus.Infof("fetching digest for image %s", image) + sha, err := GetImageDigest(ctx, image) if err != nil { return fmt.Errorf("failed to get image %s digest: %w", image, err) } @@ -69,13 +145,46 @@ var updateOperatorAddonCommand = &cli.Command{ tag := TagFromImage(image) image = RemoveTagFromImage(image) newmeta.Images[FamiliarImageName(image)] = fmt.Sprintf("%s@%s", tag, sha) + continue } - logrus.Infof("saving addon manifest") - newmeta.ReplaceImages = true - if err := newmeta.Save("embeddedclusteroperator"); err != nil { - return fmt.Errorf("failed to save embedded cluster operator metadata: %w", err) + if component.upstreamVersionInputOverride != "" { + v := os.Getenv(component.upstreamVersionInputOverride) + if v != "" { + logrus.Infof("using input override from %s: %s", component.upstreamVersionInputOverride, v) + upstreamVersion = v + } } - return nil - }, + + packageName, packageVersion, err := component.getPackageNameAndVersion(wolfiAPKIndex, upstreamVersion) + if err != nil { + return fmt.Errorf("failed to get package name and version for %s: %w", componentName, err) + } + + logrus.Infof("building and publishing %s, %s=%s", componentName, packageName, packageVersion) + + if err := ApkoBuildAndPublish(componentName, packageName, packageVersion, upstreamVersion); err != nil { + return fmt.Errorf("failed to apko build and publish for %s: %w", componentName, err) + } + + digest, err := GetDigestFromBuildFile() + if err != nil { + return fmt.Errorf("failed to get digest from build file: %w", err) + } + + newmeta.Images[componentName] = fmt.Sprintf("%s@%s", packageVersion, digest) + } + + logrus.Infof("saving addon manifest") + newmeta.ReplaceImages = true + if err := newmeta.Save("embeddedclusteroperator"); err != nil { + return fmt.Errorf("failed to save metadata: %w", err) + } + + return nil +} + +func getGitCommitHash() (string, error) { + out, err := exec.Command("git", "rev-parse", "HEAD").Output() + return string(out), err } diff --git a/cmd/buildtools/update.go b/cmd/buildtools/update.go index c747a5f73..21fc26807 100644 --- a/cmd/buildtools/update.go +++ b/cmd/buildtools/update.go @@ -39,6 +39,7 @@ var updateImagesCommand = &cli.Command{ updateK0sImagesCommand, updateOpenEBSImagesCommand, updateVeleroImagesCommand, + updateOperatorImagesCommand, updateSeaweedFSImagesCommand, }, } diff --git a/pkg/addons/embeddedclusteroperator/embeddedclusteroperator.go b/pkg/addons/embeddedclusteroperator/embeddedclusteroperator.go index 8b8ac5678..0994d3403 100644 --- a/pkg/addons/embeddedclusteroperator/embeddedclusteroperator.go +++ b/pkg/addons/embeddedclusteroperator/embeddedclusteroperator.go @@ -13,13 +13,6 @@ import ( "github.com/gosimple/slug" embeddedclusterv1beta1 "github.com/replicatedhq/embedded-cluster-kinds/apis/v1beta1" "github.com/replicatedhq/embedded-cluster-kinds/types" - kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1" - "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" - "gopkg.in/yaml.v2" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/replicatedhq/embedded-cluster/pkg/addons/adminconsole" "github.com/replicatedhq/embedded-cluster/pkg/defaults" "github.com/replicatedhq/embedded-cluster/pkg/helpers" @@ -27,6 +20,12 @@ import ( "github.com/replicatedhq/embedded-cluster/pkg/metrics" "github.com/replicatedhq/embedded-cluster/pkg/release" "github.com/replicatedhq/embedded-cluster/pkg/spinner" + kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1" + "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" + "gopkg.in/yaml.v2" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" ) const releaseName = "embedded-cluster-operator" @@ -44,7 +43,6 @@ var ( // Overwritten by -ldflags in Makefile var ( - UtilsImage = "busybox:latest" EmbeddedOperatorImageOverride = "" ) @@ -73,10 +71,6 @@ func init() { "tag": parts[1], } } - - if UtilsImage != "" { - helmValues["utilsImage"] = UtilsImage - } } // EmbeddedClusterOperator manages the installation of the embedded cluster operator @@ -152,17 +146,20 @@ func (e *EmbeddedClusterOperator) GenerateHelmConfig(onlyDefaults bool) ([]embed func (a *EmbeddedClusterOperator) GetImages() []string { var images []string for image, tag := range Metadata.Images { - images = append(images, fmt.Sprintf("proxy.replicated.com/anonymous/%s:%s", image, tag)) + // we use replicated/embedded-cluster-operator-image from upstream + if image == "replicated/embedded-cluster-operator-image" { + images = append(images, fmt.Sprintf("proxy.replicated.com/anonymous/%s:%s", image, tag)) + } else { + images = append(images, fmt.Sprintf("%s:%s", helpers.AddonImageFromComponentName(image), tag)) + } } return images } func (e *EmbeddedClusterOperator) GetAdditionalImages() []string { var images []string - if UtilsImage != "" { - images = append(images, UtilsImage) - } else if tag, ok := Metadata.Images["busybox"]; ok { - images = append(images, fmt.Sprintf("proxy.replicated.com/anonymous/busybox:%s", tag)) + if tag, ok := Metadata.Images["utils"]; ok { + images = append(images, fmt.Sprintf("%s:%s", helpers.AddonImageFromComponentName("utils"), tag)) } return images } diff --git a/pkg/addons/embeddedclusteroperator/static/metadata.yaml b/pkg/addons/embeddedclusteroperator/static/metadata.yaml index df44928d3..c4590ccb3 100644 --- a/pkg/addons/embeddedclusteroperator/static/metadata.yaml +++ b/pkg/addons/embeddedclusteroperator/static/metadata.yaml @@ -5,9 +5,8 @@ # $ make buildtools # $ output/bin/buildtools update addon # -version: 0.41.1 +version: 0.42.0-build.1 location: oci://proxy.replicated.com/anonymous/registry.replicated.com/library/embedded-cluster-operator images: - busybox: 1.36@sha256:50aa4698fa6262977cff89181b2664b99d8a56dbca847bf62f2ef04854597cf8 - replicated/embedded-cluster-operator-image: 0.41.1@sha256:9d7ee55329f05d7d69a949ee83c9fa226f5e32497befbe3354346c24ba0eab78 - gcr.io/kubebuilder/kube-rbac-proxy: v0.13.1@sha256:18f12fc3a0085bbc303cfbd2ad1151127c1c959c4641e36027547b6b66eb4c92 + replicated/embedded-cluster-operator-image: 0.42.0-build.1@sha256:a86e654653c3d558e32658f9165c1bd0fcecc992bd1827370c67d59e0a8da91f + utils: latest@sha256:f61e4346397e56553be0e1d897b6e162e41e90bc766a42a2beee0c2bca0c3bdc diff --git a/pkg/addons/embeddedclusteroperator/static/values.tpl.yaml b/pkg/addons/embeddedclusteroperator/static/values.tpl.yaml index 9a6d3356d..e24c6b6bb 100644 --- a/pkg/addons/embeddedclusteroperator/static/values.tpl.yaml +++ b/pkg/addons/embeddedclusteroperator/static/values.tpl.yaml @@ -6,6 +6,5 @@ global: image: repository: proxy.replicated.com/anonymous/replicated/embedded-cluster-operator-image tag: {{ index .Images "replicated/embedded-cluster-operator-image" }} -kubeProxyImage: 'proxy.replicated.com/anonymous/gcr.io/kubebuilder/kube-rbac-proxy:{{ index .Images "gcr.io/kubebuilder/kube-rbac-proxy" }}' -utilsImage: 'proxy.replicated.com/anonymous/busybox:{{ index .Images "busybox" }}' +utilsImage: '{{ index .Images "utils" | FormatImage "proxy.replicated.com/anonymous/replicated/ec-utils" }}' {{- end }} diff --git a/pkg/addons/embeddedclusteroperator/static/values.yaml b/pkg/addons/embeddedclusteroperator/static/values.yaml index c48d64618..cd81fcf66 100644 --- a/pkg/addons/embeddedclusteroperator/static/values.yaml +++ b/pkg/addons/embeddedclusteroperator/static/values.yaml @@ -17,6 +17,5 @@ global: replicated.com/disaster-recovery-chart: embedded-cluster-operator image: repository: proxy.replicated.com/anonymous/replicated/embedded-cluster-operator-image - tag: 0.41.1@sha256:9d7ee55329f05d7d69a949ee83c9fa226f5e32497befbe3354346c24ba0eab78 -kubeProxyImage: 'proxy.replicated.com/anonymous/gcr.io/kubebuilder/kube-rbac-proxy:v0.13.1@sha256:18f12fc3a0085bbc303cfbd2ad1151127c1c959c4641e36027547b6b66eb4c92' -utilsImage: 'proxy.replicated.com/anonymous/busybox:1.36@sha256:50aa4698fa6262977cff89181b2664b99d8a56dbca847bf62f2ef04854597cf8' + tag: 0.42.0-build.1@sha256:a86e654653c3d558e32658f9165c1bd0fcecc992bd1827370c67d59e0a8da91f +utilsImage: 'proxy.replicated.com/anonymous/replicated/ec-utils@sha256:f61e4346397e56553be0e1d897b6e162e41e90bc766a42a2beee0c2bca0c3bdc' diff --git a/pkg/release/addon.go b/pkg/release/addon.go index eb6a5bacc..b03b80279 100644 --- a/pkg/release/addon.go +++ b/pkg/release/addon.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "text/template" "gopkg.in/yaml.v3" @@ -40,13 +41,28 @@ type AddonMetadata struct { ReplaceImages bool `yaml:"-"` } +var funcMap = template.FuncMap{ + "FormatImage": func(repo, tag string) string { + switch { + case tag == "": + return repo + // The image appears in containerd images without the "latest" tag and causes an + // ImagePullBackOff error + case strings.HasPrefix(tag, "latest@"): + return fmt.Sprintf("%s@%s", repo, strings.TrimPrefix(tag, "latest@")) + default: + return fmt.Sprintf("%s:%s", repo, tag) + } + }, +} + func GetValuesWithOriginalImages(addon string) (map[string]interface{}, error) { tplpath := filepath.Join("pkg", "addons", addon, "static", "values.tpl.yaml") tpl, err := os.ReadFile(tplpath) if err != nil { return nil, fmt.Errorf("failed to read values template: %w", err) } - tmpl, err := template.New(fmt.Sprintf("builder-%s", addon)).Parse(string(tpl)) + tmpl, err := template.New(fmt.Sprintf("builder-%s", addon)).Funcs(funcMap).Parse(string(tpl)) if err != nil { return nil, fmt.Errorf("failed to parse values template: %w", err) } @@ -82,7 +98,7 @@ func (a *AddonMetadata) RenderValues(addon, tplfile, dest string) error { return fmt.Errorf("failed to read values template: %w", err) } - tmpl, err := template.New(addon).Parse(string(tpl)) + tmpl, err := template.New(addon).Funcs(funcMap).Parse(string(tpl)) if err != nil { return fmt.Errorf("failed to parse values template: %w", err) }