Skip to content

Commit

Permalink
[#3089] use a temp dir inside pb_data to prevent backups cross-device…
Browse files Browse the repository at this point in the history
… link error
  • Loading branch information
ganigeorgiev committed Aug 8, 2023
1 parent bd18688 commit 7a3223e
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 17 deletions.
8 changes: 5 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
## v0.17.3-WIP
## v0.17.3

- Fixed Docker `cross-device link` error when creating `pb_data` backups on a local mounted volume ([#3089](https://github.com/pocketbase/pocketbase/issues/3089)).

- Fixed the error messages for relation to views ([#3090](https://github.com/pocketbase/pocketbase/issues/3090)).

- Always reserve space for the scrollbar to reduce the layout shifts in the Admin UI records listing due to the deprecated `overflow: overlay`.

- Enabled lazy loading for the Admin UI thumb images.

- Fixed the error messages for relation to views ([#3090](https://github.com/pocketbase/pocketbase/issues/3090)).


## v0.17.2

Expand Down
35 changes: 21 additions & 14 deletions core/base_backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,21 @@ func (app *BaseApp) CreateBackup(ctx context.Context, name string) error {
app.Cache().Set(CacheKeyActiveBackup, name)
defer app.Cache().Remove(CacheKeyActiveBackup)

// make sure that the special temp directory exists
// note: it needs to be inside the current pb_data to avoid "cross-device link" errors
localTempDir := filepath.Join(app.DataDir(), LocalTempDirName)
if err := os.MkdirAll(localTempDir, os.ModePerm); err != nil {
return fmt.Errorf("failed to create a temp dir: %w", err)
}

// Archive pb_data in a temp directory, exluding the "backups" dir itself (if exist).
//
// Run in transaction to temporary block other writes (transactions uses the NonconcurrentDB connection).
// ---
tempPath := filepath.Join(os.TempDir(), "pb_backup_"+security.PseudorandomString(4))
tempPath := filepath.Join(localTempDir, "pb_backup_"+security.PseudorandomString(4))
createErr := app.Dao().RunInTransaction(func(txDao *daos.Dao) error {
if err := archive.Create(app.DataDir(), tempPath, LocalBackupsDirName); err != nil {
return err
}
return nil
// @todo consider experimenting with temp switching the readonly pragma after the db interface change
return archive.Create(app.DataDir(), tempPath, LocalBackupsDirName)
})
if createErr != nil {
return createErr
Expand Down Expand Up @@ -152,7 +157,15 @@ func (app *BaseApp) RestoreBackup(ctx context.Context, name string) error {
}
defer br.Close()

tempZip, err := os.CreateTemp(os.TempDir(), "pb_restore")
// make sure that the special temp directory exists
// note: it needs to be inside the current pb_data to avoid "cross-device link" errors
localTempDir := filepath.Join(app.DataDir(), LocalTempDirName)
if err := os.MkdirAll(localTempDir, os.ModePerm); err != nil {
return fmt.Errorf("failed to create a temp dir: %w", err)
}

// create a temp zip file from the blob.Reader and try to extract it
tempZip, err := os.CreateTemp(localTempDir, "pb_restore_zip")
if err != nil {
return err
}
Expand All @@ -162,13 +175,7 @@ func (app *BaseApp) RestoreBackup(ctx context.Context, name string) error {
return err
}

// make sure that the special temp directory
if err := os.MkdirAll(filepath.Join(app.DataDir(), LocalTempDirName), os.ModePerm); err != nil {
return fmt.Errorf("failed to create a temp dir: %w", err)
}

// note: it needs to be inside the current pb_data to avoid "cross-device link" errors
extractedDataDir := filepath.Join(app.DataDir(), LocalTempDirName, "pb_restore_"+security.PseudorandomString(4))
extractedDataDir := filepath.Join(localTempDir, "pb_restore_"+security.PseudorandomString(4))
defer os.RemoveAll(extractedDataDir)
if err := archive.Extract(tempZip.Name(), extractedDataDir); err != nil {
return err
Expand All @@ -192,7 +199,7 @@ func (app *BaseApp) RestoreBackup(ctx context.Context, name string) error {
// move the current pb_data content to a special temp location
// that will hold the old data between dirs replace
// (the temp dir will be automatically removed on the next app start)
oldTempDataDir := filepath.Join(app.DataDir(), LocalTempDirName, "old_pb_data_"+security.PseudorandomString(4))
oldTempDataDir := filepath.Join(localTempDir, "old_pb_data_"+security.PseudorandomString(4))
if err := osutils.MoveDirContent(app.DataDir(), oldTempDataDir, exclude...); err != nil {
return fmt.Errorf("failed to move the current pb_data content to a temp location: %w", err)
}
Expand Down
1 change: 1 addition & 0 deletions core/base_backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ func verifyBackupContent(app core.App, path string) error {
"logs.db-shm",
"logs.db-wal",
".gitignore",
".pb_temp_to_delete",
}

entries, err := os.ReadDir(dir)
Expand Down

0 comments on commit 7a3223e

Please sign in to comment.