Compare commits

..

5 Commits

Author SHA1 Message Date
6998298d32 chore: publish next tag 0.4.0-alpha-rc8
Some checks reported errors
continuous-integration/drone/push Build was killed
2022-03-30 16:28:55 +02:00
323f4467c8 fix: filtering requires case-by-case handling
Some checks reported errors
continuous-integration/drone/pr Build was killed
continuous-integration/drone/push Build was killed
See https://github.com/moby/moby/issues/32985.
2022-03-30 16:25:38 +02:00
e8e41850b5 fix: pass args to local function invocations too
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2022-03-30 11:31:16 +02:00
0e23ec53d7 refactor!: simple validation only 2022-03-30 11:30:51 +02:00
b943a8b9b1 feat: allow choosing user on remote commands 2022-03-30 11:30:36 +02:00
8 changed files with 76 additions and 32 deletions

View File

@ -32,6 +32,14 @@ var localCmdFlag = &cli.BoolFlag{
Destination: &localCmd, Destination: &localCmd,
} }
var remoteUser string
var remoteUserFlag = &cli.StringFlag{
Name: "user, u",
Value: "",
Usage: "User to run command within a service context",
Destination: &remoteUser,
}
var appCmdCommand = cli.Command{ var appCmdCommand = cli.Command{
Name: "command", Name: "command",
Aliases: []string{"cmd"}, Aliases: []string{"cmd"},
@ -52,18 +60,15 @@ Example:
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.DebugFlag, internal.DebugFlag,
localCmdFlag, localCmdFlag,
remoteUserFlag,
}, },
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
Before: internal.SubCommandBefore, Before: internal.SubCommandBefore,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
if len(c.Args()) <= 2 && !localCmd { if localCmd && remoteUser != "" {
internal.ShowSubcommandHelpAndError(c, errors.New("missing <service>/<command>? did you mean to pass --local?")) internal.ShowSubcommandHelpAndError(c, errors.New("cannot use --local & <user> together"))
}
if len(c.Args()) > 2 && localCmd {
internal.ShowSubcommandHelpAndError(c, errors.New("cannot specify <service> and --local together"))
} }
abraSh := path.Join(config.RECIPES_DIR, app.Recipe, "abra.sh") abraSh := path.Join(config.RECIPES_DIR, app.Recipe, "abra.sh")
@ -74,6 +79,20 @@ Example:
logrus.Fatal(err) logrus.Fatal(err)
} }
var parsedCmdArgs string
var cmdArgsIdx int
var hasCmdArgs bool
for idx, arg := range c.Args() {
if arg == "--" {
cmdArgsIdx = idx
hasCmdArgs = true
}
if hasCmdArgs && idx > cmdArgsIdx {
parsedCmdArgs += fmt.Sprintf("%s ", c.Args().Get(idx))
}
}
if localCmd { if localCmd {
cmdName := c.Args().Get(1) cmdName := c.Args().Get(1)
if err := ensureCommand(abraSh, app.Recipe, cmdName); err != nil { if err := ensureCommand(abraSh, app.Recipe, cmdName); err != nil {
@ -82,8 +101,17 @@ Example:
logrus.Debugf("--local detected, running %s on local work station", cmdName) logrus.Debugf("--local detected, running %s on local work station", cmdName)
sourceAndExec := fmt.Sprintf("TARGET=local; APP_NAME=%s; . %s; %s", app.StackName(), abraSh, cmdName) var sourceAndExec string
if hasCmdArgs {
logrus.Debugf("parsed following command arguments: %s", parsedCmdArgs)
sourceAndExec = fmt.Sprintf("TARGET=local; APP_NAME=%s; . %s; %s %s", app.StackName(), abraSh, cmdName, parsedCmdArgs)
} else {
logrus.Debug("did not detect any command arguments")
sourceAndExec = fmt.Sprintf("TARGET=local; APP_NAME=%s; . %s; %s", app.StackName(), abraSh, cmdName)
}
cmd := exec.Command("/bin/sh", "-c", sourceAndExec) cmd := exec.Command("/bin/sh", "-c", sourceAndExec)
if err := internal.RunCmd(cmd); err != nil { if err := internal.RunCmd(cmd); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -113,20 +141,6 @@ Example:
logrus.Debugf("running command %s within the context of %s_%s", cmdName, app.StackName(), targetServiceName) logrus.Debugf("running command %s within the context of %s_%s", cmdName, app.StackName(), targetServiceName)
var parsedCmdArgs string
var cmdArgsIdx int
var hasCmdArgs bool
for idx, arg := range c.Args() {
if arg == "--" {
cmdArgsIdx = idx
hasCmdArgs = true
}
if hasCmdArgs && idx > cmdArgsIdx {
parsedCmdArgs += fmt.Sprintf("%s ", c.Args().Get(idx))
}
}
if hasCmdArgs { if hasCmdArgs {
logrus.Debugf("parsed following command arguments: %s", parsedCmdArgs) logrus.Debugf("parsed following command arguments: %s", parsedCmdArgs)
} else { } else {
@ -200,6 +214,11 @@ func runCmdRemote(app config.App, abraSh, serviceName, cmdName, cmdArgs string)
Tty: true, Tty: true,
} }
if remoteUser != "" {
logrus.Debugf("running command with user %s", remoteUser)
execCreateOpts.User = remoteUser
}
// FIXME: avoid instantiating a new CLI // FIXME: avoid instantiating a new CLI
dcli, err := command.NewDockerCli() dcli, err := command.NewDockerCli()
if err != nil { if err != nil {

View File

@ -30,7 +30,7 @@ var logOpts = types.ContainerLogsOptions{
// stackLogs lists logs for all stack services // stackLogs lists logs for all stack services
func stackLogs(c *cli.Context, app config.App, client *dockerClient.Client) { func stackLogs(c *cli.Context, app config.App, client *dockerClient.Client) {
filters, err := app.Filters() filters, err := app.Filters(true, false)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -66,7 +66,7 @@ var appPsCommand = cli.Command{
// showPSOutput renders ps output. // showPSOutput renders ps output.
func showPSOutput(c *cli.Context, app config.App, cl *dockerClient.Client) { func showPSOutput(c *cli.Context, app config.App, cl *dockerClient.Client) {
filters, err := app.Filters() filters, err := app.Filters(true, true)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -65,7 +65,7 @@ var appRemoveCommand = cli.Command{
logrus.Fatalf("%s is still deployed. Run \"abra app undeploy %s\"", app.Name, app.Name) logrus.Fatalf("%s is still deployed. Run \"abra app undeploy %s\"", app.Name, app.Name)
} }
fs, err := app.Filters() fs, err := app.Filters(false, false)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -114,6 +114,11 @@ var appRemoveCommand = cli.Command{
logrus.Info("no secrets to remove") logrus.Info("no secrets to remove")
} }
fs, err = app.Filters(false, true)
if err != nil {
logrus.Fatal(err)
}
volumeListOKBody, err := cl.VolumeList(context.Background(), fs) volumeListOKBody, err := cl.VolumeList(context.Background(), fs)
volumeList := volumeListOKBody.Volumes volumeList := volumeListOKBody.Volumes
if err != nil { if err != nil {

View File

@ -216,7 +216,7 @@ Example:
logrus.Fatal(err) logrus.Fatal(err)
} }
filters, err := app.Filters() filters, err := app.Filters(false, false)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -293,7 +293,7 @@ var appSecretLsCommand = cli.Command{
logrus.Fatal(err) logrus.Fatal(err)
} }
filters, err := app.Filters() filters, err := app.Filters(false, false)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -26,7 +26,7 @@ var appVolumeListCommand = cli.Command{
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
filters, err := app.Filters() filters, err := app.Filters(false, true)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -80,7 +80,7 @@ Passing "--force/-f" will select all volumes for removal. Be careful.
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
filters, err := app.Filters() filters, err := app.Filters(false, true)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -64,8 +64,13 @@ func (a App) StackName() string {
return stackName return stackName
} }
// Filters retrieves exact app filters for querying the container runtime. // Filters retrieves exact app filters for querying the container runtime. Due
func (a App) Filters() (filters.Args, error) { // to upstream issues, filtering works different depending on what you're
// querying. So, for example, secrets don't work with regex! The caller needs
// to implement their own validation that the right secrets are matched. In
// order to handle these cases, we provide the `appendServiceNames` /
// `exactMatch` modifiers.
func (a App) Filters(appendServiceNames, exactMatch bool) (filters.Args, error) {
filters := filters.NewArgs() filters := filters.NewArgs()
composeFiles, err := GetAppComposeFiles(a.Recipe, a.Env) composeFiles, err := GetAppComposeFiles(a.Recipe, a.Env)
@ -80,7 +85,22 @@ func (a App) Filters() (filters.Args, error) {
} }
for _, service := range compose.Services { for _, service := range compose.Services {
filter := fmt.Sprintf("^%s_%s", a.StackName(), service.Name) var filter string
if appendServiceNames {
if exactMatch {
filter = fmt.Sprintf("^%s_%s", a.StackName(), service.Name)
} else {
filter = fmt.Sprintf("%s_%s", a.StackName(), service.Name)
}
} else {
if exactMatch {
filter = fmt.Sprintf("^%s", a.StackName())
} else {
filter = fmt.Sprintf("%s", a.StackName())
}
}
filters.Add("name", filter) filters.Add("name", filter)
} }

View File

@ -2,7 +2,7 @@
ABRA_VERSION="0.3.0-alpha" ABRA_VERSION="0.3.0-alpha"
ABRA_RELEASE_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$ABRA_VERSION" ABRA_RELEASE_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$ABRA_VERSION"
RC_VERSION="0.4.0-alpha-rc7" RC_VERSION="0.4.0-alpha-rc8"
RC_VERSION_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$RC_VERSION" RC_VERSION_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$RC_VERSION"
for arg in "$@"; do for arg in "$@"; do