mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-13 08:05:19 +09:00
feat(backups): warn on the BackupJob when the Redis snapshot is empty
A valid RDB snapshot always carries a header, so a 0-byte object means the backup is broken. sizeBytes is omitempty, though, so such a Backup read exactly like one whose size was never measured. The controller still records the artifact, and now raises a Warning EmptySnapshot Event on the BackupJob once the Backup is created. A test now also pins that a retry over an existing Backup returns it without calling Create. Assisted-by: LLM Signed-off-by: Andrey Kolkov <androndo@gmail.com>
This commit is contained in:
1 parent
2013e624ca
commit
1093f390ae
2 files changed
+34
-3
No files matched your search
@@ -17,6 +17,7 @@ import (
|
||||
"k8s.io/client-go/tools/record"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
clientfake "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
|
||||
|
||||
backupsv1alpha1 "github.com/cozystack/cozystack/api/backups/v1alpha1"
|
||||
)
|
||||
@@ -367,16 +368,39 @@ func TestCreateRedisBackupArtifact_Artifact(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("an existing Backup is returned without probing", func(t *testing.T) {
|
||||
t.Run("an existing Backup is returned without probing or creating", func(t *testing.T) {
|
||||
existing := &backupsv1alpha1.Backup{ObjectMeta: metav1.ObjectMeta{Namespace: "tenant", Name: "bj-1"}}
|
||||
l := &fakeS3Lister{statSize: 777}
|
||||
r := redisReconciler(t, l, j, existing, projectedCredsSecret(nil))
|
||||
creates := 0
|
||||
r.Client = interceptor.NewClient(r.Client.(client.WithWatch), interceptor.Funcs{
|
||||
Create: func(ctx context.Context, cl client.WithWatch, obj client.Object, opts ...client.CreateOption) error {
|
||||
creates++
|
||||
return cl.Create(ctx, obj, opts...)
|
||||
},
|
||||
})
|
||||
if _, err := r.createRedisBackupArtifact(context.Background(), j, &ResolvedBackupConfig{}, redisTestKey, nil); err != nil {
|
||||
t.Fatalf("createRedisBackupArtifact: %v", err)
|
||||
}
|
||||
if l.calls != 0 {
|
||||
t.Errorf("S3 probed %d times for a Backup that already exists", l.calls)
|
||||
}
|
||||
if creates != 0 {
|
||||
t.Errorf("Create called %d times for a Backup that already exists", creates)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("an empty snapshot is recorded and warned about", func(t *testing.T) {
|
||||
r := redisReconciler(t, &fakeS3Lister{statSize: 0}, j, projectedCredsSecret(nil))
|
||||
rec := record.NewFakeRecorder(4)
|
||||
r.Recorder = rec
|
||||
got, err := r.createRedisBackupArtifact(context.Background(), j, &ResolvedBackupConfig{}, redisTestKey, nil)
|
||||
if err != nil || got == nil || got.Status.Artifact == nil || got.Status.Artifact.URI != "s3://cozy-backups/"+redisTestKey {
|
||||
t.Fatalf("createRedisBackupArtifact = %#v, %v; want the artifact recorded", got, err)
|
||||
}
|
||||
if ev := nextEvent(rec); !strings.HasPrefix(ev, "Warning EmptySnapshot ") {
|
||||
t.Errorf("event = %q, want Warning EmptySnapshot", ev)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -526,8 +526,15 @@ func (r *BackupJobReconciler) createRedisBackupArtifact(
|
||||
}
|
||||
// Only once the Backup exists: a terminal Create error fails the
|
||||
// BackupJob, and a collision returns a Backup another pass measured.
|
||||
if unmeasured != "" && r.Recorder != nil {
|
||||
r.Recorder.Eventf(j, corev1.EventTypeNormal, "ArtifactNotMeasured", "The backup succeeded, but its location and size were not recorded: %s", unmeasured)
|
||||
if r.Recorder != nil {
|
||||
switch {
|
||||
case unmeasured != "":
|
||||
r.Recorder.Eventf(j, corev1.EventTypeNormal, "ArtifactNotMeasured", "The backup succeeded, but its location and size were not recorded: %s", unmeasured)
|
||||
case backup.Status.Artifact != nil && backup.Status.Artifact.SizeBytes == 0:
|
||||
// sizeBytes is omitempty, so a 0 reads as "not measured" on the
|
||||
// Backup; a valid RDB snapshot always carries a header.
|
||||
r.Recorder.Event(j, corev1.EventTypeWarning, "EmptySnapshot", "The backup's RDB snapshot is empty (0 bytes); a valid snapshot is never empty, so this backup is likely broken.")
|
||||
}
|
||||
}
|
||||
return backup, nil
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user