2022-03-30 23:53:11 +00:00
|
|
|
package app
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"coopcloud.tech/abra/cli/internal"
|
|
|
|
"coopcloud.tech/abra/pkg/autocomplete"
|
|
|
|
"coopcloud.tech/abra/pkg/client"
|
2024-03-12 09:34:40 +00:00
|
|
|
"coopcloud.tech/abra/pkg/recipe"
|
2022-03-30 23:53:11 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"github.com/urfave/cli"
|
|
|
|
)
|
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
var snapshot string
|
|
|
|
var snapshotFlag = &cli.StringFlag{
|
|
|
|
Name: "snapshot, s",
|
|
|
|
Usage: "Lists specific snapshot",
|
|
|
|
Destination: &snapshot,
|
2022-03-30 23:53:11 +00:00
|
|
|
}
|
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
var includePath string
|
|
|
|
var includePathFlag = &cli.StringFlag{
|
|
|
|
Name: "path, p",
|
|
|
|
Usage: "Include path",
|
|
|
|
Destination: &includePath,
|
|
|
|
}
|
|
|
|
|
|
|
|
var resticRepo string
|
|
|
|
var resticRepoFlag = &cli.StringFlag{
|
|
|
|
Name: "repo, r",
|
|
|
|
Usage: "Restic repository",
|
|
|
|
Destination: &resticRepo,
|
|
|
|
}
|
|
|
|
|
|
|
|
var appBackupListCommand = cli.Command{
|
|
|
|
Name: "list",
|
|
|
|
Aliases: []string{"ls"},
|
2022-03-30 23:53:11 +00:00
|
|
|
Flags: []cli.Flag{
|
|
|
|
internal.DebugFlag,
|
2023-07-26 06:16:07 +00:00
|
|
|
internal.OfflineFlag,
|
2024-03-12 09:34:40 +00:00
|
|
|
snapshotFlag,
|
|
|
|
includePathFlag,
|
2022-03-30 23:53:11 +00:00
|
|
|
},
|
|
|
|
Before: internal.SubCommandBefore,
|
2024-03-12 09:34:40 +00:00
|
|
|
Usage: "List all backups",
|
2022-03-30 23:53:11 +00:00
|
|
|
BashComplete: autocomplete.AppNameComplete,
|
|
|
|
Action: func(c *cli.Context) error {
|
2023-09-07 16:50:25 +00:00
|
|
|
app := internal.ValidateApp(c)
|
2022-03-30 23:53:11 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if err := recipe.EnsureExists(app.Recipe); err != nil {
|
2022-03-30 23:53:11 +00:00
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2023-09-22 07:47:36 +00:00
|
|
|
if !internal.Chaos {
|
2024-03-12 09:34:40 +00:00
|
|
|
if err := recipe.EnsureIsClean(app.Recipe); err != nil {
|
2023-09-22 07:47:36 +00:00
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !internal.Offline {
|
2024-03-12 09:34:40 +00:00
|
|
|
if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
|
2023-09-22 07:47:36 +00:00
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if err := recipe.EnsureLatest(app.Recipe); err != nil {
|
2023-09-22 07:47:36 +00:00
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-12 09:03:42 +00:00
|
|
|
cl, err := client.New(app.Server)
|
|
|
|
if err != nil {
|
2023-10-01 06:02:30 +00:00
|
|
|
logrus.Fatal(err)
|
2022-03-30 23:53:11 +00:00
|
|
|
}
|
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
targetContainer, err := internal.RetrieveBackupBotContainer(cl)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2022-03-30 23:53:11 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
execEnv := []string{fmt.Sprintf("SERVICE=%s", app.Domain)}
|
|
|
|
if snapshot != "" {
|
|
|
|
logrus.Debugf("including SNAPSHOT=%s in backupbot exec invocation", snapshot)
|
|
|
|
execEnv = append(execEnv, fmt.Sprintf("SNAPSHOT=%s", snapshot))
|
|
|
|
}
|
|
|
|
if includePath != "" {
|
|
|
|
logrus.Debugf("including INCLUDE_PATH=%s in backupbot exec invocation", includePath)
|
|
|
|
execEnv = append(execEnv, fmt.Sprintf("INCLUDE_PATH=%s", includePath))
|
|
|
|
}
|
2024-03-12 09:03:42 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if err := internal.RunBackupCmdRemote(cl, "ls", targetContainer.ID, execEnv); err != nil {
|
|
|
|
logrus.Fatal(err)
|
2024-03-12 09:03:42 +00:00
|
|
|
}
|
2023-10-01 06:02:30 +00:00
|
|
|
|
2024-03-12 09:03:42 +00:00
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
var appBackupDownloadCommand = cli.Command{
|
|
|
|
Name: "download",
|
|
|
|
Aliases: []string{"d"},
|
|
|
|
Flags: []cli.Flag{
|
|
|
|
internal.DebugFlag,
|
|
|
|
internal.OfflineFlag,
|
|
|
|
snapshotFlag,
|
|
|
|
includePathFlag,
|
|
|
|
},
|
|
|
|
Before: internal.SubCommandBefore,
|
|
|
|
Usage: "Download a backup",
|
|
|
|
BashComplete: autocomplete.AppNameComplete,
|
|
|
|
Action: func(c *cli.Context) error {
|
|
|
|
app := internal.ValidateApp(c)
|
2022-03-30 23:53:11 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if err := recipe.EnsureExists(app.Recipe); err != nil {
|
|
|
|
logrus.Fatal(err)
|
2022-03-30 23:53:11 +00:00
|
|
|
}
|
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if !internal.Chaos {
|
|
|
|
if err := recipe.EnsureIsClean(app.Recipe); err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2024-03-12 09:03:42 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if !internal.Offline {
|
|
|
|
if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2024-03-12 09:03:42 +00:00
|
|
|
}
|
2024-03-12 09:34:40 +00:00
|
|
|
|
|
|
|
if err := recipe.EnsureLatest(app.Recipe); err != nil {
|
|
|
|
logrus.Fatal(err)
|
2024-03-12 09:03:42 +00:00
|
|
|
}
|
2023-10-01 06:02:30 +00:00
|
|
|
}
|
2024-03-12 09:03:42 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
cl, err := client.New(app.Server)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Fatal(err)
|
2023-10-01 06:02:30 +00:00
|
|
|
}
|
2024-03-12 09:03:42 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
targetContainer, err := internal.RetrieveBackupBotContainer(cl)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2024-03-12 09:03:42 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
execEnv := []string{fmt.Sprintf("SERVICE=%s", app.Domain)}
|
|
|
|
if snapshot != "" {
|
|
|
|
logrus.Debugf("including SNAPSHOT=%s in backupbot exec invocation", snapshot)
|
|
|
|
execEnv = append(execEnv, fmt.Sprintf("SNAPSHOT=%s", snapshot))
|
|
|
|
}
|
|
|
|
if includePath != "" {
|
|
|
|
logrus.Debugf("including INCLUDE_PATH=%s in backupbot exec invocation", includePath)
|
|
|
|
execEnv = append(execEnv, fmt.Sprintf("INCLUDE_PATH=%s", includePath))
|
|
|
|
}
|
2024-03-12 09:03:42 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if err := internal.RunBackupCmdRemote(cl, "download", targetContainer.ID, execEnv); err != nil {
|
|
|
|
logrus.Fatal(err)
|
2022-03-30 23:53:11 +00:00
|
|
|
}
|
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
remoteBackupDir := "/tmp/backup.tar.gz"
|
|
|
|
currentWorkingDir := "."
|
|
|
|
if err = CopyFromContainer(cl, targetContainer.ID, remoteBackupDir, currentWorkingDir); err != nil {
|
|
|
|
logrus.Fatal(err)
|
2022-03-30 23:53:11 +00:00
|
|
|
}
|
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
fmt.Println("backup successfully downloaded to current working directory")
|
2022-03-30 23:53:11 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
return nil
|
|
|
|
},
|
2022-03-30 23:53:11 +00:00
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
var appBackupCreateCommand = cli.Command{
|
|
|
|
Name: "create",
|
|
|
|
Aliases: []string{"c"},
|
|
|
|
Flags: []cli.Flag{
|
|
|
|
internal.DebugFlag,
|
|
|
|
internal.OfflineFlag,
|
|
|
|
resticRepoFlag,
|
|
|
|
},
|
|
|
|
Before: internal.SubCommandBefore,
|
|
|
|
Usage: "Create a new backup",
|
|
|
|
BashComplete: autocomplete.AppNameComplete,
|
|
|
|
Action: func(c *cli.Context) error {
|
|
|
|
app := internal.ValidateApp(c)
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if err := recipe.EnsureExists(app.Recipe); err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if !internal.Chaos {
|
|
|
|
if err := recipe.EnsureIsClean(app.Recipe); err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if !internal.Offline {
|
|
|
|
if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if err := recipe.EnsureLatest(app.Recipe); err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
cl, err := client.New(app.Server)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Fatal(err)
|
2023-10-01 06:02:30 +00:00
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
targetContainer, err := internal.RetrieveBackupBotContainer(cl)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
execEnv := []string{fmt.Sprintf("SERVICE=%s", app.Domain)}
|
|
|
|
if resticRepo != "" {
|
|
|
|
logrus.Debugf("including RESTIC_REPO=%s in backupbot exec invocation", resticRepo)
|
|
|
|
execEnv = append(execEnv, fmt.Sprintf("RESTIC_REPO=%s", resticRepo))
|
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if err := internal.RunBackupCmdRemote(cl, "create", targetContainer.ID, execEnv); err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
var appBackupSnapshotsCommand = cli.Command{
|
|
|
|
Name: "snapshots",
|
|
|
|
Aliases: []string{"s"},
|
|
|
|
Flags: []cli.Flag{
|
|
|
|
internal.DebugFlag,
|
|
|
|
internal.OfflineFlag,
|
|
|
|
snapshotFlag,
|
|
|
|
},
|
|
|
|
Before: internal.SubCommandBefore,
|
|
|
|
Usage: "List backup snapshots",
|
|
|
|
BashComplete: autocomplete.AppNameComplete,
|
|
|
|
Action: func(c *cli.Context) error {
|
|
|
|
app := internal.ValidateApp(c)
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if err := recipe.EnsureExists(app.Recipe); err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if !internal.Chaos {
|
|
|
|
if err := recipe.EnsureIsClean(app.Recipe); err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if !internal.Offline {
|
|
|
|
if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
2022-04-19 10:52:30 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
if err := recipe.EnsureLatest(app.Recipe); err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2023-10-01 06:02:30 +00:00
|
|
|
}
|
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
cl, err := client.New(app.Server)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Fatal(err)
|
2022-04-19 10:52:30 +00:00
|
|
|
}
|
2024-03-12 09:03:42 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
targetContainer, err := internal.RetrieveBackupBotContainer(cl)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2024-03-12 09:03:42 +00:00
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
execEnv := []string{fmt.Sprintf("SERVICE=%s", app.Domain)}
|
|
|
|
if snapshot != "" {
|
|
|
|
logrus.Debugf("including SNAPSHOT=%s in backupbot exec invocation", snapshot)
|
|
|
|
execEnv = append(execEnv, fmt.Sprintf("SNAPSHOT=%s", snapshot))
|
2024-03-12 09:03:42 +00:00
|
|
|
}
|
2024-03-12 09:34:40 +00:00
|
|
|
|
|
|
|
if err := internal.RunBackupCmdRemote(cl, "snapshots", targetContainer.ID, execEnv); err != nil {
|
|
|
|
logrus.Fatal(err)
|
2024-03-12 09:03:42 +00:00
|
|
|
}
|
2024-03-12 09:34:40 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
2024-03-12 09:03:42 +00:00
|
|
|
}
|
|
|
|
|
2024-03-12 09:34:40 +00:00
|
|
|
var appBackupCommand = cli.Command{
|
|
|
|
Name: "backup",
|
|
|
|
Aliases: []string{"b"},
|
|
|
|
Usage: "Manage app backups",
|
|
|
|
ArgsUsage: "<domain>",
|
|
|
|
Subcommands: []cli.Command{
|
|
|
|
appBackupListCommand,
|
|
|
|
appBackupSnapshotsCommand,
|
|
|
|
appBackupDownloadCommand,
|
|
|
|
appBackupCreateCommand,
|
|
|
|
},
|
2022-04-19 10:52:30 +00:00
|
|
|
}
|