forked from toolshed/abra
refactor: urfave v3
This commit is contained in:
@ -1,15 +1,15 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var AppCommand = cli.Command{
|
||||
Name: "app",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Manage apps",
|
||||
ArgsUsage: "<domain>",
|
||||
Subcommands: []*cli.Command{
|
||||
Name: "app",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Manage apps",
|
||||
UsageText: "abra app [command] [options] [arguments]",
|
||||
Commands: []*cli.Command{
|
||||
&appBackupCommand,
|
||||
&appCheckCommand,
|
||||
&appCmdCommand,
|
||||
|
@ -1,13 +1,14 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var snapshot string
|
||||
@ -38,16 +39,16 @@ var appBackupListCommand = cli.Command{
|
||||
Name: "list",
|
||||
Aliases: []string{"ls"},
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.OfflineFlag,
|
||||
snapshotFlag,
|
||||
includePathFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "List all backups",
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "List all backups",
|
||||
UsageText: "abra app backup list <domain> [options]",
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
|
||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
@ -85,16 +86,16 @@ 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)
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "Download a backup",
|
||||
UsageText: "abra app backup download <domain> [options]",
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
|
||||
if err := app.Recipe.EnsureExists(); err != nil {
|
||||
log.Fatal(err)
|
||||
@ -156,15 +157,15 @@ 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)
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "Create a new backup",
|
||||
UsageText: "abra app backup create <domain> [options]",
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
|
||||
if err := app.Recipe.EnsureExists(); err != nil {
|
||||
log.Fatal(err)
|
||||
@ -214,15 +215,15 @@ 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)
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "List backup snapshots",
|
||||
UsageText: "abra app backup snapshots <domain> [options]",
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
|
||||
if err := app.Recipe.EnsureExists(); err != nil {
|
||||
log.Fatal(err)
|
||||
@ -272,8 +273,8 @@ var appBackupCommand = cli.Command{
|
||||
Name: "backup",
|
||||
Aliases: []string{"b"},
|
||||
Usage: "Manage app backups",
|
||||
ArgsUsage: "<domain>",
|
||||
Subcommands: []*cli.Command{
|
||||
UsageText: "abra app backup [command] [arguments] [options]",
|
||||
Commands: []*cli.Command{
|
||||
&appBackupListCommand,
|
||||
&appBackupSnapshotsCommand,
|
||||
&appBackupDownloadCommand,
|
||||
|
@ -1,6 +1,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
@ -9,16 +10,15 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appCheckCommand = cli.Command{
|
||||
Name: "check",
|
||||
Aliases: []string{"chk"},
|
||||
Usage: "Ensure an app is well configured",
|
||||
Description: `
|
||||
This command compares env vars in both the app ".env" and recipe ".env.sample"
|
||||
file.
|
||||
Name: "check",
|
||||
Aliases: []string{"chk"},
|
||||
UsageText: "abra app check <domain> [options]",
|
||||
Usage: "Ensure an app is well configured",
|
||||
Description: `Compare env vars in both the app ".env" and recipe ".env.sample" file.
|
||||
|
||||
The goal is to ensure that recipe ".env.sample" env vars are defined in your
|
||||
app ".env" file. Only env var definitions in the ".env.sample" which are
|
||||
@ -28,16 +28,15 @@ these env vars, then "check" will complain.
|
||||
Recipe maintainers may or may not provide defaults for env vars within their
|
||||
recipes regardless of commenting or not (e.g. through the use of
|
||||
${FOO:<default>} syntax). "check" does not confirm or deny this for you.`,
|
||||
ArgsUsage: "<domain>",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.ChaosFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
|
||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -14,61 +15,53 @@ import (
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appCmdCommand = cli.Command{
|
||||
Name: "command",
|
||||
Aliases: []string{"cmd"},
|
||||
Usage: "Run app commands",
|
||||
Name: "command",
|
||||
Aliases: []string{"cmd"},
|
||||
Usage: "Run app commands",
|
||||
UsageText: "abra app cmd <domain> [<service>] <cmd> [<cmd-args>] [options]",
|
||||
Description: `Run an app specific command.
|
||||
|
||||
These commands are bash functions, defined in the abra.sh of the recipe itself.
|
||||
They can be run within the context of a service (e.g. app) or locally on your
|
||||
work station by passing "--local". Arguments can be passed into these functions
|
||||
using the "-- <args>" syntax.
|
||||
|
||||
**WARNING**: options must be passed directly after the sub-command "cmd".
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
abra app cmd --local example.com app create_user -- me@example.com`,
|
||||
ArgsUsage: "<domain> [<service>] <command> [-- <args>]",
|
||||
work station by passing "--local".`,
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.LocalCmdFlag,
|
||||
internal.RemoteUserFlag,
|
||||
internal.TtyFlag,
|
||||
internal.OfflineFlag,
|
||||
internal.ChaosFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Subcommands: []*cli.Command{
|
||||
Commands: []*cli.Command{
|
||||
&appCmdListCommand,
|
||||
},
|
||||
BashComplete: func(ctx *cli.Context) {
|
||||
args := ctx.Args()
|
||||
ShellComplete: func(ctx context.Context, cmd *cli.Command) {
|
||||
args := cmd.Args()
|
||||
switch args.Len() {
|
||||
case 0:
|
||||
autocomplete.AppNameComplete(ctx)
|
||||
autocomplete.AppNameComplete(ctx, cmd)
|
||||
case 1:
|
||||
autocomplete.ServiceNameComplete(args.Get(0))
|
||||
case 2:
|
||||
cmdNameComplete(args.Get(0))
|
||||
}
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
|
||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if internal.LocalCmd && internal.RemoteUser != "" {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("cannot use --local & --user together"))
|
||||
internal.ShowSubcommandHelpAndError(cmd, errors.New("cannot use --local & --user together"))
|
||||
}
|
||||
|
||||
hasCmdArgs, parsedCmdArgs := parseCmdArgs(c.Args().Slice(), internal.LocalCmd)
|
||||
hasCmdArgs, parsedCmdArgs := parseCmdArgs(cmd.Args().Slice(), internal.LocalCmd)
|
||||
|
||||
if _, err := os.Stat(app.Recipe.AbraShPath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
@ -78,11 +71,11 @@ EXAMPLE:
|
||||
}
|
||||
|
||||
if internal.LocalCmd {
|
||||
if !(c.Args().Len() >= 2) {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments"))
|
||||
if !(cmd.Args().Len() >= 2) {
|
||||
internal.ShowSubcommandHelpAndError(cmd, errors.New("missing arguments"))
|
||||
}
|
||||
|
||||
cmdName := c.Args().Get(1)
|
||||
cmdName := cmd.Args().Get(1)
|
||||
if err := internal.EnsureCommand(app.Recipe.AbraShPath, app.Recipe.Name, cmdName); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -114,13 +107,13 @@ EXAMPLE:
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
if !(c.Args().Len() >= 3) {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments"))
|
||||
if !(cmd.Args().Len() >= 3) {
|
||||
internal.ShowSubcommandHelpAndError(cmd, errors.New("missing arguments"))
|
||||
}
|
||||
|
||||
targetServiceName := c.Args().Get(1)
|
||||
targetServiceName := cmd.Args().Get(1)
|
||||
|
||||
cmdName := c.Args().Get(2)
|
||||
cmdName := cmd.Args().Get(2)
|
||||
if err := internal.EnsureCommand(app.Recipe.AbraShPath, app.Recipe.Name, cmdName); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -200,16 +193,16 @@ var appCmdListCommand = cli.Command{
|
||||
Name: "list",
|
||||
Aliases: []string{"ls"},
|
||||
Usage: "List all available commands",
|
||||
ArgsUsage: "<domain>",
|
||||
UsageText: "abra app cmd ls <domain> [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.OfflineFlag,
|
||||
internal.ChaosFlag,
|
||||
},
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Before: internal.SubCommandBefore,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
Before: internal.SubCommandBefore,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
r := recipe.Get(app.Recipe.Name)
|
||||
|
||||
if err := app.Recipe.EnsureExists(); err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
@ -10,24 +11,22 @@ import (
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appConfigCommand = cli.Command{
|
||||
Name: "config",
|
||||
Aliases: []string{"cfg"},
|
||||
Usage: "Edit app config",
|
||||
ArgsUsage: "<domain>",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
appName := c.Args().First()
|
||||
Name: "config",
|
||||
Aliases: []string{"cfg"},
|
||||
Usage: "Edit app config",
|
||||
UsageText: "abra app config <domain> [options]",
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
appName := cmd.Args().First()
|
||||
|
||||
if appName == "" {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no app provided"))
|
||||
internal.ShowSubcommandHelpAndError(cmd, errors.New("no app provided"))
|
||||
}
|
||||
|
||||
files, err := appPkg.LoadAppFiles("")
|
||||
@ -51,11 +50,11 @@ var appConfigCommand = cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
cmd := exec.Command(ed, appFile.Path)
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
c := exec.Command(ed, appFile.Path)
|
||||
c.Stdin = os.Stdin
|
||||
c.Stdout = os.Stdout
|
||||
c.Stderr = os.Stderr
|
||||
if err := c.Run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
@ -22,21 +22,16 @@ import (
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appCpCommand = cli.Command{
|
||||
Name: "cp",
|
||||
Aliases: []string{"c"},
|
||||
ArgsUsage: "<domain> <src> <dst>",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "Copy files to/from a deployed app service",
|
||||
Description: `
|
||||
Copy files to and from any app service file system.
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "Copy files to/from a deployed app service",
|
||||
UsageText: "abra app cp <domain> <src> <dst> [options]",
|
||||
Description: `Copy files to and from any app service file system.
|
||||
|
||||
If you want to copy a myfile.txt to the root of the app service:
|
||||
|
||||
@ -44,18 +39,17 @@ If you want to copy a myfile.txt to the root of the app service:
|
||||
|
||||
And if you want to copy that file back to your current working directory locally:
|
||||
|
||||
abra app cp <domain> app:/myfile.txt .
|
||||
`,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
|
||||
abra app cp <domain> app:/myfile.txt`,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
src := c.Args().Get(1)
|
||||
dst := c.Args().Get(2)
|
||||
src := cmd.Args().Get(1)
|
||||
dst := cmd.Args().Get(2)
|
||||
if src == "" {
|
||||
log.Fatal("missing <src> argument")
|
||||
}
|
||||
|
@ -17,22 +17,19 @@ import (
|
||||
"coopcloud.tech/abra/pkg/lint"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appDeployCommand = cli.Command{
|
||||
Name: "deploy",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "Deploy an app",
|
||||
ArgsUsage: "<domain> [<version>]",
|
||||
UsageText: "abra app deploy <domain> [<version>] [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.ForceFlag,
|
||||
internal.ChaosFlag,
|
||||
internal.NoDomainChecksFlag,
|
||||
internal.DontWaitConvergeFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Description: `Deploy an app.
|
||||
@ -40,21 +37,20 @@ var appDeployCommand = cli.Command{
|
||||
This command supports chaos operations. Use "--chaos" to deploy your recipe
|
||||
checkout as-is. Recipe commit hashes are also supported values for
|
||||
"[<version>]". Please note, "upgrade"/"rollback" do not support chaos
|
||||
operations.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
abra app deploy foo.example.com
|
||||
abra app deploy foo.example.com 1.2.3+3.2.1
|
||||
abra app deploy foo.example.com 1e83340e`,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
operations.`,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
var warnMessages []string
|
||||
|
||||
app := internal.ValidateApp(c)
|
||||
app := internal.ValidateApp(cmd)
|
||||
stackName := app.StackName()
|
||||
|
||||
specificVersion := c.Args().Get(1)
|
||||
specificVersion := cmd.Args().Get(1)
|
||||
if specificVersion == "" {
|
||||
specificVersion = app.Recipe.Version
|
||||
}
|
||||
|
||||
if specificVersion != "" && internal.Chaos {
|
||||
log.Fatal("cannot use <version> and --chaos together")
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
@ -12,7 +13,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/tagcmp"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -70,26 +71,24 @@ type serverStatus struct {
|
||||
}
|
||||
|
||||
var appListCommand = cli.Command{
|
||||
Name: "list",
|
||||
Aliases: []string{"ls"},
|
||||
Usage: "List all managed apps",
|
||||
Description: `
|
||||
Read the local file system listing of apps and servers (e.g. ~/.abra/) to
|
||||
generate a report of all your apps.
|
||||
Name: "list",
|
||||
Aliases: []string{"ls"},
|
||||
Usage: "List all managed apps",
|
||||
UsageText: "abra app list [options]",
|
||||
Description: `Generate a report of all managed apps.
|
||||
|
||||
By passing the "--status/-S" flag, you can query all your servers for the
|
||||
actual live deployment status. Depending on how many servers you manage, this
|
||||
can take some time.`,
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.MachineReadableFlag,
|
||||
statusFlag,
|
||||
listAppServerFlag,
|
||||
recipeFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Action: func(c *cli.Context) error {
|
||||
Before: internal.SubCommandBefore,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
appFiles, err := appPkg.LoadAppFiles(listAppServer)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -19,23 +19,23 @@ import (
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appLogsCommand = cli.Command{
|
||||
Name: "logs",
|
||||
Aliases: []string{"l"},
|
||||
ArgsUsage: "<domain> [<service>]",
|
||||
Usage: "Tail app logs",
|
||||
UsageText: "abra app logs <domain> [<service>] [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.StdErrOnlyFlag,
|
||||
internal.SinceLogsFlag,
|
||||
internal.DebugFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
stackName := app.StackName()
|
||||
|
||||
if err := app.Recipe.EnsureExists(); err != nil {
|
||||
@ -56,7 +56,7 @@ var appLogsCommand = cli.Command{
|
||||
log.Fatalf("%s is not deployed?", app.Name)
|
||||
}
|
||||
|
||||
serviceName := c.Args().Get(1)
|
||||
serviceName := cmd.Args().Get(1)
|
||||
serviceNames := []string{}
|
||||
if serviceName != "" {
|
||||
serviceNames = []string{serviceName}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
@ -16,12 +17,13 @@ import (
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/charmbracelet/lipgloss/table"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appNewDescription = `
|
||||
Creates a new app from a default recipe. This new app configuration is stored
|
||||
in your $ABRA_DIR directory under the appropriate server.
|
||||
var appNewDescription = `Creates a new app from a default recipe.
|
||||
|
||||
This new app configuration is stored in your $ABRA_DIR directory under the
|
||||
appropriate server.
|
||||
|
||||
This command does not deploy your app for you. You will need to run "abra app
|
||||
deploy <domain>" to do so.
|
||||
@ -44,30 +46,28 @@ var appNewCommand = cli.Command{
|
||||
Name: "new",
|
||||
Aliases: []string{"n"},
|
||||
Usage: "Create a new app",
|
||||
UsageText: "abra app new [<recipe>] [<version>] [options]",
|
||||
Description: appNewDescription,
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.NewAppServerFlag,
|
||||
internal.DomainFlag,
|
||||
internal.PassFlag,
|
||||
internal.SecretsFlag,
|
||||
internal.OfflineFlag,
|
||||
internal.ChaosFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
ArgsUsage: "[<recipe>] [<version>]",
|
||||
BashComplete: func(ctx *cli.Context) {
|
||||
args := ctx.Args()
|
||||
Before: internal.SubCommandBefore,
|
||||
HideHelp: true,
|
||||
ShellComplete: func(ctx context.Context, cmd *cli.Command) {
|
||||
args := cmd.Args()
|
||||
switch args.Len() {
|
||||
case 0:
|
||||
autocomplete.RecipeNameComplete(ctx)
|
||||
autocomplete.RecipeNameComplete(ctx, cmd)
|
||||
case 1:
|
||||
autocomplete.RecipeVersionComplete(ctx.Args().Get(0))
|
||||
autocomplete.RecipeVersionComplete(cmd.Args().Get(0))
|
||||
}
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := internal.ValidateRecipe(c)
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
recipe := internal.ValidateRecipe(cmd)
|
||||
|
||||
var version string
|
||||
if !internal.Chaos {
|
||||
@ -80,7 +80,7 @@ var appNewCommand = cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
if c.Args().Get(1) == "" {
|
||||
if cmd.Args().Get(1) == "" {
|
||||
recipeVersions, err := recipe.GetRecipeVersions()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -101,7 +101,7 @@ var appNewCommand = cli.Command{
|
||||
}
|
||||
}
|
||||
} else {
|
||||
version = c.Args().Get(1)
|
||||
version = cmd.Args().Get(1)
|
||||
if _, err := recipe.EnsureVersion(version); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -18,25 +18,25 @@ import (
|
||||
containerTypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appPsCommand = cli.Command{
|
||||
Name: "ps",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Check app status",
|
||||
ArgsUsage: "<domain>",
|
||||
UsageText: "abra app ps <domain> [options]",
|
||||
Description: "Show status of a deployed app.",
|
||||
Flags: []cli.Flag{
|
||||
internal.MachineReadableFlag,
|
||||
internal.DebugFlag,
|
||||
internal.ChaosFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -12,16 +12,15 @@ import (
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appRemoveCommand = cli.Command{
|
||||
Name: "remove",
|
||||
Aliases: []string{"rm"},
|
||||
ArgsUsage: "<domain>",
|
||||
UsageText: "abra app remove <domain> [options]",
|
||||
Usage: "Remove all app data, locally and remotely",
|
||||
Description: `
|
||||
This command removes everything related to an app which is already undeployed.
|
||||
Description: `Remove everything related to an app which is already undeployed.
|
||||
|
||||
By default, it will prompt for confirmation before proceeding. All secrets,
|
||||
volumes and the local app env file will be deleted.
|
||||
@ -39,14 +38,12 @@ To delete everything without prompt, use the "--force/-f" or the "--no-input/n"
|
||||
flag.`,
|
||||
Flags: []cli.Flag{
|
||||
internal.ForceFlag,
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Before: internal.SubCommandBefore,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
Before: internal.SubCommandBefore,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
|
||||
if !internal.Force && !internal.NoInput {
|
||||
log.Warnf("ALERTA ALERTA: this will completely remove %s data and config locally and remotely", app.Name)
|
||||
|
@ -12,41 +12,35 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
upstream "coopcloud.tech/abra/pkg/upstream/service"
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appRestartCommand = cli.Command{
|
||||
Name: "restart",
|
||||
Aliases: []string{"re"},
|
||||
Usage: "Restart an app",
|
||||
ArgsUsage: "<domain> [<service>]",
|
||||
UsageText: "abra app restart <domain> [<service>] [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.OfflineFlag,
|
||||
internal.AllServicesFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Description: `
|
||||
This command restarts services within a deployed app.
|
||||
Description: `This command restarts services within a deployed app.
|
||||
|
||||
Run "abra app ps <domain>" to see a list of service names.
|
||||
|
||||
Pass "--all-services/-a" to restart all services.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
abra app restart example.com app`,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Pass "--all-services/-a" to restart all services.`,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
if err := app.Recipe.Ensure(false, false); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
serviceName := c.Args().Get(1)
|
||||
serviceName := cmd.Args().Get(1)
|
||||
if serviceName == "" && !internal.AllServices {
|
||||
err := errors.New("missing <service>")
|
||||
internal.ShowSubcommandHelpAndError(c, err)
|
||||
internal.ShowSubcommandHelpAndError(cmd, err)
|
||||
}
|
||||
|
||||
if serviceName != "" && internal.AllServices {
|
||||
|
@ -1,13 +1,14 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var targetPath string
|
||||
@ -22,16 +23,15 @@ var appRestoreCommand = cli.Command{
|
||||
Name: "restore",
|
||||
Aliases: []string{"rs"},
|
||||
Usage: "Restore an app backup",
|
||||
ArgsUsage: "<domain> <service>",
|
||||
UsageText: "abra app restore <domain> <service> [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.OfflineFlag,
|
||||
targetPathFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -16,44 +16,36 @@ import (
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appRollbackCommand = cli.Command{
|
||||
Name: "rollback",
|
||||
Aliases: []string{"rl"},
|
||||
Usage: "Roll an app back to a previous version",
|
||||
ArgsUsage: "<domain> [<version>]",
|
||||
UsageText: "abra app rollback <domain> [<version>] [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.ForceFlag,
|
||||
internal.NoDomainChecksFlag,
|
||||
internal.DontWaitConvergeFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Description: `
|
||||
This command rolls an app back to a previous version.
|
||||
Description: `This command rolls an app back to a previous version.
|
||||
|
||||
Unlike "deploy", chaos operations are not supported here. Only recipe versions
|
||||
are supported values for "[<version>]".
|
||||
|
||||
A rollback can be destructive, please ensure you have a copy of your app data
|
||||
beforehand.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
abra app rollback foo.example.com
|
||||
abra app rollback foo.example.com 1.2.3+3.2.1`,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
beforehand.`,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
var warnMessages []string
|
||||
|
||||
app := internal.ValidateApp(c)
|
||||
app := internal.ValidateApp(cmd)
|
||||
stackName := app.StackName()
|
||||
|
||||
specificVersion := c.Args().Get(1)
|
||||
specificVersion := cmd.Args().Get(1)
|
||||
if specificVersion != "" {
|
||||
log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion)
|
||||
app.Recipe.Version = specificVersion
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var user string
|
||||
@ -36,23 +36,23 @@ var appRunCommand = cli.Command{
|
||||
Name: "run",
|
||||
Aliases: []string{"r"},
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
noTTYFlag,
|
||||
userFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
ArgsUsage: "<domain> <service> <args>...",
|
||||
Usage: "Run a command in a service container",
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "Run a command in an app service",
|
||||
UsageText: "abra app run <domain> <service> <args> [options]",
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
|
||||
if c.Args().Len() < 2 {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no <service> provided?"))
|
||||
if cmd.Args().Len() < 2 {
|
||||
internal.ShowSubcommandHelpAndError(cmd, errors.New("no <service> provided?"))
|
||||
}
|
||||
|
||||
if c.Args().Len() < 3 {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no <args> provided?"))
|
||||
if cmd.Args().Len() < 3 {
|
||||
internal.ShowSubcommandHelpAndError(cmd, errors.New("no <args> provided?"))
|
||||
}
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
@ -60,7 +60,7 @@ var appRunCommand = cli.Command{
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
serviceName := c.Args().Get(1)
|
||||
serviceName := cmd.Args().Get(1)
|
||||
stackAndServiceName := fmt.Sprintf("^%s_%s", app.StackName(), serviceName)
|
||||
filters := filters.NewArgs()
|
||||
filters.Add("name", stackAndServiceName)
|
||||
@ -70,12 +70,12 @@ var appRunCommand = cli.Command{
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
cmd := c.Args().Slice()[2:]
|
||||
c := cmd.Args().Slice()[2:]
|
||||
execCreateOpts := types.ExecConfig{
|
||||
AttachStderr: true,
|
||||
AttachStdin: true,
|
||||
AttachStdout: true,
|
||||
Cmd: cmd,
|
||||
Cmd: c,
|
||||
Detach: false,
|
||||
Tty: true,
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/secret"
|
||||
"github.com/docker/docker/api/types"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -44,31 +44,30 @@ var appSecretGenerateCommand = cli.Command{
|
||||
Name: "generate",
|
||||
Aliases: []string{"g"},
|
||||
Usage: "Generate secrets",
|
||||
ArgsUsage: "<domain> <secret> <version>",
|
||||
UsageText: "abra app secret generate <domain> <secret> <version> [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
allSecretsFlag,
|
||||
internal.PassFlag,
|
||||
internal.MachineReadableFlag,
|
||||
internal.OfflineFlag,
|
||||
internal.ChaosFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if c.Args().Len() == 1 && !allSecrets {
|
||||
if cmd.Args().Len() == 1 && !allSecrets {
|
||||
err := errors.New("missing arguments <secret>/<version> or '--all'")
|
||||
internal.ShowSubcommandHelpAndError(c, err)
|
||||
internal.ShowSubcommandHelpAndError(cmd, err)
|
||||
}
|
||||
|
||||
if c.Args().Get(1) != "" && allSecrets {
|
||||
if cmd.Args().Get(1) != "" && allSecrets {
|
||||
err := errors.New("cannot use '<secret> <version>' and '--all' together")
|
||||
internal.ShowSubcommandHelpAndError(c, err)
|
||||
internal.ShowSubcommandHelpAndError(cmd, err)
|
||||
}
|
||||
|
||||
composeFiles, err := app.Recipe.GetComposeFiles(app.Env)
|
||||
@ -82,8 +81,8 @@ var appSecretGenerateCommand = cli.Command{
|
||||
}
|
||||
|
||||
if !allSecrets {
|
||||
secretName := c.Args().Get(1)
|
||||
secretVersion := c.Args().Get(2)
|
||||
secretName := cmd.Args().Get(1)
|
||||
secretVersion := cmd.Args().Get(2)
|
||||
s, ok := secrets[secretName]
|
||||
if !ok {
|
||||
log.Fatalf("%s doesn't exist in the env config?", secretName)
|
||||
@ -154,39 +153,32 @@ var appSecretGenerateCommand = cli.Command{
|
||||
}
|
||||
|
||||
var appSecretInsertCommand = cli.Command{
|
||||
Name: "insert",
|
||||
Aliases: []string{"i"},
|
||||
Usage: "Insert secret",
|
||||
Name: "insert",
|
||||
Aliases: []string{"i"},
|
||||
Usage: "Insert secret",
|
||||
UsageText: "abra app secret insert <domain> <secret> <version> <data> [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.PassFlag,
|
||||
internal.FileFlag,
|
||||
internal.TrimFlag,
|
||||
internal.ChaosFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
ArgsUsage: "<domain> <secret-name> <version> <data>",
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Description: `
|
||||
This command inserts a secret into an app environment.
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelpCommand: true,
|
||||
Description: `This command inserts a secret into an app environment.
|
||||
|
||||
This can be useful when you want to manually generate secrets for an app
|
||||
environment. Typically, you can let Abra generate them for you on app creation
|
||||
(see "abra app new --secrets" for more).
|
||||
|
||||
Example:
|
||||
|
||||
abra app secret insert myapp db_pass v1 mySecretPassword
|
||||
|
||||
`,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
(see "abra app new --secrets" for more).`,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if c.Args().Len() != 4 {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments?"))
|
||||
if cmd.Args().Len() != 4 {
|
||||
internal.ShowSubcommandHelpAndError(cmd, errors.New("missing arguments?"))
|
||||
}
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
@ -194,9 +186,9 @@ Example:
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
name := c.Args().Get(1)
|
||||
version := c.Args().Get(2)
|
||||
data := c.Args().Get(3)
|
||||
name := cmd.Args().Get(1)
|
||||
version := cmd.Args().Get(2)
|
||||
data := cmd.Args().Get(3)
|
||||
|
||||
if internal.File {
|
||||
raw, err := os.ReadFile(data)
|
||||
@ -247,29 +239,28 @@ func secretRm(cl *dockerClient.Client, app appPkg.App, secretName, parsed string
|
||||
}
|
||||
|
||||
var appSecretRmCommand = cli.Command{
|
||||
Name: "remove",
|
||||
Aliases: []string{"rm"},
|
||||
Usage: "Remove a secret",
|
||||
Name: "remove",
|
||||
Aliases: []string{"rm"},
|
||||
Usage: "Remove a secret",
|
||||
UsageText: "abra app remove <domainabra app remove <domain> [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
rmAllSecretsFlag,
|
||||
internal.PassRemoveFlag,
|
||||
internal.OfflineFlag,
|
||||
internal.ChaosFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
ArgsUsage: "<domain> [<secret-name>]",
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
Description: `
|
||||
This command removes app secrets.
|
||||
|
||||
Example:
|
||||
|
||||
abra app secret remove myapp db_pass
|
||||
`,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
abra app secret remove myapp db_pass`,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -284,12 +275,12 @@ Example:
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if c.Args().Get(1) != "" && rmAllSecrets {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("cannot use '<secret-name>' and '--all' together"))
|
||||
if cmd.Args().Get(1) != "" && rmAllSecrets {
|
||||
internal.ShowSubcommandHelpAndError(cmd, errors.New("cannot use '<secret-name>' and '--all' together"))
|
||||
}
|
||||
|
||||
if c.Args().Get(1) == "" && !rmAllSecrets {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no secret(s) specified?"))
|
||||
if cmd.Args().Get(1) == "" && !rmAllSecrets {
|
||||
internal.ShowSubcommandHelpAndError(cmd, errors.New("no secret(s) specified?"))
|
||||
}
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
@ -313,7 +304,7 @@ Example:
|
||||
}
|
||||
|
||||
match := false
|
||||
secretToRm := c.Args().Get(1)
|
||||
secretToRm := cmd.Args().Get(1)
|
||||
for secretName, val := range secrets {
|
||||
secretRemoteName := fmt.Sprintf("%s_%s_%s", app.StackName(), secretName, val.Version)
|
||||
if _, ok := remoteSecretNames[secretRemoteName]; ok {
|
||||
@ -351,16 +342,17 @@ var appSecretLsCommand = cli.Command{
|
||||
Name: "list",
|
||||
Aliases: []string{"ls"},
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.OfflineFlag,
|
||||
internal.ChaosFlag,
|
||||
internal.MachineReadableFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "List all secrets",
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "List all secrets",
|
||||
UsageText: "abra app secret list [options]",
|
||||
HideHelp: true,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -420,8 +412,8 @@ var appSecretCommand = cli.Command{
|
||||
Name: "secret",
|
||||
Aliases: []string{"s"},
|
||||
Usage: "Manage app secrets",
|
||||
ArgsUsage: "<domain>",
|
||||
Subcommands: []*cli.Command{
|
||||
UsageText: "abra app secret [command] [arguments] [options]",
|
||||
Commands: []*cli.Command{
|
||||
&appSecretGenerateCommand,
|
||||
&appSecretInsertCommand,
|
||||
&appSecretRmCommand,
|
||||
|
@ -13,21 +13,19 @@ import (
|
||||
"coopcloud.tech/abra/pkg/service"
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
containerTypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appServicesCommand = cli.Command{
|
||||
Name: "services",
|
||||
Aliases: []string{"sr"},
|
||||
Usage: "Display all services of an app",
|
||||
ArgsUsage: "<domain>",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Name: "services",
|
||||
Aliases: []string{"sr"},
|
||||
Usage: "Display all services of an app",
|
||||
UsageText: "abra app services <domain> [options]",
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var prune bool
|
||||
@ -65,25 +65,24 @@ func pruneApp(cl *dockerClient.Client, app appPkg.App) error {
|
||||
var appUndeployCommand = cli.Command{
|
||||
Name: "undeploy",
|
||||
Aliases: []string{"un"},
|
||||
ArgsUsage: "<domain>",
|
||||
UsageText: "abra app undeploy <domain> [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.OfflineFlag,
|
||||
pruneFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "Undeploy an app",
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Description: `
|
||||
This does not destroy any of the application data.
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "Undeploy an app",
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Description: `This does not destroy any of the application data.
|
||||
|
||||
However, you should remain vigilant, as your swarm installation will consider
|
||||
any previously attached volumes as eligible for pruning once undeployed.
|
||||
|
||||
Passing "-p/--prune" does not remove those volumes.`,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
stackName := app.StackName()
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
|
@ -15,45 +15,37 @@ import (
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"coopcloud.tech/tagcmp"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appUpgradeCommand = cli.Command{
|
||||
Name: "upgrade",
|
||||
Aliases: []string{"up"},
|
||||
Usage: "Upgrade an app",
|
||||
ArgsUsage: "<domain> [<version>]",
|
||||
UsageText: "abra app upgrade <domain> [<version>] [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.ForceFlag,
|
||||
internal.NoDomainChecksFlag,
|
||||
internal.DontWaitConvergeFlag,
|
||||
internal.OfflineFlag,
|
||||
internal.ReleaseNotesFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Description: `
|
||||
Upgrade an app.
|
||||
Description: `Upgrade an app.
|
||||
|
||||
Unlike "deploy", chaos operations are not supported here. Only recipe versions
|
||||
are supported values for "[<version>]".
|
||||
|
||||
An upgrade can be destructive, please ensure you have a copy of your app data
|
||||
beforehand.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
abra app upgrade foo.example.com
|
||||
abra app upgrade foo.example.com 1.2.3+3.2.1`,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
beforehand.`,
|
||||
HideHelp: true,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
var warnMessages []string
|
||||
|
||||
app := internal.ValidateApp(c)
|
||||
app := internal.ValidateApp(cmd)
|
||||
stackName := app.StackName()
|
||||
|
||||
specificVersion := c.Args().Get(1)
|
||||
specificVersion := cmd.Args().Get(1)
|
||||
if specificVersion != "" {
|
||||
log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion)
|
||||
app.Recipe.Version = specificVersion
|
||||
|
@ -11,22 +11,19 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var appVolumeListCommand = cli.Command{
|
||||
Name: "list",
|
||||
Aliases: []string{"ls"},
|
||||
ArgsUsage: "<domain>",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "List volumes associated with an app",
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Name: "list",
|
||||
Aliases: []string{"ls"},
|
||||
UsageText: "abra app volume list <domain> [options]",
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "List volumes associated with an app",
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
if err != nil {
|
||||
@ -74,27 +71,26 @@ var appVolumeListCommand = cli.Command{
|
||||
var appVolumeRemoveCommand = cli.Command{
|
||||
Name: "remove",
|
||||
Usage: "Remove volume(s) associated with an app",
|
||||
Description: `
|
||||
This command supports removing volumes associated with an app. The app in
|
||||
question must be undeployed before you try to remove volumes. See "abra app
|
||||
undeploy <domain>" for more.
|
||||
Description: `Remove volumes associated with an app.
|
||||
|
||||
The app in question must be undeployed before you try to remove volumes. See
|
||||
"abra app undeploy <domain>" for more.
|
||||
|
||||
The command is interactive and will show a multiple select input which allows
|
||||
you to make a seclection. Use the "?" key to see more help on navigating this
|
||||
interface.
|
||||
|
||||
Passing "--force/-f" will select all volumes for removal. Be careful.`,
|
||||
ArgsUsage: "<domain>",
|
||||
UsageText: "abra app volume remove [options] <domain>",
|
||||
Aliases: []string{"rm"},
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.ForceFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.AppNameComplete,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
app := internal.ValidateApp(cmd)
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
if err != nil {
|
||||
@ -158,8 +154,8 @@ var appVolumeCommand = cli.Command{
|
||||
Name: "volume",
|
||||
Aliases: []string{"vl"},
|
||||
Usage: "Manage app volumes",
|
||||
ArgsUsage: "<domain>",
|
||||
Subcommands: []*cli.Command{
|
||||
UsageText: "abra app volume [command] [options] [arguments]",
|
||||
Commands: []*cli.Command{
|
||||
&appVolumeListCommand,
|
||||
&appVolumeRemoveCommand,
|
||||
},
|
||||
|
@ -1,6 +1,7 @@
|
||||
package catalogue
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@ -15,25 +16,22 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var catalogueGenerateCommand = cli.Command{
|
||||
Name: "generate",
|
||||
Aliases: []string{"g"},
|
||||
Usage: "Generate the recipe catalogue",
|
||||
Name: "generate",
|
||||
Aliases: []string{"g"},
|
||||
Usage: "Generate the recipe catalogue",
|
||||
UsageText: "abra catalogue generate [<recipe>] [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.PublishFlag,
|
||||
internal.DryFlag,
|
||||
internal.SkipUpdatesFlag,
|
||||
internal.ChaosFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Description: `
|
||||
Generate a new copy of the recipe catalogue.
|
||||
Description: `Generate a new copy of the recipe catalogue.
|
||||
|
||||
It is possible to generate new metadata for a single recipe by passing
|
||||
<recipe>. The existing local catalogue will be updated, not overwritten.
|
||||
@ -45,14 +43,14 @@ If you have a Hub account you can have Abra log you in to avoid this. Pass
|
||||
Push your new release to git.coopcloud.tech with "-p/--publish". This requires
|
||||
that you have permission to git push to these repositories and have your SSH
|
||||
keys configured on your account.`,
|
||||
ArgsUsage: "[<recipe>]",
|
||||
BashComplete: autocomplete.RecipeNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipeName := c.Args().First()
|
||||
ShellComplete: autocomplete.RecipeNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
recipeName := cmd.Args().First()
|
||||
r := recipe.Get(recipeName)
|
||||
|
||||
if recipeName != "" {
|
||||
internal.ValidateRecipe(c)
|
||||
internal.ValidateRecipe(cmd)
|
||||
}
|
||||
|
||||
if !internal.Chaos {
|
||||
@ -208,8 +206,8 @@ var CatalogueCommand = cli.Command{
|
||||
Name: "catalogue",
|
||||
Usage: "Manage the recipe catalogue",
|
||||
Aliases: []string{"c"},
|
||||
ArgsUsage: "<recipe>",
|
||||
Subcommands: []*cli.Command{
|
||||
UsageText: "abra catalogue [command] [options] [arguments]",
|
||||
Commands: []*cli.Command{
|
||||
&catalogueGenerateCommand,
|
||||
},
|
||||
}
|
||||
|
101
cli/cli.go
101
cli/cli.go
@ -2,6 +2,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -18,31 +19,24 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/web"
|
||||
charmLog "github.com/charmbracelet/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// AutoCompleteCommand helps people set up auto-complete in their shells
|
||||
var AutoCompleteCommand = cli.Command{
|
||||
Name: "autocomplete",
|
||||
Aliases: []string{"ac"},
|
||||
Usage: "Configure shell autocompletion",
|
||||
Description: `
|
||||
Set up shell auto-completion.
|
||||
Name: "autocomplete",
|
||||
Aliases: []string{"ac"},
|
||||
Usage: "Configure shell autocompletion",
|
||||
UsageText: "abra autocomplete <shell> [options]",
|
||||
Description: `Set up shell auto-completion.
|
||||
|
||||
Supported shells are: bash, fish, fizsh & zsh.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
abra autocomplete bash`,
|
||||
ArgsUsage: "<shell>",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
shellType := c.Args().First()
|
||||
Supported shells are: bash, fish, fizsh & zsh.`,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
shellType := cmd.Args().First()
|
||||
|
||||
if shellType == "" {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no shell provided"))
|
||||
internal.ShowSubcommandHelpAndError(cmd, errors.New("no shell provided"))
|
||||
}
|
||||
|
||||
supportedShells := map[string]bool{
|
||||
@ -113,33 +107,29 @@ source /etc/fish/completions/abra
|
||||
|
||||
// UpgradeCommand upgrades abra in-place.
|
||||
var UpgradeCommand = cli.Command{
|
||||
Name: "upgrade",
|
||||
Aliases: []string{"u"},
|
||||
Usage: "Upgrade abra",
|
||||
Description: `
|
||||
Upgrade abra in-place with the latest stable or release candidate.
|
||||
Name: "upgrade",
|
||||
Aliases: []string{"u"},
|
||||
Usage: "Upgrade abra",
|
||||
UsageText: "abra upgrade [options]",
|
||||
Description: `Upgrade abra in-place with the latest stable or release candidate.
|
||||
|
||||
Use "-r/--rc" to install the latest release candidate. Please bear in mind that
|
||||
Use "--rc/-r" to install the latest release candidate. Please bear in mind that
|
||||
it may contain absolutely catastrophic deal-breaker bugs. Thank you very much
|
||||
for the testing efforts 💗
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
abra upgrade
|
||||
abra upgrade --rc`,
|
||||
Flags: []cli.Flag{internal.RCFlag},
|
||||
Action: func(c *cli.Context) error {
|
||||
for the testing efforts 💗`,
|
||||
Flags: []cli.Flag{internal.RCFlag},
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
mainURL := "https://install.abra.coopcloud.tech"
|
||||
cmd := exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash", mainURL))
|
||||
c := exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash", mainURL))
|
||||
|
||||
if internal.RC {
|
||||
releaseCandidateURL := "https://git.coopcloud.tech/coop-cloud/abra/raw/branch/main/scripts/installer/installer"
|
||||
cmd = exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash -s -- --rc", releaseCandidateURL))
|
||||
c = exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash -s -- --rc", releaseCandidateURL))
|
||||
}
|
||||
|
||||
log.Debugf("attempting to run %s", cmd)
|
||||
log.Debugf("attempting to run %s", c)
|
||||
|
||||
if err := internal.RunCmd(cmd); err != nil {
|
||||
if err := internal.RunCmd(c); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@ -147,18 +137,16 @@ EXAMPLE:
|
||||
},
|
||||
}
|
||||
|
||||
func newAbraApp(version, commit string) *cli.App {
|
||||
app := &cli.App{
|
||||
Name: "abra",
|
||||
Usage: `the Co-op Cloud command-line utility belt 🎩🐇
|
||||
____ ____ _ _
|
||||
/ ___|___ ___ _ __ / ___| | ___ _ _ __| |
|
||||
| | / _ \ _____ / _ \| '_ \ | | | |/ _ \| | | |/ _' |
|
||||
| |__| (_) |_____| (_) | |_) | | |___| | (_) | |_| | (_| |
|
||||
\____\___/ \___/| .__/ \____|_|\___/ \__,_|\__,_|
|
||||
|_|
|
||||
`,
|
||||
Version: fmt.Sprintf("%s-%s", version, commit[:7]),
|
||||
func newAbraApp(version, commit string) *cli.Command {
|
||||
app := &cli.Command{
|
||||
Name: "abra",
|
||||
Usage: "The Co-op Cloud command-line utility belt 🎩🐇",
|
||||
UsageText: "abra [command] [arguments] [options]",
|
||||
Version: fmt.Sprintf("%s-%s", version, commit[:7]),
|
||||
Flags: []cli.Flag{
|
||||
// NOTE(d1): "GLOBAL OPTIONS" flags
|
||||
internal.DebugFlag,
|
||||
},
|
||||
Commands: []*cli.Command{
|
||||
&app.AppCommand,
|
||||
&server.ServerCommand,
|
||||
@ -167,12 +155,13 @@ func newAbraApp(version, commit string) *cli.App {
|
||||
&UpgradeCommand,
|
||||
&AutoCompleteCommand,
|
||||
},
|
||||
BashComplete: autocomplete.SubcommandComplete,
|
||||
EnableShellCompletion: true,
|
||||
UseShortOptionHandling: true,
|
||||
HideHelpCommand: true,
|
||||
ShellComplete: autocomplete.SubcommandComplete,
|
||||
}
|
||||
|
||||
app.EnableBashCompletion = true
|
||||
|
||||
app.Before = func(c *cli.Context) error {
|
||||
app.Before = func(ctx context.Context, cmd *cli.Command) error {
|
||||
paths := []string{
|
||||
config.ABRA_DIR,
|
||||
config.SERVERS_DIR,
|
||||
@ -198,6 +187,12 @@ func newAbraApp(version, commit string) *cli.App {
|
||||
return nil
|
||||
}
|
||||
|
||||
cli.HelpFlag = &cli.BoolFlag{
|
||||
Name: "help",
|
||||
Aliases: []string{"h, H"},
|
||||
Usage: "Show help",
|
||||
}
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
@ -205,7 +200,7 @@ func newAbraApp(version, commit string) *cli.App {
|
||||
func RunApp(version, commit string) {
|
||||
app := newAbraApp(version, commit)
|
||||
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
if err := app.Run(context.Background(), os.Args); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// Secrets stores the variable from SecretsFlag
|
||||
@ -74,7 +75,7 @@ var Chaos bool
|
||||
var ChaosFlag = &cli.BoolFlag{
|
||||
Name: "chaos",
|
||||
Aliases: []string{"C"},
|
||||
Usage: "Proceed with uncommitted recipes changes. Use with care!",
|
||||
Usage: "Ignore uncommitted recipes changes. Use with care!",
|
||||
Destination: &Chaos,
|
||||
}
|
||||
|
||||
@ -116,7 +117,7 @@ var OfflineFlag = &cli.BoolFlag{
|
||||
Name: "offline",
|
||||
Aliases: []string{"o"},
|
||||
Destination: &Offline,
|
||||
Usage: "Prefer offline & filesystem access when possible",
|
||||
Usage: "Prefer offline & filesystem access",
|
||||
}
|
||||
|
||||
// ReleaseNotes stores the variable from ReleaseNotesFlag.
|
||||
@ -138,7 +139,7 @@ var MachineReadableFlag = &cli.BoolFlag{
|
||||
Name: "machine",
|
||||
Aliases: []string{"m"},
|
||||
Destination: &MachineReadable,
|
||||
Usage: "Output in a machine-readable format (where supported)",
|
||||
Usage: "Machine-readable output",
|
||||
}
|
||||
|
||||
// RC signifies the latest release candidate
|
||||
@ -319,7 +320,7 @@ var AllServicesFlag = &cli.BoolFlag{
|
||||
}
|
||||
|
||||
// SubCommandBefore wires up pre-action machinery (e.g. --debug handling).
|
||||
func SubCommandBefore(c *cli.Context) error {
|
||||
func SubCommandBefore(ctx context.Context, cmd *cli.Command) error {
|
||||
if Debug {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
log.SetOutput(os.Stderr)
|
||||
|
@ -4,13 +4,13 @@ import (
|
||||
"os"
|
||||
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// ShowSubcommandHelpAndError exits the program on error, logs the error to the
|
||||
// terminal, and shows the help command.
|
||||
func ShowSubcommandHelpAndError(c *cli.Context, err interface{}) {
|
||||
if err2 := cli.ShowSubcommandHelp(c); err2 != nil {
|
||||
func ShowSubcommandHelpAndError(cmd *cli.Command, err interface{}) {
|
||||
if err2 := cli.ShowSubcommandHelp(cmd); err2 != nil {
|
||||
log.Error(err2)
|
||||
}
|
||||
log.Error(err)
|
||||
|
@ -9,12 +9,12 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// ValidateRecipe ensures the recipe arg is valid.
|
||||
func ValidateRecipe(c *cli.Context) recipe.Recipe {
|
||||
recipeName := c.Args().First()
|
||||
func ValidateRecipe(cmd *cli.Command) recipe.Recipe {
|
||||
recipeName := cmd.Args().First()
|
||||
|
||||
if recipeName == "" && !NoInput {
|
||||
var recipes []string
|
||||
@ -54,7 +54,7 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe {
|
||||
}
|
||||
|
||||
if recipeName == "" {
|
||||
ShowSubcommandHelpAndError(c, errors.New("no recipe name provided"))
|
||||
ShowSubcommandHelpAndError(cmd, errors.New("no recipe name provided"))
|
||||
}
|
||||
|
||||
chosenRecipe := recipe.Get(recipeName)
|
||||
@ -64,7 +64,7 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe {
|
||||
}
|
||||
_, err = chosenRecipe.GetComposeConfig(nil)
|
||||
if err != nil {
|
||||
if c.Command.Name == "generate" {
|
||||
if cmd.Name == "generate" {
|
||||
if strings.Contains(err.Error(), "missing a compose") {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -83,11 +83,11 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe {
|
||||
}
|
||||
|
||||
// ValidateApp ensures the app name arg is valid.
|
||||
func ValidateApp(c *cli.Context) app.App {
|
||||
appName := c.Args().First()
|
||||
func ValidateApp(cmd *cli.Command) app.App {
|
||||
appName := cmd.Args().First()
|
||||
|
||||
if appName == "" {
|
||||
ShowSubcommandHelpAndError(c, errors.New("no app provided"))
|
||||
ShowSubcommandHelpAndError(cmd, errors.New("no app provided"))
|
||||
}
|
||||
|
||||
app, err := app.Get(appName)
|
||||
@ -101,8 +101,8 @@ func ValidateApp(c *cli.Context) app.App {
|
||||
}
|
||||
|
||||
// ValidateDomain ensures the domain name arg is valid.
|
||||
func ValidateDomain(c *cli.Context) string {
|
||||
domainName := c.Args().First()
|
||||
func ValidateDomain(cmd *cli.Command) string {
|
||||
domainName := cmd.Args().First()
|
||||
|
||||
if domainName == "" && !NoInput {
|
||||
prompt := &survey.Input{
|
||||
@ -115,7 +115,7 @@ func ValidateDomain(c *cli.Context) string {
|
||||
}
|
||||
|
||||
if domainName == "" {
|
||||
ShowSubcommandHelpAndError(c, errors.New("no domain provided"))
|
||||
ShowSubcommandHelpAndError(cmd, errors.New("no domain provided"))
|
||||
}
|
||||
|
||||
log.Debugf("validated %s as domain argument", domainName)
|
||||
@ -124,10 +124,10 @@ func ValidateDomain(c *cli.Context) string {
|
||||
}
|
||||
|
||||
// ValidateSubCmdFlags ensures flag order conforms to correct order
|
||||
func ValidateSubCmdFlags(c *cli.Context) bool {
|
||||
for argIdx, arg := range c.Args().Slice() {
|
||||
func ValidateSubCmdFlags(cmd *cli.Command) bool {
|
||||
for argIdx, arg := range cmd.Args().Slice() {
|
||||
if !strings.HasPrefix(arg, "--") {
|
||||
for _, flag := range c.Args().Slice()[argIdx:] {
|
||||
for _, flag := range cmd.Args().Slice()[argIdx:] {
|
||||
if strings.HasPrefix(flag, "--") {
|
||||
return false
|
||||
}
|
||||
@ -138,8 +138,8 @@ func ValidateSubCmdFlags(c *cli.Context) bool {
|
||||
}
|
||||
|
||||
// ValidateServer ensures the server name arg is valid.
|
||||
func ValidateServer(c *cli.Context) string {
|
||||
serverName := c.Args().First()
|
||||
func ValidateServer(cmd *cli.Command) string {
|
||||
serverName := cmd.Args().First()
|
||||
|
||||
serverNames, err := config.ReadServerNames()
|
||||
if err != nil {
|
||||
@ -164,11 +164,11 @@ func ValidateServer(c *cli.Context) string {
|
||||
}
|
||||
|
||||
if serverName == "" {
|
||||
ShowSubcommandHelpAndError(c, errors.New("no server provided"))
|
||||
ShowSubcommandHelpAndError(cmd, errors.New("no server provided"))
|
||||
}
|
||||
|
||||
if !matched {
|
||||
ShowSubcommandHelpAndError(c, errors.New("server doesn't exist?"))
|
||||
ShowSubcommandHelpAndError(cmd, errors.New("server doesn't exist?"))
|
||||
}
|
||||
|
||||
log.Debugf("validated %s as server argument", serverName)
|
||||
|
@ -1,27 +1,26 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
gitPkg "coopcloud.tech/abra/pkg/git"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var recipeDiffCommand = cli.Command{
|
||||
Name: "diff",
|
||||
Usage: "Show unstaged changes in recipe config",
|
||||
Description: "This command requires /usr/bin/git.",
|
||||
Aliases: []string{"d"},
|
||||
ArgsUsage: "<recipe>",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.RecipeNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
r := internal.ValidateRecipe(c)
|
||||
Name: "diff",
|
||||
Usage: "Show unstaged changes in recipe config",
|
||||
Description: "This command requires /usr/bin/git.",
|
||||
Aliases: []string{"d"},
|
||||
UsageText: "abra recipe diff <recipe> [options]",
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.RecipeNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
r := internal.ValidateRecipe(cmd)
|
||||
|
||||
if err := gitPkg.DiffUnstaged(r.Dir); err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -1,32 +1,30 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var recipeFetchCommand = cli.Command{
|
||||
Name: "fetch",
|
||||
Usage: "Fetch recipe(s)",
|
||||
Aliases: []string{"f"},
|
||||
ArgsUsage: "[<recipe>]",
|
||||
Description: "Retrieves all recipes if no <recipe> argument is passed",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.RecipeNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipeName := c.Args().First()
|
||||
Name: "fetch",
|
||||
Usage: "Fetch recipe(s)",
|
||||
Aliases: []string{"f"},
|
||||
UsageText: "abra recipe fetch [<recipe>] [options]",
|
||||
Description: "Retrieves all recipes if no <recipe> argument is passed",
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.RecipeNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
recipeName := cmd.Args().First()
|
||||
r := recipe.Get(recipeName)
|
||||
if recipeName != "" {
|
||||
internal.ValidateRecipe(c)
|
||||
internal.ValidateRecipe(cmd)
|
||||
if err := r.Ensure(false, false); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
@ -8,25 +9,23 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/lint"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var recipeLintCommand = cli.Command{
|
||||
Name: "lint",
|
||||
Usage: "Lint a recipe",
|
||||
Aliases: []string{"l"},
|
||||
ArgsUsage: "<recipe>",
|
||||
UsageText: "abra recipe lint <recipe> [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.OnlyErrorFlag,
|
||||
internal.OfflineFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.ChaosFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.RecipeNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := internal.ValidateRecipe(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.RecipeNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
recipe := internal.ValidateRecipe(cmd)
|
||||
|
||||
if err := recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
@ -10,7 +11,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var pattern string
|
||||
@ -23,17 +24,17 @@ var patternFlag = &cli.StringFlag{
|
||||
}
|
||||
|
||||
var recipeListCommand = cli.Command{
|
||||
Name: "list",
|
||||
Usage: "List available recipes",
|
||||
Aliases: []string{"ls"},
|
||||
Name: "list",
|
||||
Usage: "List recipes",
|
||||
UsageText: "abra recipe list [options]",
|
||||
Aliases: []string{"ls"},
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.MachineReadableFlag,
|
||||
patternFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Action: func(c *cli.Context) error {
|
||||
Before: internal.SubCommandBefore,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
catl, err := recipe.ReadRecipeCatalogue(internal.Offline)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
|
@ -2,6 +2,7 @@ package recipe
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -13,7 +14,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/git"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// recipeMetadata is the recipe metadata for the README.md
|
||||
@ -34,27 +35,24 @@ var recipeNewCommand = cli.Command{
|
||||
Name: "new",
|
||||
Aliases: []string{"n"},
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.OfflineFlag,
|
||||
internal.GitNameFlag,
|
||||
internal.GitEmailFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Usage: "Create a new recipe",
|
||||
ArgsUsage: "<recipe>",
|
||||
Description: `
|
||||
Create a new recipe.
|
||||
UsageText: "abra recipe new <recipe> [options]",
|
||||
Description: `Create a new recipe.
|
||||
|
||||
Abra uses the built-in example repository which is available here:
|
||||
|
||||
https://git.coopcloud.tech/coop-cloud/example`,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipeName := c.Args().First()
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
recipeName := cmd.Args().First()
|
||||
r := recipe.Get(recipeName)
|
||||
|
||||
if recipeName == "" {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no recipe name provided"))
|
||||
internal.ShowSubcommandHelpAndError(cmd, errors.New("no recipe name provided"))
|
||||
}
|
||||
|
||||
if _, err := os.Stat(r.Dir); !os.IsNotExist(err) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// RecipeCommand defines all recipe related sub-commands.
|
||||
@ -9,17 +9,17 @@ var RecipeCommand = cli.Command{
|
||||
Name: "recipe",
|
||||
Aliases: []string{"r"},
|
||||
Usage: "Manage recipes",
|
||||
ArgsUsage: "<recipe>",
|
||||
Description: `
|
||||
A recipe is a blueprint for an app. It is a bunch of config files which
|
||||
describe how to deploy and maintain an app. Recipes are maintained by the Co-op
|
||||
Cloud community and you can use Abra to read them, deploy them and create apps
|
||||
for you.
|
||||
UsageText: "abra recipe [command] [arguments] [options]",
|
||||
Description: `A recipe is a blueprint for an app.
|
||||
|
||||
It is a bunch of config files which describe how to deploy and maintain an app.
|
||||
Recipes are maintained by the Co-op Cloud community and you can use Abra to
|
||||
read them, deploy them and create apps for you.
|
||||
|
||||
Anyone who uses a recipe can become a maintainer. Maintainers typically make
|
||||
sure the recipe is in good working order and the config upgraded in a timely
|
||||
manner.`,
|
||||
Subcommands: []*cli.Command{
|
||||
Commands: []*cli.Command{
|
||||
&recipeFetchCommand,
|
||||
&recipeLintCommand,
|
||||
&recipeListCommand,
|
||||
|
@ -1,6 +1,7 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -18,17 +19,18 @@ import (
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var recipeReleaseCommand = cli.Command{
|
||||
Name: "release",
|
||||
Aliases: []string{"rl"},
|
||||
Usage: "Release a new recipe version",
|
||||
ArgsUsage: "<recipe> [<version>]",
|
||||
Description: `
|
||||
Create a new version of a recipe. These versions are then published on the
|
||||
Co-op Cloud recipe catalogue. These versions take the following form:
|
||||
UsageText: "abra recipe release <recipe> [<version>] [options]",
|
||||
Description: `Create a new version of a recipe.
|
||||
|
||||
These versions are then published on the Co-op Cloud recipe catalogue. These
|
||||
versions take the following form:
|
||||
|
||||
a.b.c+x.y.z
|
||||
|
||||
@ -46,19 +48,17 @@ Publish your new release to git.coopcloud.tech with "-p/--publish". This
|
||||
requires that you have permission to git push to these repositories and have
|
||||
your SSH keys configured on your account.`,
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.DryFlag,
|
||||
internal.MajorFlag,
|
||||
internal.MinorFlag,
|
||||
internal.PatchFlag,
|
||||
internal.PublishFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.RecipeNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := internal.ValidateRecipe(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.RecipeNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
recipe := internal.ValidateRecipe(cmd)
|
||||
|
||||
imagesTmp, err := getImageVersions(recipe)
|
||||
if err != nil {
|
||||
@ -75,7 +75,7 @@ your SSH keys configured on your account.`,
|
||||
log.Fatalf("main app service version for %s is empty?", recipe.Name)
|
||||
}
|
||||
|
||||
tagString := c.Args().Get(1)
|
||||
tagString := cmd.Args().Get(1)
|
||||
if tagString != "" {
|
||||
if _, err := tagcmp.Parse(tagString); err != nil {
|
||||
log.Fatalf("cannot parse %s, invalid tag specified?", tagString)
|
||||
|
@ -1,32 +1,31 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var recipeResetCommand = cli.Command{
|
||||
Name: "reset",
|
||||
Usage: "Remove all unstaged changes from recipe config",
|
||||
Description: "WARNING: this will delete your changes. Be Careful.",
|
||||
Aliases: []string{"rs"},
|
||||
ArgsUsage: "<recipe>",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.RecipeNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipeName := c.Args().First()
|
||||
Name: "reset",
|
||||
Usage: "Remove all unstaged changes from recipe config",
|
||||
Description: "WARNING: this will delete your changes. Be Careful.",
|
||||
Aliases: []string{"rs"},
|
||||
UsageText: "abra recipe reset <recipe> [options]",
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.RecipeNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
recipeName := cmd.Args().First()
|
||||
r := recipe.Get(recipeName)
|
||||
|
||||
if recipeName != "" {
|
||||
internal.ValidateRecipe(c)
|
||||
internal.ValidateRecipe(cmd)
|
||||
}
|
||||
|
||||
repo, err := git.PlainOpen(r.Dir)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
@ -12,35 +13,34 @@ import (
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var recipeSyncCommand = cli.Command{
|
||||
Name: "sync",
|
||||
Aliases: []string{"s"},
|
||||
Usage: "Sync recipe version label",
|
||||
ArgsUsage: "<recipe> [<version>]",
|
||||
UsageText: "abra recipe lint <recipe> [<version>] [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.DryFlag,
|
||||
internal.MajorFlag,
|
||||
internal.MinorFlag,
|
||||
internal.PatchFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Description: `
|
||||
Generate labels for the main recipe service (i.e. by convention, the service
|
||||
named "app") which corresponds to the following format:
|
||||
Description: `Generate labels for the main recipe service.
|
||||
|
||||
By convention, the service named "app" using the following format:
|
||||
|
||||
coop-cloud.${STACK_NAME}.version=<version>
|
||||
|
||||
Where <version> can be specifed on the command-line or Abra can attempt to
|
||||
auto-generate it for you. The <recipe> configuration will be updated on the
|
||||
local file system.`,
|
||||
BashComplete: autocomplete.RecipeNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := internal.ValidateRecipe(c)
|
||||
ShellComplete: autocomplete.RecipeNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
recipe := internal.ValidateRecipe(cmd)
|
||||
|
||||
mainApp, err := internal.GetMainAppImage(recipe)
|
||||
if err != nil {
|
||||
@ -59,7 +59,7 @@ local file system.`,
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
nextTag := c.Args().Get(1)
|
||||
nextTag := cmd.Args().Get(1)
|
||||
if len(tags) == 0 && nextTag == "" {
|
||||
log.Warnf("no git tags found for %s", recipe.Name)
|
||||
if internal.NoInput {
|
||||
|
@ -2,6 +2,7 @@ package recipe
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -19,7 +20,7 @@ import (
|
||||
"coopcloud.tech/tagcmp"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
type imgPin struct {
|
||||
@ -27,8 +28,8 @@ type imgPin struct {
|
||||
version tagcmp.Tag
|
||||
}
|
||||
|
||||
// anUpgrade represents a single service upgrade (as within a recipe), and the list of tags that it can be upgraded to,
|
||||
// for serialization purposes.
|
||||
// anUpgrade represents a single service upgrade (as within a recipe), and the
|
||||
// list of tags that it can be upgraded to, for serialization purposes.
|
||||
type anUpgrade struct {
|
||||
Service string `json:"service"`
|
||||
Image string `json:"image"`
|
||||
@ -37,13 +38,13 @@ type anUpgrade struct {
|
||||
}
|
||||
|
||||
var recipeUpgradeCommand = cli.Command{
|
||||
Name: "upgrade",
|
||||
Aliases: []string{"u"},
|
||||
Usage: "Upgrade recipe image tags",
|
||||
Description: `
|
||||
Parse all image tags within the given <recipe> configuration and prompt with
|
||||
more recent tags to upgrade to. It will update the relevant compose file tags
|
||||
on the local file system.
|
||||
Name: "upgrade",
|
||||
Aliases: []string{"u"},
|
||||
Usage: "Upgrade recipe image tags",
|
||||
UsageText: "abra recipe upgrade [<recipe>] [options]",
|
||||
Description: `Upgrade a given <recipe> configuration.
|
||||
|
||||
It will update the relevant compose file tags on the local file system.
|
||||
|
||||
Some image tags cannot be parsed because they do not follow some sort of
|
||||
semver-like convention. In this case, all possible tags will be listed and it
|
||||
@ -53,25 +54,19 @@ The command is interactive and will show a select input which allows you to
|
||||
make a seclection. Use the "?" key to see more help on navigating this
|
||||
interface.
|
||||
|
||||
You may invoke this command in "wizard" mode and be prompted for input.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
abra recipe upgrade`,
|
||||
ArgsUsage: "<recipe>",
|
||||
You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.PatchFlag,
|
||||
internal.MinorFlag,
|
||||
internal.MajorFlag,
|
||||
internal.MachineReadableFlag,
|
||||
internal.AllTagsFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.RecipeNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := internal.ValidateRecipe(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.RecipeNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
recipe := internal.ValidateRecipe(cmd)
|
||||
|
||||
if err := recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
@ -9,7 +10,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
func sortServiceByName(versions [][]string) func(i, j int) bool {
|
||||
@ -26,19 +27,17 @@ var recipeVersionCommand = cli.Command{
|
||||
Name: "versions",
|
||||
Aliases: []string{"v"},
|
||||
Usage: "List recipe versions",
|
||||
ArgsUsage: "<recipe>",
|
||||
UsageText: "abra recipe version <recipe> [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.OfflineFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.MachineReadableFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.RecipeNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.RecipeNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
var warnMessages []string
|
||||
|
||||
recipe := internal.ValidateRecipe(c)
|
||||
recipe := internal.ValidateRecipe(cmd)
|
||||
|
||||
catl, err := recipePkg.ReadRecipeCatalogue(internal.Offline)
|
||||
if err != nil {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -13,7 +14,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/server"
|
||||
sshPkg "coopcloud.tech/abra/pkg/ssh"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var local bool
|
||||
@ -93,15 +94,15 @@ func createServerDir(name string) (bool, error) {
|
||||
}
|
||||
|
||||
var serverAddCommand = cli.Command{
|
||||
Name: "add",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Add a new server to your configuration",
|
||||
Description: `
|
||||
Add a new server to your configuration so that it can be managed by Abra.
|
||||
Name: "add",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Add a new server",
|
||||
UsageText: "abra server add <domain> [options]",
|
||||
Description: `Add a new server to your configuration so that it can be managed by Abra.
|
||||
|
||||
Abra relies on the standard SSH command-line and ~/.ssh/config for client
|
||||
connection details. You must configure an entry per-host in your ~/.ssh/config
|
||||
for each server. For example:
|
||||
for each server:
|
||||
|
||||
Host example.com example
|
||||
Hostname example.com
|
||||
@ -109,10 +110,6 @@ for each server. For example:
|
||||
Port 12345
|
||||
IdentityFile ~/.ssh/example@somewhere
|
||||
|
||||
You can then add a server like so:
|
||||
|
||||
abra server add example.com
|
||||
|
||||
If "--local" is passed, then Abra assumes that the current local server is
|
||||
intended as the target server. This is useful when you want to have your entire
|
||||
Co-op Cloud config located on the server itself, and not on your local
|
||||
@ -120,28 +117,24 @@ developer machine. The domain is then set to "default".
|
||||
|
||||
You can also pass "--no-domain-checks/-D" flag to use any arbitrary name
|
||||
instead of a real domain. The host will be resolved with the "Hostname" entry
|
||||
of your ~/.ssh/config. Checks for a valid online domain will be skipped:
|
||||
|
||||
abra server add -D example`,
|
||||
of your ~/.ssh/config. Checks for a valid online domain will be skipped.`,
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.NoDomainChecksFlag,
|
||||
localFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
ArgsUsage: "<name>",
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.Args().Len() > 0 && local || !internal.ValidateSubCmdFlags(c) {
|
||||
Before: internal.SubCommandBefore,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
if cmd.Args().Len() > 0 && local || !internal.ValidateSubCmdFlags(cmd) {
|
||||
err := errors.New("cannot use <name> and --local together")
|
||||
internal.ShowSubcommandHelpAndError(c, err)
|
||||
internal.ShowSubcommandHelpAndError(cmd, err)
|
||||
}
|
||||
|
||||
var name string
|
||||
if local {
|
||||
name = "default"
|
||||
} else {
|
||||
name = internal.ValidateDomain(c)
|
||||
name = internal.ValidateDomain(cmd)
|
||||
}
|
||||
|
||||
// NOTE(d1): reasonable 5 second timeout for connections which can't
|
||||
|
@ -1,30 +1,31 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"coopcloud.tech/abra/pkg/context"
|
||||
contextPkg "coopcloud.tech/abra/pkg/context"
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/docker/cli/cli/connhelper/ssh"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var serverListCommand = cli.Command{
|
||||
Name: "list",
|
||||
Aliases: []string{"ls"},
|
||||
Usage: "List managed servers",
|
||||
Name: "list",
|
||||
Aliases: []string{"ls"},
|
||||
Usage: "List managed servers",
|
||||
UsageText: "abra server list [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.MachineReadableFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Action: func(c *cli.Context) error {
|
||||
dockerContextStore := context.NewDefaultDockerContextStore()
|
||||
Before: internal.SubCommandBefore,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
dockerContextStore := contextPkg.NewDefaultDockerContextStore()
|
||||
contexts, err := dockerContextStore.Store.List()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -46,14 +47,14 @@ var serverListCommand = cli.Command{
|
||||
var rows [][]string
|
||||
for _, serverName := range serverNames {
|
||||
var row []string
|
||||
for _, ctx := range contexts {
|
||||
endpoint, err := context.GetContextEndpoint(ctx)
|
||||
for _, dockerCtx := range contexts {
|
||||
endpoint, err := contextPkg.GetContextEndpoint(dockerCtx)
|
||||
if err != nil && strings.Contains(err.Error(), "does not exist") {
|
||||
// No local context found, we can continue safely
|
||||
continue
|
||||
}
|
||||
|
||||
if ctx.Name == serverName {
|
||||
if dockerCtx.Name == serverName {
|
||||
sp, err := ssh.ParseURL(endpoint)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var allFilter bool
|
||||
@ -31,26 +31,23 @@ var volumesFilterFlag = &cli.BoolFlag{
|
||||
}
|
||||
|
||||
var serverPruneCommand = cli.Command{
|
||||
Name: "prune",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Prune resources on a server",
|
||||
Description: `
|
||||
Prunes unused containers, networks, and dangling images.
|
||||
Name: "prune",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Prune resources on a server",
|
||||
UsageText: "abra server prune <server> [options]",
|
||||
Description: `Prunes unused containers, networks, and dangling images.
|
||||
|
||||
Use "-v/--volumes" to remove volumes that are not associated with a deployed
|
||||
app. This can result in unwanted data loss if not used carefully.`,
|
||||
ArgsUsage: "[<server>]",
|
||||
Flags: []cli.Flag{
|
||||
allFilterFlag,
|
||||
volumesFilterFlag,
|
||||
internal.DebugFlag,
|
||||
internal.OfflineFlag,
|
||||
internal.NoInputFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.ServerNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
serverName := internal.ValidateServer(c)
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.ServerNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
serverName := internal.ValidateServer(cmd)
|
||||
|
||||
cl, err := client.New(serverName)
|
||||
if err != nil {
|
||||
@ -59,7 +56,6 @@ app. This can result in unwanted data loss if not used carefully.`,
|
||||
|
||||
var args filters.Args
|
||||
|
||||
ctx := context.Background()
|
||||
cr, err := cl.ContainersPrune(ctx, args)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@ -9,29 +10,24 @@ import (
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var serverRemoveCommand = cli.Command{
|
||||
Name: "remove",
|
||||
Aliases: []string{"rm"},
|
||||
ArgsUsage: "<server>",
|
||||
UsageText: "abra server remove <domain> [options]",
|
||||
Usage: "Remove a managed server",
|
||||
Description: `
|
||||
Remove a managed server.
|
||||
Description: `Remove a managed server.
|
||||
|
||||
Abra will remove the internal bookkeeping (~/.abra/servers/...) and underlying
|
||||
client connection context. This server will then be lost in time, like tears in
|
||||
rain.`,
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.NoInputFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.ServerNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
serverName := internal.ValidateServer(c)
|
||||
Abra will remove the internal bookkeeping ($ABRA_DIR/servers/...) and
|
||||
underlying client connection context. This server will then be lost in time,
|
||||
like tears in rain.`,
|
||||
Before: internal.SubCommandBefore,
|
||||
ShellComplete: autocomplete.ServerNameComplete,
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
serverName := internal.ValidateServer(cmd)
|
||||
|
||||
if err := client.DeleteContext(serverName); err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -1,15 +1,16 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// ServerCommand defines the `abra server` command and its subcommands
|
||||
var ServerCommand = cli.Command{
|
||||
Name: "server",
|
||||
Aliases: []string{"s"},
|
||||
Usage: "Manage servers",
|
||||
Subcommands: []*cli.Command{
|
||||
Name: "server",
|
||||
Aliases: []string{"s"},
|
||||
Usage: "Manage servers",
|
||||
UsageText: "abra server [command] [arguments] [options]",
|
||||
Commands: []*cli.Command{
|
||||
&serverAddCommand,
|
||||
&serverListCommand,
|
||||
&serverRemoveCommand,
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
dockerclient "github.com/docker/docker/client"
|
||||
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
const SERVER = "localhost"
|
||||
@ -46,23 +46,21 @@ var allFlag = &cli.BoolFlag{
|
||||
|
||||
// Notify checks for available upgrades
|
||||
var Notify = cli.Command{
|
||||
Name: "notify",
|
||||
Aliases: []string{"n"},
|
||||
Usage: "Check for available upgrades",
|
||||
Name: "notify",
|
||||
Aliases: []string{"n"},
|
||||
Usage: "Check for available upgrades",
|
||||
UsageText: "kadabra notify [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
majorFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Description: `
|
||||
Read the deployed app versions and look for new versions in the recipe
|
||||
catalogue.
|
||||
Description: `Notify on new versions for deployed apps.
|
||||
|
||||
If a new patch/minor version is available, a notification is printed.
|
||||
|
||||
Use "--major" to include new major versions.`,
|
||||
Action: func(c *cli.Context) error {
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
cl, err := client.New("default")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -97,17 +95,14 @@ var UpgradeApp = cli.Command{
|
||||
Name: "upgrade",
|
||||
Aliases: []string{"u"},
|
||||
Usage: "Upgrade apps",
|
||||
ArgsUsage: "<stack-name> <recipe>",
|
||||
UsageText: "kadabra notify <stack> <recipe> [options]",
|
||||
Flags: []cli.Flag{
|
||||
internal.DebugFlag,
|
||||
internal.ChaosFlag,
|
||||
majorFlag,
|
||||
allFlag,
|
||||
internal.OfflineFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Description: `
|
||||
Upgrade an app by specifying stack name and recipe.
|
||||
Description: `Upgrade an app by specifying stack name and recipe.
|
||||
|
||||
Use "--all" to upgrade every deployed app.
|
||||
|
||||
@ -118,15 +113,16 @@ available, the app is upgraded.
|
||||
To include major versions use the "--major" flag. You probably don't want that
|
||||
as it will break things. Only apps that are not deployed with "--chaos" are
|
||||
upgraded, to update chaos deployments use the "--chaos" flag. Use it with care.`,
|
||||
Action: func(c *cli.Context) error {
|
||||
HideHelp: true,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
cl, err := client.New("default")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if !updateAll {
|
||||
stackName := c.Args().Get(0)
|
||||
recipeName := c.Args().Get(1)
|
||||
stackName := cmd.Args().Get(0)
|
||||
recipeName := cmd.Args().Get(1)
|
||||
err = tryUpgrade(cl, stackName, recipeName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -470,25 +466,25 @@ func upgrade(cl *dockerclient.Client, stackName, recipeName, upgradeVersion stri
|
||||
return err
|
||||
}
|
||||
|
||||
func newAbraApp(version, commit string) *cli.App {
|
||||
app := &cli.App{
|
||||
Name: "kadabra",
|
||||
Usage: `The Co-op Cloud auto-updater
|
||||
____ ____ _ _
|
||||
/ ___|___ ___ _ __ / ___| | ___ _ _ __| |
|
||||
| | / _ \ _____ / _ \| '_ \ | | | |/ _ \| | | |/ _' |
|
||||
| |__| (_) |_____| (_) | |_) | | |___| | (_) | |_| | (_| |
|
||||
\____\___/ \___/| .__/ \____|_|\___/ \__,_|\__,_|
|
||||
|_|
|
||||
`,
|
||||
Version: fmt.Sprintf("%s-%s", version, commit[:7]),
|
||||
func newKadabraApp(version, commit string) *cli.Command {
|
||||
app := &cli.Command{
|
||||
Name: "kadabra",
|
||||
Version: fmt.Sprintf("%s-%s", version, commit[:7]),
|
||||
Usage: "The Co-op Cloud auto-updater 🤖 🚀",
|
||||
UsageText: "kadabra [command] [options]",
|
||||
UseShortOptionHandling: true,
|
||||
HideHelpCommand: true,
|
||||
Flags: []cli.Flag{
|
||||
// NOTE(d1): "GLOBAL OPTIONS" flags
|
||||
internal.DebugFlag,
|
||||
},
|
||||
Commands: []*cli.Command{
|
||||
&Notify,
|
||||
&UpgradeApp,
|
||||
},
|
||||
}
|
||||
|
||||
app.Before = func(c *cli.Context) error {
|
||||
app.Before = func(ctx context.Context, cmd *cli.Command) error {
|
||||
log.Logger.SetStyles(log.Styles())
|
||||
charmLog.SetDefault(log.Logger)
|
||||
|
||||
@ -497,14 +493,20 @@ func newAbraApp(version, commit string) *cli.App {
|
||||
return nil
|
||||
}
|
||||
|
||||
cli.HelpFlag = &cli.BoolFlag{
|
||||
Name: "help",
|
||||
Aliases: []string{"h, H"},
|
||||
Usage: "Show help",
|
||||
}
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
// RunApp runs CLI abra app.
|
||||
func RunApp(version, commit string) {
|
||||
app := newAbraApp(version, commit)
|
||||
app := newKadabraApp(version, commit)
|
||||
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
if err := app.Run(context.Background(), os.Args); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user