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"
|
||||||
"github.com/docker/docker/cli/command"
|
"github.com/docker/docker/cli/command"
|
||||||
apiclient "github.com/docker/docker/client"
|
apiclient "github.com/docker/docker/client"
|
||||||
|
options "github.com/docker/docker/opts"
|
||||||
"github.com/docker/docker/pkg/promise"
|
"github.com/docker/docker/pkg/promise"
|
||||||
|
runconfigopts "github.com/docker/docker/runconfig/opts"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,11 +24,19 @@ type execOptions struct {
|
||||||
detach bool
|
detach bool
|
||||||
user string
|
user string
|
||||||
privileged bool
|
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`
|
// NewExecCommand creats a new cobra.Command for `docker exec`
|
||||||
func NewExecCommand(dockerCli *command.DockerCli) *cobra.Command {
|
func NewExecCommand(dockerCli *command.DockerCli) *cobra.Command {
|
||||||
var opts execOptions
|
opts := newExecOptions()
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "exec [OPTIONS] CONTAINER COMMAND [ARG...]",
|
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 {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
container := args[0]
|
container := args[0]
|
||||||
execCmd := args[1:]
|
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.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.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.BoolVarP(&opts.privileged, "privileged", "", false, "Give extended privileges to the command")
|
||||||
|
flags.VarP(opts.env, "env", "e", "Set environment variables")
|
||||||
|
|
||||||
return cmd
|
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
|
return execConfig, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1274,7 +1274,7 @@ _docker_exec() {
|
||||||
|
|
||||||
case "$cur" in
|
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
|
__docker_complete_containers_running
|
||||||
|
|
|
@ -1679,6 +1679,7 @@ __docker_subcommand() {
|
||||||
$opts_help \
|
$opts_help \
|
||||||
$opts_attach_exec_run_start \
|
$opts_attach_exec_run_start \
|
||||||
"($help -d --detach)"{-d,--detach}"[Detached mode: leave the container running in the background]" \
|
"($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 -i --interactive)"{-i,--interactive}"[Keep stdin open even if not attached]" \
|
||||||
"($help)--privileged[Give extended Linux capabilities to the command]" \
|
"($help)--privileged[Give extended Linux capabilities to the command]" \
|
||||||
"($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]" \
|
"($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 {
|
if err != nil {
|
||||||
return "", err
|
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 {
|
if len(execConfig.User) == 0 {
|
||||||
execConfig.User = container.Config.User
|
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 /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.
|
* `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`.
|
* `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
|
### v1.24 API changes
|
||||||
|
|
||||||
|
|
|
@ -3151,6 +3151,10 @@ Sets up an exec instance in a running container `id`
|
||||||
"AttachStderr": true,
|
"AttachStderr": true,
|
||||||
"Cmd": ["sh"],
|
"Cmd": ["sh"],
|
||||||
"DetachKeys": "ctrl-p,ctrl-q",
|
"DetachKeys": "ctrl-p,ctrl-q",
|
||||||
|
"Env": [
|
||||||
|
"FOO=bar",
|
||||||
|
"BAZ=quux"
|
||||||
|
],
|
||||||
"Privileged": true,
|
"Privileged": true,
|
||||||
"Tty": true,
|
"Tty": true,
|
||||||
"User": "123:456"
|
"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>`
|
container. Format is a single character `[a-Z]` or `ctrl-<value>`
|
||||||
where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`.
|
where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`.
|
||||||
- **Tty** - Boolean value to allocate a pseudo-TTY.
|
- **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.
|
- **Cmd** - Command to run specified as a string or an array of strings.
|
||||||
- **Privileged** - Boolean value, runs the exec process with extended privileges.
|
- **Privileged** - Boolean value, runs the exec process with extended privileges.
|
||||||
- **User** - A string value specifying the user, and optionally, group to run
|
- **User** - A string value specifying the user, and optionally, group to run
|
||||||
|
|
|
@ -14,6 +14,7 @@ Run a command in a running container
|
||||||
Options:
|
Options:
|
||||||
-d, --detach Detached mode: run command in the background
|
-d, --detach Detached mode: run command in the background
|
||||||
--detach-keys Override the key sequence for detaching a container
|
--detach-keys Override the key sequence for detaching a container
|
||||||
|
-e, --env=[] Set environment variables
|
||||||
--help Print usage
|
--help Print usage
|
||||||
-i, --interactive Keep STDIN open even if not attached
|
-i, --interactive Keep STDIN open even if not attached
|
||||||
--privileged Give extended privileges to the command
|
--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")
|
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) {
|
func (s *DockerSuite) TestExecExitStatus(c *check.C) {
|
||||||
runSleepingContainer(c, "-d", "--name", "top")
|
runSleepingContainer(c, "-d", "--name", "top")
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendly
|
||||||
sp := spec.Process
|
sp := spec.Process
|
||||||
sp.Args = specp.Args
|
sp.Args = specp.Args
|
||||||
sp.Terminal = specp.Terminal
|
sp.Terminal = specp.Terminal
|
||||||
if specp.Env != nil {
|
if len(specp.Env) > 0 {
|
||||||
sp.Env = specp.Env
|
sp.Env = specp.Env
|
||||||
}
|
}
|
||||||
if specp.Cwd != nil {
|
if specp.Cwd != nil {
|
||||||
|
|
|
@ -8,6 +8,7 @@ docker-exec - Run a command in a running container
|
||||||
**docker exec**
|
**docker exec**
|
||||||
[**-d**|**--detach**]
|
[**-d**|**--detach**]
|
||||||
[**--detach-keys**[=*[]*]]
|
[**--detach-keys**[=*[]*]]
|
||||||
|
[**-e**|**--env**[=*[]*]]
|
||||||
[**--help**]
|
[**--help**]
|
||||||
[**-i**|**--interactive**]
|
[**-i**|**--interactive**]
|
||||||
[**--privileged**]
|
[**--privileged**]
|
||||||
|
@ -32,6 +33,12 @@ container is unpaused, and then run
|
||||||
**--detach-keys**=""
|
**--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 `_`.
|
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**
|
**--help**
|
||||||
Print usage statement
|
Print usage statement
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue