@@ -26,61 +26,75 @@ import (
26
26
"strconv"
27
27
"time"
28
28
29
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
30
+
29
31
"sigs.k8s.io/controller-runtime/pkg/client"
30
32
31
33
fdbv1beta2 "github.com/FoundationDB/fdb-kubernetes-operator/v2/api/v1beta2"
32
34
"github.com/onsi/gomega"
33
35
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
34
36
)
35
37
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
+
36
44
// CreateRestoreForCluster will create a FoundationDBRestore resource based on the provided backup resource.
37
45
// For more information how the backup system with the operator is working please look at
38
46
// 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 {
40
51
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
+ },
45
64
},
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 ,
55
66
}
56
67
57
- gomega .Expect (factory .CreateIfAbsent (restore )).NotTo (gomega .HaveOccurred ())
68
+ gomega .Expect (factory .CreateIfAbsent (restore . restore )).NotTo (gomega .HaveOccurred ())
58
69
59
70
factory .AddShutdownHook (func () error {
60
- return factory .GetControllerRuntimeClient ().Delete (context .Background (), restore )
71
+ restore .Destroy ()
72
+ return nil
61
73
})
62
74
63
- waitForRestoreToComplete (backup )
75
+ restore .waitForRestoreToComplete (backup )
76
+
77
+ return restore
64
78
}
65
79
66
80
// 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 ()
69
83
70
84
lastReconcile := time .Now ()
71
85
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 )).
74
88
To (gomega .Succeed ())
75
- log .Println ("restore state:" , restore .Status .State )
89
+ log .Println ("restore state:" , currentRestore .Status .State )
76
90
77
91
if time .Since (lastReconcile ) > time .Minute {
78
92
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 )
82
96
}
83
- restore .Annotations ["foundationdb.org/reconcile" ] = strconv .FormatInt (
97
+ currentRestore .Annotations ["foundationdb.org/reconcile" ] = strconv .FormatInt (
84
98
time .Now ().UnixNano (),
85
99
10 ,
86
100
)
@@ -89,10 +103,10 @@ func waitForRestoreToComplete(backup *FdbBackup) {
89
103
// This should speed up the reconcile phase.
90
104
gomega .Expect (ctrlClient .Patch (
91
105
context .Background (),
92
- restore ,
106
+ currentRestore ,
93
107
patch )).To (gomega .Succeed ())
94
108
95
- out , _ , err := backup .fdbCluster .ExecuteCmdOnPod (
109
+ out , _ , err := restore .fdbCluster .ExecuteCmdOnPod (
96
110
* backup .GetBackupPod (),
97
111
fdbv1beta2 .MainContainerName ,
98
112
"fdbrestore status --dest_cluster_file $FDB_CLUSTER_FILE" ,
@@ -103,6 +117,27 @@ func waitForRestoreToComplete(backup *FdbBackup) {
103
117
g .Expect (err ).To (gomega .Succeed ())
104
118
}
105
119
106
- return restore .Status .State
120
+ return currentRestore .Status .State
107
121
}).WithTimeout (20 * time .Minute ).WithPolling (1 * time .Second ).Should (gomega .Equal (fdbv1beta2 .CompletedFoundationDBRestoreState ))
108
122
}
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