@@ -41,11 +41,11 @@ import (
41
41
"github.com/heptio/velero/pkg/metrics"
42
42
"github.com/heptio/velero/pkg/persistence"
43
43
"github.com/heptio/velero/pkg/plugin"
44
- "github.com/heptio/velero/pkg/plugin/velero"
45
44
"github.com/heptio/velero/pkg/restore"
46
45
"github.com/heptio/velero/pkg/util/collections"
47
46
kubeutil "github.com/heptio/velero/pkg/util/kube"
48
47
"github.com/heptio/velero/pkg/util/logging"
48
+ "github.com/heptio/velero/pkg/volume"
49
49
)
50
50
51
51
// nonRestorableResources is a blacklist for the restoration process. Any resources
@@ -204,6 +204,40 @@ func (c *restoreController) processRestore(key string) error {
204
204
// don't modify items in the cache
205
205
restore = restore .DeepCopy ()
206
206
207
+ // begin log setup from runRestore
208
+ var restoreWarnings , restoreErrors api.RestoreResult
209
+ var restoreFailure error
210
+ logFile , err := ioutil .TempFile ("" , "" )
211
+ if err != nil {
212
+ c .logger .
213
+ WithFields (
214
+ logrus.Fields {
215
+ "restore" : kubeutil .NamespaceAndName (restore ),
216
+ "backup" : restore .Spec .BackupName ,
217
+ },
218
+ ).
219
+ WithError (errors .WithStack (err )).
220
+ Error ("Error creating log temp file" )
221
+ restoreFailure = err
222
+ restoreErrors .Velero = append (restoreErrors .Velero , err .Error ())
223
+ }
224
+ gzippedLogFile := gzip .NewWriter (logFile )
225
+ // Assuming we successfully uploaded the log file, this will have already been closed below. It is safe to call
226
+ // close multiple times. If we get an error closing this, there's not really anything we can do about it.
227
+ defer gzippedLogFile .Close ()
228
+ defer closeAndRemoveFile (logFile , c .logger )
229
+
230
+ // Log the backup to both a backup log file and to stdout. This will help see what happened if the upload of the
231
+ // backup log failed for whatever reason.
232
+ logger := logging .DefaultLogger (c .restoreLogLevel )
233
+ logger .Out = io .MultiWriter (os .Stdout , gzippedLogFile )
234
+ log = logger .WithFields (
235
+ logrus.Fields {
236
+ "restore" : kubeutil .NamespaceAndName (restore ),
237
+ "backup" : restore .Spec .BackupName ,
238
+ })
239
+ // end log setup from runRestore
240
+
207
241
pluginManager := c .newPluginManager (log )
208
242
defer pluginManager .CleanupClients ()
209
243
@@ -241,22 +275,97 @@ func (c *restoreController) processRestore(key string) error {
241
275
log .Debug ("Running restore" )
242
276
243
277
// execution & upload of restore
244
- restoreRes , restoreFailure := c .runRestore (
245
- restore ,
246
- actions ,
247
- info ,
248
- pluginManager ,
249
- )
278
+ // begin runRestore
279
+ var backupFile , resultsFile * os.File
280
+ var volumeSnapshots []* volume.Snapshot
281
+ var gzippedResultsFile * gzip.Writer
282
+ if restoreFailure == nil {
283
+ backupFile , err = downloadToTempFile (restore .Spec .BackupName , info .backupStore , c .logger )
284
+ if err != nil {
285
+ log .WithError (err ).Error ("Error downloading backup" )
286
+ restoreErrors .Velero = append (restoreErrors .Velero , err .Error ())
287
+ restoreFailure = err
288
+ }
289
+ }
290
+ if restoreFailure == nil {
291
+ defer closeAndRemoveFile (backupFile , c .logger )
292
+
293
+ resultsFile , err = ioutil .TempFile ("" , "" )
294
+ if err != nil {
295
+ log .WithError (errors .WithStack (err )).Error ("Error creating results temp file" )
296
+ restoreErrors .Velero = append (restoreErrors .Velero , err .Error ())
297
+ restoreFailure = err
298
+ }
299
+ }
300
+ if restoreFailure == nil {
301
+ defer closeAndRemoveFile (resultsFile , c .logger )
302
+
303
+ volumeSnapshots , err = info .backupStore .GetBackupVolumeSnapshots (restore .Spec .BackupName )
304
+ if err != nil {
305
+ log .WithError (errors .WithStack (err )).Error ("Error fetching volume snapshots" )
306
+ restoreErrors .Velero = append (restoreErrors .Velero , err .Error ())
307
+ restoreFailure = err
308
+ }
309
+ }
310
+ // Any restoreFailure above this line means a total restore failure
311
+ // Some failures after this line *may* be a total restore failure
312
+ if restoreFailure == nil {
313
+ var stopWithoutFailure = false
314
+ log .Info ("starting restore" )
315
+ restoreWarnings , restoreErrors = c .restorer .Restore (log , restore , info .backup , volumeSnapshots , backupFile , actions , c .snapshotLocationLister , pluginManager )
316
+ log .Info ("restore completed" )
317
+
318
+ // Try to upload the log file. This is best-effort. If we fail, we'll add to the velero errors.
319
+ if err := gzippedLogFile .Close (); err != nil {
320
+ c .logger .WithError (err ).Error ("error closing gzippedLogFile" )
321
+ }
322
+ // Reset the offset to 0 for reading
323
+ if _ , err = logFile .Seek (0 , 0 ); err != nil {
324
+ restoreErrors .Velero = append (restoreErrors .Velero , fmt .Sprintf ("error resetting log file offset to 0: %v" , err ))
325
+ stopWithoutFailure = true
326
+ }
250
327
328
+ if ! stopWithoutFailure {
329
+ if err := info .backupStore .PutRestoreLog (restore .Spec .BackupName , restore .Name , logFile ); err != nil {
330
+ restoreErrors .Ark = append (restoreErrors .Ark , fmt .Sprintf ("error uploading log file to backup storage: %v" , err ))
331
+ }
332
+
333
+ m := map [string ]api.RestoreResult {
334
+ "warnings" : restoreWarnings ,
335
+ "errors" : restoreErrors ,
336
+ }
337
+
338
+ gzippedResultsFile = gzip .NewWriter (resultsFile )
339
+
340
+ if err := json .NewEncoder (gzippedResultsFile ).Encode (m ); err != nil {
341
+ log .WithError (errors .WithStack (err )).Error ("Error encoding restore results" )
342
+ stopWithoutFailure = true
343
+ }
344
+ }
345
+ if ! stopWithoutFailure {
346
+ gzippedResultsFile .Close ()
347
+
348
+ if _ , err = resultsFile .Seek (0 , 0 ); err != nil {
349
+ log .WithError (errors .WithStack (err )).Error ("Error resetting results file offset to 0" )
350
+ stopWithoutFailure = true
351
+ }
352
+ }
353
+ if ! stopWithoutFailure {
354
+ if err := info .backupStore .PutRestoreResults (restore .Spec .BackupName , restore .Name , resultsFile ); err != nil {
355
+ log .WithError (errors .WithStack (err )).Error ("Error uploading results file to backup storage" )
356
+ }
357
+ }
358
+ }
359
+ // end runRestore
251
360
//TODO(1.0): Remove warnings.Ark
252
- restore .Status .Warnings = len (restoreRes . warnings . Velero ) + len (restoreRes . warnings . Cluster ) + len (restoreRes . warnings .Ark )
253
- for _ , w := range restoreRes . warnings .Namespaces {
361
+ restore .Status .Warnings = len (restoreWarnings . Velero ) + len (restoreWarnings . Cluster ) + len (restoreWarnings .Ark )
362
+ for _ , w := range restoreWarnings .Namespaces {
254
363
restore .Status .Warnings += len (w )
255
364
}
256
365
257
366
//TODO (1.0): Remove errors.Ark
258
- restore .Status .Errors = len (restoreRes . errors . Velero ) + len (restoreRes . errors . Cluster ) + len (restoreRes . errors .Ark )
259
- for _ , e := range restoreRes . errors .Namespaces {
367
+ restore .Status .Errors = len (restoreErrors . Velero ) + len (restoreErrors . Cluster ) + len (restoreErrors .Ark )
368
+ for _ , e := range restoreErrors .Namespaces {
260
369
restore .Status .Errors += len (e )
261
370
}
262
371
@@ -431,114 +540,6 @@ func (c *restoreController) fetchBackupInfo(backupName string, pluginManager plu
431
540
}, nil
432
541
}
433
542
434
- func (c * restoreController ) runRestore (
435
- restore * api.Restore ,
436
- actions []velero.RestoreItemAction ,
437
- info backupInfo ,
438
- pluginManager plugin.Manager ,
439
- ) (restoreResult , error ) {
440
- var restoreWarnings , restoreErrors api.RestoreResult
441
- var restoreFailure error
442
- logFile , err := ioutil .TempFile ("" , "" )
443
- if err != nil {
444
- c .logger .
445
- WithFields (
446
- logrus.Fields {
447
- "restore" : kubeutil .NamespaceAndName (restore ),
448
- "backup" : restore .Spec .BackupName ,
449
- },
450
- ).
451
- WithError (errors .WithStack (err )).
452
- Error ("Error creating log temp file" )
453
- restoreErrors .Velero = append (restoreErrors .Velero , err .Error ())
454
- return restoreResult {warnings : restoreWarnings , errors : restoreErrors }, restoreFailure
455
- }
456
- gzippedLogFile := gzip .NewWriter (logFile )
457
- // Assuming we successfully uploaded the log file, this will have already been closed below. It is safe to call
458
- // close multiple times. If we get an error closing this, there's not really anything we can do about it.
459
- defer gzippedLogFile .Close ()
460
- defer closeAndRemoveFile (logFile , c .logger )
461
-
462
- // Log the backup to both a backup log file and to stdout. This will help see what happened if the upload of the
463
- // backup log failed for whatever reason.
464
- logger := logging .DefaultLogger (c .restoreLogLevel )
465
- logger .Out = io .MultiWriter (os .Stdout , gzippedLogFile )
466
- log := logger .WithFields (
467
- logrus.Fields {
468
- "restore" : kubeutil .NamespaceAndName (restore ),
469
- "backup" : restore .Spec .BackupName ,
470
- })
471
-
472
- backupFile , err := downloadToTempFile (restore .Spec .BackupName , info .backupStore , c .logger )
473
- if err != nil {
474
- log .WithError (err ).Error ("Error downloading backup" )
475
- restoreErrors .Velero = append (restoreErrors .Velero , err .Error ())
476
- restoreFailure = err
477
- return restoreResult {warnings : restoreWarnings , errors : restoreErrors }, restoreFailure
478
- }
479
- defer closeAndRemoveFile (backupFile , c .logger )
480
-
481
- resultsFile , err := ioutil .TempFile ("" , "" )
482
- if err != nil {
483
- log .WithError (errors .WithStack (err )).Error ("Error creating results temp file" )
484
- restoreErrors .Velero = append (restoreErrors .Velero , err .Error ())
485
- restoreFailure = err
486
- return restoreResult {warnings : restoreWarnings , errors : restoreErrors }, restoreFailure
487
- }
488
- defer closeAndRemoveFile (resultsFile , c .logger )
489
-
490
- volumeSnapshots , err := info .backupStore .GetBackupVolumeSnapshots (restore .Spec .BackupName )
491
- if err != nil {
492
- log .WithError (errors .WithStack (err )).Error ("Error fetching volume snapshots" )
493
- restoreErrors .Velero = append (restoreErrors .Velero , err .Error ())
494
- restoreFailure = err
495
- return restoreResult {warnings : restoreWarnings , errors : restoreErrors }, restoreFailure
496
- }
497
-
498
- // Any return statement above this line means a total restore failure
499
- // Some failures after this line *may* be a total restore failure
500
- log .Info ("starting restore" )
501
- restoreWarnings , restoreErrors = c .restorer .Restore (log , restore , info .backup , volumeSnapshots , backupFile , actions , c .snapshotLocationLister , pluginManager )
502
- log .Info ("restore completed" )
503
-
504
- // Try to upload the log file. This is best-effort. If we fail, we'll add to the velero errors.
505
- if err := gzippedLogFile .Close (); err != nil {
506
- c .logger .WithError (err ).Error ("error closing gzippedLogFile" )
507
- }
508
- // Reset the offset to 0 for reading
509
- if _ , err = logFile .Seek (0 , 0 ); err != nil {
510
- restoreErrors .Velero = append (restoreErrors .Velero , fmt .Sprintf ("error resetting log file offset to 0: %v" , err ))
511
- return restoreResult {warnings : restoreWarnings , errors : restoreErrors }, restoreFailure
512
- }
513
-
514
- if err := info .backupStore .PutRestoreLog (restore .Spec .BackupName , restore .Name , logFile ); err != nil {
515
- restoreErrors .Ark = append (restoreErrors .Ark , fmt .Sprintf ("error uploading log file to backup storage: %v" , err ))
516
- }
517
-
518
- m := map [string ]api.RestoreResult {
519
- "warnings" : restoreWarnings ,
520
- "errors" : restoreErrors ,
521
- }
522
-
523
- gzippedResultsFile := gzip .NewWriter (resultsFile )
524
-
525
- if err := json .NewEncoder (gzippedResultsFile ).Encode (m ); err != nil {
526
- log .WithError (errors .WithStack (err )).Error ("Error encoding restore results" )
527
- return restoreResult {warnings : restoreWarnings , errors : restoreErrors }, restoreFailure
528
- }
529
- gzippedResultsFile .Close ()
530
-
531
- if _ , err = resultsFile .Seek (0 , 0 ); err != nil {
532
- log .WithError (errors .WithStack (err )).Error ("Error resetting results file offset to 0" )
533
- return restoreResult {warnings : restoreWarnings , errors : restoreErrors }, restoreFailure
534
- }
535
- if err := info .backupStore .PutRestoreResults (restore .Spec .BackupName , restore .Name , resultsFile ); err != nil {
536
- log .WithError (errors .WithStack (err )).Error ("Error uploading results file to backup storage" )
537
- }
538
-
539
- return restoreResult {warnings : restoreWarnings , errors : restoreErrors }, restoreFailure
540
- }
541
-
542
543
func downloadToTempFile (
543
544
backupName string ,
544
545
backupStore persistence.BackupStore ,
0 commit comments