Treat a kopia snapshot not found after a repo refresh as deleted

Deleting a kopia snapshot refreshes the repo when the snapshot is not
found, and failed when it was still not found. When a backup deletion
was interrupted after the snapshot was deleted, e.g. by a Velero server
restart, every retry of the deletion failed with "snapshot not found",
so the backup could never be deleted.

A snapshot that is still not found after the refresh is already deleted,
so return success.

Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
This commit is contained in:
Tiger Kaovilai committed 2026-10-24 20:22:51 -04:00
1 parent 519cdcdac8
commit d3f674fd2e
2 files changed
+21 -2

No files matched your search

@@ -745,6 +745,14 @@ func (kr *kopiaRepository) DeleteSnapshot(ctx context.Context, id udmrepo.ID) er
_, err = kr.GetSnapshot(ctx, id)
if err != nil {
// The snapshot was already deleted, e.g. by a backup deletion that was
// interrupted after deleting it, so there is nothing left to do.
if errors.Is(err, snapshot.ErrSnapshotNotFound) {
if kr.logger != nil {
kr.logger.Infof("Snapshot %s is not found after repo refresh, it is already deleted", id)
}
return nil
}
return errors.Wrap(err, "error getting snapshot after repo refresh")
}
}
@@ -1719,14 +1719,25 @@ func TestDeleteSnapshot(t *testing.T) {
expectedErr: "error refreshing repo on snapshot not found: fake-refresh-error",
},
{
name: "snapshot not found in cache, refreshed, but still not found",
name: "snapshot not found in cache, refreshed, but still not found, so it is already deleted",
snapshotID: udmrepo.ID("fake-id"),
mockRepo: func(r *repomocks.MockRepository) {
r.On("GetManifest", mock.Anything, manifest.ID("fake-id"), mock.Anything).Return(nil, manifest.ErrNotFound).Once()
r.On("Refresh", mock.Anything).Return(nil).Once()
r.On("GetManifest", mock.Anything, manifest.ID("fake-id"), mock.Anything).Return(nil, manifest.ErrNotFound).Once()
},
expectedErr: "error getting snapshot after repo refresh: error getting snapshot manifest: snapshot not found",
},
{
name: "snapshot not found in cache, refreshed, then get snapshot fail",
snapshotID: udmrepo.ID("fake-id"),
mockRepo: func(r *repomocks.MockRepository) {
r.On("GetManifest", mock.Anything, manifest.ID("fake-id"), mock.Anything).Return(nil, manifest.ErrNotFound).Once()
r.On("Refresh", mock.Anything).Return(nil).Once()
r.On("GetManifest", mock.Anything, manifest.ID("fake-id"), mock.Anything).Return(&manifest.EntryMetadata{
Labels: map[string]string{manifest.TypeLabelKey: snapshot.ManifestType},
}, errors.New("fake-get-error")).Once()
},
expectedErr: "error getting snapshot after repo refresh: error getting snapshot manifest: unable to find manifest entries: fake-get-error",
},
{
name: "snapshot not found in cache, refreshed, found, and delete succeed",