From 554be0ff9e41486528d8e3efb52f82b7d90079f8 Mon Sep 17 00:00:00 2001 From: Radovan Date: Wed, 12 Jun 2024 14:36:16 +0300 Subject: [PATCH] Clean up MedusaBackupJobs and propagate MedusaTask labels (#1339) (#1347) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Clément Doucy <111791574+c3-clement@users.noreply.github.com> --- CHANGELOG/CHANGELOG-1.17.md | 2 ++ .../medusa/medusabackupjob_controller_test.go | 8 ++++- controllers/medusa/medusatask_controller.go | 15 +++++++++ .../medusa/medusatask_controller_test.go | 32 +++++++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/CHANGELOG/CHANGELOG-1.17.md b/CHANGELOG/CHANGELOG-1.17.md index e4a897d5c..ccfa96c74 100644 --- a/CHANGELOG/CHANGELOG-1.17.md +++ b/CHANGELOG/CHANGELOG-1.17.md @@ -15,6 +15,8 @@ When cutting a new release, update the `unreleased` heading to the tag being gen ## unreleased +* [BUGFIX] [#1334](https://github.com/k8ssandra/k8ssandra-operator/issues/1334) Delete `MedusaBackupJobs` during purge +* [BUGFIX] [#1336](https://github.com/k8ssandra/k8ssandra-operator/issues/1336) Propagate labels to the sync `MedusaTask` created after purge * [CHANGE] []() Update cass-operator to v1.21.0 * [CHANGE] [#1313](https://github.com/k8ssandra/k8ssandra-operator/issues/1313) upgrade controller-runtime to 1.17 series, Go to 1.21. * [BUGFIX] [#1317](https://github.com/k8ssandra/k8ssandra-operator/issues/1317) Fix issues with caches in cluster scoped deployments where they were continuing to use a multi-namespace scoped cache and not an informer cache. diff --git a/controllers/medusa/medusabackupjob_controller_test.go b/controllers/medusa/medusabackupjob_controller_test.go index d9b7e339b..163382133 100644 --- a/controllers/medusa/medusabackupjob_controller_test.go +++ b/controllers/medusa/medusabackupjob_controller_test.go @@ -34,6 +34,7 @@ const ( fakeBackupFileCount = int64(13) fakeBackupByteSize = int64(42) fakeBackupHumanSize = "42.00 B" + fakeMaxBackupCount = 1 ) func testMedusaBackupDatacenter(t *testing.T, ctx context.Context, f *framework.Framework, namespace string) { @@ -392,8 +393,13 @@ func (c *fakeMedusaClient) BackupStatus(ctx context.Context, name string) (*medu } func (c *fakeMedusaClient) PurgeBackups(ctx context.Context) (*medusa.PurgeBackupsResponse, error) { + size := len(c.RequestedBackups) + if size > fakeMaxBackupCount { + c.RequestedBackups = c.RequestedBackups[size-fakeMaxBackupCount:] + } + response := &medusa.PurgeBackupsResponse{ - NbBackupsPurged: 2, + NbBackupsPurged: int32(size - len(c.RequestedBackups)), NbObjectsPurged: 10, TotalObjectsWithinGcGrace: 0, TotalPurgedSize: 1000, diff --git a/controllers/medusa/medusatask_controller.go b/controllers/medusa/medusatask_controller.go index ec9d0419f..5f3303cfb 100644 --- a/controllers/medusa/medusatask_controller.go +++ b/controllers/medusa/medusatask_controller.go @@ -301,6 +301,20 @@ func (r *MedusaTaskReconciler) syncOperation(ctx context.Context, task *medusav1 return ctrl.Result{}, err } else { logger.Info("Deleted Cassandra Backup", "Backup", backup.ObjectMeta.Name) + + backupJob := medusav1alpha1.MedusaBackupJob{ + ObjectMeta: metav1.ObjectMeta{ + Name: backup.GetName(), + Namespace: backup.GetNamespace(), + }, + } + logger.Info("Deleting MedusaBackupJob", "MedusaBackupJob", backupJob.GetName()) + + if err := r.Delete(ctx, &backupJob); err != nil && !errors.IsNotFound(err) { + logger.Error(err, "failed to delete MedusaBackupJob", "MedusaBackupJob", backupJob.GetName()) + } else { + logger.Info("Deleted MedusaBackupJob", "MedusaBackupJob", backupJob.GetName()) + } } } } @@ -377,6 +391,7 @@ func (r *MedusaTaskReconciler) scheduleSyncForPurge(task *medusav1alpha1.MedusaT ObjectMeta: metav1.ObjectMeta{ Name: task.GetObjectMeta().GetName() + "-sync", Namespace: task.Namespace, + Labels: task.GetLabels(), }, Spec: medusav1alpha1.MedusaTaskSpec{ Operation: medusav1alpha1.OperationTypeSync, diff --git a/controllers/medusa/medusatask_controller_test.go b/controllers/medusa/medusatask_controller_test.go index 55239b6a9..7cb8b6357 100644 --- a/controllers/medusa/medusatask_controller_test.go +++ b/controllers/medusa/medusatask_controller_test.go @@ -153,6 +153,9 @@ func testMedusaTasks(t *testing.T, ctx context.Context, f *framework.Framework, backup4Created := createAndVerifyMedusaBackup(dc2Key, dc2, f, ctx, require, t, namespace, backup4) require.True(backup4Created, "failed to create backup4") + // Ensure that 4 backups and backup jobs were created + checkBackupsAndJobs(require, ctx, 4, namespace, f, []string{}) + // Purge backups and verify that only one out of three remains t.Log("purge backups") @@ -160,6 +163,9 @@ func testMedusaTasks(t *testing.T, ctx context.Context, f *framework.Framework, ObjectMeta: metav1.ObjectMeta{ Namespace: namespace, Name: "purge-backups", + Labels: map[string]string{ + "app": "medusa", + }, }, Spec: api.MedusaTaskSpec{ CassandraDatacenter: "dc1", @@ -193,9 +199,18 @@ func testMedusaTasks(t *testing.T, ctx context.Context, f *framework.Framework, return false } + v, ok := updated.Labels["app"] + if !ok || v != "medusa" { + return false + } + return !updated.Status.FinishTime.IsZero() }, timeout, interval) + // Ensure that 2 backups and backup jobs were deleted + deletedBackups := []string{backup1, backup2} + checkBackupsAndJobs(require, ctx, 2, namespace, f, deletedBackups) + medusaBackup4Key := framework.NewClusterKey(f.DataPlaneContexts[0], namespace, backup4) medusaBackup4 := &api.MedusaBackup{} err = f.Get(ctx, medusaBackup4Key, medusaBackup4) @@ -206,3 +221,20 @@ func testMedusaTasks(t *testing.T, ctx context.Context, f *framework.Framework, verifyObjectDoesNotExist(ctx, t, f, dc1Key, &cassdcapi.CassandraDatacenter{}) verifyObjectDoesNotExist(ctx, t, f, dc2Key, &cassdcapi.CassandraDatacenter{}) } + +func checkBackupsAndJobs(require *require.Assertions, ctx context.Context, expectedLen int, namespace string, f *framework.Framework, deleted []string) { + var backups api.MedusaBackupList + err := f.List(ctx, framework.NewClusterKey(f.DataPlaneContexts[0], namespace, "list-backups"), &backups) + require.NoError(err, "failed to list medusabackup") + require.Len(backups.Items, expectedLen, "expected %d backups, got %d", expectedLen, len(backups.Items)) + + var jobs api.MedusaBackupJobList + err = f.List(ctx, framework.NewClusterKey(f.DataPlaneContexts[0], namespace, "list-backup-jobs"), &jobs) + require.NoError(err, "failed to list medusabackupjobs") + require.Len(jobs.Items, expectedLen, "expected %d jobs, got %d", expectedLen, len(jobs.Items)) + + for _, d := range deleted { + require.NotContains(backups.Items, d, "MedusaBackup %s to have been deleted", d) + require.NotContains(jobs.Items, d, "MedusaBackupJob %s to have been deleted", d) + } +}