From 60d6b6f0f6214077bd3aab08979f276891e66fa9 Mon Sep 17 00:00:00 2001 From: Clement Doucy Date: Fri, 31 May 2024 20:41:45 +0200 Subject: [PATCH] Clean up MedusaBackupJobs and propagate MedusaTask labels --- .../medusa/medusabackupjob_controller_test.go | 8 +++- controllers/medusa/medusatask_controller.go | 15 +++++++ .../medusa/medusatask_controller_test.go | 40 +++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/controllers/medusa/medusabackupjob_controller_test.go b/controllers/medusa/medusabackupjob_controller_test.go index 6c1704073..257e39807 100644 --- a/controllers/medusa/medusabackupjob_controller_test.go +++ b/controllers/medusa/medusabackupjob_controller_test.go @@ -36,6 +36,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) { @@ -395,8 +396,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 fb592f3f6..63bdd975f 100644 --- a/controllers/medusa/medusatask_controller_test.go +++ b/controllers/medusa/medusatask_controller_test.go @@ -2,6 +2,7 @@ package medusa import ( "context" + "slices" "testing" cassdcapi "github.com/k8ssandra/cass-operator/apis/cassandra/v1beta1" @@ -154,6 +155,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") @@ -161,6 +165,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", @@ -194,9 +201,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) @@ -207,3 +223,27 @@ 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)) + contains := slices.ContainsFunc(backups.Items, func(item api.MedusaBackup) bool { + return slices.ContainsFunc(deleted, func(name string) bool { + return item.Name == name + }) + }) + require.False(contains, "expected backups %v to have been deleted", deleted) + + 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)) + contains = slices.ContainsFunc(backups.Items, func(item api.MedusaBackup) bool { + return slices.ContainsFunc(deleted, func(name string) bool { + return item.Name == name + }) + }) + require.False(contains, "expected jobs %v to have been deleted", deleted) +}