Backups: Improve command-line backup and restore commands #4243

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer
2024-05-15 15:25:30 +02:00
parent 6a1c92a8af
commit ca78305eac
5 changed files with 23 additions and 20 deletions

View File

@@ -91,7 +91,7 @@ func backupAction(ctx *cli.Context) error {
if fileName == "" {
if !fs.PathWritable(databasePath) {
if databasePath != "" {
log.Warnf("backup: specified database backup path not writable, using default backup path")
log.Warnf("backup: specified database backup path is not writable, using default directory instead")
}
databasePath = conf.BackupDatabasePath()
@@ -109,7 +109,7 @@ func backupAction(ctx *cli.Context) error {
if backupAlbums {
if !fs.PathWritable(albumsPath) {
if albumsPath != "" {
log.Warnf("backup: specified album backup path not writable, using default backup path")
log.Warnf("backup: specified albums backup path is not writable, using default directory instead")
}
albumsPath = conf.BackupAlbumsPath()

View File

@@ -98,12 +98,12 @@ func restoreAction(ctx *cli.Context) error {
}
if !fs.PathExists(albumsPath) {
log.Warnf("restore: album files path %s not found", clean.Log(albumsPath))
log.Warnf("restore: failed to open %s, album backups cannot be restored", clean.Log(albumsPath))
} else {
log.Infof("restore: restoring albums from %s", clean.Log(albumsPath))
log.Infof("restore: restoring album backups from %s", clean.Log(albumsPath))
if count, err := photoprism.RestoreAlbums(albumsPath, true); err != nil {
return err
if count, restoreErr := photoprism.RestoreAlbums(albumsPath, true); restoreErr != nil {
return restoreErr
} else {
log.Infof("restore: restored %s from YAML files", english.Plural(count, "album", "albums"))
}

View File

@@ -9,6 +9,7 @@ import (
"syscall"
"time"
"github.com/dustin/go-humanize/english"
"github.com/sevlyar/go-daemon"
"github.com/urfave/cli"
@@ -126,9 +127,9 @@ func startAction(ctx *cli.Context) error {
// Restore albums from YAML files.
if count, restoreErr := photoprism.RestoreAlbums(conf.BackupAlbumsPath(), false); restoreErr != nil {
log.Errorf("restore: %s", restoreErr)
log.Errorf("restore: %s (albums)", restoreErr)
} else if count > 0 {
log.Infof("%d albums restored", count)
log.Infof("restore: %s restored", english.Plural(count, "album backup", "album backups"))
}
// Start worker that periodically deletes expired sessions.

View File

@@ -19,7 +19,7 @@ func RestoreAlbums(backupPath string, force bool) (count int, result error) {
c := Config()
if !c.BackupAlbums() && !force {
log.Debugf("restore: album metadata backups are disabled")
log.Debugf("albums: metadata backup files are disabled")
return count, nil
}
@@ -30,7 +30,7 @@ func RestoreAlbums(backupPath string, force bool) (count int, result error) {
}
if len(existing) > 0 && !force {
log.Debugf("restore: found existing albums, backup not restored")
log.Debugf("albums: skipped restoring backups because albums already exist")
return count, nil
}
@@ -57,14 +57,14 @@ func RestoreAlbums(backupPath string, force bool) (count int, result error) {
a := entity.Album{}
if err = a.LoadFromYaml(fileName); err != nil {
log.Errorf("restore: %s in %s", err, clean.Log(filepath.Base(fileName)))
log.Errorf("albums: %s in %s (restore)", err, clean.Log(filepath.Base(fileName)))
result = err
} else if a.AlbumType == "" || len(a.Photos) == 0 && a.AlbumFilter == "" {
log.Debugf("restore: skipping %s", clean.Log(filepath.Base(fileName)))
log.Debugf("albums: skipped %s (restore)", clean.Log(filepath.Base(fileName)))
} else if found := a.Find(); found != nil {
log.Infof("%s: %s already exists", found.AlbumType, clean.Log(found.AlbumTitle))
log.Infof("%s: %s already exists (restore)", found.AlbumType, clean.Log(found.AlbumTitle))
} else if err = a.Create(); err != nil {
log.Errorf("%s: %s in %s", a.AlbumType, err, clean.Log(filepath.Base(fileName)))
log.Errorf("%s: %s in %s (restore)", a.AlbumType, err, clean.Log(filepath.Base(fileName)))
} else {
count++
}

View File

@@ -42,7 +42,7 @@ func RestoreDatabase(backupPath, fileName string, fromStdIn, force bool) (err er
}
if len(files) == 0 {
return fmt.Errorf("found no database backup files in %s", backupPath)
return fmt.Errorf("failed to find a backup in %s, index cannot be restored", backupPath)
}
sort.Strings(files)
@@ -50,22 +50,22 @@ func RestoreDatabase(backupPath, fileName string, fromStdIn, force bool) (err er
fileName = files[len(files)-1]
if !fs.FileExistsNotEmpty(fileName) {
return fmt.Errorf("no database backup found in %s", filepath.Base(fileName))
return fmt.Errorf("failed to open %s, index cannot be restored", filepath.Base(fileName))
}
} else if backupPath == "" {
if absName, absErr := filepath.Abs(fileName); absErr == nil && fs.FileExists(absName) {
fileName = absName
} else if dir := filepath.Dir(fileName); dir != "" && dir != "." {
return fmt.Errorf("file %s not found", clean.Log(fileName))
return fmt.Errorf("failed to find %s, index cannot be restored", clean.Log(fileName))
} else if absName = filepath.Join(c.BackupDatabasePath(), fileName); !fs.FileExists(absName) {
return fmt.Errorf("file %s not found in %s backup path", clean.Log(fileName), clean.Log(filepath.Base(c.BackupDatabasePath())))
return fmt.Errorf("failed to find %s in the %s backup path, index cannot be restored", clean.Log(fileName), clean.Log(filepath.Base(c.BackupDatabasePath())))
} else {
fileName = absName
}
} else if absName, absErr := filepath.Abs(filepath.Join(backupPath, fileName)); absErr == nil && fs.FileExists(absName) {
fileName = absName
} else {
return fmt.Errorf("file %s not found in %s", clean.Log(filepath.Base(fileName)), clean.Log(backupPath))
return fmt.Errorf("failed to find %s in %s, index cannot be restored", clean.Log(filepath.Base(fileName)), clean.Log(backupPath))
}
}
@@ -144,13 +144,15 @@ func RestoreDatabase(backupPath, fileName string, fromStdIn, force bool) (err er
// Run restore command.
if cmdErr := cmd.Run(); cmdErr != nil {
log.Errorf("restore: failed to restore database backup")
log.Errorf("restore: failed to restore index database")
if errStr := strings.TrimSpace(stderr.String()); errStr != "" {
return errors.New(errStr)
}
return cmdErr
} else {
log.Infof("restore: index database successfully restored")
}
return nil