mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Exec: Add ability to set environment variables
Keeping the current behavior for exec, i.e., inheriting variables from main process. New variables will be added to current ones. If there's already a variable with that name it will be overwritten. Example of usage: docker exec -it -e TERM=vt100 <container> top Closes #24355. Signed-off-by: Jonh Wendell <jonh.wendell@redhat.com>
This commit is contained in:
		
							parent
							
								
									15fb3fd9da
								
							
						
					
					
						commit
						e03bf1221e
					
				
					 10 changed files with 46 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -11,7 +11,9 @@ import (
 | 
			
		|||
	"github.com/docker/docker/cli"
 | 
			
		||||
	"github.com/docker/docker/cli/command"
 | 
			
		||||
	apiclient "github.com/docker/docker/client"
 | 
			
		||||
	options "github.com/docker/docker/opts"
 | 
			
		||||
	"github.com/docker/docker/pkg/promise"
 | 
			
		||||
	runconfigopts "github.com/docker/docker/runconfig/opts"
 | 
			
		||||
	"github.com/spf13/cobra"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -22,11 +24,19 @@ type execOptions struct {
 | 
			
		|||
	detach      bool
 | 
			
		||||
	user        string
 | 
			
		||||
	privileged  bool
 | 
			
		||||
	env         *options.ListOpts
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newExecOptions() *execOptions {
 | 
			
		||||
	var values []string
 | 
			
		||||
	return &execOptions{
 | 
			
		||||
		env: options.NewListOptsRef(&values, runconfigopts.ValidateEnv),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewExecCommand creats a new cobra.Command for `docker exec`
 | 
			
		||||
func NewExecCommand(dockerCli *command.DockerCli) *cobra.Command {
 | 
			
		||||
	var opts execOptions
 | 
			
		||||
	opts := newExecOptions()
 | 
			
		||||
 | 
			
		||||
	cmd := &cobra.Command{
 | 
			
		||||
		Use:   "exec [OPTIONS] CONTAINER COMMAND [ARG...]",
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +45,7 @@ func NewExecCommand(dockerCli *command.DockerCli) *cobra.Command {
 | 
			
		|||
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
			
		||||
			container := args[0]
 | 
			
		||||
			execCmd := args[1:]
 | 
			
		||||
			return runExec(dockerCli, &opts, container, execCmd)
 | 
			
		||||
			return runExec(dockerCli, opts, container, execCmd)
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +58,7 @@ func NewExecCommand(dockerCli *command.DockerCli) *cobra.Command {
 | 
			
		|||
	flags.BoolVarP(&opts.detach, "detach", "d", false, "Detached mode: run command in the background")
 | 
			
		||||
	flags.StringVarP(&opts.user, "user", "u", "", "Username or UID (format: <name|uid>[:<group|gid>])")
 | 
			
		||||
	flags.BoolVarP(&opts.privileged, "privileged", "", false, "Give extended privileges to the command")
 | 
			
		||||
	flags.VarP(opts.env, "env", "e", "Set environment variables")
 | 
			
		||||
 | 
			
		||||
	return cmd
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -188,5 +199,9 @@ func parseExec(opts *execOptions, container string, execCmd []string) (*types.Ex
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if opts.env != nil {
 | 
			
		||||
		execConfig.Env = opts.env.GetAll()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return execConfig, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1274,7 +1274,7 @@ _docker_exec() {
 | 
			
		|||
 | 
			
		||||
	case "$cur" in
 | 
			
		||||
		-*)
 | 
			
		||||
			COMPREPLY=( $( compgen -W "--detach -d --detach-keys --help --interactive -i --privileged -t --tty -u --user" -- "$cur" ) )
 | 
			
		||||
			COMPREPLY=( $( compgen -W "--detach -d --detach-keys -e --env --help --interactive -i --privileged -t --tty -u --user" -- "$cur" ) )
 | 
			
		||||
			;;
 | 
			
		||||
		*)
 | 
			
		||||
			__docker_complete_containers_running
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1679,6 +1679,7 @@ __docker_subcommand() {
 | 
			
		|||
                $opts_help \
 | 
			
		||||
                $opts_attach_exec_run_start \
 | 
			
		||||
                "($help -d --detach)"{-d,--detach}"[Detached mode: leave the container running in the background]" \
 | 
			
		||||
                "($help -e --env)"{-e,--env}"[Set environment variables]" \
 | 
			
		||||
                "($help -i --interactive)"{-i,--interactive}"[Keep stdin open even if not attached]" \
 | 
			
		||||
                "($help)--privileged[Give extended Linux capabilities to the command]" \
 | 
			
		||||
                "($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]" \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -127,7 +127,7 @@ func (d *Daemon) ContainerExecCreate(name string, config *types.ExecConfig) (str
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	execConfig.Env = utils.ReplaceOrAppendEnvValues(container.CreateDaemonEnvironment(config.Tty, linkedEnv), execConfig.Env)
 | 
			
		||||
	execConfig.Env = utils.ReplaceOrAppendEnvValues(container.CreateDaemonEnvironment(config.Tty, linkedEnv), config.Env)
 | 
			
		||||
	if len(execConfig.User) == 0 {
 | 
			
		||||
		execConfig.User = container.Config.User
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -131,6 +131,7 @@ This section lists each version from latest to oldest.  Each listing includes a
 | 
			
		|||
* `POST /containers/create` now takes `StopTimeout` field.
 | 
			
		||||
* `POST /services/create` and `POST /services/(id or name)/update` now accept `Monitor` and `MaxFailureRatio` parameters, which control the response to failures during service updates.
 | 
			
		||||
* `GET /networks/(name)` now returns `Created`.
 | 
			
		||||
* `POST /containers/(id or name)/exec` now accepts an `Env` field, which holds a list of environment variables to be set in the context of the command execution.
 | 
			
		||||
 | 
			
		||||
### v1.24 API changes
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3151,6 +3151,10 @@ Sets up an exec instance in a running container `id`
 | 
			
		|||
      "AttachStderr": true,
 | 
			
		||||
      "Cmd": ["sh"],
 | 
			
		||||
      "DetachKeys": "ctrl-p,ctrl-q",
 | 
			
		||||
      "Env": [
 | 
			
		||||
        "FOO=bar",
 | 
			
		||||
        "BAZ=quux"
 | 
			
		||||
      ],
 | 
			
		||||
      "Privileged": true,
 | 
			
		||||
      "Tty": true,
 | 
			
		||||
      "User": "123:456"
 | 
			
		||||
| 
						 | 
				
			
			@ -3175,6 +3179,7 @@ Sets up an exec instance in a running container `id`
 | 
			
		|||
        container. Format is a single character `[a-Z]` or `ctrl-<value>`
 | 
			
		||||
        where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`.
 | 
			
		||||
-   **Tty** - Boolean value to allocate a pseudo-TTY.
 | 
			
		||||
-   **Env** - A list of environment variables in the form of `["VAR=value", ...]`
 | 
			
		||||
-   **Cmd** - Command to run specified as a string or an array of strings.
 | 
			
		||||
-   **Privileged** - Boolean value, runs the exec process with extended privileges.
 | 
			
		||||
-   **User** - A string value specifying the user, and optionally, group to run
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@ Run a command in a running container
 | 
			
		|||
Options:
 | 
			
		||||
  -d, --detach         Detached mode: run command in the background
 | 
			
		||||
      --detach-keys    Override the key sequence for detaching a container
 | 
			
		||||
  -e, --env=[]         Set environment variables
 | 
			
		||||
      --help           Print usage
 | 
			
		||||
  -i, --interactive    Keep STDIN open even if not attached
 | 
			
		||||
      --privileged     Give extended privileges to the command
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -119,6 +119,17 @@ func (s *DockerSuite) TestExecEnv(c *check.C) {
 | 
			
		|||
	c.Assert(out, checker.Contains, "HOME=/root")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *DockerSuite) TestExecSetEnv(c *check.C) {
 | 
			
		||||
	testRequires(c, DaemonIsLinux)
 | 
			
		||||
	runSleepingContainer(c, "-e", "HOME=/root", "-d", "--name", "testing")
 | 
			
		||||
	c.Assert(waitRun("testing"), check.IsNil)
 | 
			
		||||
 | 
			
		||||
	out, _ := dockerCmd(c, "exec", "-e", "HOME=/another", "-e", "ABC=xyz", "testing", "env")
 | 
			
		||||
	c.Assert(out, checker.Not(checker.Contains), "HOME=/root")
 | 
			
		||||
	c.Assert(out, checker.Contains, "HOME=/another")
 | 
			
		||||
	c.Assert(out, checker.Contains, "ABC=xyz")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *DockerSuite) TestExecExitStatus(c *check.C) {
 | 
			
		||||
	runSleepingContainer(c, "-d", "--name", "top")
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendly
 | 
			
		|||
	sp := spec.Process
 | 
			
		||||
	sp.Args = specp.Args
 | 
			
		||||
	sp.Terminal = specp.Terminal
 | 
			
		||||
	if specp.Env != nil {
 | 
			
		||||
	if len(specp.Env) > 0 {
 | 
			
		||||
		sp.Env = specp.Env
 | 
			
		||||
	}
 | 
			
		||||
	if specp.Cwd != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ docker-exec - Run a command in a running container
 | 
			
		|||
**docker exec**
 | 
			
		||||
[**-d**|**--detach**]
 | 
			
		||||
[**--detach-keys**[=*[]*]]
 | 
			
		||||
[**-e**|**--env**[=*[]*]]
 | 
			
		||||
[**--help**]
 | 
			
		||||
[**-i**|**--interactive**]
 | 
			
		||||
[**--privileged**]
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +33,12 @@ container is unpaused, and then run
 | 
			
		|||
**--detach-keys**=""
 | 
			
		||||
  Override the key sequence for detaching a container. Format is a single character `[a-Z]` or `ctrl-<value>` where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`.
 | 
			
		||||
 | 
			
		||||
**-e**, **--env**=[]
 | 
			
		||||
   Set environment variables
 | 
			
		||||
 | 
			
		||||
   This option allows you to specify arbitrary environment variables that are
 | 
			
		||||
available for the command to be executed.
 | 
			
		||||
 | 
			
		||||
**--help**
 | 
			
		||||
  Print usage statement
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue