From 0e688f1407a1f17333ea6cf4c4f64ba9b9d800fa Mon Sep 17 00:00:00 2001 From: cellarspoon Date: Tue, 18 Jan 2022 14:13:20 +0100 Subject: [PATCH] refactor!: migrate to urfave/cli v1 Better flexible flags handling. --- cli/app/app.go | 8 +- cli/app/backup.go | 20 ++-- cli/app/check.go | 11 +- cli/app/config.go | 9 +- cli/app/cp.go | 18 ++- cli/app/deploy.go | 7 +- cli/app/errors.go | 20 ++-- cli/app/list.go | 23 ++-- cli/app/logs.go | 16 ++- cli/app/new.go | 9 +- cli/app/ps.go | 14 ++- cli/app/remove.go | 21 ++-- cli/app/restart.go | 26 +++-- cli/app/restore.go | 23 ++-- cli/app/rollback.go | 12 +- cli/app/run.go | 21 ++-- cli/app/secret.go | 79 ++++++++----- cli/app/undeploy.go | 17 ++- cli/app/upgrade.go | 10 +- cli/app/version.go | 15 ++- cli/app/volume.go | 30 +++-- cli/catalogue/catalogue.go | 11 +- cli/cli.go | 30 ++--- cli/internal/{flags.go => cli.go} | 187 +++++++++++------------------- cli/internal/deploy.go | 5 +- cli/internal/errors.go | 2 +- cli/internal/new.go | 2 +- cli/internal/validate.go | 10 +- cli/recipe/lint.go | 19 +-- cli/recipe/list.go | 11 +- cli/recipe/new.go | 13 ++- cli/recipe/recipe.go | 8 +- cli/recipe/release.go | 9 +- cli/recipe/sync.go | 9 +- cli/recipe/upgrade.go | 9 +- cli/recipe/version.go | 17 ++- cli/record/list.go | 10 +- cli/record/new.go | 16 ++- cli/record/record.go | 6 +- cli/record/remove.go | 12 +- cli/server/add.go | 47 ++++---- cli/server/list.go | 18 +-- cli/server/new.go | 15 ++- cli/server/remove.go | 16 +-- cli/server/server.go | 6 +- go.mod | 2 +- go.sum | 6 +- pkg/autocomplete/autocomplete.go | 2 +- 48 files changed, 502 insertions(+), 405 deletions(-) rename cli/internal/{flags.go => cli.go} (72%) diff --git a/cli/app/app.go b/cli/app/app.go index 2135b063..1d76b81b 100644 --- a/cli/app/app.go +++ b/cli/app/app.go @@ -1,21 +1,21 @@ package app import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // AppCommand defines the `abra app` command and ets subcommands -var AppCommand = &cli.Command{ +var AppCommand = cli.Command{ Name: "app", - Usage: "Manage apps", Aliases: []string{"a"}, + Usage: "Manage apps", ArgsUsage: "", Description: ` This command provides all the functionality you need to manage the life cycle of your apps. From initial deployment, day-2 operations (e.g. backup/restore) to scaling apps up and spinning them down. `, - Subcommands: []*cli.Command{ + Subcommands: []cli.Command{ appNewCommand, appConfigCommand, appRestartCommand, diff --git a/cli/app/backup.go b/cli/app/backup.go index cfe4be86..96d1927b 100644 --- a/cli/app/backup.go +++ b/cli/app/backup.go @@ -13,23 +13,25 @@ import ( "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/config" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) var backupAllServices bool var backupAllServicesFlag = &cli.BoolFlag{ - Name: "all", - Value: false, + Name: "all, a", Destination: &backupAllServices, - Aliases: []string{"a"}, Usage: "Backup all services", } -var appBackupCommand = &cli.Command{ - Name: "backup", - Usage: "Backup an app", - Aliases: []string{"b"}, - Flags: []cli.Flag{backupAllServicesFlag}, +var appBackupCommand = cli.Command{ + Name: "backup", + Aliases: []string{"b"}, + Usage: "Backup an app", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + backupAllServicesFlag}, + Before: internal.SubCommandBefore, ArgsUsage: "", Action: func(c *cli.Context) error { app := internal.ValidateApp(c) diff --git a/cli/app/check.go b/cli/app/check.go index 14e64223..047d6991 100644 --- a/cli/app/check.go +++ b/cli/app/check.go @@ -9,14 +9,19 @@ import ( "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/config" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var appCheckCommand = &cli.Command{ +var appCheckCommand = cli.Command{ Name: "check", - Usage: "Check if app is configured correctly", Aliases: []string{"c"}, + Usage: "Check if app is configured correctly", ArgsUsage: "", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) diff --git a/cli/app/config.go b/cli/app/config.go index 6d182f67..a2a98bcf 100644 --- a/cli/app/config.go +++ b/cli/app/config.go @@ -10,13 +10,18 @@ import ( "coopcloud.tech/abra/pkg/config" "github.com/AlecAivazis/survey/v2" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var appConfigCommand = &cli.Command{ +var appConfigCommand = cli.Command{ Name: "config", Aliases: []string{"c"}, Usage: "Edit app config", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, Action: func(c *cli.Context) error { appName := c.Args().First() diff --git a/cli/app/cp.go b/cli/app/cp.go index 63f7c386..7c53a964 100644 --- a/cli/app/cp.go +++ b/cli/app/cp.go @@ -1,6 +1,7 @@ package app import ( + "context" "fmt" "os" "strings" @@ -15,14 +16,19 @@ import ( "github.com/docker/docker/api/types/filters" "github.com/docker/docker/pkg/archive" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var appCpCommand = &cli.Command{ +var appCpCommand = cli.Command{ Name: "cp", Aliases: []string{"c"}, ArgsUsage: " ", - Usage: "Copy files to/from a running app service", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, + Usage: "Copy files to/from a running app service", Description: ` This command supports copying files to and from any app service file system. @@ -118,7 +124,7 @@ func configureAndCp( filters := filters.NewArgs() filters.Add("name", fmt.Sprintf("%s_%s", appEnv.StackName(), service)) - container, err := container.GetContainer(c.Context, cl, filters, true) + container, err := container.GetContainer(context.Background(), cl, filters, true) if err != nil { logrus.Fatal(err) } @@ -137,11 +143,11 @@ func configureAndCp( } copyOpts := types.CopyToContainerOptions{AllowOverwriteDirWithFile: false, CopyUIDGID: false} - if err := cl.CopyToContainer(c.Context, container.ID, dstPath, content, copyOpts); err != nil { + if err := cl.CopyToContainer(context.Background(), container.ID, dstPath, content, copyOpts); err != nil { logrus.Fatal(err) } } else { - content, _, err := cl.CopyFromContainer(c.Context, container.ID, srcPath) + content, _, err := cl.CopyFromContainer(context.Background(), container.ID, srcPath) if err != nil { logrus.Fatal(err) } diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 1e89fcaa..3b5a8b02 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -3,19 +3,22 @@ package app import ( "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var appDeployCommand = &cli.Command{ +var appDeployCommand = cli.Command{ Name: "deploy", Aliases: []string{"d"}, Usage: "Deploy an app", Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, internal.ForceFlag, internal.ChaosFlag, internal.NoDomainChecksFlag, internal.DontWaitConvergeFlag, }, + Before: internal.SubCommandBefore, Description: ` This command deploys an app. It does not support incrementing the version of a deployed app, for this you need to look at the "abra app upgrade " diff --git a/cli/app/errors.go b/cli/app/errors.go index c848518b..e000945e 100644 --- a/cli/app/errors.go +++ b/cli/app/errors.go @@ -1,6 +1,7 @@ package app import ( + "context" "strconv" "strings" "time" @@ -15,10 +16,10 @@ import ( "github.com/docker/docker/api/types/filters" dockerClient "github.com/docker/docker/client" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var appErrorsCommand = &cli.Command{ +var appErrorsCommand = cli.Command{ Name: "errors", Usage: "List errors for a deployed app", Description: ` @@ -44,8 +45,13 @@ further information which can help you debug the cause of an app failure via the logs. `, - Aliases: []string{"e"}, - Flags: []cli.Flag{internal.WatchFlag}, + Aliases: []string{"e"}, + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + internal.WatchFlag, + }, + Before: internal.SubCommandBefore, BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) @@ -55,7 +61,7 @@ the logs. logrus.Fatal(err) } - isDeployed, _, err := stack.IsDeployed(c.Context, cl, app.StackName()) + isDeployed, _, err := stack.IsDeployed(context.Background(), cl, app.StackName()) if err != nil { logrus.Fatal(err) } @@ -91,7 +97,7 @@ func checkErrors(c *cli.Context, cl *dockerClient.Client, app config.App) error for _, service := range recipe.Config.Services { filters := filters.NewArgs() filters.Add("name", service.Name) - containers, err := cl.ContainerList(c.Context, types.ContainerListOptions{Filters: filters}) + containers, err := cl.ContainerList(context.Background(), types.ContainerListOptions{Filters: filters}) if err != nil { return err } @@ -102,7 +108,7 @@ func checkErrors(c *cli.Context, cl *dockerClient.Client, app config.App) error } container := containers[0] - containerState, err := cl.ContainerInspect(c.Context, container.ID) + containerState, err := cl.ContainerInspect(context.Background(), container.ID) if err != nil { logrus.Fatal(err) } diff --git a/cli/app/list.go b/cli/app/list.go index 38baa6db..3c7f2143 100644 --- a/cli/app/list.go +++ b/cli/app/list.go @@ -12,22 +12,19 @@ import ( "coopcloud.tech/abra/pkg/ssh" "coopcloud.tech/tagcmp" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) var status bool var statusFlag = &cli.BoolFlag{ - Name: "status", - Aliases: []string{"S"}, - Value: false, + Name: "status, S", Usage: "Show app deployment status", Destination: &status, } var appType string var typeFlag = &cli.StringFlag{ - Name: "type", - Aliases: []string{"t"}, + Name: "type, t", Value: "", Usage: "Show apps of a specific type", Destination: &appType, @@ -35,8 +32,7 @@ var typeFlag = &cli.StringFlag{ var listAppServer string var listAppServerFlag = &cli.StringFlag{ - Name: "server", - Aliases: []string{"s"}, + Name: "server, s", Value: "", Usage: "Show apps of a specific server", Destination: &listAppServer, @@ -61,9 +57,10 @@ type serverStatus struct { upgradeCount int } -var appListCommand = &cli.Command{ - Name: "list", - Usage: "List all managed apps", +var appListCommand = cli.Command{ + Name: "list", + Aliases: []string{"ls"}, + Usage: "List all managed apps", Description: ` This command looks at your local file system listing of apps and servers (e.g. in ~/.abra/) to generate a report of all your apps. @@ -72,12 +69,14 @@ 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. `, - Aliases: []string{"ls"}, Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, statusFlag, listAppServerFlag, typeFlag, }, + Before: internal.SubCommandBefore, Action: func(c *cli.Context) error { appFiles, err := config.LoadAppFiles(listAppServer) if err != nil { diff --git a/cli/app/logs.go b/cli/app/logs.go index b8f5fed7..f530c07f 100644 --- a/cli/app/logs.go +++ b/cli/app/logs.go @@ -1,6 +1,7 @@ package app import ( + "context" "fmt" "io" "os" @@ -15,7 +16,7 @@ import ( "github.com/docker/docker/api/types/filters" dockerClient "github.com/docker/docker/client" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) var logOpts = types.ContainerLogsOptions{ @@ -32,7 +33,7 @@ func stackLogs(c *cli.Context, stackName string, client *dockerClient.Client) { filters := filters.NewArgs() filters.Add("name", stackName) serviceOpts := types.ServiceListOptions{Filters: filters} - services, err := client.ServiceList(c.Context, serviceOpts) + services, err := client.ServiceList(context.Background(), serviceOpts) if err != nil { logrus.Fatal(err) } @@ -45,7 +46,7 @@ func stackLogs(c *cli.Context, stackName string, client *dockerClient.Client) { logOpts.ShowStdout = false } - logs, err := client.ServiceLogs(c.Context, s, logOpts) + logs, err := client.ServiceLogs(context.Background(), s, logOpts) if err != nil { logrus.Fatal(err) } @@ -63,14 +64,17 @@ func stackLogs(c *cli.Context, stackName string, client *dockerClient.Client) { os.Exit(0) } -var appLogsCommand = &cli.Command{ +var appLogsCommand = cli.Command{ Name: "logs", Aliases: []string{"l"}, ArgsUsage: "[]", Usage: "Tail app logs", Flags: []cli.Flag{ internal.StdErrOnlyFlag, + internal.DebugFlag, + internal.NoInputFlag, }, + Before: internal.SubCommandBefore, BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) @@ -98,7 +102,7 @@ var appLogsCommand = &cli.Command{ func tailServiceLogs(c *cli.Context, cl *dockerClient.Client, app config.App, serviceName string) error { filters := filters.NewArgs() filters.Add("name", fmt.Sprintf("%s_%s", app.StackName(), serviceName)) - chosenService, err := service.GetService(c.Context, cl, filters, internal.NoInput) + chosenService, err := service.GetService(context.Background(), cl, filters, internal.NoInput) if err != nil { logrus.Fatal(err) } @@ -107,7 +111,7 @@ func tailServiceLogs(c *cli.Context, cl *dockerClient.Client, app config.App, se logOpts.ShowStdout = false } - logs, err := cl.ServiceLogs(c.Context, chosenService.ID, logOpts) + logs, err := cl.ServiceLogs(context.Background(), chosenService.ID, logOpts) if err != nil { logrus.Fatal(err) } diff --git a/cli/app/new.go b/cli/app/new.go index 7ba14475..54244594 100644 --- a/cli/app/new.go +++ b/cli/app/new.go @@ -3,7 +3,7 @@ package app import ( "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) var appNewDescription = ` @@ -26,18 +26,21 @@ pass store (see passwordstore.org for more). The pass command must be available on your $PATH. ` -var appNewCommand = &cli.Command{ +var appNewCommand = cli.Command{ Name: "new", - Usage: "Create a new app", Aliases: []string{"n"}, + Usage: "Create a new app", Description: appNewDescription, Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, internal.NewAppServerFlag, internal.DomainFlag, internal.NewAppNameFlag, internal.PassFlag, internal.SecretsFlag, }, + Before: internal.SubCommandBefore, ArgsUsage: "", Action: internal.NewAction, BashComplete: autocomplete.RecipeNameComplete, diff --git a/cli/app/ps.go b/cli/app/ps.go index e1215cf8..68b33ed6 100644 --- a/cli/app/ps.go +++ b/cli/app/ps.go @@ -1,6 +1,7 @@ package app import ( + "context" "strings" "time" @@ -17,17 +18,20 @@ import ( "github.com/docker/docker/api/types/filters" dockerClient "github.com/docker/docker/client" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var appPsCommand = &cli.Command{ +var appPsCommand = cli.Command{ Name: "ps", + Aliases: []string{"p"}, Usage: "Check app status", Description: "This command shows a more detailed status output of a specific deployed app.", - Aliases: []string{"p"}, Flags: []cli.Flag{ internal.WatchFlag, + internal.DebugFlag, + internal.NoInputFlag, }, + Before: internal.SubCommandBefore, BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) @@ -37,7 +41,7 @@ var appPsCommand = &cli.Command{ logrus.Fatal(err) } - isDeployed, _, err := stack.IsDeployed(c.Context, cl, app.StackName()) + isDeployed, _, err := stack.IsDeployed(context.Background(), cl, app.StackName()) if err != nil { logrus.Fatal(err) } @@ -66,7 +70,7 @@ func showPSOutput(c *cli.Context, app config.App, cl *dockerClient.Client) { filters := filters.NewArgs() filters.Add("name", app.StackName()) - containers, err := cl.ContainerList(c.Context, types.ContainerListOptions{Filters: filters}) + containers, err := cl.ContainerList(context.Background(), types.ContainerListOptions{Filters: filters}) if err != nil { logrus.Fatal(err) } diff --git a/cli/app/remove.go b/cli/app/remove.go index 7bc06a4a..8998a1d2 100644 --- a/cli/app/remove.go +++ b/cli/app/remove.go @@ -1,6 +1,7 @@ package app import ( + "context" "fmt" "os" @@ -12,7 +13,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // Volumes stores the variable from VolumesFlag @@ -21,18 +22,20 @@ var Volumes bool // VolumesFlag is used to specify if volumes should be deleted when deleting an app var VolumesFlag = &cli.BoolFlag{ Name: "volumes", - Value: false, Destination: &Volumes, } -var appRemoveCommand = &cli.Command{ +var appRemoveCommand = cli.Command{ Name: "remove", - Usage: "Remove an already undeployed app", Aliases: []string{"rm"}, + Usage: "Remove an already undeployed app", Flags: []cli.Flag{ VolumesFlag, internal.ForceFlag, + internal.DebugFlag, + internal.NoInputFlag, }, + Before: internal.SubCommandBefore, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) @@ -54,7 +57,7 @@ var appRemoveCommand = &cli.Command{ logrus.Fatal(err) } - isDeployed, _, err := stack.IsDeployed(c.Context, cl, app.StackName()) + isDeployed, _, err := stack.IsDeployed(context.Background(), cl, app.StackName()) if err != nil { logrus.Fatal(err) } @@ -64,7 +67,7 @@ var appRemoveCommand = &cli.Command{ fs := filters.NewArgs() fs.Add("name", app.StackName()) - secretList, err := cl.SecretList(c.Context, types.SecretListOptions{Filters: fs}) + secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: fs}) if err != nil { logrus.Fatal(err) } @@ -94,7 +97,7 @@ var appRemoveCommand = &cli.Command{ } for _, name := range secretNamesToRemove { - err := cl.SecretRemove(c.Context, secrets[name]) + err := cl.SecretRemove(context.Background(), secrets[name]) if err != nil { logrus.Fatal(err) } @@ -104,7 +107,7 @@ var appRemoveCommand = &cli.Command{ logrus.Info("no secrets to remove") } - volumeListOKBody, err := cl.VolumeList(c.Context, fs) + volumeListOKBody, err := cl.VolumeList(context.Background(), fs) volumeList := volumeListOKBody.Volumes if err != nil { logrus.Fatal(err) @@ -131,7 +134,7 @@ var appRemoveCommand = &cli.Command{ } } for _, vol := range removeVols { - err := cl.VolumeRemove(c.Context, vol, internal.Force) // last argument is for force removing + err := cl.VolumeRemove(context.Background(), vol, internal.Force) // last argument is for force removing if err != nil { logrus.Fatal(err) } diff --git a/cli/app/restart.go b/cli/app/restart.go index 47714bf4..6585565d 100644 --- a/cli/app/restart.go +++ b/cli/app/restart.go @@ -1,6 +1,7 @@ package app import ( + "context" "errors" "fmt" @@ -10,14 +11,19 @@ import ( upstream "coopcloud.tech/abra/pkg/upstream/service" stack "coopcloud.tech/abra/pkg/upstream/stack" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var appRestartCommand = &cli.Command{ - Name: "restart", - Usage: "Restart an app", - Aliases: []string{"re"}, - ArgsUsage: "", +var appRestartCommand = cli.Command{ + Name: "restart", + Aliases: []string{"re"}, + Usage: "Restart an app", + ArgsUsage: "", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, Description: `This command restarts a service within a deployed app.`, BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { @@ -37,22 +43,22 @@ var appRestartCommand = &cli.Command{ serviceName := fmt.Sprintf("%s_%s", app.StackName(), serviceNameShort) logrus.Debugf("attempting to scale %s to 0 (restart logic)", serviceName) - if err := upstream.RunServiceScale(c.Context, cl, serviceName, 0); err != nil { + if err := upstream.RunServiceScale(context.Background(), cl, serviceName, 0); err != nil { logrus.Fatal(err) } - if err := stack.WaitOnService(c.Context, cl, serviceName, app.Name); err != nil { + if err := stack.WaitOnService(context.Background(), cl, serviceName, app.Name); err != nil { logrus.Fatal(err) } logrus.Debugf("%s has been scaled to 0 (restart logic)", serviceName) logrus.Debugf("attempting to scale %s to 1 (restart logic)", serviceName) - if err := upstream.RunServiceScale(c.Context, cl, serviceName, 1); err != nil { + if err := upstream.RunServiceScale(context.Background(), cl, serviceName, 1); err != nil { logrus.Fatal(err) } - if err := stack.WaitOnService(c.Context, cl, serviceName, app.Name); err != nil { + if err := stack.WaitOnService(context.Background(), cl, serviceName, app.Name); err != nil { logrus.Fatal(err) } diff --git a/cli/app/restore.go b/cli/app/restore.go index 35471b36..0aed03e4 100644 --- a/cli/app/restore.go +++ b/cli/app/restore.go @@ -12,28 +12,31 @@ import ( "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/config" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) var restoreAllServices bool var restoreAllServicesFlag = &cli.BoolFlag{ - Name: "all", - Value: false, + Name: "all, a", Destination: &restoreAllServices, - Aliases: []string{"a"}, Usage: "Restore all services", } -var appRestoreCommand = &cli.Command{ - Name: "restore", - Usage: "Restore an app from a backup", - Aliases: []string{"rs"}, - Flags: []cli.Flag{restoreAllServicesFlag}, +var appRestoreCommand = cli.Command{ + Name: "restore", + Aliases: []string{"rs"}, + Usage: "Restore an app from a backup", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + restoreAllServicesFlag, + }, + Before: internal.SubCommandBefore, ArgsUsage: " []", Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - if c.Args().Len() > 1 && restoreAllServices { + if len(c.Args()) > 1 && restoreAllServices { internal.ShowSubcommandHelpAndError(c, errors.New("cannot use / and '--all' together")) } diff --git a/cli/app/rollback.go b/cli/app/rollback.go index 518d0164..afbfb935 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -1,6 +1,7 @@ package app import ( + "context" "fmt" "coopcloud.tech/abra/pkg/autocomplete" @@ -14,19 +15,22 @@ import ( "coopcloud.tech/abra/pkg/client" "github.com/AlecAivazis/survey/v2" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var appRollbackCommand = &cli.Command{ +var appRollbackCommand = cli.Command{ Name: "rollback", - Usage: "Roll an app back to a previous version", Aliases: []string{"rl"}, + Usage: "Roll an app back to a previous version", ArgsUsage: "", Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, internal.ForceFlag, internal.ChaosFlag, internal.DontWaitConvergeFlag, }, + Before: internal.SubCommandBefore, Description: ` This command rolls an app back to a previous version if one exists. @@ -67,7 +71,7 @@ recipes. logrus.Debugf("checking whether %s is already deployed", stackName) - isDeployed, deployedVersion, err := stack.IsDeployed(c.Context, cl, stackName) + isDeployed, deployedVersion, err := stack.IsDeployed(context.Background(), cl, stackName) if err != nil { logrus.Fatal(err) } diff --git a/cli/app/run.go b/cli/app/run.go index 368dc500..59c6a0df 100644 --- a/cli/app/run.go +++ b/cli/app/run.go @@ -1,6 +1,7 @@ package app import ( + "context" "errors" "fmt" @@ -13,7 +14,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) var user string @@ -26,28 +27,30 @@ var userFlag = &cli.StringFlag{ var noTTY bool var noTTYFlag = &cli.BoolFlag{ Name: "no-tty", - Value: false, Destination: &noTTY, } -var appRunCommand = &cli.Command{ - Name: "run", +var appRunCommand = cli.Command{ + Name: "run", + Aliases: []string{"r"}, Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, noTTYFlag, userFlag, }, - Aliases: []string{"r"}, + Before: internal.SubCommandBefore, ArgsUsage: " ...", Usage: "Run a command in a service container", BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - if c.Args().Len() < 2 { + if len(c.Args()) < 2 { internal.ShowSubcommandHelpAndError(c, errors.New("no provided?")) } - if c.Args().Len() < 3 { + if len(c.Args()) < 3 { internal.ShowSubcommandHelpAndError(c, errors.New("no provided?")) } @@ -61,12 +64,12 @@ var appRunCommand = &cli.Command{ filters := filters.NewArgs() filters.Add("name", stackAndServiceName) - targetContainer, err := containerPkg.GetContainer(c.Context, cl, filters, true) + targetContainer, err := containerPkg.GetContainer(context.Background(), cl, filters, true) if err != nil { logrus.Fatal(err) } - cmd := c.Args().Slice()[2:] + cmd := c.Args()[2:] execCreateOpts := types.ExecConfig{ AttachStderr: true, AttachStdin: true, diff --git a/cli/app/secret.go b/cli/app/secret.go index 78cdb495..03def335 100644 --- a/cli/app/secret.go +++ b/cli/app/secret.go @@ -1,6 +1,7 @@ package app import ( + "context" "errors" "fmt" "os" @@ -14,29 +15,32 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) var allSecrets bool var allSecretsFlag = &cli.BoolFlag{ - Name: "all", - Aliases: []string{"a"}, - Value: false, + Name: "all, a", Destination: &allSecrets, Usage: "Generate all secrets", } -var appSecretGenerateCommand = &cli.Command{ - Name: "generate", - Aliases: []string{"g"}, - Usage: "Generate secrets", - ArgsUsage: " ", - Flags: []cli.Flag{allSecretsFlag, internal.PassFlag}, +var appSecretGenerateCommand = cli.Command{ + Name: "generate", + Aliases: []string{"g"}, + Usage: "Generate secrets", + ArgsUsage: " ", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + allSecretsFlag, internal.PassFlag, + }, + Before: internal.SubCommandBefore, BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - if c.Args().Len() == 1 && !allSecrets { + if len(c.Args()) == 1 && !allSecrets { err := errors.New("missing arguments / or '--all'") internal.ShowSubcommandHelpAndError(c, err) } @@ -95,11 +99,16 @@ var appSecretGenerateCommand = &cli.Command{ }, } -var appSecretInsertCommand = &cli.Command{ - Name: "insert", - Aliases: []string{"i"}, - Usage: "Insert secret", - Flags: []cli.Flag{internal.PassFlag}, +var appSecretInsertCommand = cli.Command{ + Name: "insert", + Aliases: []string{"i"}, + Usage: "Insert secret", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + internal.PassFlag, + }, + Before: internal.SubCommandBefore, ArgsUsage: " ", BashComplete: autocomplete.AppNameComplete, Description: ` @@ -117,7 +126,7 @@ Example: Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - if c.Args().Len() != 4 { + if len(c.Args()) != 4 { internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments?")) } @@ -140,11 +149,16 @@ Example: }, } -var appSecretRmCommand = &cli.Command{ - Name: "remove", - Usage: "Remove a secret", - Aliases: []string{"rm"}, - Flags: []cli.Flag{allSecretsFlag, internal.PassFlag}, +var appSecretRmCommand = cli.Command{ + Name: "remove", + Aliases: []string{"rm"}, + Usage: "Remove a secret", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + allSecretsFlag, internal.PassFlag, + }, + Before: internal.SubCommandBefore, ArgsUsage: " ", BashComplete: autocomplete.AppNameComplete, Description: ` @@ -173,7 +187,7 @@ Example: filters := filters.NewArgs() filters.Add("name", app.StackName()) - secretList, err := cl.SecretList(c.Context, types.SecretListOptions{Filters: filters}) + secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: filters}) if err != nil { logrus.Fatal(err) } @@ -183,7 +197,7 @@ Example: secretName := cont.Spec.Annotations.Name parsed := secret.ParseGeneratedSecretName(secretName, app) if allSecrets { - if err := cl.SecretRemove(c.Context, secretName); err != nil { + if err := cl.SecretRemove(context.Background(), secretName); err != nil { logrus.Fatal(err) } logrus.Infof("deleted %s successfully from server", secretName) @@ -197,7 +211,7 @@ Example: } } else { if parsed == secretToRm { - if err := cl.SecretRemove(c.Context, secretName); err != nil { + if err := cl.SecretRemove(context.Background(), secretName); err != nil { logrus.Fatal(err) } @@ -218,10 +232,15 @@ Example: }, } -var appSecretLsCommand = &cli.Command{ +var appSecretLsCommand = cli.Command{ Name: "list", - Usage: "List all secrets", Aliases: []string{"ls"}, + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, + Usage: "List all secrets", Action: func(c *cli.Context) error { app := internal.ValidateApp(c) secrets := secret.ReadSecretEnvVars(app.Env) @@ -236,7 +255,7 @@ var appSecretLsCommand = &cli.Command{ filters := filters.NewArgs() filters.Add("name", app.StackName()) - secretList, err := cl.SecretList(c.Context, types.SecretListOptions{Filters: filters}) + secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: filters}) if err != nil { logrus.Fatal(err) } @@ -272,12 +291,12 @@ var appSecretLsCommand = &cli.Command{ BashComplete: autocomplete.AppNameComplete, } -var appSecretCommand = &cli.Command{ +var appSecretCommand = cli.Command{ Name: "secret", Aliases: []string{"s"}, Usage: "Manage app secrets", ArgsUsage: "", - Subcommands: []*cli.Command{ + Subcommands: []cli.Command{ appSecretGenerateCommand, appSecretInsertCommand, appSecretRmCommand, diff --git a/cli/app/undeploy.go b/cli/app/undeploy.go index a57f1b79..49958b87 100644 --- a/cli/app/undeploy.go +++ b/cli/app/undeploy.go @@ -1,18 +1,25 @@ package app import ( + "context" + "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" stack "coopcloud.tech/abra/pkg/upstream/stack" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var appUndeployCommand = &cli.Command{ +var appUndeployCommand = cli.Command{ Name: "undeploy", Aliases: []string{"un"}, - Usage: "Undeploy an app", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, + Usage: "Undeploy an app", Description: ` This does not destroy any of the application data. However, you should remain vigilant, as your swarm installation will consider any previously attached @@ -29,7 +36,7 @@ volumes as eligiblef or pruning once undeployed. logrus.Debugf("checking whether %s is already deployed", stackName) - isDeployed, deployedVersion, err := stack.IsDeployed(c.Context, cl, stackName) + isDeployed, deployedVersion, err := stack.IsDeployed(context.Background(), cl, stackName) if err != nil { logrus.Fatal(err) } @@ -43,7 +50,7 @@ volumes as eligiblef or pruning once undeployed. } rmOpts := stack.Remove{Namespaces: []string{app.StackName()}} - if err := stack.RunRemove(c.Context, cl, rmOpts); err != nil { + if err := stack.RunRemove(context.Background(), cl, rmOpts); err != nil { logrus.Fatal(err) } diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index 61239b98..fad96f93 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -1,6 +1,7 @@ package app import ( + "context" "fmt" "coopcloud.tech/abra/cli/internal" @@ -13,19 +14,22 @@ import ( "coopcloud.tech/tagcmp" "github.com/AlecAivazis/survey/v2" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var appUpgradeCommand = &cli.Command{ +var appUpgradeCommand = cli.Command{ Name: "upgrade", Aliases: []string{"up"}, Usage: "Upgrade an app", ArgsUsage: "", Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, internal.ForceFlag, internal.ChaosFlag, internal.NoDomainChecksFlag, }, + Before: internal.SubCommandBefore, Description: ` This command supports upgrading an app. You can use it to choose and roll out a new upgrade to an existing app. @@ -70,7 +74,7 @@ recipes. logrus.Debugf("checking whether %s is already deployed", stackName) - isDeployed, deployedVersion, err := stack.IsDeployed(c.Context, cl, stackName) + isDeployed, deployedVersion, err := stack.IsDeployed(context.Background(), cl, stackName) if err != nil { logrus.Fatal(err) } diff --git a/cli/app/version.go b/cli/app/version.go index 80d4f37f..cf041826 100644 --- a/cli/app/version.go +++ b/cli/app/version.go @@ -1,6 +1,8 @@ package app import ( + "context" + "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" @@ -9,7 +11,7 @@ import ( "coopcloud.tech/abra/pkg/upstream/stack" "github.com/docker/distribution/reference" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // getImagePath returns the image name @@ -28,10 +30,15 @@ func getImagePath(image string) (string, error) { return path, nil } -var appVersionCommand = &cli.Command{ +var appVersionCommand = cli.Command{ Name: "version", Aliases: []string{"v"}, - Usage: "Show app versions", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, + Usage: "Show app versions", Description: ` This command shows all information about versioning related to a deployed app. This includes the individual image names, tags and digests. But also the Co-op @@ -48,7 +55,7 @@ Cloud recipe version. logrus.Debugf("checking whether %s is already deployed", stackName) - isDeployed, deployedVersion, err := stack.IsDeployed(c.Context, cl, stackName) + isDeployed, deployedVersion, err := stack.IsDeployed(context.Background(), cl, stackName) if err != nil { logrus.Fatal(err) } diff --git a/cli/app/volume.go b/cli/app/volume.go index 7b89086d..53017062 100644 --- a/cli/app/volume.go +++ b/cli/app/volume.go @@ -1,24 +1,31 @@ package app import ( + "context" + "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/formatter" "github.com/AlecAivazis/survey/v2" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var appVolumeListCommand = &cli.Command{ - Name: "list", +var appVolumeListCommand = cli.Command{ + Name: "list", + Aliases: []string{"ls"}, + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, Usage: "List volumes associated with an app", - Aliases: []string{"ls"}, BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - volumeList, err := client.GetVolumes(c.Context, app.Server, app.Name) + volumeList, err := client.GetVolumes(context.Background(), app.Server, app.Name) if err != nil { logrus.Fatal(err) } @@ -45,7 +52,7 @@ var appVolumeListCommand = &cli.Command{ }, } -var appVolumeRemoveCommand = &cli.Command{ +var appVolumeRemoveCommand = cli.Command{ Name: "remove", Usage: "Remove volume(s) associated with an app", Description: ` @@ -62,12 +69,15 @@ Passing "--force" will select all volumes for removal. Be careful. ArgsUsage: "", Aliases: []string{"rm"}, Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, internal.ForceFlag, }, + Before: internal.SubCommandBefore, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - volumeList, err := client.GetVolumes(c.Context, app.Server, app.Name) + volumeList, err := client.GetVolumes(context.Background(), app.Server, app.Name) if err != nil { logrus.Fatal(err) } @@ -89,7 +99,7 @@ Passing "--force" will select all volumes for removal. Be careful. volumesToRemove = volumeNames } - err = client.RemoveVolumes(c.Context, app.Server, volumesToRemove, internal.Force) + err = client.RemoveVolumes(context.Background(), app.Server, volumesToRemove, internal.Force) if err != nil { logrus.Fatal(err) } @@ -101,12 +111,12 @@ Passing "--force" will select all volumes for removal. Be careful. BashComplete: autocomplete.AppNameComplete, } -var appVolumeCommand = &cli.Command{ +var appVolumeCommand = cli.Command{ Name: "volume", Aliases: []string{"vl"}, Usage: "Manage app volumes", ArgsUsage: "", - Subcommands: []*cli.Command{ + Subcommands: []cli.Command{ appVolumeListCommand, appVolumeRemoveCommand, }, diff --git a/cli/catalogue/catalogue.go b/cli/catalogue/catalogue.go index f6ab2f88..3a5dc7d6 100644 --- a/cli/catalogue/catalogue.go +++ b/cli/catalogue/catalogue.go @@ -15,7 +15,7 @@ import ( "coopcloud.tech/abra/pkg/recipe" "github.com/go-git/go-git/v5" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // CatalogueSkipList is all the repos that are not recipes. @@ -56,17 +56,20 @@ var CatalogueSkipList = map[string]bool{ "tyop": true, } -var catalogueGenerateCommand = &cli.Command{ +var catalogueGenerateCommand = cli.Command{ Name: "generate", Aliases: []string{"g"}, Usage: "Generate the recipe catalogue", Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, internal.PublishFlag, internal.DryFlag, internal.SkipUpdatesFlag, internal.RegistryUsernameFlag, internal.RegistryPasswordFlag, }, + Before: internal.SubCommandBefore, Description: ` This command generates a new copy of the recipe catalogue which can be found on: @@ -247,13 +250,13 @@ keys configured on your account. } // CatalogueCommand defines the `abra catalogue` command and sub-commands. -var CatalogueCommand = &cli.Command{ +var CatalogueCommand = cli.Command{ Name: "catalogue", Usage: "Manage the recipe catalogue", Aliases: []string{"c"}, ArgsUsage: "", Description: "This command helps recipe packagers interact with the recipe catalogue", - Subcommands: []*cli.Command{ + Subcommands: []cli.Command{ catalogueGenerateCommand, }, } diff --git a/cli/cli.go b/cli/cli.go index ad184a12..1066fb77 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -16,16 +16,15 @@ import ( "coopcloud.tech/abra/cli/server" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/web" - logrusStack "github.com/Gurpartap/logrus-stack" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // AutoCompleteCommand helps people set up auto-complete in their shells -var AutoCompleteCommand = &cli.Command{ +var AutoCompleteCommand = cli.Command{ Name: "autocomplete", - Usage: "Configure shell autocompletion (recommended)", Aliases: []string{"ac"}, + Usage: "Configure shell autocompletion (recommended)", Description: ` This command helps set up autocompletion in your shell by downloading the relevant autocompletion files and laying out what additional information must @@ -43,6 +42,10 @@ Supported shells are as follows: `, ArgsUsage: "", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, Action: func(c *cli.Context) error { shellType := c.Args().First() @@ -105,10 +108,10 @@ echo "PROG=abra\n_CLI_ZSH_AUTOCOMPLETE_HACK=1\nsource /etc/zsh/completion.d/abra } // UpgradeCommand upgrades abra in-place. -var UpgradeCommand = &cli.Command{ +var UpgradeCommand = cli.Command{ Name: "upgrade", - Usage: "Upgrade Abra itself", Aliases: []string{"u"}, + Usage: "Upgrade Abra itself", Description: ` This command allows you to upgrade Abra in-place with the latest stable or release candidate. @@ -150,7 +153,7 @@ func newAbraApp(version, commit string) *cli.App { |_| `, Version: fmt.Sprintf("%s-%s", version, commit[:7]), - Commands: []*cli.Command{ + Commands: []cli.Command{ app.AppCommand, server.ServerCommand, recipe.RecipeCommand, @@ -159,11 +162,7 @@ func newAbraApp(version, commit string) *cli.App { UpgradeCommand, AutoCompleteCommand, }, - Flags: []cli.Flag{ - internal.DebugFlag, - internal.NoInputFlag, - }, - Authors: []*cli.Author{ + Authors: []cli.Author{ // If you're looking at this and you hack on Abra and you're not listed // here, please do add yourself! This is a community project, let's show // some love @@ -178,13 +177,6 @@ func newAbraApp(version, commit string) *cli.App { app.EnableBashCompletion = true app.Before = func(c *cli.Context) error { - if internal.Debug { - logrus.SetLevel(logrus.DebugLevel) - logrus.SetFormatter(&logrus.TextFormatter{}) - logrus.SetOutput(os.Stderr) - logrus.AddHook(logrusStack.StandardHook()) - } - paths := []string{ config.ABRA_DIR, path.Join(config.SERVERS_DIR), diff --git a/cli/internal/flags.go b/cli/internal/cli.go similarity index 72% rename from cli/internal/flags.go rename to cli/internal/cli.go index 3d506148..259047e4 100644 --- a/cli/internal/flags.go +++ b/cli/internal/cli.go @@ -1,7 +1,11 @@ package internal import ( - "github.com/urfave/cli/v2" + "os" + + logrusStack "github.com/Gurpartap/logrus-stack" + "github.com/sirupsen/logrus" + "github.com/urfave/cli" ) // Secrets stores the variable from SecretsFlag @@ -9,9 +13,7 @@ var Secrets bool // SecretsFlag turns on/off automatically generating secrets var SecretsFlag = &cli.BoolFlag{ - Name: "secrets", - Aliases: []string{"ss"}, - Value: false, + Name: "secrets, ss", Usage: "Automatically generate secrets", Destination: &Secrets, } @@ -21,9 +23,7 @@ var Pass bool // PassFlag turns on/off storing generated secrets in pass var PassFlag = &cli.BoolFlag{ - Name: "pass", - Aliases: []string{"p"}, - Value: false, + Name: "pass, p", Usage: "Store the generated secrets in a local pass store", Destination: &Pass, } @@ -33,9 +33,8 @@ var Context string // ContextFlag is temp var ContextFlag = &cli.StringFlag{ - Name: "context", + Name: "context, c", Value: "", - Aliases: []string{"c"}, Destination: &Context, } @@ -44,9 +43,7 @@ var Force bool // ForceFlag turns on/off force functionality. var ForceFlag = &cli.BoolFlag{ - Name: "force", - Value: false, - Aliases: []string{"f"}, + Name: "force, f", Usage: "Perform action without further prompt. Use with care!", Destination: &Force, } @@ -56,9 +53,7 @@ var Chaos bool // ChaosFlag turns on/off chaos functionality. var ChaosFlag = &cli.BoolFlag{ - Name: "chaos", - Value: false, - Aliases: []string{"ch"}, + Name: "chaos, ch", Usage: "Deploy uncommitted recipes changes. Use with care!", Destination: &Chaos, } @@ -68,18 +63,15 @@ var DNSProvider string // DNSProviderFlag selects a DNS provider. var DNSProviderFlag = &cli.StringFlag{ - Name: "provider", + Name: "provider, p", Value: "", - Aliases: []string{"p"}, Usage: "DNS provider", Destination: &DNSProvider, } var NoInput bool var NoInputFlag = &cli.BoolFlag{ - Name: "no-input", - Value: false, - Aliases: []string{"n"}, + Name: "no-input, n", Usage: "Toggle non-interactive mode", Destination: &NoInput, } @@ -87,9 +79,8 @@ var NoInputFlag = &cli.BoolFlag{ var DNSType string var DNSTypeFlag = &cli.StringFlag{ - Name: "type", + Name: "type, t", Value: "", - Aliases: []string{"t"}, Usage: "Domain name record type (e.g. A)", Destination: &DNSType, } @@ -97,9 +88,8 @@ var DNSTypeFlag = &cli.StringFlag{ var DNSName string var DNSNameFlag = &cli.StringFlag{ - Name: "name", + Name: "name, n", Value: "", - Aliases: []string{"n"}, Usage: "Domain name record name (e.g. mysubdomain)", Destination: &DNSName, } @@ -107,18 +97,16 @@ var DNSNameFlag = &cli.StringFlag{ var DNSValue string var DNSValueFlag = &cli.StringFlag{ - Name: "value", + Name: "value, v", Value: "", - Aliases: []string{"v"}, Usage: "Domain name record value (e.g. 192.168.1.1)", Destination: &DNSValue, } var DNSTTL string var DNSTTLFlag = &cli.StringFlag{ - Name: "ttl", + Name: "ttl, T", Value: "600s", - Aliases: []string{"T"}, Usage: "Domain name TTL value (seconds)", Destination: &DNSTTL, } @@ -126,9 +114,8 @@ var DNSTTLFlag = &cli.StringFlag{ var DNSPriority int var DNSPriorityFlag = &cli.IntFlag{ - Name: "priority", + Name: "priority, P", Value: 10, - Aliases: []string{"P"}, Usage: "Domain name priority value", Destination: &DNSPriority, } @@ -136,8 +123,7 @@ var DNSPriorityFlag = &cli.IntFlag{ var ServerProvider string var ServerProviderFlag = &cli.StringFlag{ - Name: "provider", - Aliases: []string{"p"}, + Name: "provider, p", Usage: "3rd party server provider", Destination: &ServerProvider, } @@ -145,9 +131,8 @@ var ServerProviderFlag = &cli.StringFlag{ var CapsulInstanceURL string var CapsulInstanceURLFlag = &cli.StringFlag{ - Name: "capsul-url", + Name: "capsul-url, cu", Value: "yolo.servers.coop", - Aliases: []string{"cu"}, Usage: "capsul instance URL", Destination: &CapsulInstanceURL, } @@ -155,9 +140,8 @@ var CapsulInstanceURLFlag = &cli.StringFlag{ var CapsulName string var CapsulNameFlag = &cli.StringFlag{ - Name: "capsul-name", + Name: "capsul-name, cn", Value: "", - Aliases: []string{"cn"}, Usage: "capsul name", Destination: &CapsulName, } @@ -165,9 +149,8 @@ var CapsulNameFlag = &cli.StringFlag{ var CapsulType string var CapsulTypeFlag = &cli.StringFlag{ - Name: "capsul-type", + Name: "capsul-type, ct", Value: "f1-xs", - Aliases: []string{"ct"}, Usage: "capsul type", Destination: &CapsulType, } @@ -175,38 +158,33 @@ var CapsulTypeFlag = &cli.StringFlag{ var CapsulImage string var CapsulImageFlag = &cli.StringFlag{ - Name: "capsul-image", + Name: "capsul-image, ci", Value: "debian10", - Aliases: []string{"ci"}, Usage: "capsul image", Destination: &CapsulImage, } var CapsulSSHKeys cli.StringSlice - var CapsulSSHKeysFlag = &cli.StringSliceFlag{ - Name: "capsul-ssh-keys", - Aliases: []string{"cs"}, - Usage: "capsul SSH key", - Destination: &CapsulSSHKeys, + Name: "capsul-ssh-keys, cs", + Usage: "capsul SSH key", + Value: &CapsulSSHKeys, } var CapsulAPIToken string var CapsulAPITokenFlag = &cli.StringFlag{ - Name: "capsul-token", - Aliases: []string{"ca"}, + Name: "capsul-token, ca", Usage: "capsul API token", - EnvVars: []string{"CAPSUL_TOKEN"}, + EnvVar: "CAPSUL_TOKEN", Destination: &CapsulAPIToken, } var HetznerCloudName string var HetznerCloudNameFlag = &cli.StringFlag{ - Name: "hetzner-name", + Name: "hetzner-name, hn", Value: "", - Aliases: []string{"hn"}, Usage: "hetzner cloud name", Destination: &HetznerCloudName, } @@ -214,8 +192,7 @@ var HetznerCloudNameFlag = &cli.StringFlag{ var HetznerCloudType string var HetznerCloudTypeFlag = &cli.StringFlag{ - Name: "hetzner-type", - Aliases: []string{"ht"}, + Name: "hetzner-type, ht", Usage: "hetzner cloud type", Destination: &HetznerCloudType, Value: "cx11", @@ -224,8 +201,7 @@ var HetznerCloudTypeFlag = &cli.StringFlag{ var HetznerCloudImage string var HetznerCloudImageFlag = &cli.StringFlag{ - Name: "hetzner-image", - Aliases: []string{"hi"}, + Name: "hetzner-image, hi", Usage: "hetzner cloud image", Value: "debian-10", Destination: &HetznerCloudImage, @@ -234,17 +210,15 @@ var HetznerCloudImageFlag = &cli.StringFlag{ var HetznerCloudSSHKeys cli.StringSlice var HetznerCloudSSHKeysFlag = &cli.StringSliceFlag{ - Name: "hetzner-ssh-keys", - Aliases: []string{"hs"}, - Usage: "hetzner cloud SSH keys (e.g. me@foo.com)", - Destination: &HetznerCloudSSHKeys, + Name: "hetzner-ssh-keys, hs", + Usage: "hetzner cloud SSH keys (e.g. me@foo.com)", + Value: &HetznerCloudSSHKeys, } var HetznerCloudLocation string var HetznerCloudLocationFlag = &cli.StringFlag{ - Name: "hetzner-location", - Aliases: []string{"hl"}, + Name: "hetzner-location, hl", Usage: "hetzner cloud server location", Value: "hel1", Destination: &HetznerCloudLocation, @@ -253,10 +227,9 @@ var HetznerCloudLocationFlag = &cli.StringFlag{ var HetznerCloudAPIToken string var HetznerCloudAPITokenFlag = &cli.StringFlag{ - Name: "hetzner-token", - Aliases: []string{"ha"}, + Name: "hetzner-token, ha", Usage: "hetzner cloud API token", - EnvVars: []string{"HCLOUD_TOKEN"}, + EnvVar: "HCLOUD_TOKEN", Destination: &HetznerCloudAPIToken, } @@ -265,9 +238,7 @@ var Debug bool // DebugFlag turns on/off verbose logging down to the DEBUG level. var DebugFlag = &cli.BoolFlag{ - Name: "debug", - Aliases: []string{"d"}, - Value: false, + Name: "debug, d", Destination: &Debug, Usage: "Show DEBUG messages", } @@ -278,60 +249,48 @@ var RC bool // RCFlag chooses the latest release candidate for install var RCFlag = &cli.BoolFlag{ Name: "rc", - Value: false, Destination: &RC, Usage: "Insatll the latest release candidate", } var Major bool var MajorFlag = &cli.BoolFlag{ - Name: "major", + Name: "major, ma, x", Usage: "Increase the major part of the version", - Value: false, - Aliases: []string{"ma", "x"}, Destination: &Major, } var Minor bool var MinorFlag = &cli.BoolFlag{ - Name: "minor", + Name: "minor, mi, y", Usage: "Increase the minor part of the version", - Value: false, - Aliases: []string{"mi", "y"}, Destination: &Minor, } var Patch bool var PatchFlag = &cli.BoolFlag{ - Name: "patch", + Name: "patch, pa, z", Usage: "Increase the patch part of the version", - Value: false, - Aliases: []string{"pa", "z"}, Destination: &Patch, } var Dry bool var DryFlag = &cli.BoolFlag{ - Name: "dry-run", + Name: "dry-run, d", Usage: "Only reports changes that would be made", - Value: false, - Aliases: []string{"d"}, Destination: &Dry, } var Publish bool var PublishFlag = &cli.BoolFlag{ - Name: "publish", + Name: "publish, p", Usage: "Publish changes to git.coopcloud.tech", - Value: false, - Aliases: []string{"p"}, Destination: &Publish, } var Domain string var DomainFlag = &cli.StringFlag{ - Name: "domain", - Aliases: []string{"d"}, + Name: "domain, dn", Value: "", Usage: "Choose a domain name", Destination: &Domain, @@ -339,8 +298,7 @@ var DomainFlag = &cli.StringFlag{ var NewAppServer string var NewAppServerFlag = &cli.StringFlag{ - Name: "server", - Aliases: []string{"s"}, + Name: "server, s", Value: "", Usage: "Show apps of a specific server", Destination: &NewAppServer, @@ -348,8 +306,7 @@ var NewAppServerFlag = &cli.StringFlag{ var NewAppName string var NewAppNameFlag = &cli.StringFlag{ - Name: "app-name", - Aliases: []string{"a"}, + Name: "app-name, a", Value: "", Usage: "Choose an app name", Destination: &NewAppName, @@ -357,92 +314,74 @@ var NewAppNameFlag = &cli.StringFlag{ var NoDomainChecks bool var NoDomainChecksFlag = &cli.BoolFlag{ - Name: "no-domain-checks", - Aliases: []string{"nd"}, - Value: false, + Name: "no-domain-checks, nd", Usage: "Disable app domain sanity checks", Destination: &NoDomainChecks, } var StdErrOnly bool var StdErrOnlyFlag = &cli.BoolFlag{ - Name: "stderr", - Aliases: []string{"s"}, - Value: false, + Name: "stderr, s", Usage: "Only tail stderr", Destination: &StdErrOnly, } var AutoDNSRecord bool var AutoDNSRecordFlag = &cli.BoolFlag{ - Name: "auto", - Aliases: []string{"a"}, - Value: false, + Name: "auto, a", Usage: "Automatically configure DNS records", Destination: &AutoDNSRecord, } var DontWaitConverge bool var DontWaitConvergeFlag = &cli.BoolFlag{ - Name: "no-converge-checks", - Aliases: []string{"nc"}, - Value: false, + Name: "no-converge-checks, nc", Usage: "Don't wait for converge logic checks", Destination: &DontWaitConverge, } var Watch bool var WatchFlag = &cli.BoolFlag{ - Name: "watch", - Aliases: []string{"w"}, - Value: false, + Name: "watch, w", Usage: "Watch status by polling repeatedly", Destination: &Watch, } var OnlyErrors bool var OnlyErrorFlag = &cli.BoolFlag{ - Name: "errors", - Aliases: []string{"e"}, - Value: false, + Name: "errors, e", Usage: "Only show errors", Destination: &OnlyErrors, } var SkipUpdates bool var SkipUpdatesFlag = &cli.BoolFlag{ - Name: "skip-updates", - Aliases: []string{"s"}, - Value: false, + Name: "skip-updates, s", Usage: "Skip updating recipe repositories", Destination: &SkipUpdates, } var RegistryUsername string var RegistryUsernameFlag = &cli.StringFlag{ - Name: "username", - Aliases: []string{"user"}, + Name: "username, user", Value: "", Usage: "Registry username", - EnvVars: []string{"REGISTRY_USERNAME"}, + EnvVar: "REGISTRY_USERNAME", Destination: &RegistryUsername, } var RegistryPassword string var RegistryPasswordFlag = &cli.StringFlag{ - Name: "password", - Aliases: []string{"pass"}, + Name: "password, pass", Value: "", Usage: "Registry password", - EnvVars: []string{"REGISTRY_PASSWORD"}, + EnvVar: "REGISTRY_PASSWORD", Destination: &RegistryUsername, } var AllTags bool var AllTagsFlag = &cli.BoolFlag{ - Name: "all-tags", - Aliases: []string{"a"}, - Value: false, + Name: "all-tags, a", Usage: "List all tags, not just upgrades", Destination: &AllTags, } @@ -495,3 +434,15 @@ Host foo.coopcloud.tech Good luck! ` + +// SubCommandBefore wires up pre-action machinery (e.g. --debug handling). +func SubCommandBefore(c *cli.Context) error { + if Debug { + logrus.SetLevel(logrus.DebugLevel) + logrus.SetFormatter(&logrus.TextFormatter{}) + logrus.SetOutput(os.Stderr) + logrus.AddHook(logrusStack.StandardHook()) + } + + return nil +} diff --git a/cli/internal/deploy.go b/cli/internal/deploy.go index 349250b5..08e29891 100644 --- a/cli/internal/deploy.go +++ b/cli/internal/deploy.go @@ -1,6 +1,7 @@ package internal import ( + "context" "fmt" "io/ioutil" "os" @@ -17,7 +18,7 @@ import ( "coopcloud.tech/abra/pkg/upstream/stack" "github.com/AlecAivazis/survey/v2" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // DeployAction is the main command-line action for this package @@ -46,7 +47,7 @@ func DeployAction(c *cli.Context) error { logrus.Debugf("checking whether %s is already deployed", app.StackName()) - isDeployed, deployedVersion, err := stack.IsDeployed(c.Context, cl, app.StackName()) + isDeployed, deployedVersion, err := stack.IsDeployed(context.Background(), cl, app.StackName()) if err != nil { logrus.Fatal(err) } diff --git a/cli/internal/errors.go b/cli/internal/errors.go index ccd6e3fb..b2885dba 100644 --- a/cli/internal/errors.go +++ b/cli/internal/errors.go @@ -4,7 +4,7 @@ import ( "os" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // ShowSubcommandHelpAndError exits the program on error, logs the error to the diff --git a/cli/internal/new.go b/cli/internal/new.go index 18d155b9..bae9170b 100644 --- a/cli/internal/new.go +++ b/cli/internal/new.go @@ -12,7 +12,7 @@ import ( "coopcloud.tech/abra/pkg/ssh" "github.com/AlecAivazis/survey/v2" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // AppSecrets represents all app secrest diff --git a/cli/internal/validate.go b/cli/internal/validate.go index 81d43267..46745b94 100644 --- a/cli/internal/validate.go +++ b/cli/internal/validate.go @@ -12,7 +12,7 @@ import ( "coopcloud.tech/abra/pkg/ssh" "github.com/AlecAivazis/survey/v2" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // AppName is used for configuring app name programmatically @@ -160,9 +160,9 @@ func ValidateDomain(c *cli.Context) (string, error) { // ValidateSubCmdFlags ensures flag order conforms to correct order func ValidateSubCmdFlags(c *cli.Context) bool { - for argIdx, arg := range c.Args().Slice() { + for argIdx, arg := range c.Args() { if !strings.HasPrefix(arg, "--") { - for _, flag := range c.Args().Slice()[argIdx:] { + for _, flag := range c.Args()[argIdx:] { if strings.HasPrefix(flag, "--") { return false } @@ -369,7 +369,7 @@ func EnsureNewCapsulVPSFlags(c *cli.Context) error { if err := survey.AskOne(prompt, &CapsulSSHKeys); err != nil { return err } - CapsulSSHKeys = *cli.NewStringSlice(strings.Split(sshKeys, ",")...) + CapsulSSHKeys = cli.StringSlice(strings.Split(sshKeys, ",")) } if CapsulAPIToken == "" && !NoInput { @@ -448,7 +448,7 @@ func EnsureNewHetznerCloudVPSFlags(c *cli.Context) error { if err := survey.AskOne(prompt, &sshKeys); err != nil { return err } - HetznerCloudSSHKeys = *cli.NewStringSlice(strings.Split(sshKeys, ",")...) + HetznerCloudSSHKeys = cli.StringSlice(strings.Split(sshKeys, ",")) } if !NoInput { diff --git a/cli/recipe/lint.go b/cli/recipe/lint.go index 51236811..c1ad584e 100644 --- a/cli/recipe/lint.go +++ b/cli/recipe/lint.go @@ -9,15 +9,20 @@ import ( "coopcloud.tech/abra/pkg/lint" recipePkg "coopcloud.tech/abra/pkg/recipe" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var recipeLintCommand = &cli.Command{ - Name: "lint", - Usage: "Lint a recipe", - Aliases: []string{"l"}, - ArgsUsage: "", - Flags: []cli.Flag{internal.OnlyErrorFlag}, +var recipeLintCommand = cli.Command{ + Name: "lint", + Usage: "Lint a recipe", + Aliases: []string{"l"}, + ArgsUsage: "", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + internal.OnlyErrorFlag, + }, + Before: internal.SubCommandBefore, BashComplete: autocomplete.RecipeNameComplete, Action: func(c *cli.Context) error { recipe := internal.ValidateRecipe(c) diff --git a/cli/recipe/list.go b/cli/recipe/list.go index cc337889..8736d7a7 100644 --- a/cli/recipe/list.go +++ b/cli/recipe/list.go @@ -6,28 +6,31 @@ import ( "strconv" "strings" + "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/recipe" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) var pattern string var patternFlag = &cli.StringFlag{ - Name: "pattern", + Name: "pattern, p", Value: "", - Aliases: []string{"p"}, Usage: "Simple string to filter recipes", Destination: &pattern, } -var recipeListCommand = &cli.Command{ +var recipeListCommand = cli.Command{ Name: "list", Usage: "List available recipes", Aliases: []string{"ls"}, Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, patternFlag, }, + Before: internal.SubCommandBefore, Action: func(c *cli.Context) error { catl, err := recipe.ReadRecipeCatalogue() if err != nil { diff --git a/cli/recipe/new.go b/cli/recipe/new.go index b2a9a172..f7c199c1 100644 --- a/cli/recipe/new.go +++ b/cli/recipe/new.go @@ -13,7 +13,7 @@ import ( "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/git" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // recipeMetadata is the recipe metadata for the README.md @@ -30,10 +30,15 @@ type recipeMetadata struct { SSO string } -var recipeNewCommand = &cli.Command{ - Name: "new", +var recipeNewCommand = cli.Command{ + Name: "new", + Aliases: []string{"n"}, + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, Usage: "Create a new recipe", - Aliases: []string{"n"}, ArgsUsage: "", Description: ` This command creates a new recipe. diff --git a/cli/recipe/recipe.go b/cli/recipe/recipe.go index 5933b190..2a4b75f4 100644 --- a/cli/recipe/recipe.go +++ b/cli/recipe/recipe.go @@ -1,15 +1,15 @@ package recipe import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // RecipeCommand defines all recipe related sub-commands. -var RecipeCommand = &cli.Command{ +var RecipeCommand = cli.Command{ Name: "recipe", + Aliases: []string{"r"}, Usage: "Manage recipes", ArgsUsage: "", - Aliases: []string{"r"}, 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 @@ -20,7 +20,7 @@ sure the recipe is in good working order and the config upgraded in a timely manner. Abra supports convenient automation for recipe maintainenace, see the "abra recipe upgrade", "abra recipe sync" and "abra recipe release" commands. `, - Subcommands: []*cli.Command{ + Subcommands: []cli.Command{ recipeListCommand, recipeVersionCommand, recipeReleaseCommand, diff --git a/cli/recipe/release.go b/cli/recipe/release.go index 33610b17..a37849fa 100644 --- a/cli/recipe/release.go +++ b/cli/recipe/release.go @@ -18,13 +18,13 @@ import ( "github.com/docker/distribution/reference" "github.com/go-git/go-git/v5" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var recipeReleaseCommand = &cli.Command{ +var recipeReleaseCommand = cli.Command{ Name: "release", - Usage: "Release a new recipe version", Aliases: []string{"rl"}, + Usage: "Release a new recipe version", ArgsUsage: " []", Description: ` This command is used to specify a new version of a recipe. These versions are @@ -48,12 +48,15 @@ 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, }, + Before: internal.SubCommandBefore, BashComplete: autocomplete.RecipeNameComplete, Action: func(c *cli.Context) error { recipe := internal.ValidateRecipeWithPrompt(c) diff --git a/cli/recipe/sync.go b/cli/recipe/sync.go index 63e443cd..f6cedb07 100644 --- a/cli/recipe/sync.go +++ b/cli/recipe/sync.go @@ -13,20 +13,23 @@ import ( "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var recipeSyncCommand = &cli.Command{ +var recipeSyncCommand = cli.Command{ Name: "sync", - Usage: "Sync recipe version label", Aliases: []string{"s"}, + Usage: "Sync recipe version label", ArgsUsage: " []", Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, internal.DryFlag, internal.MajorFlag, internal.MinorFlag, internal.PatchFlag, }, + Before: internal.SubCommandBefore, Description: ` This command will generate labels for the main recipe service (i.e. by convention, the service named 'app') which corresponds to the following format: diff --git a/cli/recipe/upgrade.go b/cli/recipe/upgrade.go index e99b3d24..ac05423b 100644 --- a/cli/recipe/upgrade.go +++ b/cli/recipe/upgrade.go @@ -17,7 +17,7 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/docker/distribution/reference" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) type imgPin struct { @@ -25,10 +25,10 @@ type imgPin struct { version tagcmp.Tag } -var recipeUpgradeCommand = &cli.Command{ +var recipeUpgradeCommand = cli.Command{ Name: "upgrade", - Usage: "Upgrade recipe image tags", Aliases: []string{"u"}, + Usage: "Upgrade recipe image tags", Description: ` This command reads and attempts to parse all image tags within the given configuration and prompt with more recent tags to upgrade to. It will @@ -50,11 +50,14 @@ You may invoke this command in "wizard" mode and be prompted for input: BashComplete: autocomplete.RecipeNameComplete, ArgsUsage: "", Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, internal.PatchFlag, internal.MinorFlag, internal.MajorFlag, internal.AllTagsFlag, }, + Before: internal.SubCommandBefore, Action: func(c *cli.Context) error { recipe := internal.ValidateRecipeWithPrompt(c) diff --git a/cli/recipe/version.go b/cli/recipe/version.go index 48dd7fce..5e268e25 100644 --- a/cli/recipe/version.go +++ b/cli/recipe/version.go @@ -6,14 +6,19 @@ import ( "coopcloud.tech/abra/pkg/formatter" recipePkg "coopcloud.tech/abra/pkg/recipe" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var recipeVersionCommand = &cli.Command{ - Name: "versions", - Usage: "List recipe versions", - Aliases: []string{"v"}, - ArgsUsage: "", +var recipeVersionCommand = cli.Command{ + Name: "versions", + Aliases: []string{"v"}, + Usage: "List recipe versions", + ArgsUsage: "", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, BashComplete: autocomplete.RecipeNameComplete, Action: func(c *cli.Context) error { recipe := internal.ValidateRecipe(c) diff --git a/cli/record/list.go b/cli/record/list.go index d12a9243..16d5fbb0 100644 --- a/cli/record/list.go +++ b/cli/record/list.go @@ -1,6 +1,7 @@ package record import ( + "context" "fmt" "strconv" @@ -9,18 +10,21 @@ import ( "coopcloud.tech/abra/pkg/formatter" "github.com/libdns/gandi" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // RecordListCommand lists domains. -var RecordListCommand = &cli.Command{ +var RecordListCommand = cli.Command{ Name: "list", Usage: "List domain name records", Aliases: []string{"ls"}, ArgsUsage: "", Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, internal.DNSProviderFlag, }, + Before: internal.SubCommandBefore, Description: ` This command lists all domain name records managed by a 3rd party provider for a specific zone. @@ -49,7 +53,7 @@ are listed. This zone must already be created on your provider account. logrus.Fatalf("%s is not a supported DNS provider", internal.DNSProvider) } - records, err := provider.GetRecords(c.Context, zone) + records, err := provider.GetRecords(context.Background(), zone) if err != nil { logrus.Fatal(err) } diff --git a/cli/record/new.go b/cli/record/new.go index f494056c..68a4eb89 100644 --- a/cli/record/new.go +++ b/cli/record/new.go @@ -1,6 +1,7 @@ package record import ( + "context" "fmt" "strconv" @@ -11,16 +12,18 @@ import ( "github.com/libdns/gandi" "github.com/libdns/libdns" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // RecordNewCommand creates a new domain name record. -var RecordNewCommand = &cli.Command{ +var RecordNewCommand = cli.Command{ Name: "new", Usage: "Create a new domain record", Aliases: []string{"n"}, ArgsUsage: "", Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, internal.DNSProviderFlag, internal.DNSTypeFlag, internal.DNSNameFlag, @@ -29,6 +32,7 @@ var RecordNewCommand = &cli.Command{ internal.DNSPriorityFlag, internal.AutoDNSRecordFlag, }, + Before: internal.SubCommandBefore, Description: ` This command creates a new domain name record for a specific zone. @@ -118,7 +122,7 @@ You may also invoke this command in "wizard" mode and be prompted for input record.Priority = internal.DNSPriority } - records, err := provider.GetRecords(c.Context, zone) + records, err := provider.GetRecords(context.Background(), zone) if err != nil { logrus.Fatal(err) } @@ -132,7 +136,7 @@ You may also invoke this command in "wizard" mode and be prompted for input } createdRecords, err := provider.SetRecords( - c.Context, + context.Background(), zone, []libdns.Record{record}, ) @@ -196,7 +200,7 @@ func autoConfigure(c *cli.Context, provider *gandi.Provider, zone, ipv4 string) table := formatter.CreateTable(tableCol) for _, record := range records { - existingRecords, err := provider.GetRecords(c.Context, zone) + existingRecords, err := provider.GetRecords(context.Background(), zone) if err != nil { return err } @@ -216,7 +220,7 @@ func autoConfigure(c *cli.Context, provider *gandi.Provider, zone, ipv4 string) } createdRecords, err := provider.SetRecords( - c.Context, + context.Background(), zone, []libdns.Record{record}, ) diff --git a/cli/record/record.go b/cli/record/record.go index 587a6e9d..34738cd1 100644 --- a/cli/record/record.go +++ b/cli/record/record.go @@ -1,11 +1,11 @@ package record import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // RecordCommand supports managing DNS entries. -var RecordCommand = &cli.Command{ +var RecordCommand = cli.Command{ Name: "record", Usage: "Manage domain name records", Aliases: []string{"rc"}, @@ -30,7 +30,7 @@ to implement new provider support easily. https://pkg.go.dev/github.com/libdns/libdns `, - Subcommands: []*cli.Command{ + Subcommands: []cli.Command{ RecordListCommand, RecordNewCommand, RecordRemoveCommand, diff --git a/cli/record/remove.go b/cli/record/remove.go index 5c989cf8..58e0ee2d 100644 --- a/cli/record/remove.go +++ b/cli/record/remove.go @@ -1,6 +1,7 @@ package record import ( + "context" "fmt" "strconv" @@ -11,20 +12,23 @@ import ( "github.com/libdns/gandi" "github.com/libdns/libdns" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // RecordRemoveCommand lists domains. -var RecordRemoveCommand = &cli.Command{ +var RecordRemoveCommand = cli.Command{ Name: "remove", Usage: "Remove a domain name record", Aliases: []string{"rm"}, ArgsUsage: "", Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, internal.DNSProviderFlag, internal.DNSTypeFlag, internal.DNSNameFlag, }, + Before: internal.SubCommandBefore, Description: ` This command removes a domain name record for a specific zone. @@ -70,7 +74,7 @@ You may also invoke this command in "wizard" mode and be prompted for input logrus.Fatal(err) } - records, err := provider.GetRecords(c.Context, zone) + records, err := provider.GetRecords(context.Background(), zone) if err != nil { logrus.Fatal(err) } @@ -120,7 +124,7 @@ You may also invoke this command in "wizard" mode and be prompted for input } } - _, err = provider.DeleteRecords(c.Context, zone, []libdns.Record{toDelete}) + _, err = provider.DeleteRecords(context.Background(), zone, []libdns.Record{toDelete}) if err != nil { logrus.Fatal(err) } diff --git a/cli/server/add.go b/cli/server/add.go index 58140338..9b24bfc6 100644 --- a/cli/server/add.go +++ b/cli/server/add.go @@ -1,6 +1,7 @@ package server import ( + "context" "errors" "fmt" "os" @@ -22,7 +23,7 @@ import ( "github.com/docker/docker/api/types/swarm" dockerClient "github.com/docker/docker/client" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) var ( @@ -47,26 +48,21 @@ source for this script can be seen here: var local bool var localFlag = &cli.BoolFlag{ - Name: "local", - Aliases: []string{"l"}, - Value: false, + Name: "local, l", Usage: "Use local server", Destination: &local, } var provision bool var provisionFlag = &cli.BoolFlag{ - Name: "provision", - Aliases: []string{"p"}, - Value: false, + Name: "provision, p", Usage: "Provision server so it can deploy apps", Destination: &provision, } var sshAuth string var sshAuthFlag = &cli.StringFlag{ - Name: "ssh-auth", - Aliases: []string{"sh"}, + Name: "ssh-auth, sh", Value: "identity-file", Usage: "Select SSH authentication method (identity-file, password)", Destination: &sshAuth, @@ -74,18 +70,14 @@ var sshAuthFlag = &cli.StringFlag{ var askSudoPass bool var askSudoPassFlag = &cli.BoolFlag{ - Name: "ask-sudo-pass", - Aliases: []string{"as"}, - Value: false, + Name: "ask-sudo-pass, as", Usage: "Ask for sudo password", Destination: &askSudoPass, } var traefik bool var traefikFlag = &cli.BoolFlag{ - Name: "traefik", - Aliases: []string{"t"}, - Value: false, + Name: "traefik, t", Usage: "Deploy traefik", Destination: &traefik, } @@ -320,7 +312,7 @@ If nothing works, you try running the Docker install script manually on your ser func initSwarmLocal(c *cli.Context, cl *dockerClient.Client, domainName string) error { initReq := swarm.InitRequest{ListenAddr: "0.0.0.0:2377"} - if _, err := cl.SwarmInit(c.Context, initReq); err != nil { + if _, err := cl.SwarmInit(context.Background(), initReq); err != nil { if strings.Contains(err.Error(), "is already part of a swarm") || strings.Contains(err.Error(), "must specify a listening address") { logrus.Infof("swarm mode already initialised on %s", domainName) @@ -332,7 +324,7 @@ func initSwarmLocal(c *cli.Context, cl *dockerClient.Client, domainName string) } netOpts := types.NetworkCreate{Driver: "overlay", Scope: "swarm"} - if _, err := cl.NetworkCreate(c.Context, "proxy", netOpts); err != nil { + if _, err := cl.NetworkCreate(context.Background(), "proxy", netOpts); err != nil { if !strings.Contains(err.Error(), "proxy already exists") { return err } @@ -354,7 +346,7 @@ func initSwarm(c *cli.Context, cl *dockerClient.Client, domainName string) error ListenAddr: "0.0.0.0:2377", AdvertiseAddr: ipv4, } - if _, err := cl.SwarmInit(c.Context, initReq); err != nil { + if _, err := cl.SwarmInit(context.Background(), initReq); err != nil { if strings.Contains(err.Error(), "is already part of a swarm") || strings.Contains(err.Error(), "must specify a listening address") { logrus.Infof("swarm mode already initialised on %s", domainName) @@ -366,7 +358,7 @@ func initSwarm(c *cli.Context, cl *dockerClient.Client, domainName string) error } netOpts := types.NetworkCreate{Driver: "overlay", Scope: "swarm"} - if _, err := cl.NetworkCreate(c.Context, "proxy", netOpts); err != nil { + if _, err := cl.NetworkCreate(context.Background(), "proxy", netOpts); err != nil { if !strings.Contains(err.Error(), "proxy already exists") { return err } @@ -414,9 +406,10 @@ func deployTraefik(c *cli.Context, cl *dockerClient.Client, domainName string) e return nil } -var serverAddCommand = &cli.Command{ - Name: "add", - Usage: "Add a server to your configuration", +var serverAddCommand = cli.Command{ + Name: "add", + Aliases: []string{"a"}, + Usage: "Add a server to your configuration", Description: ` This command adds a new server to your configuration so that it can be managed by Abra. This can be useful when you already have a server provisioned and want @@ -467,17 +460,21 @@ In this example, Abra will run the following operations: You may omit flags to avoid performing this provisioning logic. `, - Aliases: []string{"a"}, Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, localFlag, provisionFlag, sshAuthFlag, askSudoPassFlag, traefikFlag, + internal.DebugFlag, + internal.NoInputFlag, }, + Before: internal.SubCommandBefore, ArgsUsage: " [] []", Action: func(c *cli.Context) error { - if c.Args().Len() > 0 && local || !internal.ValidateSubCmdFlags(c) { + if len(c.Args()) > 0 && local || !internal.ValidateSubCmdFlags(c) { err := errors.New("cannot use and --local together") internal.ShowSubcommandHelpAndError(c, err) } @@ -543,7 +540,7 @@ You may omit flags to avoid performing this provisioning logic. } } - if _, err := cl.Info(c.Context); err != nil { + if _, err := cl.Info(context.Background()); err != nil { cleanUp(domainName) logrus.Fatalf("couldn't make a remote docker connection to %s? use --provision/-p to attempt to install", domainName) } diff --git a/cli/server/list.go b/cli/server/list.go index 492b3797..6240f1b7 100644 --- a/cli/server/list.go +++ b/cli/server/list.go @@ -3,20 +3,24 @@ package server import ( "strings" + "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/context" "coopcloud.tech/abra/pkg/formatter" "github.com/docker/cli/cli/connhelper/ssh" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) -var serverListCommand = &cli.Command{ - Name: "list", - Aliases: []string{"ls"}, - Usage: "List managed servers", - ArgsUsage: " ", - HideHelp: true, +var serverListCommand = cli.Command{ + Name: "list", + Aliases: []string{"ls"}, + Usage: "List managed servers", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, Action: func(c *cli.Context) error { dockerContextStore := context.NewDefaultDockerContextStore() contexts, err := dockerContextStore.Store.List() diff --git a/cli/server/new.go b/cli/server/new.go index 814882f3..07b770c4 100644 --- a/cli/server/new.go +++ b/cli/server/new.go @@ -1,6 +1,7 @@ package server import ( + "context" "fmt" "strings" @@ -10,7 +11,7 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/hetznercloud/hcloud-go/hcloud" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) func newHetznerCloudVPS(c *cli.Context) error { @@ -27,7 +28,7 @@ func newHetznerCloudVPS(c *cli.Context) error { continue } - sshKey, _, err := client.SSHKey.GetByName(c.Context, sshKey) + sshKey, _, err := client.SSHKey.GetByName(context.Background(), sshKey) if err != nil { return err } @@ -72,7 +73,7 @@ func newHetznerCloudVPS(c *cli.Context) error { logrus.Fatal("exiting as requested") } - res, _, err := client.Server.Create(c.Context, serverOpts) + res, _, err := client.Server.Create(context.Background(), serverOpts) if err != nil { return err } @@ -200,7 +201,7 @@ bar.example.com). return nil } -var serverNewCommand = &cli.Command{ +var serverNewCommand = cli.Command{ Name: "new", Aliases: []string{"n"}, Usage: "Create a new server using a 3rd party provider", @@ -223,7 +224,12 @@ API tokens are read from the environment if specified, e.g. Where "$provider_TOKEN" is the expected env var format. `, Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + internal.ServerProviderFlag, + internal.DebugFlag, + internal.NoInputFlag, // Capsul internal.CapsulInstanceURLFlag, @@ -240,6 +246,7 @@ Where "$provider_TOKEN" is the expected env var format. internal.HetznerCloudLocationFlag, internal.HetznerCloudAPITokenFlag, }, + Before: internal.SubCommandBefore, Action: func(c *cli.Context) error { if err := internal.EnsureServerProvider(); err != nil { logrus.Fatal(err) diff --git a/cli/server/remove.go b/cli/server/remove.go index 72e54528..daabe291 100644 --- a/cli/server/remove.go +++ b/cli/server/remove.go @@ -1,6 +1,7 @@ package server import ( + "context" "fmt" "os" "path/filepath" @@ -12,14 +13,12 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/hetznercloud/hcloud-go/hcloud" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) var rmServer bool var rmServerFlag = &cli.BoolFlag{ - Name: "server", - Aliases: []string{"s"}, - Value: false, + Name: "server, s", Usage: "remove the actual server also", Destination: &rmServer, } @@ -50,7 +49,7 @@ func rmHetznerCloudVPS(c *cli.Context) error { client := hcloud.NewClient(hcloud.WithToken(internal.HetznerCloudAPIToken)) - server, _, err := client.Server.Get(c.Context, internal.HetznerCloudName) + server, _, err := client.Server.Get(context.Background(), internal.HetznerCloudName) if err != nil { return err } @@ -89,7 +88,7 @@ destroyed. logrus.Fatal("exiting as requested") } - _, err = client.Server.Delete(c.Context, server) + _, err = client.Server.Delete(context.Background(), server) if err != nil { return err } @@ -99,7 +98,7 @@ destroyed. return nil } -var serverRemoveCommand = &cli.Command{ +var serverRemoveCommand = cli.Command{ Name: "remove", Aliases: []string{"rm"}, ArgsUsage: "[]", @@ -116,6 +115,8 @@ underlying client connection context. This server will then be lost in time, like tears in rain. `, Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, rmServerFlag, internal.ServerProviderFlag, @@ -123,6 +124,7 @@ like tears in rain. internal.HetznerCloudNameFlag, internal.HetznerCloudAPITokenFlag, }, + Before: internal.SubCommandBefore, Action: func(c *cli.Context) error { serverName := c.Args().Get(1) if serverName != "" { diff --git a/cli/server/server.go b/cli/server/server.go index e8018a86..17cad545 100644 --- a/cli/server/server.go +++ b/cli/server/server.go @@ -1,11 +1,11 @@ package server import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // ServerCommand defines the `abra server` command and its subcommands -var ServerCommand = &cli.Command{ +var ServerCommand = cli.Command{ Name: "server", Aliases: []string{"s"}, Usage: "Manage servers", @@ -18,7 +18,7 @@ already have a server, you can add it to your configuration using "abra server add". Abra can provision servers so that they are ready to deploy Co-op Cloud apps, see available flags on "server add" for more. `, - Subcommands: []*cli.Command{ + Subcommands: []cli.Command{ serverNewCommand, serverAddCommand, serverListCommand, diff --git a/go.mod b/go.mod index c63dd3d5..e4c27ead 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,6 @@ require ( github.com/schollz/progressbar/v3 v3.8.5 github.com/schultz-is/passgen v1.0.1 github.com/sirupsen/logrus v1.8.1 - github.com/urfave/cli/v2 v2.3.0 gotest.tools/v3 v3.1.0 ) @@ -43,6 +42,7 @@ require ( github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/runc v1.0.2 // indirect github.com/theupdateframework/notary v0.7.0 // indirect + github.com/urfave/cli v1.22.5 github.com/xeipuuv/gojsonschema v1.2.0 // indirect golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e diff --git a/go.sum b/go.sum index 3515524d..ed357f4b 100644 --- a/go.sum +++ b/go.sum @@ -769,10 +769,9 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= -github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= +github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= @@ -1149,7 +1148,6 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkg/autocomplete/autocomplete.go b/pkg/autocomplete/autocomplete.go index 4d37b62c..8e24adca 100644 --- a/pkg/autocomplete/autocomplete.go +++ b/pkg/autocomplete/autocomplete.go @@ -6,7 +6,7 @@ import ( "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/recipe" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/urfave/cli" ) // AppNameComplete copletes app names