@@ -24,15 +24,19 @@ import (
2424
2525// WALServiceImplementation is the implementation of the WAL Service
2626type WALServiceImplementation struct {
27- ServerName string
28- BarmanObjectKey client.ObjectKey
27+ wal.UnimplementedWALServer
2928 ClusterObjectKey client.ObjectKey
3029 Client client.Client
3130 InstanceName string
3231 SpoolDirectory string
3332 PGDataPath string
3433 PGWALPath string
35- wal.UnimplementedWALServer
34+
35+ BarmanObjectKey client.ObjectKey
36+ ServerName string
37+
38+ RecoveryBarmanObjectKey client.ObjectKey
39+ RecoveryServerName string
3640}
3741
3842// GetCapabilities implements the WALService interface
@@ -123,22 +127,55 @@ func (w WALServiceImplementation) Restore(
123127 ctx context.Context ,
124128 request * wal.WALRestoreRequest ,
125129) (* wal.WALRestoreResult , error ) {
126- contextLogger := log .FromContext (ctx )
127- startTime := time .Now ()
130+ // TODO: build full paths
131+ walName := request .GetSourceWalName ()
132+ destinationPath := request .GetDestinationFileName ()
128133
129134 var cluster cnpgv1.Cluster
130135 if err := w .Client .Get (ctx , w .ClusterObjectKey , & cluster ); err != nil {
131136 return nil , err
132137 }
133138
134139 var objectStore barmancloudv1.ObjectStore
135- if err := w .Client .Get (ctx , w .BarmanObjectKey , & objectStore ); err != nil {
136- return nil , err
140+ var serverName string
141+
142+ switch {
143+ case cluster .IsReplica () && cluster .Status .CurrentPrimary == w .InstanceName :
144+ // Designated primary on replica cluster, using recovery object store
145+ serverName = w .RecoveryServerName
146+ if err := w .Client .Get (ctx , w .RecoveryBarmanObjectKey , & objectStore ); err != nil {
147+ return nil , err
148+ }
149+
150+ case cluster .Status .CurrentPrimary == "" :
151+ // Recovery from object store, using recovery object store
152+ serverName = w .RecoveryServerName
153+ if err := w .Client .Get (ctx , w .RecoveryBarmanObjectKey , & objectStore ); err != nil {
154+ return nil , err
155+ }
156+
157+ default :
158+ // Using cluster object store
159+ serverName = w .ServerName
160+ if err := w .Client .Get (ctx , w .BarmanObjectKey , & objectStore ); err != nil {
161+ return nil , err
162+ }
137163 }
138164
139- // TODO: build full paths
140- walName := request .GetSourceWalName ()
141- destinationPath := request .GetDestinationFileName ()
165+ return & wal.WALRestoreResult {}, w .restoreFromBarmanObjectStore (
166+ ctx , & cluster , & objectStore , serverName , walName , destinationPath )
167+ }
168+
169+ func (w WALServiceImplementation ) restoreFromBarmanObjectStore (
170+ ctx context.Context ,
171+ cluster * cnpgv1.Cluster ,
172+ objectStore * barmancloudv1.ObjectStore ,
173+ serverName string ,
174+ walName string ,
175+ destinationPath string ,
176+ ) error {
177+ contextLogger := log .FromContext (ctx )
178+ startTime := time .Now ()
142179
143180 barmanConfiguration := & objectStore .Spec .Configuration
144181
@@ -151,37 +188,37 @@ func (w WALServiceImplementation) Restore(
151188 os .Environ (),
152189 )
153190 if err != nil {
154- return nil , fmt .Errorf ("while getting recover credentials: %w" , err )
191+ return fmt .Errorf ("while getting recover credentials: %w" , err )
155192 }
156193 env = MergeEnv (env , credentialsEnv )
157194
158- options , err := barmanCommand .CloudWalRestoreOptions (ctx , barmanConfiguration , w . ServerName )
195+ options , err := barmanCommand .CloudWalRestoreOptions (ctx , barmanConfiguration , serverName )
159196 if err != nil {
160- return nil , fmt .Errorf ("while getting barman-cloud-wal-restore options: %w" , err )
197+ return fmt .Errorf ("while getting barman-cloud-wal-restore options: %w" , err )
161198 }
162199
163200 // Create the restorer
164201 var walRestorer * barmanRestorer.WALRestorer
165202 if walRestorer , err = barmanRestorer .New (ctx , env , w .SpoolDirectory ); err != nil {
166- return nil , fmt .Errorf ("while creating the restorer: %w" , err )
203+ return fmt .Errorf ("while creating the restorer: %w" , err )
167204 }
168205
169206 // Step 1: check if this WAL file is not already in the spool
170207 var wasInSpool bool
171208 if wasInSpool , err = walRestorer .RestoreFromSpool (walName , destinationPath ); err != nil {
172- return nil , fmt .Errorf ("while restoring a file from the spool directory: %w" , err )
209+ return fmt .Errorf ("while restoring a file from the spool directory: %w" , err )
173210 }
174211 if wasInSpool {
175212 contextLogger .Info ("Restored WAL file from spool (parallel)" ,
176213 "walName" , walName ,
177214 )
178- return nil , nil
215+ return nil
179216 }
180217
181218 // We skip this step if streaming connection is not available
182- if isStreamingAvailable (& cluster , w .InstanceName ) {
219+ if isStreamingAvailable (cluster , w .InstanceName ) {
183220 if err := checkEndOfWALStreamFlag (walRestorer ); err != nil {
184- return nil , err
221+ return err
185222 }
186223 }
187224
@@ -194,7 +231,7 @@ func (w WALServiceImplementation) Restore(
194231 if IsWALFile (walName ) {
195232 // If this is a regular WAL file, we try to prefetch
196233 if walFilesList , err = gatherWALFilesToRestore (walName , maxParallel ); err != nil {
197- return nil , fmt .Errorf ("while generating the list of WAL files to restore: %w" , err )
234+ return fmt .Errorf ("while generating the list of WAL files to restore: %w" , err )
198235 }
199236 } else {
200237 // This is not a regular WAL file, we fetch it directly
@@ -209,18 +246,18 @@ func (w WALServiceImplementation) Restore(
209246 // is the one that PostgreSQL has requested to restore.
210247 // The failure has already been logged in walRestorer.RestoreList method
211248 if walStatus [0 ].Err != nil {
212- return nil , walStatus [0 ].Err
249+ return walStatus [0 ].Err
213250 }
214251
215252 // We skip this step if streaming connection is not available
216253 endOfWALStream := isEndOfWALStream (walStatus )
217- if isStreamingAvailable (& cluster , w .InstanceName ) && endOfWALStream {
254+ if isStreamingAvailable (cluster , w .InstanceName ) && endOfWALStream {
218255 contextLogger .Info (
219256 "Set end-of-wal-stream flag as one of the WAL files to be prefetched was not found" )
220257
221258 err = walRestorer .SetEndOfWALStream ()
222259 if err != nil {
223- return nil , err
260+ return err
224261 }
225262 }
226263
@@ -241,7 +278,7 @@ func (w WALServiceImplementation) Restore(
241278 "downloadTotalTime" , time .Since (downloadStartTime ),
242279 "totalTime" , time .Since (startTime ))
243280
244- return & wal. WALRestoreResult {}, nil
281+ return nil
245282}
246283
247284// Status implements the WALService interface
0 commit comments