refactor!: migrate to urfave/cli v1
continuous-integration/drone/push Build is passing Details

Better flexible flags handling.
This commit is contained in:
decentral1se 2022-01-18 14:13:20 +01:00
parent c6db9ee355
commit 0e688f1407
Signed by: decentral1se
GPG Key ID: 03789458B3D0C410
48 changed files with 502 additions and 405 deletions

View File

@ -1,21 +1,21 @@
package app package app
import ( import (
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// AppCommand defines the `abra app` command and ets subcommands // AppCommand defines the `abra app` command and ets subcommands
var AppCommand = &cli.Command{ var AppCommand = cli.Command{
Name: "app", Name: "app",
Usage: "Manage apps",
Aliases: []string{"a"}, Aliases: []string{"a"},
Usage: "Manage apps",
ArgsUsage: "<app>", ArgsUsage: "<app>",
Description: ` Description: `
This command provides all the functionality you need to manage the life cycle 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) of your apps. From initial deployment, day-2 operations (e.g. backup/restore)
to scaling apps up and spinning them down. to scaling apps up and spinning them down.
`, `,
Subcommands: []*cli.Command{ Subcommands: []cli.Command{
appNewCommand, appNewCommand,
appConfigCommand, appConfigCommand,
appRestartCommand, appRestartCommand,

View File

@ -13,23 +13,25 @@ import (
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var backupAllServices bool var backupAllServices bool
var backupAllServicesFlag = &cli.BoolFlag{ var backupAllServicesFlag = &cli.BoolFlag{
Name: "all", Name: "all, a",
Value: false,
Destination: &backupAllServices, Destination: &backupAllServices,
Aliases: []string{"a"},
Usage: "Backup all services", Usage: "Backup all services",
} }
var appBackupCommand = &cli.Command{ var appBackupCommand = cli.Command{
Name: "backup", Name: "backup",
Usage: "Backup an app", Aliases: []string{"b"},
Aliases: []string{"b"}, Usage: "Backup an app",
Flags: []cli.Flag{backupAllServicesFlag}, Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
backupAllServicesFlag},
Before: internal.SubCommandBefore,
ArgsUsage: "<service>", ArgsUsage: "<service>",
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)

View File

@ -9,14 +9,19 @@ import (
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var appCheckCommand = &cli.Command{ var appCheckCommand = cli.Command{
Name: "check", Name: "check",
Usage: "Check if app is configured correctly",
Aliases: []string{"c"}, Aliases: []string{"c"},
Usage: "Check if app is configured correctly",
ArgsUsage: "<service>", ArgsUsage: "<service>",
Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
},
Before: internal.SubCommandBefore,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)

View File

@ -10,13 +10,18 @@ import (
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var appConfigCommand = &cli.Command{ var appConfigCommand = cli.Command{
Name: "config", Name: "config",
Aliases: []string{"c"}, Aliases: []string{"c"},
Usage: "Edit app config", Usage: "Edit app config",
Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
},
Before: internal.SubCommandBefore,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
appName := c.Args().First() appName := c.Args().First()

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"context"
"fmt" "fmt"
"os" "os"
"strings" "strings"
@ -15,14 +16,19 @@ import (
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/archive"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var appCpCommand = &cli.Command{ var appCpCommand = cli.Command{
Name: "cp", Name: "cp",
Aliases: []string{"c"}, Aliases: []string{"c"},
ArgsUsage: "<src> <dst>", ArgsUsage: "<src> <dst>",
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: ` Description: `
This command supports copying files to and from any app service file system. This command supports copying files to and from any app service file system.
@ -118,7 +124,7 @@ func configureAndCp(
filters := filters.NewArgs() filters := filters.NewArgs()
filters.Add("name", fmt.Sprintf("%s_%s", appEnv.StackName(), service)) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -137,11 +143,11 @@ func configureAndCp(
} }
copyOpts := types.CopyToContainerOptions{AllowOverwriteDirWithFile: false, CopyUIDGID: false} 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) logrus.Fatal(err)
} }
} else { } else {
content, _, err := cl.CopyFromContainer(c.Context, container.ID, srcPath) content, _, err := cl.CopyFromContainer(context.Background(), container.ID, srcPath)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -3,19 +3,22 @@ package app
import ( import (
"coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var appDeployCommand = &cli.Command{ var appDeployCommand = cli.Command{
Name: "deploy", Name: "deploy",
Aliases: []string{"d"}, Aliases: []string{"d"},
Usage: "Deploy an app", Usage: "Deploy an app",
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.ForceFlag, internal.ForceFlag,
internal.ChaosFlag, internal.ChaosFlag,
internal.NoDomainChecksFlag, internal.NoDomainChecksFlag,
internal.DontWaitConvergeFlag, internal.DontWaitConvergeFlag,
}, },
Before: internal.SubCommandBefore,
Description: ` Description: `
This command deploys an app. It does not support incrementing the version of a 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 <app>" deployed app, for this you need to look at the "abra app upgrade <app>"

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"context"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -15,10 +16,10 @@ import (
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
dockerClient "github.com/docker/docker/client" dockerClient "github.com/docker/docker/client"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var appErrorsCommand = &cli.Command{ var appErrorsCommand = cli.Command{
Name: "errors", Name: "errors",
Usage: "List errors for a deployed app", Usage: "List errors for a deployed app",
Description: ` Description: `
@ -44,8 +45,13 @@ further information which can help you debug the cause of an app failure via
the logs. the logs.
`, `,
Aliases: []string{"e"}, Aliases: []string{"e"},
Flags: []cli.Flag{internal.WatchFlag}, Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.WatchFlag,
},
Before: internal.SubCommandBefore,
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
@ -55,7 +61,7 @@ the logs.
logrus.Fatal(err) logrus.Fatal(err)
} }
isDeployed, _, err := stack.IsDeployed(c.Context, cl, app.StackName()) isDeployed, _, err := stack.IsDeployed(context.Background(), cl, app.StackName())
if err != nil { if err != nil {
logrus.Fatal(err) 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 { for _, service := range recipe.Config.Services {
filters := filters.NewArgs() filters := filters.NewArgs()
filters.Add("name", service.Name) 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 { if err != nil {
return err return err
} }
@ -102,7 +108,7 @@ func checkErrors(c *cli.Context, cl *dockerClient.Client, app config.App) error
} }
container := containers[0] container := containers[0]
containerState, err := cl.ContainerInspect(c.Context, container.ID) containerState, err := cl.ContainerInspect(context.Background(), container.ID)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -12,22 +12,19 @@ import (
"coopcloud.tech/abra/pkg/ssh" "coopcloud.tech/abra/pkg/ssh"
"coopcloud.tech/tagcmp" "coopcloud.tech/tagcmp"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var status bool var status bool
var statusFlag = &cli.BoolFlag{ var statusFlag = &cli.BoolFlag{
Name: "status", Name: "status, S",
Aliases: []string{"S"},
Value: false,
Usage: "Show app deployment status", Usage: "Show app deployment status",
Destination: &status, Destination: &status,
} }
var appType string var appType string
var typeFlag = &cli.StringFlag{ var typeFlag = &cli.StringFlag{
Name: "type", Name: "type, t",
Aliases: []string{"t"},
Value: "", Value: "",
Usage: "Show apps of a specific type", Usage: "Show apps of a specific type",
Destination: &appType, Destination: &appType,
@ -35,8 +32,7 @@ var typeFlag = &cli.StringFlag{
var listAppServer string var listAppServer string
var listAppServerFlag = &cli.StringFlag{ var listAppServerFlag = &cli.StringFlag{
Name: "server", Name: "server, s",
Aliases: []string{"s"},
Value: "", Value: "",
Usage: "Show apps of a specific server", Usage: "Show apps of a specific server",
Destination: &listAppServer, Destination: &listAppServer,
@ -61,9 +57,10 @@ type serverStatus struct {
upgradeCount int upgradeCount int
} }
var appListCommand = &cli.Command{ var appListCommand = cli.Command{
Name: "list", Name: "list",
Usage: "List all managed apps", Aliases: []string{"ls"},
Usage: "List all managed apps",
Description: ` Description: `
This command looks at your local file system listing of apps and servers (e.g. 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. 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 actual live deployment status. Depending on how many servers you manage, this
can take some time. can take some time.
`, `,
Aliases: []string{"ls"},
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
statusFlag, statusFlag,
listAppServerFlag, listAppServerFlag,
typeFlag, typeFlag,
}, },
Before: internal.SubCommandBefore,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
appFiles, err := config.LoadAppFiles(listAppServer) appFiles, err := config.LoadAppFiles(listAppServer)
if err != nil { if err != nil {

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"context"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -15,7 +16,7 @@ import (
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
dockerClient "github.com/docker/docker/client" dockerClient "github.com/docker/docker/client"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var logOpts = types.ContainerLogsOptions{ var logOpts = types.ContainerLogsOptions{
@ -32,7 +33,7 @@ func stackLogs(c *cli.Context, stackName string, client *dockerClient.Client) {
filters := filters.NewArgs() filters := filters.NewArgs()
filters.Add("name", stackName) filters.Add("name", stackName)
serviceOpts := types.ServiceListOptions{Filters: filters} serviceOpts := types.ServiceListOptions{Filters: filters}
services, err := client.ServiceList(c.Context, serviceOpts) services, err := client.ServiceList(context.Background(), serviceOpts)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -45,7 +46,7 @@ func stackLogs(c *cli.Context, stackName string, client *dockerClient.Client) {
logOpts.ShowStdout = false logOpts.ShowStdout = false
} }
logs, err := client.ServiceLogs(c.Context, s, logOpts) logs, err := client.ServiceLogs(context.Background(), s, logOpts)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -63,14 +64,17 @@ func stackLogs(c *cli.Context, stackName string, client *dockerClient.Client) {
os.Exit(0) os.Exit(0)
} }
var appLogsCommand = &cli.Command{ var appLogsCommand = cli.Command{
Name: "logs", Name: "logs",
Aliases: []string{"l"}, Aliases: []string{"l"},
ArgsUsage: "[<service>]", ArgsUsage: "[<service>]",
Usage: "Tail app logs", Usage: "Tail app logs",
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.StdErrOnlyFlag, internal.StdErrOnlyFlag,
internal.DebugFlag,
internal.NoInputFlag,
}, },
Before: internal.SubCommandBefore,
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) 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 { func tailServiceLogs(c *cli.Context, cl *dockerClient.Client, app config.App, serviceName string) error {
filters := filters.NewArgs() filters := filters.NewArgs()
filters.Add("name", fmt.Sprintf("%s_%s", app.StackName(), serviceName)) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -107,7 +111,7 @@ func tailServiceLogs(c *cli.Context, cl *dockerClient.Client, app config.App, se
logOpts.ShowStdout = false logOpts.ShowStdout = false
} }
logs, err := cl.ServiceLogs(c.Context, chosenService.ID, logOpts) logs, err := cl.ServiceLogs(context.Background(), chosenService.ID, logOpts)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -3,7 +3,7 @@ package app
import ( import (
"coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var appNewDescription = ` var appNewDescription = `
@ -26,18 +26,21 @@ pass store (see passwordstore.org for more). The pass command must be available
on your $PATH. on your $PATH.
` `
var appNewCommand = &cli.Command{ var appNewCommand = cli.Command{
Name: "new", Name: "new",
Usage: "Create a new app",
Aliases: []string{"n"}, Aliases: []string{"n"},
Usage: "Create a new app",
Description: appNewDescription, Description: appNewDescription,
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.NewAppServerFlag, internal.NewAppServerFlag,
internal.DomainFlag, internal.DomainFlag,
internal.NewAppNameFlag, internal.NewAppNameFlag,
internal.PassFlag, internal.PassFlag,
internal.SecretsFlag, internal.SecretsFlag,
}, },
Before: internal.SubCommandBefore,
ArgsUsage: "<recipe>", ArgsUsage: "<recipe>",
Action: internal.NewAction, Action: internal.NewAction,
BashComplete: autocomplete.RecipeNameComplete, BashComplete: autocomplete.RecipeNameComplete,

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"context"
"strings" "strings"
"time" "time"
@ -17,17 +18,20 @@ import (
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
dockerClient "github.com/docker/docker/client" dockerClient "github.com/docker/docker/client"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var appPsCommand = &cli.Command{ var appPsCommand = cli.Command{
Name: "ps", Name: "ps",
Aliases: []string{"p"},
Usage: "Check app status", Usage: "Check app status",
Description: "This command shows a more detailed status output of a specific deployed app.", Description: "This command shows a more detailed status output of a specific deployed app.",
Aliases: []string{"p"},
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.WatchFlag, internal.WatchFlag,
internal.DebugFlag,
internal.NoInputFlag,
}, },
Before: internal.SubCommandBefore,
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
@ -37,7 +41,7 @@ var appPsCommand = &cli.Command{
logrus.Fatal(err) logrus.Fatal(err)
} }
isDeployed, _, err := stack.IsDeployed(c.Context, cl, app.StackName()) isDeployed, _, err := stack.IsDeployed(context.Background(), cl, app.StackName())
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -66,7 +70,7 @@ func showPSOutput(c *cli.Context, app config.App, cl *dockerClient.Client) {
filters := filters.NewArgs() filters := filters.NewArgs()
filters.Add("name", app.StackName()) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"context"
"fmt" "fmt"
"os" "os"
@ -12,7 +13,7 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// Volumes stores the variable from VolumesFlag // 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 // VolumesFlag is used to specify if volumes should be deleted when deleting an app
var VolumesFlag = &cli.BoolFlag{ var VolumesFlag = &cli.BoolFlag{
Name: "volumes", Name: "volumes",
Value: false,
Destination: &Volumes, Destination: &Volumes,
} }
var appRemoveCommand = &cli.Command{ var appRemoveCommand = cli.Command{
Name: "remove", Name: "remove",
Usage: "Remove an already undeployed app",
Aliases: []string{"rm"}, Aliases: []string{"rm"},
Usage: "Remove an already undeployed app",
Flags: []cli.Flag{ Flags: []cli.Flag{
VolumesFlag, VolumesFlag,
internal.ForceFlag, internal.ForceFlag,
internal.DebugFlag,
internal.NoInputFlag,
}, },
Before: internal.SubCommandBefore,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
@ -54,7 +57,7 @@ var appRemoveCommand = &cli.Command{
logrus.Fatal(err) logrus.Fatal(err)
} }
isDeployed, _, err := stack.IsDeployed(c.Context, cl, app.StackName()) isDeployed, _, err := stack.IsDeployed(context.Background(), cl, app.StackName())
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -64,7 +67,7 @@ var appRemoveCommand = &cli.Command{
fs := filters.NewArgs() fs := filters.NewArgs()
fs.Add("name", app.StackName()) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -94,7 +97,7 @@ var appRemoveCommand = &cli.Command{
} }
for _, name := range secretNamesToRemove { for _, name := range secretNamesToRemove {
err := cl.SecretRemove(c.Context, secrets[name]) err := cl.SecretRemove(context.Background(), secrets[name])
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -104,7 +107,7 @@ var appRemoveCommand = &cli.Command{
logrus.Info("no secrets to remove") logrus.Info("no secrets to remove")
} }
volumeListOKBody, err := cl.VolumeList(c.Context, fs) volumeListOKBody, err := cl.VolumeList(context.Background(), fs)
volumeList := volumeListOKBody.Volumes volumeList := volumeListOKBody.Volumes
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
@ -131,7 +134,7 @@ var appRemoveCommand = &cli.Command{
} }
} }
for _, vol := range removeVols { 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
@ -10,14 +11,19 @@ import (
upstream "coopcloud.tech/abra/pkg/upstream/service" upstream "coopcloud.tech/abra/pkg/upstream/service"
stack "coopcloud.tech/abra/pkg/upstream/stack" stack "coopcloud.tech/abra/pkg/upstream/stack"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var appRestartCommand = &cli.Command{ var appRestartCommand = cli.Command{
Name: "restart", Name: "restart",
Usage: "Restart an app", Aliases: []string{"re"},
Aliases: []string{"re"}, Usage: "Restart an app",
ArgsUsage: "<service>", ArgsUsage: "<service>",
Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
},
Before: internal.SubCommandBefore,
Description: `This command restarts a service within a deployed app.`, Description: `This command restarts a service within a deployed app.`,
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
@ -37,22 +43,22 @@ var appRestartCommand = &cli.Command{
serviceName := fmt.Sprintf("%s_%s", app.StackName(), serviceNameShort) serviceName := fmt.Sprintf("%s_%s", app.StackName(), serviceNameShort)
logrus.Debugf("attempting to scale %s to 0 (restart logic)", serviceName) 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) 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.Fatal(err)
} }
logrus.Debugf("%s has been scaled to 0 (restart logic)", serviceName) logrus.Debugf("%s has been scaled to 0 (restart logic)", serviceName)
logrus.Debugf("attempting to scale %s to 1 (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) 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.Fatal(err)
} }

View File

@ -12,28 +12,31 @@ import (
"coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var restoreAllServices bool var restoreAllServices bool
var restoreAllServicesFlag = &cli.BoolFlag{ var restoreAllServicesFlag = &cli.BoolFlag{
Name: "all", Name: "all, a",
Value: false,
Destination: &restoreAllServices, Destination: &restoreAllServices,
Aliases: []string{"a"},
Usage: "Restore all services", Usage: "Restore all services",
} }
var appRestoreCommand = &cli.Command{ var appRestoreCommand = cli.Command{
Name: "restore", Name: "restore",
Usage: "Restore an app from a backup", Aliases: []string{"rs"},
Aliases: []string{"rs"}, Usage: "Restore an app from a backup",
Flags: []cli.Flag{restoreAllServicesFlag}, Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
restoreAllServicesFlag,
},
Before: internal.SubCommandBefore,
ArgsUsage: "<service> [<backup file>]", ArgsUsage: "<service> [<backup file>]",
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
if c.Args().Len() > 1 && restoreAllServices { if len(c.Args()) > 1 && restoreAllServices {
internal.ShowSubcommandHelpAndError(c, errors.New("cannot use <service>/<backup file> and '--all' together")) internal.ShowSubcommandHelpAndError(c, errors.New("cannot use <service>/<backup file> and '--all' together"))
} }

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"context"
"fmt" "fmt"
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
@ -14,19 +15,22 @@ import (
"coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/client"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var appRollbackCommand = &cli.Command{ var appRollbackCommand = cli.Command{
Name: "rollback", Name: "rollback",
Usage: "Roll an app back to a previous version",
Aliases: []string{"rl"}, Aliases: []string{"rl"},
Usage: "Roll an app back to a previous version",
ArgsUsage: "<app>", ArgsUsage: "<app>",
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.ForceFlag, internal.ForceFlag,
internal.ChaosFlag, internal.ChaosFlag,
internal.DontWaitConvergeFlag, internal.DontWaitConvergeFlag,
}, },
Before: internal.SubCommandBefore,
Description: ` Description: `
This command rolls an app back to a previous version if one exists. 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) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
@ -13,7 +14,7 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var user string var user string
@ -26,28 +27,30 @@ var userFlag = &cli.StringFlag{
var noTTY bool var noTTY bool
var noTTYFlag = &cli.BoolFlag{ var noTTYFlag = &cli.BoolFlag{
Name: "no-tty", Name: "no-tty",
Value: false,
Destination: &noTTY, Destination: &noTTY,
} }
var appRunCommand = &cli.Command{ var appRunCommand = cli.Command{
Name: "run", Name: "run",
Aliases: []string{"r"},
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
noTTYFlag, noTTYFlag,
userFlag, userFlag,
}, },
Aliases: []string{"r"}, Before: internal.SubCommandBefore,
ArgsUsage: "<service> <args>...", ArgsUsage: "<service> <args>...",
Usage: "Run a command in a service container", Usage: "Run a command in a service container",
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
if c.Args().Len() < 2 { if len(c.Args()) < 2 {
internal.ShowSubcommandHelpAndError(c, errors.New("no <service> provided?")) internal.ShowSubcommandHelpAndError(c, errors.New("no <service> provided?"))
} }
if c.Args().Len() < 3 { if len(c.Args()) < 3 {
internal.ShowSubcommandHelpAndError(c, errors.New("no <args> provided?")) internal.ShowSubcommandHelpAndError(c, errors.New("no <args> provided?"))
} }
@ -61,12 +64,12 @@ var appRunCommand = &cli.Command{
filters := filters.NewArgs() filters := filters.NewArgs()
filters.Add("name", stackAndServiceName) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
cmd := c.Args().Slice()[2:] cmd := c.Args()[2:]
execCreateOpts := types.ExecConfig{ execCreateOpts := types.ExecConfig{
AttachStderr: true, AttachStderr: true,
AttachStdin: true, AttachStdin: true,

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"os" "os"
@ -14,29 +15,32 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var allSecrets bool var allSecrets bool
var allSecretsFlag = &cli.BoolFlag{ var allSecretsFlag = &cli.BoolFlag{
Name: "all", Name: "all, a",
Aliases: []string{"a"},
Value: false,
Destination: &allSecrets, Destination: &allSecrets,
Usage: "Generate all secrets", Usage: "Generate all secrets",
} }
var appSecretGenerateCommand = &cli.Command{ var appSecretGenerateCommand = cli.Command{
Name: "generate", Name: "generate",
Aliases: []string{"g"}, Aliases: []string{"g"},
Usage: "Generate secrets", Usage: "Generate secrets",
ArgsUsage: "<secret> <version>", ArgsUsage: "<secret> <version>",
Flags: []cli.Flag{allSecretsFlag, internal.PassFlag}, Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
allSecretsFlag, internal.PassFlag,
},
Before: internal.SubCommandBefore,
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
if c.Args().Len() == 1 && !allSecrets { if len(c.Args()) == 1 && !allSecrets {
err := errors.New("missing arguments <secret>/<version> or '--all'") err := errors.New("missing arguments <secret>/<version> or '--all'")
internal.ShowSubcommandHelpAndError(c, err) internal.ShowSubcommandHelpAndError(c, err)
} }
@ -95,11 +99,16 @@ var appSecretGenerateCommand = &cli.Command{
}, },
} }
var appSecretInsertCommand = &cli.Command{ var appSecretInsertCommand = cli.Command{
Name: "insert", Name: "insert",
Aliases: []string{"i"}, Aliases: []string{"i"},
Usage: "Insert secret", Usage: "Insert secret",
Flags: []cli.Flag{internal.PassFlag}, Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.PassFlag,
},
Before: internal.SubCommandBefore,
ArgsUsage: "<app> <secret-name> <version> <data>", ArgsUsage: "<app> <secret-name> <version> <data>",
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
Description: ` Description: `
@ -117,7 +126,7 @@ Example:
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
if c.Args().Len() != 4 { if len(c.Args()) != 4 {
internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments?")) internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments?"))
} }
@ -140,11 +149,16 @@ Example:
}, },
} }
var appSecretRmCommand = &cli.Command{ var appSecretRmCommand = cli.Command{
Name: "remove", Name: "remove",
Usage: "Remove a secret", Aliases: []string{"rm"},
Aliases: []string{"rm"}, Usage: "Remove a secret",
Flags: []cli.Flag{allSecretsFlag, internal.PassFlag}, Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
allSecretsFlag, internal.PassFlag,
},
Before: internal.SubCommandBefore,
ArgsUsage: "<app> <secret-name>", ArgsUsage: "<app> <secret-name>",
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
Description: ` Description: `
@ -173,7 +187,7 @@ Example:
filters := filters.NewArgs() filters := filters.NewArgs()
filters.Add("name", app.StackName()) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -183,7 +197,7 @@ Example:
secretName := cont.Spec.Annotations.Name secretName := cont.Spec.Annotations.Name
parsed := secret.ParseGeneratedSecretName(secretName, app) parsed := secret.ParseGeneratedSecretName(secretName, app)
if allSecrets { if allSecrets {
if err := cl.SecretRemove(c.Context, secretName); err != nil { if err := cl.SecretRemove(context.Background(), secretName); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
logrus.Infof("deleted %s successfully from server", secretName) logrus.Infof("deleted %s successfully from server", secretName)
@ -197,7 +211,7 @@ Example:
} }
} else { } else {
if parsed == secretToRm { if parsed == secretToRm {
if err := cl.SecretRemove(c.Context, secretName); err != nil { if err := cl.SecretRemove(context.Background(), secretName); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -218,10 +232,15 @@ Example:
}, },
} }
var appSecretLsCommand = &cli.Command{ var appSecretLsCommand = cli.Command{
Name: "list", Name: "list",
Usage: "List all secrets",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
},
Before: internal.SubCommandBefore,
Usage: "List all secrets",
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
secrets := secret.ReadSecretEnvVars(app.Env) secrets := secret.ReadSecretEnvVars(app.Env)
@ -236,7 +255,7 @@ var appSecretLsCommand = &cli.Command{
filters := filters.NewArgs() filters := filters.NewArgs()
filters.Add("name", app.StackName()) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -272,12 +291,12 @@ var appSecretLsCommand = &cli.Command{
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
} }
var appSecretCommand = &cli.Command{ var appSecretCommand = cli.Command{
Name: "secret", Name: "secret",
Aliases: []string{"s"}, Aliases: []string{"s"},
Usage: "Manage app secrets", Usage: "Manage app secrets",
ArgsUsage: "<command>", ArgsUsage: "<command>",
Subcommands: []*cli.Command{ Subcommands: []cli.Command{
appSecretGenerateCommand, appSecretGenerateCommand,
appSecretInsertCommand, appSecretInsertCommand,
appSecretRmCommand, appSecretRmCommand,

View File

@ -1,18 +1,25 @@
package app package app
import ( import (
"context"
"coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/client"
stack "coopcloud.tech/abra/pkg/upstream/stack" stack "coopcloud.tech/abra/pkg/upstream/stack"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var appUndeployCommand = &cli.Command{ var appUndeployCommand = cli.Command{
Name: "undeploy", Name: "undeploy",
Aliases: []string{"un"}, Aliases: []string{"un"},
Usage: "Undeploy an app", Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
},
Before: internal.SubCommandBefore,
Usage: "Undeploy an app",
Description: ` Description: `
This does not destroy any of the application data. However, you should remain This does not destroy any of the application data. However, you should remain
vigilant, as your swarm installation will consider any previously attached 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) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -43,7 +50,7 @@ volumes as eligiblef or pruning once undeployed.
} }
rmOpts := stack.Remove{Namespaces: []string{app.StackName()}} 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) logrus.Fatal(err)
} }

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"context"
"fmt" "fmt"
"coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/cli/internal"
@ -13,19 +14,22 @@ import (
"coopcloud.tech/tagcmp" "coopcloud.tech/tagcmp"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var appUpgradeCommand = &cli.Command{ var appUpgradeCommand = cli.Command{
Name: "upgrade", Name: "upgrade",
Aliases: []string{"up"}, Aliases: []string{"up"},
Usage: "Upgrade an app", Usage: "Upgrade an app",
ArgsUsage: "<app>", ArgsUsage: "<app>",
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.ForceFlag, internal.ForceFlag,
internal.ChaosFlag, internal.ChaosFlag,
internal.NoDomainChecksFlag, internal.NoDomainChecksFlag,
}, },
Before: internal.SubCommandBefore,
Description: ` Description: `
This command supports upgrading an app. You can use it to choose and roll out a This command supports upgrading an app. You can use it to choose and roll out a
new upgrade to an existing app. new upgrade to an existing app.
@ -70,7 +74,7 @@ recipes.
logrus.Debugf("checking whether %s is already deployed", stackName) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -1,6 +1,8 @@
package app package app
import ( import (
"context"
"coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/client"
@ -9,7 +11,7 @@ import (
"coopcloud.tech/abra/pkg/upstream/stack" "coopcloud.tech/abra/pkg/upstream/stack"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// getImagePath returns the image name // getImagePath returns the image name
@ -28,10 +30,15 @@ func getImagePath(image string) (string, error) {
return path, nil return path, nil
} }
var appVersionCommand = &cli.Command{ var appVersionCommand = cli.Command{
Name: "version", Name: "version",
Aliases: []string{"v"}, Aliases: []string{"v"},
Usage: "Show app versions", Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
},
Before: internal.SubCommandBefore,
Usage: "Show app versions",
Description: ` Description: `
This command shows all information about versioning related to a deployed app. 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 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) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -1,24 +1,31 @@
package app package app
import ( import (
"context"
"coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var appVolumeListCommand = &cli.Command{ var appVolumeListCommand = cli.Command{
Name: "list", Name: "list",
Aliases: []string{"ls"},
Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
},
Before: internal.SubCommandBefore,
Usage: "List volumes associated with an app", Usage: "List volumes associated with an app",
Aliases: []string{"ls"},
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -45,7 +52,7 @@ var appVolumeListCommand = &cli.Command{
}, },
} }
var appVolumeRemoveCommand = &cli.Command{ var appVolumeRemoveCommand = cli.Command{
Name: "remove", Name: "remove",
Usage: "Remove volume(s) associated with an app", Usage: "Remove volume(s) associated with an app",
Description: ` Description: `
@ -62,12 +69,15 @@ Passing "--force" will select all volumes for removal. Be careful.
ArgsUsage: "<app>", ArgsUsage: "<app>",
Aliases: []string{"rm"}, Aliases: []string{"rm"},
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.ForceFlag, internal.ForceFlag,
}, },
Before: internal.SubCommandBefore,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -89,7 +99,7 @@ Passing "--force" will select all volumes for removal. Be careful.
volumesToRemove = volumeNames 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -101,12 +111,12 @@ Passing "--force" will select all volumes for removal. Be careful.
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
} }
var appVolumeCommand = &cli.Command{ var appVolumeCommand = cli.Command{
Name: "volume", Name: "volume",
Aliases: []string{"vl"}, Aliases: []string{"vl"},
Usage: "Manage app volumes", Usage: "Manage app volumes",
ArgsUsage: "<command>", ArgsUsage: "<command>",
Subcommands: []*cli.Command{ Subcommands: []cli.Command{
appVolumeListCommand, appVolumeListCommand,
appVolumeRemoveCommand, appVolumeRemoveCommand,
}, },

View File

@ -15,7 +15,7 @@ import (
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// CatalogueSkipList is all the repos that are not recipes. // CatalogueSkipList is all the repos that are not recipes.
@ -56,17 +56,20 @@ var CatalogueSkipList = map[string]bool{
"tyop": true, "tyop": true,
} }
var catalogueGenerateCommand = &cli.Command{ var catalogueGenerateCommand = cli.Command{
Name: "generate", Name: "generate",
Aliases: []string{"g"}, Aliases: []string{"g"},
Usage: "Generate the recipe catalogue", Usage: "Generate the recipe catalogue",
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.PublishFlag, internal.PublishFlag,
internal.DryFlag, internal.DryFlag,
internal.SkipUpdatesFlag, internal.SkipUpdatesFlag,
internal.RegistryUsernameFlag, internal.RegistryUsernameFlag,
internal.RegistryPasswordFlag, internal.RegistryPasswordFlag,
}, },
Before: internal.SubCommandBefore,
Description: ` Description: `
This command generates a new copy of the recipe catalogue which can be found on: 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. // CatalogueCommand defines the `abra catalogue` command and sub-commands.
var CatalogueCommand = &cli.Command{ var CatalogueCommand = cli.Command{
Name: "catalogue", Name: "catalogue",
Usage: "Manage the recipe catalogue", Usage: "Manage the recipe catalogue",
Aliases: []string{"c"}, Aliases: []string{"c"},
ArgsUsage: "<recipe>", ArgsUsage: "<recipe>",
Description: "This command helps recipe packagers interact with the recipe catalogue", Description: "This command helps recipe packagers interact with the recipe catalogue",
Subcommands: []*cli.Command{ Subcommands: []cli.Command{
catalogueGenerateCommand, catalogueGenerateCommand,
}, },
} }

View File

@ -16,16 +16,15 @@ import (
"coopcloud.tech/abra/cli/server" "coopcloud.tech/abra/cli/server"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/web" "coopcloud.tech/abra/pkg/web"
logrusStack "github.com/Gurpartap/logrus-stack"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// AutoCompleteCommand helps people set up auto-complete in their shells // AutoCompleteCommand helps people set up auto-complete in their shells
var AutoCompleteCommand = &cli.Command{ var AutoCompleteCommand = cli.Command{
Name: "autocomplete", Name: "autocomplete",
Usage: "Configure shell autocompletion (recommended)",
Aliases: []string{"ac"}, Aliases: []string{"ac"},
Usage: "Configure shell autocompletion (recommended)",
Description: ` Description: `
This command helps set up autocompletion in your shell by downloading the This command helps set up autocompletion in your shell by downloading the
relevant autocompletion files and laying out what additional information must relevant autocompletion files and laying out what additional information must
@ -43,6 +42,10 @@ Supported shells are as follows:
`, `,
ArgsUsage: "<shell>", ArgsUsage: "<shell>",
Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
},
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
shellType := c.Args().First() 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. // UpgradeCommand upgrades abra in-place.
var UpgradeCommand = &cli.Command{ var UpgradeCommand = cli.Command{
Name: "upgrade", Name: "upgrade",
Usage: "Upgrade Abra itself",
Aliases: []string{"u"}, Aliases: []string{"u"},
Usage: "Upgrade Abra itself",
Description: ` Description: `
This command allows you to upgrade Abra in-place with the latest stable or This command allows you to upgrade Abra in-place with the latest stable or
release candidate. release candidate.
@ -150,7 +153,7 @@ func newAbraApp(version, commit string) *cli.App {
|_| |_|
`, `,
Version: fmt.Sprintf("%s-%s", version, commit[:7]), Version: fmt.Sprintf("%s-%s", version, commit[:7]),
Commands: []*cli.Command{ Commands: []cli.Command{
app.AppCommand, app.AppCommand,
server.ServerCommand, server.ServerCommand,
recipe.RecipeCommand, recipe.RecipeCommand,
@ -159,11 +162,7 @@ func newAbraApp(version, commit string) *cli.App {
UpgradeCommand, UpgradeCommand,
AutoCompleteCommand, AutoCompleteCommand,
}, },
Flags: []cli.Flag{ Authors: []cli.Author{
internal.DebugFlag,
internal.NoInputFlag,
},
Authors: []*cli.Author{
// If you're looking at this and you hack on Abra and you're not listed // 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 // here, please do add yourself! This is a community project, let's show
// some love // some love
@ -178,13 +177,6 @@ func newAbraApp(version, commit string) *cli.App {
app.EnableBashCompletion = true app.EnableBashCompletion = true
app.Before = func(c *cli.Context) error { 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{ paths := []string{
config.ABRA_DIR, config.ABRA_DIR,
path.Join(config.SERVERS_DIR), path.Join(config.SERVERS_DIR),

View File

@ -1,7 +1,11 @@
package internal package internal
import ( 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 // Secrets stores the variable from SecretsFlag
@ -9,9 +13,7 @@ var Secrets bool
// SecretsFlag turns on/off automatically generating secrets // SecretsFlag turns on/off automatically generating secrets
var SecretsFlag = &cli.BoolFlag{ var SecretsFlag = &cli.BoolFlag{
Name: "secrets", Name: "secrets, ss",
Aliases: []string{"ss"},
Value: false,
Usage: "Automatically generate secrets", Usage: "Automatically generate secrets",
Destination: &Secrets, Destination: &Secrets,
} }
@ -21,9 +23,7 @@ var Pass bool
// PassFlag turns on/off storing generated secrets in pass // PassFlag turns on/off storing generated secrets in pass
var PassFlag = &cli.BoolFlag{ var PassFlag = &cli.BoolFlag{
Name: "pass", Name: "pass, p",
Aliases: []string{"p"},
Value: false,
Usage: "Store the generated secrets in a local pass store", Usage: "Store the generated secrets in a local pass store",
Destination: &Pass, Destination: &Pass,
} }
@ -33,9 +33,8 @@ var Context string
// ContextFlag is temp // ContextFlag is temp
var ContextFlag = &cli.StringFlag{ var ContextFlag = &cli.StringFlag{
Name: "context", Name: "context, c",
Value: "", Value: "",
Aliases: []string{"c"},
Destination: &Context, Destination: &Context,
} }
@ -44,9 +43,7 @@ var Force bool
// ForceFlag turns on/off force functionality. // ForceFlag turns on/off force functionality.
var ForceFlag = &cli.BoolFlag{ var ForceFlag = &cli.BoolFlag{
Name: "force", Name: "force, f",
Value: false,
Aliases: []string{"f"},
Usage: "Perform action without further prompt. Use with care!", Usage: "Perform action without further prompt. Use with care!",
Destination: &Force, Destination: &Force,
} }
@ -56,9 +53,7 @@ var Chaos bool
// ChaosFlag turns on/off chaos functionality. // ChaosFlag turns on/off chaos functionality.
var ChaosFlag = &cli.BoolFlag{ var ChaosFlag = &cli.BoolFlag{
Name: "chaos", Name: "chaos, ch",
Value: false,
Aliases: []string{"ch"},
Usage: "Deploy uncommitted recipes changes. Use with care!", Usage: "Deploy uncommitted recipes changes. Use with care!",
Destination: &Chaos, Destination: &Chaos,
} }
@ -68,18 +63,15 @@ var DNSProvider string
// DNSProviderFlag selects a DNS provider. // DNSProviderFlag selects a DNS provider.
var DNSProviderFlag = &cli.StringFlag{ var DNSProviderFlag = &cli.StringFlag{
Name: "provider", Name: "provider, p",
Value: "", Value: "",
Aliases: []string{"p"},
Usage: "DNS provider", Usage: "DNS provider",
Destination: &DNSProvider, Destination: &DNSProvider,
} }
var NoInput bool var NoInput bool
var NoInputFlag = &cli.BoolFlag{ var NoInputFlag = &cli.BoolFlag{
Name: "no-input", Name: "no-input, n",
Value: false,
Aliases: []string{"n"},
Usage: "Toggle non-interactive mode", Usage: "Toggle non-interactive mode",
Destination: &NoInput, Destination: &NoInput,
} }
@ -87,9 +79,8 @@ var NoInputFlag = &cli.BoolFlag{
var DNSType string var DNSType string
var DNSTypeFlag = &cli.StringFlag{ var DNSTypeFlag = &cli.StringFlag{
Name: "type", Name: "type, t",
Value: "", Value: "",
Aliases: []string{"t"},
Usage: "Domain name record type (e.g. A)", Usage: "Domain name record type (e.g. A)",
Destination: &DNSType, Destination: &DNSType,
} }
@ -97,9 +88,8 @@ var DNSTypeFlag = &cli.StringFlag{
var DNSName string var DNSName string
var DNSNameFlag = &cli.StringFlag{ var DNSNameFlag = &cli.StringFlag{
Name: "name", Name: "name, n",
Value: "", Value: "",
Aliases: []string{"n"},
Usage: "Domain name record name (e.g. mysubdomain)", Usage: "Domain name record name (e.g. mysubdomain)",
Destination: &DNSName, Destination: &DNSName,
} }
@ -107,18 +97,16 @@ var DNSNameFlag = &cli.StringFlag{
var DNSValue string var DNSValue string
var DNSValueFlag = &cli.StringFlag{ var DNSValueFlag = &cli.StringFlag{
Name: "value", Name: "value, v",
Value: "", Value: "",
Aliases: []string{"v"},
Usage: "Domain name record value (e.g. 192.168.1.1)", Usage: "Domain name record value (e.g. 192.168.1.1)",
Destination: &DNSValue, Destination: &DNSValue,
} }
var DNSTTL string var DNSTTL string
var DNSTTLFlag = &cli.StringFlag{ var DNSTTLFlag = &cli.StringFlag{
Name: "ttl", Name: "ttl, T",
Value: "600s", Value: "600s",
Aliases: []string{"T"},
Usage: "Domain name TTL value (seconds)", Usage: "Domain name TTL value (seconds)",
Destination: &DNSTTL, Destination: &DNSTTL,
} }
@ -126,9 +114,8 @@ var DNSTTLFlag = &cli.StringFlag{
var DNSPriority int var DNSPriority int
var DNSPriorityFlag = &cli.IntFlag{ var DNSPriorityFlag = &cli.IntFlag{
Name: "priority", Name: "priority, P",
Value: 10, Value: 10,
Aliases: []string{"P"},
Usage: "Domain name priority value", Usage: "Domain name priority value",
Destination: &DNSPriority, Destination: &DNSPriority,
} }
@ -136,8 +123,7 @@ var DNSPriorityFlag = &cli.IntFlag{
var ServerProvider string var ServerProvider string
var ServerProviderFlag = &cli.StringFlag{ var ServerProviderFlag = &cli.StringFlag{
Name: "provider", Name: "provider, p",
Aliases: []string{"p"},
Usage: "3rd party server provider", Usage: "3rd party server provider",
Destination: &ServerProvider, Destination: &ServerProvider,
} }
@ -145,9 +131,8 @@ var ServerProviderFlag = &cli.StringFlag{
var CapsulInstanceURL string var CapsulInstanceURL string
var CapsulInstanceURLFlag = &cli.StringFlag{ var CapsulInstanceURLFlag = &cli.StringFlag{
Name: "capsul-url", Name: "capsul-url, cu",
Value: "yolo.servers.coop", Value: "yolo.servers.coop",
Aliases: []string{"cu"},
Usage: "capsul instance URL", Usage: "capsul instance URL",
Destination: &CapsulInstanceURL, Destination: &CapsulInstanceURL,
} }
@ -155,9 +140,8 @@ var CapsulInstanceURLFlag = &cli.StringFlag{
var CapsulName string var CapsulName string
var CapsulNameFlag = &cli.StringFlag{ var CapsulNameFlag = &cli.StringFlag{
Name: "capsul-name", Name: "capsul-name, cn",
Value: "", Value: "",
Aliases: []string{"cn"},
Usage: "capsul name", Usage: "capsul name",
Destination: &CapsulName, Destination: &CapsulName,
} }
@ -165,9 +149,8 @@ var CapsulNameFlag = &cli.StringFlag{
var CapsulType string var CapsulType string
var CapsulTypeFlag = &cli.StringFlag{ var CapsulTypeFlag = &cli.StringFlag{
Name: "capsul-type", Name: "capsul-type, ct",
Value: "f1-xs", Value: "f1-xs",
Aliases: []string{"ct"},
Usage: "capsul type", Usage: "capsul type",
Destination: &CapsulType, Destination: &CapsulType,
} }
@ -175,38 +158,33 @@ var CapsulTypeFlag = &cli.StringFlag{
var CapsulImage string var CapsulImage string
var CapsulImageFlag = &cli.StringFlag{ var CapsulImageFlag = &cli.StringFlag{
Name: "capsul-image", Name: "capsul-image, ci",
Value: "debian10", Value: "debian10",
Aliases: []string{"ci"},
Usage: "capsul image", Usage: "capsul image",
Destination: &CapsulImage, Destination: &CapsulImage,
} }
var CapsulSSHKeys cli.StringSlice var CapsulSSHKeys cli.StringSlice
var CapsulSSHKeysFlag = &cli.StringSliceFlag{ var CapsulSSHKeysFlag = &cli.StringSliceFlag{
Name: "capsul-ssh-keys", Name: "capsul-ssh-keys, cs",
Aliases: []string{"cs"}, Usage: "capsul SSH key",
Usage: "capsul SSH key", Value: &CapsulSSHKeys,
Destination: &CapsulSSHKeys,
} }
var CapsulAPIToken string var CapsulAPIToken string
var CapsulAPITokenFlag = &cli.StringFlag{ var CapsulAPITokenFlag = &cli.StringFlag{
Name: "capsul-token", Name: "capsul-token, ca",
Aliases: []string{"ca"},
Usage: "capsul API token", Usage: "capsul API token",
EnvVars: []string{"CAPSUL_TOKEN"}, EnvVar: "CAPSUL_TOKEN",
Destination: &CapsulAPIToken, Destination: &CapsulAPIToken,
} }
var HetznerCloudName string var HetznerCloudName string
var HetznerCloudNameFlag = &cli.StringFlag{ var HetznerCloudNameFlag = &cli.StringFlag{
Name: "hetzner-name", Name: "hetzner-name, hn",
Value: "", Value: "",
Aliases: []string{"hn"},
Usage: "hetzner cloud name", Usage: "hetzner cloud name",
Destination: &HetznerCloudName, Destination: &HetznerCloudName,
} }
@ -214,8 +192,7 @@ var HetznerCloudNameFlag = &cli.StringFlag{
var HetznerCloudType string var HetznerCloudType string
var HetznerCloudTypeFlag = &cli.StringFlag{ var HetznerCloudTypeFlag = &cli.StringFlag{
Name: "hetzner-type", Name: "hetzner-type, ht",
Aliases: []string{"ht"},
Usage: "hetzner cloud type", Usage: "hetzner cloud type",
Destination: &HetznerCloudType, Destination: &HetznerCloudType,
Value: "cx11", Value: "cx11",
@ -224,8 +201,7 @@ var HetznerCloudTypeFlag = &cli.StringFlag{
var HetznerCloudImage string var HetznerCloudImage string
var HetznerCloudImageFlag = &cli.StringFlag{ var HetznerCloudImageFlag = &cli.StringFlag{
Name: "hetzner-image", Name: "hetzner-image, hi",
Aliases: []string{"hi"},
Usage: "hetzner cloud image", Usage: "hetzner cloud image",
Value: "debian-10", Value: "debian-10",
Destination: &HetznerCloudImage, Destination: &HetznerCloudImage,
@ -234,17 +210,15 @@ var HetznerCloudImageFlag = &cli.StringFlag{
var HetznerCloudSSHKeys cli.StringSlice var HetznerCloudSSHKeys cli.StringSlice
var HetznerCloudSSHKeysFlag = &cli.StringSliceFlag{ var HetznerCloudSSHKeysFlag = &cli.StringSliceFlag{
Name: "hetzner-ssh-keys", Name: "hetzner-ssh-keys, hs",
Aliases: []string{"hs"}, Usage: "hetzner cloud SSH keys (e.g. me@foo.com)",
Usage: "hetzner cloud SSH keys (e.g. me@foo.com)", Value: &HetznerCloudSSHKeys,
Destination: &HetznerCloudSSHKeys,
} }
var HetznerCloudLocation string var HetznerCloudLocation string
var HetznerCloudLocationFlag = &cli.StringFlag{ var HetznerCloudLocationFlag = &cli.StringFlag{
Name: "hetzner-location", Name: "hetzner-location, hl",
Aliases: []string{"hl"},
Usage: "hetzner cloud server location", Usage: "hetzner cloud server location",
Value: "hel1", Value: "hel1",
Destination: &HetznerCloudLocation, Destination: &HetznerCloudLocation,
@ -253,10 +227,9 @@ var HetznerCloudLocationFlag = &cli.StringFlag{
var HetznerCloudAPIToken string var HetznerCloudAPIToken string
var HetznerCloudAPITokenFlag = &cli.StringFlag{ var HetznerCloudAPITokenFlag = &cli.StringFlag{
Name: "hetzner-token", Name: "hetzner-token, ha",
Aliases: []string{"ha"},
Usage: "hetzner cloud API token", Usage: "hetzner cloud API token",
EnvVars: []string{"HCLOUD_TOKEN"}, EnvVar: "HCLOUD_TOKEN",
Destination: &HetznerCloudAPIToken, Destination: &HetznerCloudAPIToken,
} }
@ -265,9 +238,7 @@ var Debug bool
// DebugFlag turns on/off verbose logging down to the DEBUG level. // DebugFlag turns on/off verbose logging down to the DEBUG level.
var DebugFlag = &cli.BoolFlag{ var DebugFlag = &cli.BoolFlag{
Name: "debug", Name: "debug, d",
Aliases: []string{"d"},
Value: false,
Destination: &Debug, Destination: &Debug,
Usage: "Show DEBUG messages", Usage: "Show DEBUG messages",
} }
@ -278,60 +249,48 @@ var RC bool
// RCFlag chooses the latest release candidate for install // RCFlag chooses the latest release candidate for install
var RCFlag = &cli.BoolFlag{ var RCFlag = &cli.BoolFlag{
Name: "rc", Name: "rc",
Value: false,
Destination: &RC, Destination: &RC,
Usage: "Insatll the latest release candidate", Usage: "Insatll the latest release candidate",
} }
var Major bool var Major bool
var MajorFlag = &cli.BoolFlag{ var MajorFlag = &cli.BoolFlag{
Name: "major", Name: "major, ma, x",
Usage: "Increase the major part of the version", Usage: "Increase the major part of the version",
Value: false,
Aliases: []string{"ma", "x"},
Destination: &Major, Destination: &Major,
} }
var Minor bool var Minor bool
var MinorFlag = &cli.BoolFlag{ var MinorFlag = &cli.BoolFlag{
Name: "minor", Name: "minor, mi, y",
Usage: "Increase the minor part of the version", Usage: "Increase the minor part of the version",
Value: false,
Aliases: []string{"mi", "y"},
Destination: &Minor, Destination: &Minor,
} }
var Patch bool var Patch bool
var PatchFlag = &cli.BoolFlag{ var PatchFlag = &cli.BoolFlag{
Name: "patch", Name: "patch, pa, z",
Usage: "Increase the patch part of the version", Usage: "Increase the patch part of the version",
Value: false,
Aliases: []string{"pa", "z"},
Destination: &Patch, Destination: &Patch,
} }
var Dry bool var Dry bool
var DryFlag = &cli.BoolFlag{ var DryFlag = &cli.BoolFlag{
Name: "dry-run", Name: "dry-run, d",
Usage: "Only reports changes that would be made", Usage: "Only reports changes that would be made",
Value: false,
Aliases: []string{"d"},
Destination: &Dry, Destination: &Dry,
} }
var Publish bool var Publish bool
var PublishFlag = &cli.BoolFlag{ var PublishFlag = &cli.BoolFlag{
Name: "publish", Name: "publish, p",
Usage: "Publish changes to git.coopcloud.tech", Usage: "Publish changes to git.coopcloud.tech",
Value: false,
Aliases: []string{"p"},
Destination: &Publish, Destination: &Publish,
} }
var Domain string var Domain string
var DomainFlag = &cli.StringFlag{ var DomainFlag = &cli.StringFlag{
Name: "domain", Name: "domain, dn",
Aliases: []string{"d"},
Value: "", Value: "",
Usage: "Choose a domain name", Usage: "Choose a domain name",
Destination: &Domain, Destination: &Domain,
@ -339,8 +298,7 @@ var DomainFlag = &cli.StringFlag{
var NewAppServer string var NewAppServer string
var NewAppServerFlag = &cli.StringFlag{ var NewAppServerFlag = &cli.StringFlag{
Name: "server", Name: "server, s",
Aliases: []string{"s"},
Value: "", Value: "",
Usage: "Show apps of a specific server", Usage: "Show apps of a specific server",
Destination: &NewAppServer, Destination: &NewAppServer,
@ -348,8 +306,7 @@ var NewAppServerFlag = &cli.StringFlag{
var NewAppName string var NewAppName string
var NewAppNameFlag = &cli.StringFlag{ var NewAppNameFlag = &cli.StringFlag{
Name: "app-name", Name: "app-name, a",
Aliases: []string{"a"},
Value: "", Value: "",
Usage: "Choose an app name", Usage: "Choose an app name",
Destination: &NewAppName, Destination: &NewAppName,
@ -357,92 +314,74 @@ var NewAppNameFlag = &cli.StringFlag{
var NoDomainChecks bool var NoDomainChecks bool
var NoDomainChecksFlag = &cli.BoolFlag{ var NoDomainChecksFlag = &cli.BoolFlag{
Name: "no-domain-checks", Name: "no-domain-checks, nd",
Aliases: []string{"nd"},
Value: false,
Usage: "Disable app domain sanity checks", Usage: "Disable app domain sanity checks",
Destination: &NoDomainChecks, Destination: &NoDomainChecks,
} }
var StdErrOnly bool var StdErrOnly bool
var StdErrOnlyFlag = &cli.BoolFlag{ var StdErrOnlyFlag = &cli.BoolFlag{
Name: "stderr", Name: "stderr, s",
Aliases: []string{"s"},
Value: false,
Usage: "Only tail stderr", Usage: "Only tail stderr",
Destination: &StdErrOnly, Destination: &StdErrOnly,
} }
var AutoDNSRecord bool var AutoDNSRecord bool
var AutoDNSRecordFlag = &cli.BoolFlag{ var AutoDNSRecordFlag = &cli.BoolFlag{
Name: "auto", Name: "auto, a",
Aliases: []string{"a"},
Value: false,
Usage: "Automatically configure DNS records", Usage: "Automatically configure DNS records",
Destination: &AutoDNSRecord, Destination: &AutoDNSRecord,
} }
var DontWaitConverge bool var DontWaitConverge bool
var DontWaitConvergeFlag = &cli.BoolFlag{ var DontWaitConvergeFlag = &cli.BoolFlag{
Name: "no-converge-checks", Name: "no-converge-checks, nc",
Aliases: []string{"nc"},
Value: false,
Usage: "Don't wait for converge logic checks", Usage: "Don't wait for converge logic checks",
Destination: &DontWaitConverge, Destination: &DontWaitConverge,
} }
var Watch bool var Watch bool
var WatchFlag = &cli.BoolFlag{ var WatchFlag = &cli.BoolFlag{
Name: "watch", Name: "watch, w",
Aliases: []string{"w"},
Value: false,
Usage: "Watch status by polling repeatedly", Usage: "Watch status by polling repeatedly",
Destination: &Watch, Destination: &Watch,
} }
var OnlyErrors bool var OnlyErrors bool
var OnlyErrorFlag = &cli.BoolFlag{ var OnlyErrorFlag = &cli.BoolFlag{
Name: "errors", Name: "errors, e",
Aliases: []string{"e"},
Value: false,
Usage: "Only show errors", Usage: "Only show errors",
Destination: &OnlyErrors, Destination: &OnlyErrors,
} }
var SkipUpdates bool var SkipUpdates bool
var SkipUpdatesFlag = &cli.BoolFlag{ var SkipUpdatesFlag = &cli.BoolFlag{
Name: "skip-updates", Name: "skip-updates, s",
Aliases: []string{"s"},
Value: false,
Usage: "Skip updating recipe repositories", Usage: "Skip updating recipe repositories",
Destination: &SkipUpdates, Destination: &SkipUpdates,
} }
var RegistryUsername string var RegistryUsername string
var RegistryUsernameFlag = &cli.StringFlag{ var RegistryUsernameFlag = &cli.StringFlag{
Name: "username", Name: "username, user",
Aliases: []string{"user"},
Value: "", Value: "",
Usage: "Registry username", Usage: "Registry username",
EnvVars: []string{"REGISTRY_USERNAME"}, EnvVar: "REGISTRY_USERNAME",
Destination: &RegistryUsername, Destination: &RegistryUsername,
} }
var RegistryPassword string var RegistryPassword string
var RegistryPasswordFlag = &cli.StringFlag{ var RegistryPasswordFlag = &cli.StringFlag{
Name: "password", Name: "password, pass",
Aliases: []string{"pass"},
Value: "", Value: "",
Usage: "Registry password", Usage: "Registry password",
EnvVars: []string{"REGISTRY_PASSWORD"}, EnvVar: "REGISTRY_PASSWORD",
Destination: &RegistryUsername, Destination: &RegistryUsername,
} }
var AllTags bool var AllTags bool
var AllTagsFlag = &cli.BoolFlag{ var AllTagsFlag = &cli.BoolFlag{
Name: "all-tags", Name: "all-tags, a",
Aliases: []string{"a"},
Value: false,
Usage: "List all tags, not just upgrades", Usage: "List all tags, not just upgrades",
Destination: &AllTags, Destination: &AllTags,
} }
@ -495,3 +434,15 @@ Host foo.coopcloud.tech
Good luck! 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
}

View File

@ -1,6 +1,7 @@
package internal package internal
import ( import (
"context"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -17,7 +18,7 @@ import (
"coopcloud.tech/abra/pkg/upstream/stack" "coopcloud.tech/abra/pkg/upstream/stack"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// DeployAction is the main command-line action for this package // 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()) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -4,7 +4,7 @@ import (
"os" "os"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// ShowSubcommandHelpAndError exits the program on error, logs the error to the // ShowSubcommandHelpAndError exits the program on error, logs the error to the

View File

@ -12,7 +12,7 @@ import (
"coopcloud.tech/abra/pkg/ssh" "coopcloud.tech/abra/pkg/ssh"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// AppSecrets represents all app secrest // AppSecrets represents all app secrest

View File

@ -12,7 +12,7 @@ import (
"coopcloud.tech/abra/pkg/ssh" "coopcloud.tech/abra/pkg/ssh"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// AppName is used for configuring app name programmatically // 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 // ValidateSubCmdFlags ensures flag order conforms to correct order
func ValidateSubCmdFlags(c *cli.Context) bool { func ValidateSubCmdFlags(c *cli.Context) bool {
for argIdx, arg := range c.Args().Slice() { for argIdx, arg := range c.Args() {
if !strings.HasPrefix(arg, "--") { if !strings.HasPrefix(arg, "--") {
for _, flag := range c.Args().Slice()[argIdx:] { for _, flag := range c.Args()[argIdx:] {
if strings.HasPrefix(flag, "--") { if strings.HasPrefix(flag, "--") {
return false return false
} }
@ -369,7 +369,7 @@ func EnsureNewCapsulVPSFlags(c *cli.Context) error {
if err := survey.AskOne(prompt, &CapsulSSHKeys); err != nil { if err := survey.AskOne(prompt, &CapsulSSHKeys); err != nil {
return err return err
} }
CapsulSSHKeys = *cli.NewStringSlice(strings.Split(sshKeys, ",")...) CapsulSSHKeys = cli.StringSlice(strings.Split(sshKeys, ","))
} }
if CapsulAPIToken == "" && !NoInput { if CapsulAPIToken == "" && !NoInput {
@ -448,7 +448,7 @@ func EnsureNewHetznerCloudVPSFlags(c *cli.Context) error {
if err := survey.AskOne(prompt, &sshKeys); err != nil { if err := survey.AskOne(prompt, &sshKeys); err != nil {
return err return err
} }
HetznerCloudSSHKeys = *cli.NewStringSlice(strings.Split(sshKeys, ",")...) HetznerCloudSSHKeys = cli.StringSlice(strings.Split(sshKeys, ","))
} }
if !NoInput { if !NoInput {

View File

@ -9,15 +9,20 @@ import (
"coopcloud.tech/abra/pkg/lint" "coopcloud.tech/abra/pkg/lint"
recipePkg "coopcloud.tech/abra/pkg/recipe" recipePkg "coopcloud.tech/abra/pkg/recipe"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var recipeLintCommand = &cli.Command{ var recipeLintCommand = cli.Command{
Name: "lint", Name: "lint",
Usage: "Lint a recipe", Usage: "Lint a recipe",
Aliases: []string{"l"}, Aliases: []string{"l"},
ArgsUsage: "<recipe>", ArgsUsage: "<recipe>",
Flags: []cli.Flag{internal.OnlyErrorFlag}, Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.OnlyErrorFlag,
},
Before: internal.SubCommandBefore,
BashComplete: autocomplete.RecipeNameComplete, BashComplete: autocomplete.RecipeNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
recipe := internal.ValidateRecipe(c) recipe := internal.ValidateRecipe(c)

View File

@ -6,28 +6,31 @@ import (
"strconv" "strconv"
"strings" "strings"
"coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var pattern string var pattern string
var patternFlag = &cli.StringFlag{ var patternFlag = &cli.StringFlag{
Name: "pattern", Name: "pattern, p",
Value: "", Value: "",
Aliases: []string{"p"},
Usage: "Simple string to filter recipes", Usage: "Simple string to filter recipes",
Destination: &pattern, Destination: &pattern,
} }
var recipeListCommand = &cli.Command{ var recipeListCommand = cli.Command{
Name: "list", Name: "list",
Usage: "List available recipes", Usage: "List available recipes",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
patternFlag, patternFlag,
}, },
Before: internal.SubCommandBefore,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
catl, err := recipe.ReadRecipeCatalogue() catl, err := recipe.ReadRecipeCatalogue()
if err != nil { if err != nil {

View File

@ -13,7 +13,7 @@ import (
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/git" "coopcloud.tech/abra/pkg/git"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// recipeMetadata is the recipe metadata for the README.md // recipeMetadata is the recipe metadata for the README.md
@ -30,10 +30,15 @@ type recipeMetadata struct {
SSO string SSO string
} }
var recipeNewCommand = &cli.Command{ var recipeNewCommand = cli.Command{
Name: "new", Name: "new",
Aliases: []string{"n"},
Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
},
Before: internal.SubCommandBefore,
Usage: "Create a new recipe", Usage: "Create a new recipe",
Aliases: []string{"n"},
ArgsUsage: "<recipe>", ArgsUsage: "<recipe>",
Description: ` Description: `
This command creates a new recipe. This command creates a new recipe.

View File

@ -1,15 +1,15 @@
package recipe package recipe
import ( import (
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// RecipeCommand defines all recipe related sub-commands. // RecipeCommand defines all recipe related sub-commands.
var RecipeCommand = &cli.Command{ var RecipeCommand = cli.Command{
Name: "recipe", Name: "recipe",
Aliases: []string{"r"},
Usage: "Manage recipes", Usage: "Manage recipes",
ArgsUsage: "<recipe>", ArgsUsage: "<recipe>",
Aliases: []string{"r"},
Description: ` Description: `
A recipe is a blueprint for an app. It is a bunch of config files which 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 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 manner. Abra supports convenient automation for recipe maintainenace, see the
"abra recipe upgrade", "abra recipe sync" and "abra recipe release" commands. "abra recipe upgrade", "abra recipe sync" and "abra recipe release" commands.
`, `,
Subcommands: []*cli.Command{ Subcommands: []cli.Command{
recipeListCommand, recipeListCommand,
recipeVersionCommand, recipeVersionCommand,
recipeReleaseCommand, recipeReleaseCommand,

View File

@ -18,13 +18,13 @@ import (
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var recipeReleaseCommand = &cli.Command{ var recipeReleaseCommand = cli.Command{
Name: "release", Name: "release",
Usage: "Release a new recipe version",
Aliases: []string{"rl"}, Aliases: []string{"rl"},
Usage: "Release a new recipe version",
ArgsUsage: "<recipe> [<version>]", ArgsUsage: "<recipe> [<version>]",
Description: ` Description: `
This command is used to specify a new version of a recipe. These versions are 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. your SSH keys configured on your account.
`, `,
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.DryFlag, internal.DryFlag,
internal.MajorFlag, internal.MajorFlag,
internal.MinorFlag, internal.MinorFlag,
internal.PatchFlag, internal.PatchFlag,
internal.PublishFlag, internal.PublishFlag,
}, },
Before: internal.SubCommandBefore,
BashComplete: autocomplete.RecipeNameComplete, BashComplete: autocomplete.RecipeNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
recipe := internal.ValidateRecipeWithPrompt(c) recipe := internal.ValidateRecipeWithPrompt(c)

View File

@ -13,20 +13,23 @@ import (
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var recipeSyncCommand = &cli.Command{ var recipeSyncCommand = cli.Command{
Name: "sync", Name: "sync",
Usage: "Sync recipe version label",
Aliases: []string{"s"}, Aliases: []string{"s"},
Usage: "Sync recipe version label",
ArgsUsage: "<recipe> [<version>]", ArgsUsage: "<recipe> [<version>]",
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.DryFlag, internal.DryFlag,
internal.MajorFlag, internal.MajorFlag,
internal.MinorFlag, internal.MinorFlag,
internal.PatchFlag, internal.PatchFlag,
}, },
Before: internal.SubCommandBefore,
Description: ` Description: `
This command will generate labels for the main recipe service (i.e. by This command will generate labels for the main recipe service (i.e. by
convention, the service named 'app') which corresponds to the following format: convention, the service named 'app') which corresponds to the following format:

View File

@ -17,7 +17,7 @@ import (
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
type imgPin struct { type imgPin struct {
@ -25,10 +25,10 @@ type imgPin struct {
version tagcmp.Tag version tagcmp.Tag
} }
var recipeUpgradeCommand = &cli.Command{ var recipeUpgradeCommand = cli.Command{
Name: "upgrade", Name: "upgrade",
Usage: "Upgrade recipe image tags",
Aliases: []string{"u"}, Aliases: []string{"u"},
Usage: "Upgrade recipe image tags",
Description: ` Description: `
This command reads and attempts to parse all image tags within the given This command reads and attempts to parse all image tags within the given
<recipe> configuration and prompt with more recent tags to upgrade to. It will <recipe> 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, BashComplete: autocomplete.RecipeNameComplete,
ArgsUsage: "<recipe>", ArgsUsage: "<recipe>",
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.PatchFlag, internal.PatchFlag,
internal.MinorFlag, internal.MinorFlag,
internal.MajorFlag, internal.MajorFlag,
internal.AllTagsFlag, internal.AllTagsFlag,
}, },
Before: internal.SubCommandBefore,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
recipe := internal.ValidateRecipeWithPrompt(c) recipe := internal.ValidateRecipeWithPrompt(c)

View File

@ -6,14 +6,19 @@ import (
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
recipePkg "coopcloud.tech/abra/pkg/recipe" recipePkg "coopcloud.tech/abra/pkg/recipe"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var recipeVersionCommand = &cli.Command{ var recipeVersionCommand = cli.Command{
Name: "versions", Name: "versions",
Usage: "List recipe versions", Aliases: []string{"v"},
Aliases: []string{"v"}, Usage: "List recipe versions",
ArgsUsage: "<recipe>", ArgsUsage: "<recipe>",
Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
},
Before: internal.SubCommandBefore,
BashComplete: autocomplete.RecipeNameComplete, BashComplete: autocomplete.RecipeNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
recipe := internal.ValidateRecipe(c) recipe := internal.ValidateRecipe(c)

View File

@ -1,6 +1,7 @@
package record package record
import ( import (
"context"
"fmt" "fmt"
"strconv" "strconv"
@ -9,18 +10,21 @@ import (
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
"github.com/libdns/gandi" "github.com/libdns/gandi"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// RecordListCommand lists domains. // RecordListCommand lists domains.
var RecordListCommand = &cli.Command{ var RecordListCommand = cli.Command{
Name: "list", Name: "list",
Usage: "List domain name records", Usage: "List domain name records",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
ArgsUsage: "<zone>", ArgsUsage: "<zone>",
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.DNSProviderFlag, internal.DNSProviderFlag,
}, },
Before: internal.SubCommandBefore,
Description: ` Description: `
This command lists all domain name records managed by a 3rd party provider for This command lists all domain name records managed by a 3rd party provider for
a specific zone. 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) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -1,6 +1,7 @@
package record package record
import ( import (
"context"
"fmt" "fmt"
"strconv" "strconv"
@ -11,16 +12,18 @@ import (
"github.com/libdns/gandi" "github.com/libdns/gandi"
"github.com/libdns/libdns" "github.com/libdns/libdns"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// RecordNewCommand creates a new domain name record. // RecordNewCommand creates a new domain name record.
var RecordNewCommand = &cli.Command{ var RecordNewCommand = cli.Command{
Name: "new", Name: "new",
Usage: "Create a new domain record", Usage: "Create a new domain record",
Aliases: []string{"n"}, Aliases: []string{"n"},
ArgsUsage: "<zone>", ArgsUsage: "<zone>",
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.DNSProviderFlag, internal.DNSProviderFlag,
internal.DNSTypeFlag, internal.DNSTypeFlag,
internal.DNSNameFlag, internal.DNSNameFlag,
@ -29,6 +32,7 @@ var RecordNewCommand = &cli.Command{
internal.DNSPriorityFlag, internal.DNSPriorityFlag,
internal.AutoDNSRecordFlag, internal.AutoDNSRecordFlag,
}, },
Before: internal.SubCommandBefore,
Description: ` Description: `
This command creates a new domain name record for a specific zone. 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 record.Priority = internal.DNSPriority
} }
records, err := provider.GetRecords(c.Context, zone) records, err := provider.GetRecords(context.Background(), zone)
if err != nil { if err != nil {
logrus.Fatal(err) 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( createdRecords, err := provider.SetRecords(
c.Context, context.Background(),
zone, zone,
[]libdns.Record{record}, []libdns.Record{record},
) )
@ -196,7 +200,7 @@ func autoConfigure(c *cli.Context, provider *gandi.Provider, zone, ipv4 string)
table := formatter.CreateTable(tableCol) table := formatter.CreateTable(tableCol)
for _, record := range records { for _, record := range records {
existingRecords, err := provider.GetRecords(c.Context, zone) existingRecords, err := provider.GetRecords(context.Background(), zone)
if err != nil { if err != nil {
return err return err
} }
@ -216,7 +220,7 @@ func autoConfigure(c *cli.Context, provider *gandi.Provider, zone, ipv4 string)
} }
createdRecords, err := provider.SetRecords( createdRecords, err := provider.SetRecords(
c.Context, context.Background(),
zone, zone,
[]libdns.Record{record}, []libdns.Record{record},
) )

View File

@ -1,11 +1,11 @@
package record package record
import ( import (
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// RecordCommand supports managing DNS entries. // RecordCommand supports managing DNS entries.
var RecordCommand = &cli.Command{ var RecordCommand = cli.Command{
Name: "record", Name: "record",
Usage: "Manage domain name records", Usage: "Manage domain name records",
Aliases: []string{"rc"}, Aliases: []string{"rc"},
@ -30,7 +30,7 @@ to implement new provider support easily.
https://pkg.go.dev/github.com/libdns/libdns https://pkg.go.dev/github.com/libdns/libdns
`, `,
Subcommands: []*cli.Command{ Subcommands: []cli.Command{
RecordListCommand, RecordListCommand,
RecordNewCommand, RecordNewCommand,
RecordRemoveCommand, RecordRemoveCommand,

View File

@ -1,6 +1,7 @@
package record package record
import ( import (
"context"
"fmt" "fmt"
"strconv" "strconv"
@ -11,20 +12,23 @@ import (
"github.com/libdns/gandi" "github.com/libdns/gandi"
"github.com/libdns/libdns" "github.com/libdns/libdns"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// RecordRemoveCommand lists domains. // RecordRemoveCommand lists domains.
var RecordRemoveCommand = &cli.Command{ var RecordRemoveCommand = cli.Command{
Name: "remove", Name: "remove",
Usage: "Remove a domain name record", Usage: "Remove a domain name record",
Aliases: []string{"rm"}, Aliases: []string{"rm"},
ArgsUsage: "<zone>", ArgsUsage: "<zone>",
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.DNSProviderFlag, internal.DNSProviderFlag,
internal.DNSTypeFlag, internal.DNSTypeFlag,
internal.DNSNameFlag, internal.DNSNameFlag,
}, },
Before: internal.SubCommandBefore,
Description: ` Description: `
This command removes a domain name record for a specific zone. 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) logrus.Fatal(err)
} }
records, err := provider.GetRecords(c.Context, zone) records, err := provider.GetRecords(context.Background(), zone)
if err != nil { if err != nil {
logrus.Fatal(err) 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 { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -1,6 +1,7 @@
package server package server
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"os" "os"
@ -22,7 +23,7 @@ import (
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
dockerClient "github.com/docker/docker/client" dockerClient "github.com/docker/docker/client"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var ( var (
@ -47,26 +48,21 @@ source for this script can be seen here:
var local bool var local bool
var localFlag = &cli.BoolFlag{ var localFlag = &cli.BoolFlag{
Name: "local", Name: "local, l",
Aliases: []string{"l"},
Value: false,
Usage: "Use local server", Usage: "Use local server",
Destination: &local, Destination: &local,
} }
var provision bool var provision bool
var provisionFlag = &cli.BoolFlag{ var provisionFlag = &cli.BoolFlag{
Name: "provision", Name: "provision, p",
Aliases: []string{"p"},
Value: false,
Usage: "Provision server so it can deploy apps", Usage: "Provision server so it can deploy apps",
Destination: &provision, Destination: &provision,
} }
var sshAuth string var sshAuth string
var sshAuthFlag = &cli.StringFlag{ var sshAuthFlag = &cli.StringFlag{
Name: "ssh-auth", Name: "ssh-auth, sh",
Aliases: []string{"sh"},
Value: "identity-file", Value: "identity-file",
Usage: "Select SSH authentication method (identity-file, password)", Usage: "Select SSH authentication method (identity-file, password)",
Destination: &sshAuth, Destination: &sshAuth,
@ -74,18 +70,14 @@ var sshAuthFlag = &cli.StringFlag{
var askSudoPass bool var askSudoPass bool
var askSudoPassFlag = &cli.BoolFlag{ var askSudoPassFlag = &cli.BoolFlag{
Name: "ask-sudo-pass", Name: "ask-sudo-pass, as",
Aliases: []string{"as"},
Value: false,
Usage: "Ask for sudo password", Usage: "Ask for sudo password",
Destination: &askSudoPass, Destination: &askSudoPass,
} }
var traefik bool var traefik bool
var traefikFlag = &cli.BoolFlag{ var traefikFlag = &cli.BoolFlag{
Name: "traefik", Name: "traefik, t",
Aliases: []string{"t"},
Value: false,
Usage: "Deploy traefik", Usage: "Deploy traefik",
Destination: &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 { func initSwarmLocal(c *cli.Context, cl *dockerClient.Client, domainName string) error {
initReq := swarm.InitRequest{ListenAddr: "0.0.0.0:2377"} 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") || if strings.Contains(err.Error(), "is already part of a swarm") ||
strings.Contains(err.Error(), "must specify a listening address") { strings.Contains(err.Error(), "must specify a listening address") {
logrus.Infof("swarm mode already initialised on %s", domainName) 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"} 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") { if !strings.Contains(err.Error(), "proxy already exists") {
return err return err
} }
@ -354,7 +346,7 @@ func initSwarm(c *cli.Context, cl *dockerClient.Client, domainName string) error
ListenAddr: "0.0.0.0:2377", ListenAddr: "0.0.0.0:2377",
AdvertiseAddr: ipv4, 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") || if strings.Contains(err.Error(), "is already part of a swarm") ||
strings.Contains(err.Error(), "must specify a listening address") { strings.Contains(err.Error(), "must specify a listening address") {
logrus.Infof("swarm mode already initialised on %s", domainName) 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"} 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") { if !strings.Contains(err.Error(), "proxy already exists") {
return err return err
} }
@ -414,9 +406,10 @@ func deployTraefik(c *cli.Context, cl *dockerClient.Client, domainName string) e
return nil return nil
} }
var serverAddCommand = &cli.Command{ var serverAddCommand = cli.Command{
Name: "add", Name: "add",
Usage: "Add a server to your configuration", Aliases: []string{"a"},
Usage: "Add a server to your configuration",
Description: ` Description: `
This command adds a new server to your configuration so that it can be managed 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 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. You may omit flags to avoid performing this provisioning logic.
`, `,
Aliases: []string{"a"},
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
localFlag, localFlag,
provisionFlag, provisionFlag,
sshAuthFlag, sshAuthFlag,
askSudoPassFlag, askSudoPassFlag,
traefikFlag, traefikFlag,
internal.DebugFlag,
internal.NoInputFlag,
}, },
Before: internal.SubCommandBefore,
ArgsUsage: "<domain> [<user>] [<port>]", ArgsUsage: "<domain> [<user>] [<port>]",
Action: func(c *cli.Context) error { 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 <domain> and --local together") err := errors.New("cannot use <domain> and --local together")
internal.ShowSubcommandHelpAndError(c, err) 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) cleanUp(domainName)
logrus.Fatalf("couldn't make a remote docker connection to %s? use --provision/-p to attempt to install", domainName) logrus.Fatalf("couldn't make a remote docker connection to %s? use --provision/-p to attempt to install", domainName)
} }

View File

@ -3,20 +3,24 @@ package server
import ( import (
"strings" "strings"
"coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/context" "coopcloud.tech/abra/pkg/context"
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
"github.com/docker/cli/cli/connhelper/ssh" "github.com/docker/cli/cli/connhelper/ssh"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var serverListCommand = &cli.Command{ var serverListCommand = cli.Command{
Name: "list", Name: "list",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
Usage: "List managed servers", Usage: "List managed servers",
ArgsUsage: " ", Flags: []cli.Flag{
HideHelp: true, internal.DebugFlag,
internal.NoInputFlag,
},
Before: internal.SubCommandBefore,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
dockerContextStore := context.NewDefaultDockerContextStore() dockerContextStore := context.NewDefaultDockerContextStore()
contexts, err := dockerContextStore.Store.List() contexts, err := dockerContextStore.Store.List()

View File

@ -1,6 +1,7 @@
package server package server
import ( import (
"context"
"fmt" "fmt"
"strings" "strings"
@ -10,7 +11,7 @@ import (
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/hetznercloud/hcloud-go/hcloud" "github.com/hetznercloud/hcloud-go/hcloud"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
func newHetznerCloudVPS(c *cli.Context) error { func newHetznerCloudVPS(c *cli.Context) error {
@ -27,7 +28,7 @@ func newHetznerCloudVPS(c *cli.Context) error {
continue continue
} }
sshKey, _, err := client.SSHKey.GetByName(c.Context, sshKey) sshKey, _, err := client.SSHKey.GetByName(context.Background(), sshKey)
if err != nil { if err != nil {
return err return err
} }
@ -72,7 +73,7 @@ func newHetznerCloudVPS(c *cli.Context) error {
logrus.Fatal("exiting as requested") logrus.Fatal("exiting as requested")
} }
res, _, err := client.Server.Create(c.Context, serverOpts) res, _, err := client.Server.Create(context.Background(), serverOpts)
if err != nil { if err != nil {
return err return err
} }
@ -200,7 +201,7 @@ bar.example.com).
return nil return nil
} }
var serverNewCommand = &cli.Command{ var serverNewCommand = cli.Command{
Name: "new", Name: "new",
Aliases: []string{"n"}, Aliases: []string{"n"},
Usage: "Create a new server using a 3rd party provider", 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. Where "$provider_TOKEN" is the expected env var format.
`, `,
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.ServerProviderFlag, internal.ServerProviderFlag,
internal.DebugFlag,
internal.NoInputFlag,
// Capsul // Capsul
internal.CapsulInstanceURLFlag, internal.CapsulInstanceURLFlag,
@ -240,6 +246,7 @@ Where "$provider_TOKEN" is the expected env var format.
internal.HetznerCloudLocationFlag, internal.HetznerCloudLocationFlag,
internal.HetznerCloudAPITokenFlag, internal.HetznerCloudAPITokenFlag,
}, },
Before: internal.SubCommandBefore,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
if err := internal.EnsureServerProvider(); err != nil { if err := internal.EnsureServerProvider(); err != nil {
logrus.Fatal(err) logrus.Fatal(err)

View File

@ -1,6 +1,7 @@
package server package server
import ( import (
"context"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -12,14 +13,12 @@ import (
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/hetznercloud/hcloud-go/hcloud" "github.com/hetznercloud/hcloud-go/hcloud"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
var rmServer bool var rmServer bool
var rmServerFlag = &cli.BoolFlag{ var rmServerFlag = &cli.BoolFlag{
Name: "server", Name: "server, s",
Aliases: []string{"s"},
Value: false,
Usage: "remove the actual server also", Usage: "remove the actual server also",
Destination: &rmServer, Destination: &rmServer,
} }
@ -50,7 +49,7 @@ func rmHetznerCloudVPS(c *cli.Context) error {
client := hcloud.NewClient(hcloud.WithToken(internal.HetznerCloudAPIToken)) 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 { if err != nil {
return err return err
} }
@ -89,7 +88,7 @@ destroyed.
logrus.Fatal("exiting as requested") logrus.Fatal("exiting as requested")
} }
_, err = client.Server.Delete(c.Context, server) _, err = client.Server.Delete(context.Background(), server)
if err != nil { if err != nil {
return err return err
} }
@ -99,7 +98,7 @@ destroyed.
return nil return nil
} }
var serverRemoveCommand = &cli.Command{ var serverRemoveCommand = cli.Command{
Name: "remove", Name: "remove",
Aliases: []string{"rm"}, Aliases: []string{"rm"},
ArgsUsage: "[<server>]", ArgsUsage: "[<server>]",
@ -116,6 +115,8 @@ underlying client connection context. This server will then be lost in time,
like tears in rain. like tears in rain.
`, `,
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
rmServerFlag, rmServerFlag,
internal.ServerProviderFlag, internal.ServerProviderFlag,
@ -123,6 +124,7 @@ like tears in rain.
internal.HetznerCloudNameFlag, internal.HetznerCloudNameFlag,
internal.HetznerCloudAPITokenFlag, internal.HetznerCloudAPITokenFlag,
}, },
Before: internal.SubCommandBefore,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
serverName := c.Args().Get(1) serverName := c.Args().Get(1)
if serverName != "" { if serverName != "" {

View File

@ -1,11 +1,11 @@
package server package server
import ( import (
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// ServerCommand defines the `abra server` command and its subcommands // ServerCommand defines the `abra server` command and its subcommands
var ServerCommand = &cli.Command{ var ServerCommand = cli.Command{
Name: "server", Name: "server",
Aliases: []string{"s"}, Aliases: []string{"s"},
Usage: "Manage servers", 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 add". Abra can provision servers so that they are ready to deploy Co-op Cloud
apps, see available flags on "server add" for more. apps, see available flags on "server add" for more.
`, `,
Subcommands: []*cli.Command{ Subcommands: []cli.Command{
serverNewCommand, serverNewCommand,
serverAddCommand, serverAddCommand,
serverListCommand, serverListCommand,

2
go.mod
View File

@ -20,7 +20,6 @@ require (
github.com/schollz/progressbar/v3 v3.8.5 github.com/schollz/progressbar/v3 v3.8.5
github.com/schultz-is/passgen v1.0.1 github.com/schultz-is/passgen v1.0.1
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1
github.com/urfave/cli/v2 v2.3.0
gotest.tools/v3 v3.1.0 gotest.tools/v3 v3.1.0
) )
@ -43,6 +42,7 @@ require (
github.com/morikuni/aec v1.0.0 // indirect github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/runc v1.0.2 // indirect github.com/opencontainers/runc v1.0.2 // indirect
github.com/theupdateframework/notary v0.7.0 // indirect github.com/theupdateframework/notary v0.7.0 // indirect
github.com/urfave/cli v1.22.5
github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e

6
go.sum
View File

@ -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 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.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.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 v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= 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 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.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= 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.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.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.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.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.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -6,7 +6,7 @@ import (
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli"
) )
// AppNameComplete copletes app names // AppNameComplete copletes app names