From 135f57e271a3b19b785ca23307397bc6c9b691b5 Mon Sep 17 00:00:00 2001 From: Tom Bojer Date: Wed, 13 May 2026 09:49:27 +0200 Subject: [PATCH] fix: prevent setup labels leaking into scheduled task cronjob --- internal/cronjob/scheduled_task.go | 39 +++++++++++--------- internal/cronjob/scheduled_task_test.go | 49 +++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 internal/cronjob/scheduled_task_test.go diff --git a/internal/cronjob/scheduled_task.go b/internal/cronjob/scheduled_task.go index 45faba7..8b2999b 100644 --- a/internal/cronjob/scheduled_task.go +++ b/internal/cronjob/scheduled_task.go @@ -30,7 +30,8 @@ func GetScheduledCronJob(ctx context.Context, client client.Client, store v1.Sto func ScheduledTaskJob(store v1.Store) *batchv1.CronJob { // Merge Overwritten jobContainer fields into container fields - store.Spec.Container.Merge(store.Spec.SetupJobContainer) + containerSpec := store.Spec.Container.DeepCopy() + containerSpec.Merge(store.Spec.SetupJobContainer) parallelism := int32(1) completions := int32(1) @@ -42,11 +43,12 @@ func ScheduledTaskJob(store v1.Store) *batchv1.CronJob { sa = store.Spec.ServiceAccountName } // Per container way - if store.Spec.Container.ServiceAccountName != "" { - sa = store.Spec.Container.ServiceAccountName + if containerSpec.ServiceAccountName != "" { + sa = containerSpec.ServiceAccountName } - labels := util.GetDefaultContainerStoreLabels(store, store.Spec.SetupJobContainer.Labels) + labels := util.GetDefaultContainerStoreLabels(store, nil) + labels["component"] = "scheduled-task" labels[util.ShopwareKey("store.type")] = "scheduled-task" // Hack: The current size of the CRD is at the limit. @@ -58,16 +60,17 @@ func ScheduledTaskJob(store v1.Store) *batchv1.CronJob { } annotations := util.GetDefaultContainerAnnotations(CONTAINER_NAME_SCHEDULED_JOB, store, store.Spec.SetupJobContainer.Annotations) + envs := util.MergeEnv(store.GetEnv(), containerSpec.ExtraEnvs) - containers := append(store.Spec.Container.ExtraContainers, corev1.Container{ + containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: CONTAINER_NAME_SCHEDULED_JOB, - VolumeMounts: store.Spec.Container.VolumeMounts, - ImagePullPolicy: store.Spec.Container.ImagePullPolicy, - Image: store.Spec.Container.Image, + VolumeMounts: containerSpec.VolumeMounts, + ImagePullPolicy: containerSpec.ImagePullPolicy, + Image: containerSpec.Image, Command: []string{"sh", "-c"}, Args: []string{store.Spec.ScheduledTask.Command}, - Env: store.GetEnv(), - Resources: store.Spec.Container.Resources, // Add Resources here + Env: envs, + Resources: containerSpec.Resources, // Add Resources here }) job := &batchv1.CronJob{ @@ -103,17 +106,17 @@ func ScheduledTaskJob(store v1.Store) *batchv1.CronJob { }, Spec: corev1.PodSpec{ ShareProcessNamespace: &sharedProcessNamespace, - TerminationGracePeriodSeconds: &store.Spec.Container.TerminationGracePeriodSeconds, - Volumes: store.Spec.Container.Volumes, - TopologySpreadConstraints: store.Spec.Container.TopologySpreadConstraints, - NodeSelector: store.Spec.Container.NodeSelector, - ImagePullSecrets: store.Spec.Container.ImagePullSecrets, - EnableServiceLinks: store.Spec.Container.EnableServiceLinks, + TerminationGracePeriodSeconds: &containerSpec.TerminationGracePeriodSeconds, + Volumes: containerSpec.Volumes, + TopologySpreadConstraints: containerSpec.TopologySpreadConstraints, + NodeSelector: containerSpec.NodeSelector, + ImagePullSecrets: containerSpec.ImagePullSecrets, + EnableServiceLinks: containerSpec.EnableServiceLinks, RestartPolicy: "Never", Containers: containers, - SecurityContext: store.Spec.Container.SecurityContext, + SecurityContext: containerSpec.SecurityContext, ServiceAccountName: sa, - InitContainers: store.Spec.Container.InitContainers, + InitContainers: containerSpec.InitContainers, }, }, }, diff --git a/internal/cronjob/scheduled_task_test.go b/internal/cronjob/scheduled_task_test.go new file mode 100644 index 0000000..0c59ace --- /dev/null +++ b/internal/cronjob/scheduled_task_test.go @@ -0,0 +1,49 @@ +package cronjob_test + +import ( + "testing" + + v1 "github.com/shopware/shopware-operator/api/v1" + "github.com/shopware/shopware-operator/internal/cronjob" + "github.com/shopware/shopware-operator/internal/util" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestScheduledTaskJobUsesScheduledTaskComponentLabel(t *testing.T) { + store := v1.Store{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-store", + Namespace: "test", + }, + Spec: v1.StoreSpec{ + Container: v1.ContainerSpec{ + Image: "shopware:latest", + Labels: map[string]string{ + "application-id": "app-id", + "component": "store", + }, + }, + SetupJobContainer: v1.ContainerMergeSpec{ + Labels: map[string]string{ + "component": "setup", + "setup-only": "setup", + }, + }, + ScheduledTask: v1.ScheduledTaskSpec{ + TimeZone: "Etc/UTC", + Schedule: "*/5 * * * *", + Command: "bin/console scheduled-task:run -v -n --no-wait", + }, + }, + } + + result := cronjob.ScheduledTaskJob(store) + + assert.Equal(t, "scheduled-task", result.Labels["component"]) + assert.Equal(t, "scheduled-task", result.Spec.JobTemplate.Labels["component"]) + assert.Equal(t, "scheduled-task", result.Spec.JobTemplate.Spec.Template.Labels["component"]) + assert.Equal(t, "scheduled-task", result.Labels[util.ShopwareKey("store.type")]) + assert.Equal(t, "app-id", result.Labels["application-id"]) + assert.NotContains(t, result.Labels, "setup-only") +}