diff --git a/internal/pkg/callbacks/rolling_upgrade.go b/internal/pkg/callbacks/rolling_upgrade.go index 81c0b659d..c7b2e5ccb 100644 --- a/internal/pkg/callbacks/rolling_upgrade.go +++ b/internal/pkg/callbacks/rolling_upgrade.go @@ -16,6 +16,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" patchtypes "k8s.io/apimachinery/pkg/types" + "maps" + argorolloutv1alpha1 "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" ) @@ -443,11 +445,21 @@ func PatchDeployment(clients kube.Clients, namespace string, resource runtime.Ob // CreateJobFromCronjob performs rolling upgrade on cronjob func CreateJobFromCronjob(clients kube.Clients, namespace string, resource runtime.Object) error { cronJob := resource.(*batchv1.CronJob) + + annotations := make(map[string]string) + annotations["cronjob.kubernetes.io/instantiate"] = "manual" + maps.Copy(annotations, cronJob.Spec.JobTemplate.Annotations) + job := &batchv1.Job{ - ObjectMeta: cronJob.Spec.JobTemplate.ObjectMeta, - Spec: cronJob.Spec.JobTemplate.Spec, + ObjectMeta: meta_v1.ObjectMeta{ + GenerateName: cronJob.Name + "-", + Namespace: cronJob.Namespace, + Annotations: annotations, + Labels: cronJob.Spec.JobTemplate.Labels, + OwnerReferences: []meta_v1.OwnerReference{*meta_v1.NewControllerRef(cronJob, batchv1.SchemeGroupVersion.WithKind("CronJob"))}, + }, + Spec: cronJob.Spec.JobTemplate.Spec, } - job.GenerateName = cronJob.Name + "-" _, err := clients.KubernetesClient.BatchV1().Jobs(namespace).Create(context.TODO(), job, meta_v1.CreateOptions{FieldManager: "Reloader"}) return err } diff --git a/internal/pkg/callbacks/rolling_upgrade_test.go b/internal/pkg/callbacks/rolling_upgrade_test.go index 31d441180..b9f48f3fd 100644 --- a/internal/pkg/callbacks/rolling_upgrade_test.go +++ b/internal/pkg/callbacks/rolling_upgrade_test.go @@ -415,13 +415,26 @@ func TestPatchResources(t *testing.T) { func TestCreateJobFromCronjob(t *testing.T) { fixtures := newTestFixtures() - cronJob, err := createTestCronJobWithAnnotations(clients, fixtures.namespace, "1") + runtimeObj, err := createTestCronJobWithAnnotations(clients, fixtures.namespace, "1") assert.NoError(t, err) - err = callbacks.CreateJobFromCronjob(clients, fixtures.namespace, cronJob.(*batchv1.CronJob)) + cronJob := runtimeObj.(*batchv1.CronJob) + err = callbacks.CreateJobFromCronjob(clients, fixtures.namespace, cronJob) assert.NoError(t, err) - err = deleteTestCronJob(clients, fixtures.namespace, "test-cronjob") + jobList, err := clients.KubernetesClient.BatchV1().Jobs(fixtures.namespace).List(context.TODO(), metav1.ListOptions{}) + assert.NoError(t, err) + + ownerFound := false + for _, job := range jobList.Items { + if isControllerOwner("CronJob", cronJob.Name, job.OwnerReferences) { + ownerFound = true + break + } + } + assert.Truef(t, ownerFound, "Missing CronJob owner reference") + + err = deleteTestCronJob(clients, fixtures.namespace, cronJob.Name) assert.NoError(t, err) } @@ -749,3 +762,12 @@ func createTestJobWithAnnotations(clients kube.Clients, namespace, version strin func deleteTestJob(clients kube.Clients, namespace, name string) error { return clients.KubernetesClient.BatchV1().Jobs(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}) } + +func isControllerOwner(kind, name string, ownerRefs []metav1.OwnerReference) bool { + for _, ownerRef := range ownerRefs { + if *ownerRef.Controller && ownerRef.Kind == kind && ownerRef.Name == name { + return true + } + } + return false +}