package app import ( "context" "fmt" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" containerPkg "coopcloud.tech/abra/pkg/container" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/upstream/container" "github.com/docker/cli/cli/command" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/spf13/cobra" ) var AppRunCommand = &cobra.Command{ Use: "run [[args] [flags] | [flags] -- [args]]", Aliases: []string{"r"}, Short: "Run a command inside a service container", Example: ` # run with args/flags abra app run 1312.net app -- ls -lha # run without args/flags abra app run 1312.net app bash --user nobody # run with both kinds of args/flags abra app run 1312.net app --user nobody -- ls -lha`, Args: cobra.MinimumNArgs(3), ValidArgsFunction: func( cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { switch l := len(args); l { case 0: return autocomplete.AppNameComplete() case 1: return autocomplete.ServiceNameComplete(args[0]) case 2: return autocomplete.CommandNameComplete(args[0]) default: return nil, cobra.ShellCompDirectiveError } }, Run: func(cmd *cobra.Command, args []string) { app := internal.ValidateApp(args) cl, err := client.New(app.Server) if err != nil { log.Fatal(err) } serviceName := args[1] stackAndServiceName := fmt.Sprintf("^%s_%s", app.StackName(), serviceName) filters := filters.NewArgs() filters.Add("name", stackAndServiceName) targetContainer, err := containerPkg.GetContainer(context.Background(), cl, filters, false) if err != nil { log.Fatal(err) } userCmd := args[2:] execCreateOpts := types.ExecConfig{ AttachStderr: true, AttachStdin: true, AttachStdout: true, Cmd: userCmd, Detach: false, Tty: true, } if runAsUser != "" { execCreateOpts.User = runAsUser } if noTTY { execCreateOpts.Tty = false } dcli, err := command.NewDockerCli() if err != nil { log.Fatal(err) } if _, err := container.RunExec(dcli, cl, targetContainer.ID, &execCreateOpts); err != nil { log.Fatal(err) } }, } var ( noTTY bool runAsUser string ) func init() { AppRunCommand.Flags().BoolVarP(&noTTY, "no-tty", "t", false, "do not request a TTY", ) AppRunCommand.Flags().StringVarP( &runAsUser, "user", "u", "", "run command as user", ) }