diff --git a/src/internal/controller/zitadelcluster_controller.go b/src/internal/controller/zitadelcluster_controller.go index 966b12d..8c548f7 100644 --- a/src/internal/controller/zitadelcluster_controller.go +++ b/src/internal/controller/zitadelcluster_controller.go @@ -277,41 +277,114 @@ func (r *ZitadelClusterReconciler) reconcileConfig(ctx context.Context, zitadel func (r *ZitadelClusterReconciler) reconcileInitJob(ctx context.Context, zitadel *zitadelv1alpha1.ZitadelCluster) (ctrl.Result, error) { key := client.ObjectKeyFromObject(zitadel) key.Name = "init-job-" + key.Name + + // Build the desired InitJob desiredInitJob, err := r.Builder.BuildInitJob(zitadel, key) if err != nil { return ctrl.Result{}, fmt.Errorf("error building InitJob: %v", err) } + var existingJob batchv1.Job - if err := r.Get(ctx, key, &existingJob); err != nil { + err = r.Get(ctx, key, &existingJob) + if err != nil { if !errors.IsNotFound(err) { return ctrl.Result{}, fmt.Errorf("error getting InitJob: %v", err) } + // If job not found, create the InitJob if err := r.Create(ctx, desiredInitJob); err != nil { return ctrl.Result{}, fmt.Errorf("error creating InitJob: %v", err) } return ctrl.Result{}, nil } + + // Compare the image in the existing job with the desired image + existingImage := existingJob.Spec.Template.Spec.Containers[0].Image + desiredImage := desiredInitJob.Spec.Template.Spec.Containers[0].Image + + // If the images don't match, delete the existing job and wait for deletion + if existingImage != desiredImage { + if err := r.Delete(ctx, &existingJob); err != nil { + return ctrl.Result{}, fmt.Errorf("error deleting existing InitJob: %v", err) + } + + // Wait for the job to be fully deleted before creating a new one + for { + err := r.Get(ctx, key, &existingJob) + if errors.IsNotFound(err) { + break // Job has been deleted, we can proceed + } + if err != nil { + return ctrl.Result{}, fmt.Errorf("error checking if InitJob is deleted: %v", err) + } + // Sleep for a short interval to avoid tight loop + time.Sleep(1 * time.Second) + } + + // Now create the new InitJob + if err := r.Create(ctx, desiredInitJob); err != nil { + return ctrl.Result{}, fmt.Errorf("error creating new InitJob: %v", err) + } + return ctrl.Result{}, nil + } + + // If the job exists and the image matches, no action is needed return ctrl.Result{}, nil } func (r *ZitadelClusterReconciler) reconcileSetupJob(ctx context.Context, zitadel *zitadelv1alpha1.ZitadelCluster) (ctrl.Result, error) { key := client.ObjectKeyFromObject(zitadel) key.Name = "setup-job-" + key.Name - desiredSetupjob, err := r.Builder.BuildSetupJob(zitadel, key) + + // Build the desired job + desiredSetupJob, err := r.Builder.BuildSetupJob(zitadel, key) if err != nil { - return ctrl.Result{}, fmt.Errorf("error building Setupjob: %v", err) + return ctrl.Result{}, fmt.Errorf("error building SetupJob: %v", err) } + var existingJob batchv1.Job - if err := r.Get(ctx, key, &existingJob); err != nil { + err = r.Get(ctx, key, &existingJob) + if err != nil { if !errors.IsNotFound(err) { - return ctrl.Result{}, fmt.Errorf("error getting Setupjob: %v", err) + return ctrl.Result{}, fmt.Errorf("error getting SetupJob: %v", err) } - if err := r.Create(ctx, desiredSetupjob); err != nil { - return ctrl.Result{}, fmt.Errorf("error creating Setupjob: %v", err) + // If job is not found, create the job + if err := r.Create(ctx, desiredSetupJob); err != nil { + return ctrl.Result{}, fmt.Errorf("error creating SetupJob: %v", err) } return ctrl.Result{}, nil } + // Compare the image in the existing job with the desired image + existingImage := existingJob.Spec.Template.Spec.Containers[0].Image + desiredImage := desiredSetupJob.Spec.Template.Spec.Containers[0].Image + + // If the images don't match, delete the existing job and wait for deletion + if existingImage != desiredImage { + if err := r.Delete(ctx, &existingJob); err != nil { + return ctrl.Result{}, fmt.Errorf("error deleting existing SetupJob: %v", err) + } + + // Wait for the job to be fully deleted before creating a new one + for { + err := r.Get(ctx, key, &existingJob) + if errors.IsNotFound(err) { + break // Job has been deleted, we can proceed + } + if err != nil { + return ctrl.Result{}, fmt.Errorf("error checking if SetupJob is deleted: %v", err) + } + // Sleep for a short interval to avoid tight loop + time.Sleep(1 * time.Second) + } + + // Now create the new job + if err := r.Create(ctx, desiredSetupJob); err != nil { + return ctrl.Result{}, fmt.Errorf("error creating new SetupJob: %v", err) + } + return ctrl.Result{}, nil + } + + // If the job exists and the image matches, no action is needed return ctrl.Result{}, nil }