diff --git a/api/datastore/backup.go b/api/datastore/backup.go index df0ad9583..0a18346b4 100644 --- a/api/datastore/backup.go +++ b/api/datastore/backup.go @@ -1,9 +1,11 @@ package datastore import ( + "fmt" "os" "path" + portainer "github.com/portainer/portainer/api" "github.com/rs/zerolog/log" ) @@ -14,10 +16,22 @@ func (store *Store) Backup() (string, error) { backupFilename := store.backupFilename() log.Info().Str("from", store.connection.GetDatabaseFilePath()).Str("to", backupFilename).Msgf("Backing up database") - err := store.fileService.Copy(store.connection.GetDatabaseFilePath(), backupFilename, true) + + // Close the store before backing up + err := store.Close() if err != nil { - log.Warn().Err(err).Msg("failed to create backup file") - return "", err + return "", fmt.Errorf("failed to close store before backup: %w", err) + } + + err = store.fileService.Copy(store.connection.GetDatabaseFilePath(), backupFilename, true) + if err != nil { + return "", fmt.Errorf("failed to create backup file: %w", err) + } + + // reopen the store + _, err = store.Open() + if err != nil { + return "", fmt.Errorf("failed to reopen store after backup: %w", err) } return backupFilename, nil @@ -29,31 +43,25 @@ func (store *Store) Restore() error { } func (store *Store) RestoreFromFile(backupFilename string) error { - if exists, _ := store.fileService.FileExists(backupFilename); !exists { - log.Error().Str("backupFilename", backupFilename).Msg("backup file does not exist") - return os.ErrNotExist - } - if err := store.fileService.Copy(backupFilename, store.connection.GetDatabaseFilePath(), true); err != nil { - log.Error().Err(err).Msg("error while restoring backup.") - return err + return fmt.Errorf("unable to restore backup file %q. err: %w", backupFilename, err) } log.Info().Str("from", store.connection.GetDatabaseFilePath()).Str("to", backupFilename).Msgf("database restored") + _, err := store.Open() + if err != nil { + return fmt.Errorf("unable to determine version of restored portainer backup file: %w", err) + } + // determine the db version - store.Open() version, err := store.VersionService.Version() - - edition := "CE" - if version.Edition == 2 { - edition = "EE" - } - - if err == nil { - log.Info().Str("version", version.SchemaVersion).Msgf("Restored database version: Portainer %s %s", edition, version.SchemaVersion) + if err != nil { + return fmt.Errorf("unable to determine restored database version. err: %w", err) } + editionLabel := portainer.SoftwareEdition(version.Edition).GetEditionLabel() + log.Info().Str("version", version.SchemaVersion).Msgf("Restored database version: Portainer %s %s ", editionLabel, version.SchemaVersion) return nil } @@ -61,8 +69,7 @@ func (store *Store) createBackupPath() error { backupDir := path.Join(store.connection.GetStorePath(), "backups") if exists, _ := store.fileService.FileExists(backupDir); !exists { if err := os.MkdirAll(backupDir, 0700); err != nil { - log.Error().Err(err).Msg("error while creating backup folder") - return err + return fmt.Errorf("unable to create backup folder: %w", err) } } return nil