diff --git a/argocd-operator/api/v1beta1/argocd_types.go b/argocd-operator/api/v1beta1/argocd_types.go index 99398fb0db2..adaca86aca7 100644 --- a/argocd-operator/api/v1beta1/argocd_types.go +++ b/argocd-operator/api/v1beta1/argocd_types.go @@ -367,6 +367,9 @@ type ArgoCDImageUpdaterSpec struct { // Enabled defines whether argocd image updater controller should be deployed or not Enabled bool `json:"enabled"` + // Image is the image to be used for the Argo CD Image Updater + Image string `json:"image,omitempty"` + // Env let you specify environment variables for ImageUpdater pods Env []corev1.EnvVar `json:"env,omitempty"` diff --git a/argocd-operator/bundle/manifests/argoproj.io_argocds.yaml b/argocd-operator/bundle/manifests/argoproj.io_argocds.yaml index e0eb9145916..13ea2f0379b 100644 --- a/argocd-operator/bundle/manifests/argoproj.io_argocds.yaml +++ b/argocd-operator/bundle/manifests/argoproj.io_argocds.yaml @@ -22028,6 +22028,10 @@ spec: - name type: object type: array + image: + description: Image is the image to be used for the Argo CD Image + Updater + type: string resources: description: Resources defines the Compute Resources required by the container for Argo CD Image Updater. diff --git a/argocd-operator/config/crd/bases/argoproj.io_argocds.yaml b/argocd-operator/config/crd/bases/argoproj.io_argocds.yaml index 05ecfdef384..6155238283d 100644 --- a/argocd-operator/config/crd/bases/argoproj.io_argocds.yaml +++ b/argocd-operator/config/crd/bases/argoproj.io_argocds.yaml @@ -22017,6 +22017,10 @@ spec: - name type: object type: array + image: + description: Image is the image to be used for the Argo CD Image + Updater + type: string resources: description: Resources defines the Compute Resources required by the container for Argo CD Image Updater. diff --git a/argocd-operator/controllers/argocd/image_updater.go b/argocd-operator/controllers/argocd/image_updater.go index b18acd1b5a9..391cbf42f0f 100644 --- a/argocd-operator/controllers/argocd/image_updater.go +++ b/argocd-operator/controllers/argocd/image_updater.go @@ -714,10 +714,6 @@ func (r *ReconcileArgoCD) reconcileImageUpdaterDeployment(cr *argoproj.ArgoCD, s }, } - image := os.Getenv(common.ArgoCDImageUpdaterImageEnvName) - if image == "" { - image = argoutil.CombineImageTag(DefaultImageUpdaterImage, DefaultImageUpdaterTag) - } args := []string{"run"} imageUpdaterTLSProfileArguments := BuildTLSArgsFromClusterTLSProfile(r.CentralTLSConfigProfile) args = append(args, imageUpdaterTLSProfileArguments...) @@ -725,7 +721,7 @@ func (r *ReconcileArgoCD) reconcileImageUpdaterDeployment(cr *argoproj.ArgoCD, s podSpec.Containers = []corev1.Container{{ Command: []string{"/manager"}, Args: args, - Image: image, + Image: selectImageUpdaterImage(cr), ImagePullPolicy: argoutil.GetImagePullPolicy(cr.Spec.ImagePullPolicy), Name: common.ArgoCDImageUpdaterControllerComponent, Env: imageUpdaterEnv, @@ -1124,3 +1120,17 @@ func getImageUpdaterResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { return resources } + +// selectImageUpdaterImage selects the image to be used for the ImageUpdater based on the following priority +// CR's .Spec.ImageUpdater.Image field -> ARGOCD_IMAGE_UPDATER_IMAGE env variable -> Default Image on argoproj-labs quay repository +func selectImageUpdaterImage(cr *argoproj.ArgoCD) string { + if cr.Spec.ImageUpdater.Image != "" { + return cr.Spec.ImageUpdater.Image + } + + if image := os.Getenv(common.ArgoCDImageUpdaterImageEnvName); image != "" { + return image + } + + return argoutil.CombineImageTag(DefaultImageUpdaterImage, DefaultImageUpdaterTag) +} diff --git a/argocd-operator/controllers/argocd/image_updater_test.go b/argocd-operator/controllers/argocd/image_updater_test.go index 4f37301f55f..5bf50c66c25 100644 --- a/argocd-operator/controllers/argocd/image_updater_test.go +++ b/argocd-operator/controllers/argocd/image_updater_test.go @@ -2,6 +2,7 @@ package argocd import ( "context" + "os" "strings" "testing" @@ -1461,3 +1462,75 @@ func TestReconcileImageUpdaterDeployment_TLSArgs(t *testing.T) { }) } } + +func TestSelectImageUpdaterImage(t *testing.T) { + tests := []struct { + name string + crImageOverride string // .Spec.ImageUpdater.Image + envImage string // ARGOCD_IMAGE_UPDATER_IMAGE env var + expectedImage string // expected result + envVarShouldExist bool // whether the env var should be set for this test + }{ + { + name: "CR Image takes priority over environment variable", + crImageOverride: "my-registry.io/custom-image-updater:custom-tag", + envImage: "env-registry.io/env-image-updater:env-tag", + expectedImage: "my-registry.io/custom-image-updater:custom-tag", + envVarShouldExist: true, + }, + { + name: "Environment variable is used when CR Image is empty", + crImageOverride: "", + envImage: "env-registry.io/env-image-updater:env-tag", + expectedImage: "env-registry.io/env-image-updater:env-tag", + envVarShouldExist: true, + }, + { + name: "Default image is used when both CR and env are empty", + crImageOverride: "", + envImage: "", + expectedImage: argoutil.CombineImageTag(DefaultImageUpdaterImage, DefaultImageUpdaterTag), + envVarShouldExist: false, + }, + { + name: "CR Image is used even with whitespace in env var", + crImageOverride: "cr-image:latest", + envImage: " ", + expectedImage: "cr-image:latest", + envVarShouldExist: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Save original env var value + originalEnv, wasSet := os.LookupEnv(common.ArgoCDImageUpdaterImageEnvName) + defer func() { + if wasSet { + os.Setenv(common.ArgoCDImageUpdaterImageEnvName, originalEnv) + } else { + os.Unsetenv(common.ArgoCDImageUpdaterImageEnvName) + } + }() + + // Set or unset the env var + if tt.envVarShouldExist { + os.Setenv(common.ArgoCDImageUpdaterImageEnvName, tt.envImage) + } else { + os.Unsetenv(common.ArgoCDImageUpdaterImageEnvName) + } + + // Create test ArgoCD CR + cr := makeTestArgoCD(func(a *argoproj.ArgoCD) { + a.Spec.ImageUpdater.Enabled = true + a.Spec.ImageUpdater.Image = tt.crImageOverride + }) + + // Test the function + result := selectImageUpdaterImage(cr) + + // Verify the result matches expected image + assert.Equal(t, tt.expectedImage, result, "selectImageUpdaterImage returned unexpected image") + }) + } +} diff --git a/argocd-operator/deploy/olm-catalog/argocd-operator/0.20.0/argoproj.io_argocds.yaml b/argocd-operator/deploy/olm-catalog/argocd-operator/0.20.0/argoproj.io_argocds.yaml index e0eb9145916..13ea2f0379b 100644 --- a/argocd-operator/deploy/olm-catalog/argocd-operator/0.20.0/argoproj.io_argocds.yaml +++ b/argocd-operator/deploy/olm-catalog/argocd-operator/0.20.0/argoproj.io_argocds.yaml @@ -22028,6 +22028,10 @@ spec: - name type: object type: array + image: + description: Image is the image to be used for the Argo CD Image + Updater + type: string resources: description: Resources defines the Compute Resources required by the container for Argo CD Image Updater. diff --git a/argocd-operator/docs/reference/argocd.md b/argocd-operator/docs/reference/argocd.md index 5a324ba85ec..7837fd598db 100644 --- a/argocd-operator/docs/reference/argocd.md +++ b/argocd-operator/docs/reference/argocd.md @@ -543,11 +543,12 @@ spec: The following properties are available for configuring the Image Updater controller component. -Name | Default | Description ---- | --- | --- -Enabled | `false` | The toggle that determines whether image updater controller should be started or not. -Env | [Empty] | Environment to set for the image updater workloads. -Resources | [Empty] | The container compute resources. +| Name | Default | Description | +|-----------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Enabled | `false` | The toggle that determines whether image updater controller should be started or not. | +| Image | [Empty] | The container image for Image Updater. Takes precedence over the `ARGOCD_IMAGE_UPDATER_IMAGE` environment variable; when both are unset, defaults to the stable Image Updater image at quay.io for this version of OpenShift GitOps. | +| Env | [Empty] | Environment to set for the image updater workloads. | +| Resources | [Empty] | The container compute resources. | ### Image Updater Controller Example diff --git a/bundle/manifests/argoproj.io_argocds.yaml b/bundle/manifests/argoproj.io_argocds.yaml index f6c7a7a9b4e..436d8015f42 100644 --- a/bundle/manifests/argoproj.io_argocds.yaml +++ b/bundle/manifests/argoproj.io_argocds.yaml @@ -22028,6 +22028,10 @@ spec: - name type: object type: array + image: + description: Image is the image to be used for the Argo CD Image + Updater + type: string resources: description: Resources defines the Compute Resources required by the container for Argo CD Image Updater. diff --git a/config/crd/bases/argoproj.io_argocds.yaml b/config/crd/bases/argoproj.io_argocds.yaml index 05ecfdef384..6155238283d 100644 --- a/config/crd/bases/argoproj.io_argocds.yaml +++ b/config/crd/bases/argoproj.io_argocds.yaml @@ -22017,6 +22017,10 @@ spec: - name type: object type: array + image: + description: Image is the image to be used for the Argo CD Image + Updater + type: string resources: description: Resources defines the Compute Resources required by the container for Argo CD Image Updater.