diff --git a/CHANGELOG/CHANGELOG-1.14.md b/CHANGELOG/CHANGELOG-1.14.md index 888ee13d6..3fb7092aa 100644 --- a/CHANGELOG/CHANGELOG-1.14.md +++ b/CHANGELOG/CHANGELOG-1.14.md @@ -13,6 +13,11 @@ Changelog for the K8ssandra Operator, new PRs should update the `unreleased` sec When cutting a new release, update the `unreleased` heading to the tag being generated and date, like `## vX.Y.Z - YYYY-MM-DD` and create a new placeholder section for `unreleased` entries. +## 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 + ## v1.14.0 - 2024-04-02 * [FEATURE] [#1242](https://github.com/k8ssandra/k8ssandra-operator/issues/1242) Allow for creation of replicated secrets with a prefix, so that we can distinguish between multiple secrets with the same origin but targeting different clusters. 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..a3ba65a56 100644 --- a/controllers/medusa/medusatask_controller_test.go +++ b/controllers/medusa/medusatask_controller_test.go @@ -154,6 +154,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 +164,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 +200,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 +222,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) + } +}