@@ -26,61 +26,75 @@ import (
2626 "strconv"
2727 "time"
2828
29+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
30+
2931 "sigs.k8s.io/controller-runtime/pkg/client"
3032
3133 fdbv1beta2 "github.com/FoundationDB/fdb-kubernetes-operator/v2/api/v1beta2"
3234 "github.com/onsi/gomega"
3335 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3436)
3537
38+ // FdbRestore represents a fdbv1beta2.FoundationDBRestore resource for doing restores to a FdbCluster.
39+ type FdbRestore struct {
40+ restore * fdbv1beta2.FoundationDBRestore
41+ fdbCluster * FdbCluster
42+ }
43+
3644// CreateRestoreForCluster will create a FoundationDBRestore resource based on the provided backup resource.
3745// For more information how the backup system with the operator is working please look at
3846// the operator documentation: https://github.com/FoundationDB/fdb-kubernetes-operator/v2/blob/master/docs/manual/backup.md
39- func (factory * Factory ) CreateRestoreForCluster (backup * FdbBackup , backupVersion * uint64 ) {
47+ func (factory * Factory ) CreateRestoreForCluster (
48+ backup * FdbBackup ,
49+ backupVersion * uint64 ,
50+ ) * FdbRestore {
4051 gomega .Expect (backup ).NotTo (gomega .BeNil ())
41- restore := & fdbv1beta2.FoundationDBRestore {
42- ObjectMeta : metav1.ObjectMeta {
43- Name : backup .fdbCluster .Name (),
44- Namespace : backup .fdbCluster .Namespace (),
52+ restore := & FdbRestore {
53+ restore : & fdbv1beta2.FoundationDBRestore {
54+ ObjectMeta : metav1.ObjectMeta {
55+ Name : backup .fdbCluster .Name (),
56+ Namespace : backup .fdbCluster .Namespace (),
57+ },
58+ Spec : fdbv1beta2.FoundationDBRestoreSpec {
59+ DestinationClusterName : backup .fdbCluster .Name (),
60+ BlobStoreConfiguration : backup .backup .Spec .BlobStoreConfiguration ,
61+ CustomParameters : backup .backup .Spec .CustomParameters ,
62+ BackupVersion : backupVersion ,
63+ },
4564 },
46- Spec : fdbv1beta2.FoundationDBRestoreSpec {
47- DestinationClusterName : backup .fdbCluster .Name (),
48- BlobStoreConfiguration : backup .backup .Spec .BlobStoreConfiguration ,
49- CustomParameters : backup .backup .Spec .CustomParameters ,
50- },
51- }
52-
53- if backupVersion != nil {
54- restore .Spec .BackupVersion = backupVersion
65+ fdbCluster : backup .fdbCluster ,
5566 }
5667
57- gomega .Expect (factory .CreateIfAbsent (restore )).NotTo (gomega .HaveOccurred ())
68+ gomega .Expect (factory .CreateIfAbsent (restore . restore )).NotTo (gomega .HaveOccurred ())
5869
5970 factory .AddShutdownHook (func () error {
60- return factory .GetControllerRuntimeClient ().Delete (context .Background (), restore )
71+ restore .Destroy ()
72+ return nil
6173 })
6274
63- waitForRestoreToComplete (backup )
75+ restore .waitForRestoreToComplete (backup )
76+
77+ return restore
6478}
6579
6680// waitForRestoreToComplete waits until the restore completed.
67- func waitForRestoreToComplete (backup * FdbBackup ) {
68- ctrlClient := backup .fdbCluster .getClient ()
81+ func ( restore * FdbRestore ) waitForRestoreToComplete (backup * FdbBackup ) {
82+ ctrlClient := restore .fdbCluster .getClient ()
6983
7084 lastReconcile := time .Now ()
7185 gomega .Eventually (func (g gomega.Gomega ) fdbv1beta2.FoundationDBRestoreState {
72- restore := & fdbv1beta2.FoundationDBRestore {}
73- g .Expect (ctrlClient .Get (context .Background (), client .ObjectKeyFromObject (backup . backup ), restore )).
86+ currentRestore := & fdbv1beta2.FoundationDBRestore {}
87+ g .Expect (ctrlClient .Get (context .Background (), client .ObjectKeyFromObject (restore . restore ), currentRestore )).
7488 To (gomega .Succeed ())
75- log .Println ("restore state:" , restore .Status .State )
89+ log .Println ("restore state:" , currentRestore .Status .State )
7690
7791 if time .Since (lastReconcile ) > time .Minute {
7892 lastReconcile = time .Now ()
79- patch := client .MergeFrom (restore .DeepCopy ())
80- if restore .Annotations == nil {
81- restore .Annotations = make (map [string ]string )
93+ patch := client .MergeFrom (currentRestore .DeepCopy ())
94+ if currentRestore .Annotations == nil {
95+ currentRestore .Annotations = make (map [string ]string )
8296 }
83- restore .Annotations ["foundationdb.org/reconcile" ] = strconv .FormatInt (
97+ currentRestore .Annotations ["foundationdb.org/reconcile" ] = strconv .FormatInt (
8498 time .Now ().UnixNano (),
8599 10 ,
86100 )
@@ -89,10 +103,10 @@ func waitForRestoreToComplete(backup *FdbBackup) {
89103 // This should speed up the reconcile phase.
90104 gomega .Expect (ctrlClient .Patch (
91105 context .Background (),
92- restore ,
106+ currentRestore ,
93107 patch )).To (gomega .Succeed ())
94108
95- out , _ , err := backup .fdbCluster .ExecuteCmdOnPod (
109+ out , _ , err := restore .fdbCluster .ExecuteCmdOnPod (
96110 * backup .GetBackupPod (),
97111 fdbv1beta2 .MainContainerName ,
98112 "fdbrestore status --dest_cluster_file $FDB_CLUSTER_FILE" ,
@@ -103,6 +117,27 @@ func waitForRestoreToComplete(backup *FdbBackup) {
103117 g .Expect (err ).To (gomega .Succeed ())
104118 }
105119
106- return restore .Status .State
120+ return currentRestore .Status .State
107121 }).WithTimeout (20 * time .Minute ).WithPolling (1 * time .Second ).Should (gomega .Equal (fdbv1beta2 .CompletedFoundationDBRestoreState ))
108122}
123+
124+ // Destroy will delete the FoundationDBRestore for the associated FdbBackup if it exists.
125+ func (restore * FdbRestore ) Destroy () {
126+ gomega .Eventually (func (g gomega.Gomega ) {
127+ err := restore .fdbCluster .factory .GetControllerRuntimeClient ().
128+ Delete (context .Background (), restore .restore )
129+ if k8serrors .IsNotFound (err ) {
130+ return
131+ }
132+
133+ g .Expect (err ).NotTo (gomega .HaveOccurred ())
134+ }).WithTimeout (4 * time .Minute ).WithPolling (1 * time .Second ).Should (gomega .Succeed ())
135+
136+ // Ensure that the resource is removed.
137+ gomega .Eventually (func (g gomega.Gomega ) {
138+ currentRestore := & fdbv1beta2.FoundationDBRestore {}
139+ err := restore .fdbCluster .getClient ().
140+ Get (context .Background (), client .ObjectKeyFromObject (restore .restore ), currentRestore )
141+ g .Expect (k8serrors .IsNotFound (err )).To (gomega .BeTrue ())
142+ }).WithTimeout (10 * time .Minute ).WithPolling (1 * time .Second ).To (gomega .Succeed ())
143+ }
0 commit comments