diff --git a/cli/command/container/exec.go b/cli/command/container/exec.go index 46775f3048..258f3a860a 100644 --- a/cli/command/container/exec.go +++ b/cli/command/container/exec.go @@ -24,6 +24,7 @@ type execOptions struct { user string privileged bool env opts.ListOpts + workdir string container string command []string } @@ -58,6 +59,8 @@ func NewExecCommand(dockerCli command.Cli) *cobra.Command { flags.BoolVarP(&options.privileged, "privileged", "", false, "Give extended privileges to the command") flags.VarP(&options.env, "env", "e", "Set environment variables") flags.SetAnnotation("env", "version", []string{"1.25"}) + flags.StringVarP(&options.workdir, "workdir", "w", "", "Working directory inside the container") + flags.SetAnnotation("workdir", "version", []string{"1.35"}) return cmd } @@ -190,6 +193,7 @@ func parseExec(opts execOptions, configFile *configfile.ConfigFile) *types.ExecC Cmd: opts.command, Detach: opts.detach, Env: opts.env.GetAll(), + WorkingDir: opts.workdir, } // If -d is not set, attach to everything by default diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index 69d1ba65a2..314ed1797b 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -1439,11 +1439,14 @@ _docker_container_exec() { __docker_complete_user_group return ;; + --workdir|-w) + return + ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--detach -d --detach-keys --env -e --help --interactive -i --privileged -t --tty -u --user" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--detach -d --detach-keys --env -e --help --interactive -i --privileged -t --tty -u --user --workdir -w" -- "$cur" ) ) ;; *) __docker_complete_containers_running diff --git a/contrib/completion/fish/docker.fish b/contrib/completion/fish/docker.fish index d825922776..178aa9c3ab 100644 --- a/contrib/completion/fish/docker.fish +++ b/contrib/completion/fish/docker.fish @@ -174,6 +174,7 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from exec' -s d -l detach -d complete -c docker -A -f -n '__fish_seen_subcommand_from exec' -l help -d 'Print usage' complete -c docker -A -f -n '__fish_seen_subcommand_from exec' -s i -l interactive -d 'Keep STDIN open even if not attached' complete -c docker -A -f -n '__fish_seen_subcommand_from exec' -s t -l tty -d 'Allocate a pseudo-TTY' +complete -c docker -A -f -n '__fish_seen_subcommand_from exec' -s w -l workdir -d 'Working directory inside the container' complete -c docker -A -f -n '__fish_seen_subcommand_from exec' -a '(__fish_print_docker_containers running)' -d "Container" # export diff --git a/contrib/completion/zsh/_docker b/contrib/completion/zsh/_docker index 309db74ff6..a2a04a438a 100644 --- a/contrib/completion/zsh/_docker +++ b/contrib/completion/zsh/_docker @@ -745,6 +745,7 @@ __docker_container_subcommand() { "($help)--privileged[Give extended Linux capabilities to the command]" \ "($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]" \ "($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users" \ + "($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories" "($help -):containers:__docker_complete_running_containers" \ "($help -)*::command:->anycommand" && ret=0 case $state in diff --git a/docs/reference/commandline/exec.md b/docs/reference/commandline/exec.md index 63635b2f40..35072dad1f 100644 --- a/docs/reference/commandline/exec.md +++ b/docs/reference/commandline/exec.md @@ -29,6 +29,7 @@ Options: --privileged Give extended privileges to the command -t, --tty Allocate a pseudo-TTY -u, --user Username or UID (format: [:]) + -w, --workdir Working directory inside the container ``` ## Description @@ -86,6 +87,20 @@ This will create a new Bash session in the container `ubuntu_bash` with environm variable `$VAR` set to "1". Note that this environment variable will only be valid on the current Bash session. +By default `docker exec` command runs in the same working directory set when container was created. + +```bash +$ docker exec -it ubuntu_bash pwd +/ +``` + +You can select working directory for the command to execute into + +```bash +$ docker exec -it -w /root ubuntu_bash pwd +/root +``` + ### Try to run `docker exec` on a paused container diff --git a/vendor.conf b/vendor.conf index 97f8374527..f2b9246614 100755 --- a/vendor.conf +++ b/vendor.conf @@ -5,7 +5,7 @@ github.com/coreos/etcd v3.2.1 github.com/cpuguy83/go-md2man a65d4d2de4d5f7c74868dfa9b202a3c8be315aaa github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 github.com/docker/distribution edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c -github.com/docker/docker f4d4f5863156b82ef146b6ff1e845f8dcf019f12 +github.com/docker/docker 5e5fadb3c0201553929d4a6ea8dc8f9d8a1e56fe github.com/docker/docker-credential-helpers 3c90bd29a46b943b2a9842987b58fb91a7c1819b # the docker/go package contains a customized version of canonical/json diff --git a/vendor/github.com/docker/docker/api/types/configs.go b/vendor/github.com/docker/docker/api/types/configs.go index 20c19f2132..54d3e39fb9 100644 --- a/vendor/github.com/docker/docker/api/types/configs.go +++ b/vendor/github.com/docker/docker/api/types/configs.go @@ -50,6 +50,7 @@ type ExecConfig struct { Detach bool // Execute in detach mode DetachKeys string // Escape keys for detach Env []string // Environment variables + WorkingDir string // Working directory Cmd []string // Execution commands and args } diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto index 06eb7ba650..6d63b7783f 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto +++ b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto @@ -1,5 +1,7 @@ syntax = "proto3"; +option go_package = "github.com/docker/docker/api/types/swarm/runtime;runtime"; + // PluginSpec defines the base payload which clients can specify for creating // a service with the plugin runtime. message PluginSpec { diff --git a/vendor/github.com/docker/docker/pkg/idtools/idtools.go b/vendor/github.com/docker/docker/pkg/idtools/idtools.go index 68a072db22..6108ae3f43 100644 --- a/vendor/github.com/docker/docker/pkg/idtools/idtools.go +++ b/vendor/github.com/docker/docker/pkg/idtools/idtools.go @@ -34,39 +34,26 @@ const ( subgidFileName string = "/etc/subgid" ) -// MkdirAllAs creates a directory (include any along the path) and then modifies -// ownership to the requested uid/gid. If the directory already exists, this -// function will still change ownership to the requested uid/gid pair. -// Deprecated: Use MkdirAllAndChown -func MkdirAllAs(path string, mode os.FileMode, ownerUID, ownerGID int) error { - return mkdirAs(path, mode, ownerUID, ownerGID, true, true) -} - -// MkdirAs creates a directory and then modifies ownership to the requested uid/gid. -// If the directory already exists, this function still changes ownership -// Deprecated: Use MkdirAndChown with a IDPair -func MkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int) error { - return mkdirAs(path, mode, ownerUID, ownerGID, false, true) -} - // MkdirAllAndChown creates a directory (include any along the path) and then modifies // ownership to the requested uid/gid. If the directory already exists, this // function will still change ownership to the requested uid/gid pair. -func MkdirAllAndChown(path string, mode os.FileMode, ids IDPair) error { - return mkdirAs(path, mode, ids.UID, ids.GID, true, true) +func MkdirAllAndChown(path string, mode os.FileMode, owner IDPair) error { + return mkdirAs(path, mode, owner.UID, owner.GID, true, true) } // MkdirAndChown creates a directory and then modifies ownership to the requested uid/gid. -// If the directory already exists, this function still changes ownership -func MkdirAndChown(path string, mode os.FileMode, ids IDPair) error { - return mkdirAs(path, mode, ids.UID, ids.GID, false, true) +// If the directory already exists, this function still changes ownership. +// Note that unlike os.Mkdir(), this function does not return IsExist error +// in case path already exists. +func MkdirAndChown(path string, mode os.FileMode, owner IDPair) error { + return mkdirAs(path, mode, owner.UID, owner.GID, false, true) } // MkdirAllAndChownNew creates a directory (include any along the path) and then modifies // ownership ONLY of newly created directories to the requested uid/gid. If the // directories along the path exist, no change of ownership will be performed -func MkdirAllAndChownNew(path string, mode os.FileMode, ids IDPair) error { - return mkdirAs(path, mode, ids.UID, ids.GID, true, false) +func MkdirAllAndChownNew(path string, mode os.FileMode, owner IDPair) error { + return mkdirAs(path, mode, owner.UID, owner.GID, true, false) } // GetRootUIDGID retrieves the remapped root uid/gid pair from the set of maps. diff --git a/vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go b/vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go index ff7968f854..aedf8ad343 100644 --- a/vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go +++ b/vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go @@ -10,6 +10,7 @@ import ( "path/filepath" "strings" "sync" + "syscall" "github.com/docker/docker/pkg/system" "github.com/opencontainers/runc/libcontainer/user" @@ -29,6 +30,9 @@ func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chown stat, err := system.Stat(path) if err == nil { + if !stat.IsDir() { + return &os.PathError{Op: "mkdir", Path: path, Err: syscall.ENOTDIR} + } if !chownExisting { return nil } @@ -54,7 +58,7 @@ func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chown paths = append(paths, dirPath) } } - if err := system.MkdirAll(path, mode, ""); err != nil && !os.IsExist(err) { + if err := system.MkdirAll(path, mode, ""); err != nil { return err } } else { diff --git a/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go b/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go index 45d2878e38..94ca33afb1 100644 --- a/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go +++ b/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go @@ -11,7 +11,7 @@ import ( // Platforms such as Windows do not support the UID/GID concept. So make this // just a wrapper around system.MkdirAll. func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chownExisting bool) error { - if err := system.MkdirAll(path, mode, ""); err != nil && !os.IsExist(err) { + if err := system.MkdirAll(path, mode, ""); err != nil { return err } return nil diff --git a/vendor/github.com/docker/docker/pkg/system/stat_unix.go b/vendor/github.com/docker/docker/pkg/system/stat_unix.go index 91c7d121cc..9dcec6afbd 100644 --- a/vendor/github.com/docker/docker/pkg/system/stat_unix.go +++ b/vendor/github.com/docker/docker/pkg/system/stat_unix.go @@ -47,6 +47,11 @@ func (s StatT) Mtim() syscall.Timespec { return s.mtim } +// IsDir reports whether s describes a directory. +func (s StatT) IsDir() bool { + return s.mode&syscall.S_IFDIR != 0 +} + // Stat takes a path to a file and returns // a system.StatT type pertaining to that file. // diff --git a/vendor/github.com/docker/docker/vendor.conf b/vendor/github.com/docker/docker/vendor.conf index dc94fb4cf5..120dd9d378 100644 --- a/vendor/github.com/docker/docker/vendor.conf +++ b/vendor/github.com/docker/docker/vendor.conf @@ -1,6 +1,6 @@ # the following lines are in sorted order, FYI github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109 -github.com/Microsoft/hcsshim v0.6.5 +github.com/Microsoft/hcsshim v0.6.7 github.com/Microsoft/go-winio v0.4.5 github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a @@ -30,7 +30,7 @@ github.com/moby/buildkit aaff9d591ef128560018433fe61beb802e149de8 github.com/tonistiigi/fsutil dea3a0da73aee887fc02142d995be764106ac5e2 #get libnetwork packages -github.com/docker/libnetwork 72fd7e5495eba86e28012e39b5ed63ef9ca9a97b +github.com/docker/libnetwork 64ae58878fc8f95e4a167499d654e13fa36abdc7 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec @@ -65,7 +65,7 @@ github.com/pborman/uuid v1.0 google.golang.org/grpc v1.3.0 # When updating, also update RUNC_COMMIT in hack/dockerfile/binaries-commits accordingly -github.com/opencontainers/runc 0351df1c5a66838d0c392b4ac4cf9450de844e2d +github.com/opencontainers/runc b2567b37d7b75eb4cf325b77297b140ea686ce8f github.com/opencontainers/runtime-spec v1.0.0 github.com/opencontainers/image-spec v1.0.0 github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0 @@ -79,13 +79,13 @@ github.com/golang/protobuf 7a211bcf3bce0e3f1d74f9894916e6f116ae83b4 # gelf logging driver deps github.com/Graylog2/go-gelf v2 -github.com/fluent/fluent-logger-golang v1.2.1 +github.com/fluent/fluent-logger-golang v1.3.0 # fluent-logger-golang deps github.com/philhofer/fwd 98c11a7a6ec829d672b03833c3d69a7fae1ca972 -github.com/tinylib/msgp 75ee40d2601edf122ef667e2a07d600d4c44490c +github.com/tinylib/msgp 3b556c64540842d4f82967be066a7f7fffc3adad # fsnotify -github.com/fsnotify/fsnotify v1.4.2 +github.com/fsnotify/fsnotify 4da3e2cfbabc9f751898f250b49f2439785783a1 # awslogs deps github.com/aws/aws-sdk-go v1.4.22 @@ -103,14 +103,15 @@ github.com/googleapis/gax-go da06d194a00e19ce00d9011a13931c3f6f6887c7 google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 # containerd -github.com/containerd/containerd 992280e8e265f491f7a624ab82f3e238be086e49 +github.com/containerd/containerd v1.0.0 github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6 github.com/containerd/continuity 35d55c5e8dd23b32037d56cf97174aff3efdfa83 -github.com/containerd/cgroups f7dd103d3e4e696aa67152f6b4ddd1779a3455a9 +github.com/containerd/cgroups 29da22c6171a4316169f9205ab6c49f59b5b852f github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e github.com/containerd/go-runc ed1cbe1fc31f5fb2359d3a54b6330d1a097858b7 github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788 -github.com/dmcgowan/go-tar 2e2c51242e8993c50445dab7c03c8e7febddd0cf +github.com/dmcgowan/go-tar go1.10 +github.com/stevvooe/ttrpc 76e68349ad9ab4d03d764c713826d31216715e4f # cluster github.com/docker/swarmkit de950a7ed842c7b7e47e9451cde9bf8f96031894