forked from toolshed/abra
		
	
		
			
				
	
	
		
			123 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package app
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 	"strings"
 | |
| 
 | |
| 	"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/i18n"
 | |
| 	"coopcloud.tech/abra/pkg/log"
 | |
| 	"coopcloud.tech/abra/pkg/upstream/container"
 | |
| 	"github.com/docker/cli/cli/command"
 | |
| 	containertypes "github.com/docker/docker/api/types/container"
 | |
| 	"github.com/docker/docker/api/types/filters"
 | |
| 	"github.com/spf13/cobra"
 | |
| )
 | |
| 
 | |
| // translators: `abra app run` aliases. use a comma separated list of aliases
 | |
| // with no spaces in between
 | |
| var appRunAliases = i18n.G("r")
 | |
| 
 | |
| var AppRunCommand = &cobra.Command{
 | |
| 	// translators: `app run` command
 | |
| 	Use:     i18n.G("run <domain> <service> <cmd> [[args] [flags] | [flags] -- [args]]"),
 | |
| 	Aliases: strings.Split(appRunAliases, ","),
 | |
| 	// translators: Short description for `app run` command
 | |
| 	Short: i18n.G("Run a command inside a service container"),
 | |
| 	Example: i18n.G(`  # run <cmd> with args/flags
 | |
|   abra app run 1312.net app -- ls -lha
 | |
| 
 | |
|   # run <cmd> without args/flags
 | |
|   abra app run 1312.net app bash --user nobody
 | |
| 
 | |
|   # run <cmd> 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 := containertypes.ExecOptions{
 | |
| 			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,
 | |
| 		i18n.G("no-tty"),
 | |
| 		i18n.G("t"),
 | |
| 		false,
 | |
| 		i18n.G("do not request a TTY"),
 | |
| 	)
 | |
| 
 | |
| 	AppRunCommand.Flags().StringVarP(
 | |
| 		&runAsUser,
 | |
| 		i18n.G("user"),
 | |
| 		i18n.G("u"),
 | |
| 		"",
 | |
| 		i18n.G("run command as user"),
 | |
| 	)
 | |
| }
 |