Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cmd/sidecar/handler/backup/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ type fakeStorageClient struct {
}

func (c *fakeStorageClient) ListObjects(_ context.Context, destination string) ([]string, error) {
if destination == "non-existing-backup" {
if destination == "non-existing-backup/" {
return nil, nil
}
switch destination {
case "non-existing-backup":
case "non-existing-backup/":
return nil, nil
case "existing-backup":
case "existing-backup/":
return []string{"some-dest/backup1", "some-dest/backup2"}, nil
default:
return nil, errors.New("fake list objects error")
Expand Down
2 changes: 1 addition & 1 deletion cmd/sidecar/handler/backup/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (h *Handler) backupExists(ctx context.Context, cfg *xb.BackupConfig) (bool,
if err != nil {
return false, errors.Wrap(err, "new storage")
}
objects, err := storage.ListObjects(ctx, cfg.Destination)
objects, err := storage.ListObjects(ctx, cfg.Destination+"/")
if err != nil {
return false, errors.Wrap(err, "list objects")
}
Expand Down
29 changes: 16 additions & 13 deletions pkg/controller/psbackup/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,20 +478,13 @@ func (r *PerconaServerMySQLBackupReconciler) runPostFinishTasks(
}

func (r *PerconaServerMySQLBackupReconciler) checkFinalizers(ctx context.Context, cr *apiv1.PerconaServerMySQLBackup) error {
if cr.DeletionTimestamp == nil || cr.Status.State == apiv1.BackupStarting || cr.Status.State == apiv1.BackupRunning {
if cr.DeletionTimestamp == nil || cr.Status.State == apiv1.BackupStarting || cr.Status.State == apiv1.BackupRunning || len(cr.Finalizers) == 0 {
return nil
}
log := logf.FromContext(ctx).WithName("checkFinalizers")

finalizers := sets.NewString()

switch cr.Status.State {
case apiv1.BackupError, apiv1.BackupNew:
if cr.Finalizers == nil {
return nil
}
}

for _, finalizer := range cr.GetFinalizers() {
var err error
switch finalizer {
Expand All @@ -510,12 +503,22 @@ func (r *PerconaServerMySQLBackupReconciler) checkFinalizers(ctx context.Context
}
}

cr.Finalizers = finalizers.List()
if len(cr.Finalizers) == 0 {
cr.Finalizers = nil
}
err := k8sretry.OnError(k8sretry.DefaultRetry, func(error) bool { return true }, func() error {
c := new(apiv1.PerconaServerMySQLBackup)
if err := r.Get(ctx, client.ObjectKeyFromObject(cr), c); err != nil {
if k8serrors.IsNotFound(err) {
return nil
}
return errors.Wrapf(err, "get %v", client.ObjectKeyFromObject(cr).String())
}

if err := r.Update(ctx, cr); err != nil {
c.Finalizers = finalizers.List()
if len(c.Finalizers) == 0 {
c.Finalizers = nil
}
return r.Update(ctx, c)
})
if err != nil {
return errors.Wrap(err, "failed to update finalizers for backup")
}

Expand Down
41 changes: 22 additions & 19 deletions pkg/controller/psbackup/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,19 +281,13 @@ func TestStateDescCleanup(t *testing.T) {
}

func TestCheckFinalizers(t *testing.T) {
ctx := context.Background()
scheme := runtime.NewScheme()
if err := clientgoscheme.AddToScheme(scheme); err != nil {
t.Fatal(err, "failed to add client-go scheme")
}
if err := apiv1.AddToScheme(scheme); err != nil {
t.Fatal(err, "failed to add apis scheme")
}
require.NoError(t, clientgoscheme.AddToScheme(scheme))
require.NoError(t, apiv1.AddToScheme(scheme))
namespace := "some-namespace"

cr, err := readDefaultCRBackup("some-name", namespace)
if err != nil {
t.Fatal(err, "failed to read default backup")
}
require.NoError(t, err)

tests := []struct {
name string
Expand Down Expand Up @@ -414,9 +408,10 @@ func TestCheckFinalizers(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.cr.Status.Storage = storage
cr := tt.cr.DeepCopy()
cr.Status.Storage = storage

job := xtrabackup.GetDeleteJob(new(apiv1.PerconaServerMySQL), tt.cr, new(xtrabackup.BackupConfig))
job := xtrabackup.GetDeleteJob(new(apiv1.PerconaServerMySQL), cr, new(xtrabackup.BackupConfig))
cond := batchv1.JobCondition{
Type: batchv1.JobComplete,
Status: corev1.ConditionTrue,
Expand All @@ -426,25 +421,33 @@ func TestCheckFinalizers(t *testing.T) {
}
job.Status.Conditions = append(job.Status.Conditions, cond)

cb := fake.NewClientBuilder().WithScheme(scheme).WithObjects(tt.cr, sec, job)
cb := fake.NewClientBuilder().WithScheme(scheme).WithObjects(cr, sec, job)
r := PerconaServerMySQLBackupReconciler{
Client: cb.Build(),
Scheme: scheme,
ServerVersion: &platform.ServerVersion{Platform: platform.PlatformKubernetes},
}
err := r.Delete(ctx, tt.cr)
if err != nil {

require.NoError(t, r.Delete(t.Context(), cr))

// Getting backup with deletion timestamp
if err := r.Get(t.Context(), client.ObjectKeyFromObject(cr), cr); err != nil {
if k8serrors.IsNotFound(err) && len(tt.expectedFinalizers) == 0 {
return
}
t.Fatal(err)
}
cr := new(apiv1.PerconaServerMySQLBackup)
if err := r.Get(ctx, types.NamespacedName{Name: tt.cr.Name, Namespace: tt.cr.Namespace}, cr); err != nil {
if k8serrors.IsNotFound(err) && len(cr.Finalizers) == 0 {

assert.NoError(t, r.checkFinalizers(t.Context(), cr))
Comment on lines +431 to +441
Copy link

Copilot AI Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method t.Context() is not a standard Go testing method. This should be context.Background() or define a proper context variable.

Copilot uses AI. Check for mistakes.


// Getting backup with updated finalizers
if err := r.Get(t.Context(), client.ObjectKeyFromObject(cr), cr); err != nil {
Comment on lines +431 to +444
Copy link

Copilot AI Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method t.Context() is not a standard Go testing method. These should use context.Background() or a properly defined context variable.

Copilot uses AI. Check for mistakes.

Comment on lines +431 to +444
Copy link

Copilot AI Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method t.Context() is not a standard Go testing method. These should use context.Background() or a properly defined context variable.

Copilot uses AI. Check for mistakes.

if k8serrors.IsNotFound(err) && len(tt.expectedFinalizers) == 0 {
return
}
t.Fatal(err)
}

r.checkFinalizers(ctx, cr)
assert.Equal(t, tt.expectedFinalizers, cr.Finalizers)
})
}
Expand Down
Loading