@@ -16,62 +16,65 @@ import (
1616 "github.com/spf13/cobra"
1717)
1818
19- type execOptions struct {
20- detachKeys string
21- interactive bool
22- tty bool
23- detach bool
24- user string
25- privileged bool
26- env opts.ListOpts
27- workdir string
28- container string
29- command []string
30- envFile opts.ListOpts
19+ // ExecOptions group options for `exec` command
20+ type ExecOptions struct {
21+ DetachKeys string
22+ Interactive bool
23+ TTY bool
24+ Detach bool
25+ User string
26+ Privileged bool
27+ Env opts.ListOpts
28+ Workdir string
29+ Container string
30+ Command []string
31+ EnvFile opts.ListOpts
3132}
3233
33- func newExecOptions () execOptions {
34- return execOptions {
35- env : opts .NewListOpts (opts .ValidateEnv ),
36- envFile : opts .NewListOpts (nil ),
34+ // NewExecOptions initialize an ExecOptions
35+ func NewExecOptions () ExecOptions {
36+ return ExecOptions {
37+ Env : opts .NewListOpts (opts .ValidateEnv ),
38+ EnvFile : opts .NewListOpts (nil ),
3739 }
3840}
3941
4042// NewExecCommand creates a new cobra.Command for `docker exec`
4143func NewExecCommand (dockerCli command.Cli ) * cobra.Command {
42- options := newExecOptions ()
44+ options := NewExecOptions ()
4345
4446 cmd := & cobra.Command {
4547 Use : "exec [OPTIONS] CONTAINER COMMAND [ARG...]" ,
4648 Short : "Run a command in a running container" ,
4749 Args : cli .RequiresMinArgs (2 ),
4850 RunE : func (cmd * cobra.Command , args []string ) error {
49- options .container = args [0 ]
50- options .command = args [1 :]
51- return runExec (dockerCli , options )
51+ options .Container = args [0 ]
52+ options .Command = args [1 :]
53+ return RunExec (dockerCli , options )
5254 },
5355 }
5456
5557 flags := cmd .Flags ()
5658 flags .SetInterspersed (false )
5759
58- flags .StringVarP (& options .detachKeys , "detach-keys" , "" , "" , "Override the key sequence for detaching a container" )
59- flags .BoolVarP (& options .interactive , "interactive" , "i" , false , "Keep STDIN open even if not attached" )
60- flags .BoolVarP (& options .tty , "tty" , "t" , false , "Allocate a pseudo-TTY" )
61- flags .BoolVarP (& options .detach , "detach" , "d" , false , "Detached mode: run command in the background" )
62- flags .StringVarP (& options .user , "user" , "u" , "" , "Username or UID (format: <name|uid>[:<group|gid>])" )
63- flags .BoolVarP (& options .privileged , "privileged" , "" , false , "Give extended privileges to the command" )
64- flags .VarP (& options .env , "env" , "e" , "Set environment variables" )
60+ flags .StringVarP (& options .DetachKeys , "detach-keys" , "" , "" , "Override the key sequence for detaching a container" )
61+ flags .BoolVarP (& options .Interactive , "interactive" , "i" , false , "Keep STDIN open even if not attached" )
62+ flags .BoolVarP (& options .TTY , "tty" , "t" , false , "Allocate a pseudo-TTY" )
63+ flags .BoolVarP (& options .Detach , "detach" , "d" , false , "Detached mode: run command in the background" )
64+ flags .StringVarP (& options .User , "user" , "u" , "" , "Username or UID (format: <name|uid>[:<group|gid>])" )
65+ flags .BoolVarP (& options .Privileged , "privileged" , "" , false , "Give extended privileges to the command" )
66+ flags .VarP (& options .Env , "env" , "e" , "Set environment variables" )
6567 flags .SetAnnotation ("env" , "version" , []string {"1.25" })
66- flags .Var (& options .envFile , "env-file" , "Read in a file of environment variables" )
68+ flags .Var (& options .EnvFile , "env-file" , "Read in a file of environment variables" )
6769 flags .SetAnnotation ("env-file" , "version" , []string {"1.25" })
68- flags .StringVarP (& options .workdir , "workdir" , "w" , "" , "Working directory inside the container" )
70+ flags .StringVarP (& options .Workdir , "workdir" , "w" , "" , "Working directory inside the container" )
6971 flags .SetAnnotation ("workdir" , "version" , []string {"1.35" })
7072
7173 return cmd
7274}
7375
74- func runExec (dockerCli command.Cli , options execOptions ) error {
76+ // RunExec executes an `exec` command
77+ func RunExec (dockerCli command.Cli , options ExecOptions ) error {
7578 execConfig , err := parseExec (options , dockerCli .ConfigFile ())
7679 if err != nil {
7780 return err
@@ -84,7 +87,7 @@ func runExec(dockerCli command.Cli, options execOptions) error {
8487 // otherwise if we error out we will leak execIDs on the server (and
8588 // there's no easy way to clean those up). But also in order to make "not
8689 // exist" errors take precedence we do a dummy inspect first.
87- if _ , err := client .ContainerInspect (ctx , options .container ); err != nil {
90+ if _ , err := client .ContainerInspect (ctx , options .Container ); err != nil {
8891 return err
8992 }
9093 if ! execConfig .Detach {
@@ -93,7 +96,7 @@ func runExec(dockerCli command.Cli, options execOptions) error {
9396 }
9497 }
9598
96- response , err := client .ContainerExecCreate (ctx , options .container , * execConfig )
99+ response , err := client .ContainerExecCreate (ctx , options .Container , * execConfig )
97100 if err != nil {
98101 return err
99102 }
@@ -195,33 +198,33 @@ func getExecExitStatus(ctx context.Context, client apiclient.ContainerAPIClient,
195198
196199// parseExec parses the specified args for the specified command and generates
197200// an ExecConfig from it.
198- func parseExec (execOpts execOptions , configFile * configfile.ConfigFile ) (* types.ExecConfig , error ) {
201+ func parseExec (execOpts ExecOptions , configFile * configfile.ConfigFile ) (* types.ExecConfig , error ) {
199202 execConfig := & types.ExecConfig {
200- User : execOpts .user ,
201- Privileged : execOpts .privileged ,
202- Tty : execOpts .tty ,
203- Cmd : execOpts .command ,
204- Detach : execOpts .detach ,
205- WorkingDir : execOpts .workdir ,
203+ User : execOpts .User ,
204+ Privileged : execOpts .Privileged ,
205+ Tty : execOpts .TTY ,
206+ Cmd : execOpts .Command ,
207+ Detach : execOpts .Detach ,
208+ WorkingDir : execOpts .Workdir ,
206209 }
207210
208211 // collect all the environment variables for the container
209212 var err error
210- if execConfig .Env , err = opts .ReadKVEnvStrings (execOpts .envFile .GetAll (), execOpts .env .GetAll ()); err != nil {
213+ if execConfig .Env , err = opts .ReadKVEnvStrings (execOpts .EnvFile .GetAll (), execOpts .Env .GetAll ()); err != nil {
211214 return nil , err
212215 }
213216
214217 // If -d is not set, attach to everything by default
215- if ! execOpts .detach {
218+ if ! execOpts .Detach {
216219 execConfig .AttachStdout = true
217220 execConfig .AttachStderr = true
218- if execOpts .interactive {
221+ if execOpts .Interactive {
219222 execConfig .AttachStdin = true
220223 }
221224 }
222225
223- if execOpts .detachKeys != "" {
224- execConfig .DetachKeys = execOpts .detachKeys
226+ if execOpts .DetachKeys != "" {
227+ execConfig .DetachKeys = execOpts .DetachKeys
225228 } else {
226229 execConfig .DetachKeys = configFile .DetachKeys
227230 }
0 commit comments