package app import ( "fmt" "strings" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "github.com/spf13/cobra" ) // translators: `abra app restore` aliases. use a comma separated list of // aliases with no spaces in between var appRestoreAliases = i18n.G("rs") var AppRestoreCommand = &cobra.Command{ // translators: `app restore` command Use: i18n.G("restore [flags]"), Aliases: strings.Split(appRestoreAliases, ","), // translators: Short description for `app restore` command Short: i18n.G("Restore a snapshot"), Long: i18n.G(`Snapshots are restored while apps are deployed. Some restore scenarios may require service / app restarts.`), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return autocomplete.AppNameComplete() }, Run: func(cmd *cobra.Command, args []string) { app := internal.ValidateApp(args) if err := app.Recipe.Ensure(internal.GetEnsureContext()); err != nil { log.Fatal(err) } cl, err := client.New(app.Server) if err != nil { log.Fatal(err) } targetContainer, err := internal.RetrieveBackupBotContainer(cl) if err != nil { log.Fatal(err) } execEnv := []string{ fmt.Sprintf("SERVICE=%s", app.Domain), "MACHINE_LOGS=true", } if snapshot != "" { log.Debug(i18n.G("including SNAPSHOT=%s in backupbot exec invocation", snapshot)) execEnv = append(execEnv, fmt.Sprintf("SNAPSHOT=%s", snapshot)) } if targetPath != "" { log.Debug(i18n.G("including TARGET=%s in backupbot exec invocation", targetPath)) execEnv = append(execEnv, fmt.Sprintf("TARGET=%s", targetPath)) } if internal.NoInput { log.Debug(i18n.G("including NONINTERACTIVE=%v in backupbot exec invocation", internal.NoInput)) execEnv = append(execEnv, fmt.Sprintf("NONINTERACTIVE=%v", internal.NoInput)) } if len(volumes) > 0 { allVolumes := strings.Join(volumes, ",") log.Debug(i18n.G("including VOLUMES=%s in backupbot exec invocation", allVolumes)) execEnv = append(execEnv, fmt.Sprintf("VOLUMES=%s", allVolumes)) } if len(services) > 0 { allServices := strings.Join(services, ",") log.Debug(i18n.G("including CONTAINER=%s in backupbot exec invocation", allServices)) execEnv = append(execEnv, fmt.Sprintf("CONTAINER=%s", allServices)) } if hooks { log.Debug(i18n.G("including NO_COMMANDS=%v in backupbot exec invocation", false)) execEnv = append(execEnv, fmt.Sprintf("NO_COMMANDS=%v", false)) } if _, err := internal.RunBackupCmdRemote(cl, "restore", targetContainer.ID, execEnv); err != nil { log.Fatal(err) } }, } var ( targetPath string hooks bool services []string volumes []string ) func init() { AppRestoreCommand.Flags().StringVarP( &targetPath, i18n.G("target"), i18n.G("t"), "/", i18n.G("target path"), ) AppRestoreCommand.Flags().StringArrayVarP( &services, i18n.G("services"), i18n.G("s"), []string{}, i18n.G("restore specific services"), ) AppRestoreCommand.Flags().StringArrayVarP( &volumes, i18n.G("volumes"), i18n.G("v"), []string{}, i18n.G("restore specific volumes"), ) AppRestoreCommand.Flags().BoolVarP( &hooks, i18n.G("hooks"), i18n.G("H"), false, i18n.G("enable pre/post-hook command execution"), ) AppRestoreCommand.Flags().BoolVarP( &internal.Chaos, i18n.G("chaos"), i18n.G("C"), false, i18n.G("ignore uncommitted recipes changes"), ) }