Skip to content

Commit 615461e

Browse files
authored
Merge pull request #8 from sseago/fix-restore-logging
Fixes logger configuration for restore plugins
2 parents ca33d4d + c75404f commit 615461e

File tree

1 file changed

+120
-119
lines changed

1 file changed

+120
-119
lines changed

pkg/controller/restore_controller.go

+120-119
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ import (
4141
"github.com/heptio/velero/pkg/metrics"
4242
"github.com/heptio/velero/pkg/persistence"
4343
"github.com/heptio/velero/pkg/plugin"
44-
"github.com/heptio/velero/pkg/plugin/velero"
4544
"github.com/heptio/velero/pkg/restore"
4645
"github.com/heptio/velero/pkg/util/collections"
4746
kubeutil "github.com/heptio/velero/pkg/util/kube"
4847
"github.com/heptio/velero/pkg/util/logging"
48+
"github.com/heptio/velero/pkg/volume"
4949
)
5050

5151
// nonRestorableResources is a blacklist for the restoration process. Any resources
@@ -204,6 +204,40 @@ func (c *restoreController) processRestore(key string) error {
204204
// don't modify items in the cache
205205
restore = restore.DeepCopy()
206206

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+
207241
pluginManager := c.newPluginManager(log)
208242
defer pluginManager.CleanupClients()
209243

@@ -241,22 +275,97 @@ func (c *restoreController) processRestore(key string) error {
241275
log.Debug("Running restore")
242276

243277
// 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+
}
250327

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
251360
//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 {
254363
restore.Status.Warnings += len(w)
255364
}
256365

257366
//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 {
260369
restore.Status.Errors += len(e)
261370
}
262371

@@ -431,114 +540,6 @@ func (c *restoreController) fetchBackupInfo(backupName string, pluginManager plu
431540
}, nil
432541
}
433542

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-
542543
func downloadToTempFile(
543544
backupName string,
544545
backupStore persistence.BackupStore,

0 commit comments

Comments
 (0)