diff --git a/cli/app/restore.go b/cli/app/restore.go index e2e4e5db..44db9b9c 100644 --- a/cli/app/restore.go +++ b/cli/app/restore.go @@ -30,7 +30,7 @@ var appRestoreCommand = cli.Command{ Name: "restore", Aliases: []string{"rs"}, Usage: "Run app restore", - ArgsUsage: " ", + ArgsUsage: " ", Flags: []cli.Flag{ internal.DebugFlag, }, @@ -40,12 +40,17 @@ var appRestoreCommand = cli.Command{ This command runs an app restore. Pre/post hook commands are defined in the recipe configuration. Abra reads this -config and run the comands in the context of the service before restoring the -backup. +configuration and run the comands in the context of the service before +restoring the backup. + +Unlike "abra app backup", restore must be run on a per-service basis. You can +not restore all services in one go. Backup files produced by Abra are +compressed archives which use absolute paths. This allows Abra to restore +according to standard tar command logic. Example: - abra app restore example.com app mybackup.tar.gz /var/lib/content + abra app restore example.com app ~/.abra/backups/example_com_app_609341138.tar.gz `, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) @@ -60,11 +65,6 @@ Example: internal.ShowSubcommandHelpAndError(c, errors.New("missing ?")) } - restorePath := c.Args().Get(3) - if restorePath == "" { - internal.ShowSubcommandHelpAndError(c, errors.New("missing ?")) - } - if _, err := os.Stat(backupPath); err != nil { if os.IsNotExist(err) { logrus.Fatalf("%s doesn't exist?", backupPath) @@ -104,7 +104,7 @@ Example: if !ok { rsConfig = restoreConfig{} } - if err := runRestore(app, backupPath, restorePath, serviceName, rsConfig); err != nil { + if err := runRestore(app, backupPath, serviceName, rsConfig); err != nil { logrus.Fatal(err) } @@ -113,7 +113,7 @@ Example: } // runRestore does the actual restore logic. -func runRestore(app config.App, backupPath, restorePath, serviceName string, rsConfig restoreConfig) error { +func runRestore(app config.App, backupPath, serviceName string, rsConfig restoreConfig) error { cl, err := client.New(app.Server) if err != nil { return err @@ -165,12 +165,16 @@ func runRestore(app config.App, backupPath, restorePath, serviceName string, rsC return err } + // we use absolute paths so tar knows what to do. it will restore files + // according to the paths set in the compresed archive + restorePath := "/" + copyOpts := types.CopyToContainerOptions{AllowOverwriteDirWithFile: false, CopyUIDGID: false} if err := cl.CopyToContainer(context.Background(), targetContainer.ID, restorePath, content, copyOpts); err != nil { return err } - logrus.Infof("restored %s to %s:%s", backupPath, fullServiceName, restorePath) + logrus.Infof("restored %s to %s", backupPath, fullServiceName) if rsConfig.postHookCmd != "" { splitCmd := internal.SafeSplit(rsConfig.postHookCmd)