> Legacy PEM encryption as specified in RFC 1423 is insecure by design. Since
> it does not authenticate the ciphertext, it is vulnerable to padding oracle
> attacks that can let an attacker recover the plaintext
From https://go-review.googlesource.com/c/go/+/264159
> It's unfortunate that we don't implement PKCS#8 encryption so we can't
> recommend an alternative but PEM encryption is so broken that it's worth
> deprecating outright.
This feature allowed using an encrypted private key with a supplied password,
but did not provide additional security as the encryption is known to be broken,
and the key is sitting next to the password in the filesystem. Users are recommended
to decrypt the private key, and store it un-encrypted to continue using it.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit fixes spelling mistakes (typos) at a few places in the codebase.
Signed-off-by: Amey Shrivastava <72866602+AmeyShrivastava@users.noreply.github.com>
The DefaultStopSignal const has been deprecated, because the daemon already
handles a default value. The current code did not actually send the default
value unless the flag was set, which also made the flag description incorrect,
because in that case, the _daemon's_ default would be used, which could
potentially be different as was specified here.
This patch removes the default value from the flag, leaving it to the daemon
to set a default.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Locking was removed in https://github.com/docker/cli/pull/3025 which
allows for parallel calls to config.Load to modify global state.
The consequence in this case is innocuous, but it does trigger a
`DATA RACE` exception when tests run with `-race` option.
Signed-off-by: coryb <cbennett@netflix.com>
This allows us to drop the `//go:generate` and use of the github.com/mjibson/esc
utility.
worth noting that Go's native "embed" does not compress files. We could compress
these files as part of a build / validate step (which would add some complexity
when updating these files) if this is a concern, but not sure if the additional
complexity is warranted.
Comparing before/after sizes (see below);
macOS: 54125840 - 54005264 = 120576 (+120.58 kB)
Linux: 52393231 - 52277701 = 115530 (+115.53 kB)
Before:
ls -l build/
total 208736
lrwxr-xr-x 1 sebastiaan staff 19 Aug 15 09:36 docker@ -> docker-linux-amd64
-rwxr-xr-x 1 sebastiaan staff 54005264 Aug 15 09:35 docker-darwin-amd64*
-rwxr-xr-x 1 sebastiaan staff 52277701 Aug 15 09:36 docker-linux-amd64*
After:
ls -l build/
total 208960
lrwxr-xr-x 1 sebastiaan staff 18 Aug 15 09:32 docker@ -> docker-linux-amd64
-rwxr-xr-x 1 sebastiaan staff 54125840 Aug 15 09:31 docker-darwin-amd64*
-rwxr-xr-x 1 sebastiaan staff 52393231 Aug 15 09:32 docker-linux-amd64*
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Commit 73aef6edfe
modified archive.ReplaceFileTarWrapper to set the Name field in the tar header,
if the field was not set.
That change exposed an issue in how a Dockerfile from stdin was sent to the daemon.
When attempting to build using a build-context, and a Dockerfile from stdin, the
following happened:
```bash
mkdir build-stdin && cd build-stdin && echo hello > hello.txt
DOCKER_BUILDKIT=0 docker build --no-cache -t foo -f- . <<'EOF'
FROM alpine
COPY . .
EOF
Sending build context to Docker daemon 2.607kB
Error response from daemon: dockerfile parse error line 1: unknown instruction: .DOCKERIGNORE
```
Removing the `-t foo`, oddly lead to a different failure:
```bash
DOCKER_BUILDKIT=0 docker build --no-cache -f- . <<'EOF'
FROM alpine
COPY . .
EOF
Sending build context to Docker daemon 2.581kB
Error response from daemon: Cannot locate specified Dockerfile: .dockerfile.701d0d71fb1497d6a7ce
```
From the above, it looks like the tar headers got mangled, causing (in the first
case) the daemon to use the build-context tar as a plain-text file, and therefore
parsing it as Dockerfile, and in the second case, causing it to not being able to
find the Dockerfile in the context.
I noticed that both TarModifierFuncs were using the same `hdrTmpl` struct, which
looks to caused them to step on each other's toes. Changing them to each initialize
their own struct made the issue go away.
After this change:
```bash
DOCKER_BUILDKIT=0 docker build --no-cache -t foo -f- . <<'EOF'
FROM alpine
COPY . .
EOF
Sending build context to Docker daemon 2.607kB
Step 1/2 : FROM alpine
---> d4ff818577bc
Step 2/2 : COPY . .
---> 556f745e6938
Successfully built 556f745e6938
Successfully tagged foo:latest
DOCKER_BUILDKIT=0 docker build --no-cache -f- . <<'EOF'
FROM alpine
COPY . .
EOF
Sending build context to Docker daemon 2.607kB
Step 1/2 : FROM alpine
---> d4ff818577bc
Step 2/2 : COPY . .
---> aaaee43bec5e
Successfully built aaaee43bec5e
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This warning will be moved to the daemon-side, similar to how it returns
other warnings. There's work in progress to change the name of the default
profile, so we may need to backport this change to prevent existing clients
from printing an incorrect warning if they're connecting to a newer daemon.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
It's the only use of this function, and it's better to check that
the client actually sends the header.
This also simplifies some asserts, and makes sure that "actual" and "expected"
are in the correct order.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Golang uses a `sync.Once` when determining the proxy to use. This means
that it's not possible to test the proxy configuration in unit tests,
because the proxy configuration will be "fixated" the first time Golang
detects the proxy configuration.
This patch changes TestNewAPIClientFromFlagsWithHttpProxyEnv to an e2e
test so that we can verify the CLI picks up the proxy configuration.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
> Legacy PEM encryption as specified in RFC 1423 is insecure by design. Since
> it does not authenticate the ciphertext, it is vulnerable to padding oracle
> attacks that can let an attacker recover the plaintext
From https://go-review.googlesource.com/c/go/+/264159
> It's unfortunate that we don't implement PKCS#8 encryption so we can't
> recommend an alternative but PEM encryption is so broken that it's worth
> deprecating outright.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
From https://go-review.googlesource.com/c/go/+/264159
> It's unfortunate that we don't implement PKCS#8 encryption so we can't
> recommend an alternative but PEM encryption is so broken that it's worth
> deprecating outright.
When linting on Go 1.16:
cli/context/docker/load.go:69:6: SA1019: x509.IsEncryptedPEMBlock is deprecated: Legacy PEM encryption as specified in RFC 1423 is insecure by design. Since it does not authenticate the ciphertext, it is vulnerable to padding oracle attacks that can let an attacker recover the plaintext. (staticcheck)
if x509.IsEncryptedPEMBlock(pemBlock) {
^
cli/context/docker/load.go:70:20: SA1019: x509.DecryptPEMBlock is deprecated: Legacy PEM encryption as specified in RFC 1423 is insecure by design. Since it does not authenticate the ciphertext, it is vulnerable to padding oracle attacks that can let an attacker recover the plaintext. (staticcheck)
keyBytes, err = x509.DecryptPEMBlock(pemBlock, []byte(c.TLSPassword))
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Support for ALL_PROXY as default build-arg was added recently in
buildkit and the classic builder.
This patch adds the `ALL_PROXY` environment variable to the list of
configurable proxy variables, and updates the documentation.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Errors always need to go to stderr.
This also fixes a test in moby/moby's integration-cli which is checking
to see if errors connecting to the daemon are output on stderr.
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The docker info output contains both "local" and "remote" (daemon-side) information.
The API endpoint to collect daemon information (`/info`) is known to be "heavy",
and (depending on what information is needed) not needed.
This patch checks if the template (`--format`) used requires information from the
daemon, and if not, omits making an API request.
This will improve performance if (for example), the current "context" is requested
from `docker info` or if only plugin information is requested.
Before:
time docker info --format '{{range .ClientInfo.Plugins}}Plugin: {{.Name}}, {{end}}'
Plugin: buildx, Plugin: compose, Plugin: scan,
________________________________________________________
Executed in 301.91 millis fish external
usr time 168.64 millis 82.00 micros 168.56 millis
sys time 113.72 millis 811.00 micros 112.91 millis
time docker info --format '{{json .ClientInfo.Plugins}}'
time docker info --format '{{.ClientInfo.Context}}'
default
________________________________________________________
Executed in 334.38 millis fish external
usr time 177.23 millis 93.00 micros 177.13 millis
sys time 124.90 millis 927.00 micros 123.97 millis
docker context use remote-ssh-daemon
time docker info --format '{{.ClientInfo.Context}}'
remote-ssh-daemon
________________________________________________________
Executed in 1.22 secs fish external
usr time 116.93 millis 110.00 micros 116.82 millis
sys time 144.36 millis 887.00 micros 143.47 millis
And daemon logs:
Jul 06 12:42:12 remote-ssh-daemon dockerd[14377]: time="2021-07-06T12:42:12.139529947Z" level=debug msg="Calling HEAD /_ping"
Jul 06 12:42:12 remote-ssh-daemon dockerd[14377]: time="2021-07-06T12:42:12.140772052Z" level=debug msg="Calling HEAD /_ping"
Jul 06 12:42:12 remote-ssh-daemon dockerd[14377]: time="2021-07-06T12:42:12.163832016Z" level=debug msg="Calling GET /v1.41/info"
After:
time ./build/docker info --format '{{range .ClientInfo.Plugins}}Plugin: {{.Name}}, {{end}}'
Plugin: buildx, Plugin: compose, Plugin: scan,
________________________________________________________
Executed in 139.84 millis fish external
usr time 76.53 millis 62.00 micros 76.46 millis
sys time 69.25 millis 723.00 micros 68.53 millis
time ./build/docker info --format '{{.ClientInfo.Context}}'
default
________________________________________________________
Executed in 136.94 millis fish external
usr time 74.61 millis 74.00 micros 74.54 millis
sys time 65.77 millis 858.00 micros 64.91 millis
docker context use remote-ssh-daemon
time ./build/docker info --format '{{.ClientInfo.Context}}'
remote-ssh-daemon
________________________________________________________
Executed in 1.02 secs fish external
usr time 74.25 millis 76.00 micros 74.17 millis
sys time 65.09 millis 643.00 micros 64.44 millis
And daemon logs:
Jul 06 12:42:55 remote-ssh-daemon dockerd[14377]: time="2021-07-06T12:42:55.313654687Z" level=debug msg="Calling HEAD /_ping"
Jul 06 12:42:55 remote-ssh-daemon dockerd[14377]: time="2021-07-06T12:42:55.314811624Z" level=debug msg="Calling HEAD /_ping"
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Commit 330a003533
introduced "synchronous" service update and rollback, using progress bars to show
current status for each task.
As part of that change, progress bars were "reversed" when doing a rollback, to
indicate that status was rolled back to a previous state.
Reversing direction is somewhat confusing, as progress bars now return to their
"initial" state to indicate it was "completed"; for an "automatic" rollback, this
may be somewhat clear (progress bars "move to the right", then "roll back" if the
update failed), but when doing a manual rollback, it feels counter-intuitive
(rolling back is the _expected_ outcome).
This patch removes the code to reverse the direction of progress-bars, and makes
progress-bars always move from left ("start") to right ("finished").
Before this patch
----------------------------------------
1. create a service with automatic rollback on failure
$ docker service create --update-failure-action=rollback --name foo --tty --replicas=5 nginx:alpine
9xi1w3mv5sqtyexsuh78qg0cb
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [==================================================>]
verify: Waiting 2 seconds to verify that tasks are stable...
2. update the service, making it fail after 3 seconds
$ docker service update --entrypoint="/bin/sh -c 'sleep 3; exit 1'" foo
overall progress: rolling back update: 2 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: starting [============================================> ]
4/5: running [==================================================>]
5/5: running [==================================================>]
3. Once the service starts failing, automatic rollback is started; progress-bars now move in the reverse direction;
overall progress: rolling back update: 3 out of 5 tasks
1/5: ready [===========> ]
2/5: ready [===========> ]
3/5: running [> ]
4/5: running [> ]
5/5: running [> ]
4. When the rollback is completed, the progressbars are at the "start" to indicate they completed;
overall progress: rolling back update: 5 out of 5 tasks
1/5: running [> ]
2/5: running [> ]
3/5: running [> ]
4/5: running [> ]
5/5: running [> ]
rollback: update rolled back due to failure or early termination of task bndiu8a998agr8s6sjlg9tnrw
verify: Service converged
After this patch
----------------------------------------
Progress bars always go from left to right; also in a rollback situation;
After updating to the "faulty" entrypoint, task are deployed:
$ docker service update --entrypoint="/bin/sh -c 'sleep 3; exit 1'" foo
foo
overall progress: 1 out of 5 tasks
1/5:
2/5: running [==================================================>]
3/5: ready [======================================> ]
4/5:
5/5:
Once tasks start failing, rollback is started, and presented the same as a regular
update; progress bars go from left to right;
overall progress: rolling back update: 3 out of 5 tasks
1/5: ready [======================================> ]
2/5: starting [============================================> ]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [==================================================>]
rollback: update rolled back due to failure or early termination of task c11dxd7ud3d5pq8g45qkb4rjx
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This extends #2929 to Darwin as well as Linux.
Running the example in https://github.com/golang/go/issues/37942
I see lots of:
```
dave@m1 sigurg % uname -ms
Darwin arm64
dave@m1 sigurg % go run main.go
received urgent I/O condition: 2021-05-21 16:03:03.482211 +0100 BST m=+0.014553751
received urgent I/O condition: 2021-05-21 16:03:03.507171 +0100 BST m=+0.039514459
```
Signed-off-by: David Scott <dave@recoil.org>
The kernel memory limit is deprecated in Docker 20.10.0,
and its support was removed in runc v1.0.0-rc94.
So, this warning can be safely removed.
Relevant: b8ca7de823
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
- use var/const blocks when declaring a list of variables
- use const where possible
TestCheckKubernetesConfigurationRaiseAnErrorOnInvalidValue:
- use keys when assigning values
- make sure test is dereferenced in the loop
- use subtests
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Some tests were using domain names that were intended to be "fake", but are
actually registered domain names (such as mycorp.com).
Even though we were not actually making connections to these domains, it's
better to use domains that are designated for testing/examples in RFC2606:
https://tools.ietf.org/html/rfc2606
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
New solution is not hardcoded to amd64 but integrates
with the cross toolchain and support creating arm binaries.
Go has been updated so that ASLR works
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Relates to the deprecation, added in 3c0a167ed5
The docker CLI up until v1.7.0 used the `~/.dockercfg` file to store credentials
after authenticating to a registry (`docker login`). Docker v1.7.0 replaced this
file with a new CLI configuration file, located in `~/.docker/config.json`. When
implementing the new configuration file, the old file (and file-format) was kept
as a fall-back, to assist existing users with migrating to the new file.
Given that the old file format encourages insecure storage of credentials
(credentials are stored unencrypted), and that no version of the CLI since
Docker v1.7.0 has created this file, the file is marked deprecated, and support
for this file will be removed in a future release.
This patch adds a deprecation warning, which is printed if the CLI falls back
to using the deprecated ~/.dockercfg file.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
We refactorted `ForwardAllSignals` so it blocks but did not update the
call in `start` to call it in a goroutine.
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Commit fff164c22e modified ForwardAllSignals to
take `SIGURG` signals into account, which can be generated by the Go runtime
on Go 1.14 and up as an interrupt to support pre-emptable system calls on Linux.
With the updated code, the signal (`s`) would sometimes be `nil`, causing spurious
(but otherwise harmless) warnings to be printed;
Unsupported signal: <nil>. Discarding.
To debug this issue, I patched v20.10.4 to handle `nil`, and added a debug line
to print the signal in all cases;
```patch
diff --git a/cli/command/container/signals.go b/cli/command/container/signals.go
index 06e4d9eb6..0cb53ef06 100644
--- a/cli/command/container/signals.go
+++ b/cli/command/container/signals.go
@@ -22,8 +22,9 @@ func ForwardAllSignals(ctx context.Context, cli command.Cli, cid string, sigc <-
case <-ctx.Done():
return
}
+ fmt.Fprintf(cli.Err(), "Signal: %v\n", s)
if s == signal.SIGCHLD || s == signal.SIGPIPE {
```
When running a cross-compiled macOS binary with Go 1.13 (`make -f docker.Makefile binary-osx`):
# regular "docker run" (note that the `<nil>` signal only happens "sometimes"):
./build/docker run --rm alpine/git clone https://github.com/docker/getting-started.git
Cloning into 'getting-started'...
Signal: <nil>
# when cancelling with CTRL-C:
./build/docker run --rm alpine/git clone https://github.com/docker/getting-started.git
^CSignal: interrupt
Cloning into 'getting-started'...
error: could not lock config file /git/getting-started/.git/config: No such file or directory
fatal: could not set 'core.repositoryformatversion' to '0'
Signal: <nil>
Signal: <nil>
When running a macOS binary built with Go 1.15 (`DISABLE_WARN_OUTSIDE_CONTAINER=1 make binary`):
# regular "docker run" (note that the `<nil>` signal only happens "sometimes"):
# this is the same as on Go 1.13
./build/docker run --rm alpine/git clone https://github.com/docker/getting-started.git
Cloning into 'getting-started'...
Signal: <nil>
# when cancelling with CTRL-C:
./build/docker run --rm alpine/git clone https://github.com/docker/getting-started.git
Cloning into 'getting-started'...
^CSignal: interrupt
Signal: urgent I/O condition
Signal: urgent I/O condition
fatal: --stdin requires a git repository
fatal: index-pack failed
Signal: <nil>
Signal: <nil>
This patch checks if the channel is closed, and removes the warning (to prevent warnings if new
signals are added that are not in our known list of signals)
We should also consider updating `notfiyAllSignals()`, which currently forwards
_all_ signals (`signal.Notify(sigc)` without passing a list of signals), and
instead pass it "all signals _minus_ the signals we don't want forwarded":
35f023a7c2/cli/command/container/signals.go (L55)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
On Windows, the os/exec.{Command,CommandContext,LookPath} functions
resolve command names that have neither path separators nor file extension
(e.g., "git") by first looking in the current working directory before
looking in the PATH environment variable.
Go maintainers intended to match cmd.exe's historical behavior.
However, this is pretty much never the intended behavior and as an abundance of precaution
this patch prevents that when executing commands.
Example of commands that docker.exe may execute: `git`, `docker-buildx` (or other cli plugin), `docker-credential-wincred`, `docker`.
Note that this was prompted by the [Go 1.15.7 security fixes](https://blog.golang.org/path-security), but unlike in `go.exe`,
the windows path lookups in docker are not in a code path allowing remote code execution, thus there is no security impact on docker.
Signed-off-by: Tibor Vass <tibor@docker.com>
Prior to this change, progressbars would sometimes be hidden, and the function
would return early. In addition, the direction of the progressbars would sometimes
be "incrementing" (similar to "docker service update"), and sometimes be "decrementing"
(to indicate a "rollback" is being performed).
This fix makes sure that we always proceed with the "verifying" step, and now
prints a message _after_ the verifying stage was completed;
$ docker service rollback foo
foo
overall progress: rolling back update: 5 out of 5 tasks
1/5: running [> ]
2/5: starting [===========> ]
3/5: starting [===========> ]
4/5: running [> ]
5/5: running [> ]
verify: Service converged
rollback: rollback completed
$ docker service rollback foo
foo
overall progress: rolling back update: 1 out of 1 tasks
1/1: running [> ]
verify: Service converged
rollback: rollback completed
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this change:
--------------------------------------------
$ docker service create --replicas=1 --name foo -p 8080:80 nginx:alpine
t33qvykv8y0zbz266rxynsbo3
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
$ echo $?
0
$ docker service update --replicas=5 foo
foo
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [==================================================>]
verify: Service converged
$ echo $?
0
$ docker service rollback foo
foo
rollback: manually requested rollback
overall progress: rolling back update: 1 out of 1 tasks
1/1: running [> ]
verify: Service converged
$ echo $?
0
$ docker service rollback foo
foo
service rolled back: rollback completed
$ echo $?
1
After this change:
--------------------------------------------
$ docker service create --replicas=1 --name foo -p 8080:80 nginx:alpine
t33qvykv8y0zbz266rxynsbo3
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
$ echo $?
0
$ docker service update --replicas=5 foo
foo
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [==================================================>]
verify: Waiting 1 seconds to verify that tasks are stable...
$ echo $?
0
$ docker service rollback foo
foo
rollback: manually requested rollback
overall progress: rolling back update: 1 out of 1 tasks
1/1: running [> ]
verify: Service converged
$ echo $?
0
$ docker service rollback foo
foo
service rolled back: rollback completed
$ echo $?
0
$ docker service ps foo
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4dt4ms4c5qfb foo.1 nginx:alpine docker-desktop Running Running 2 minutes ago
Remaining issues with reconciliation
--------------------------------------------
Note that both before, and after this change, the command sometimes terminates
early, and does not wait for the service to reconcile; this is most apparent
when rolling back is scaling up (so more tasks are deployed);
$ docker service rollback foo
foo
service rolled back: rollback completed
$ docker service rollback foo
foo
rollback: manually requested rollback
overall progress: rolling back update: 1 out of 5 tasks
1/5: pending [=================================> ]
2/5: running [> ]
3/5: pending [=================================> ]
4/5: pending [=================================> ]
5/5: pending [=================================> ]
service rolled back: rollback completed
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
commit c2626a8270 replaced the use of
github.com/docker/docker/pkg/homedir with Golang's os.UserHomeDir().
This change was partially reverted in 7a279af43d
to account for situations where `$HOME` is not set.
In situations where no configuration file is present in `~/.config/`, the CLI
falls back to looking for the (deprecated) `~/.dockercfg` configuration file,
which was still using `os.UserHomeDir()`, which produces an error/warning if
`$HOME` is not set.
This patch introduces a helper function and a global variable to get the user's
home-directory. The global variable is used to prevent repeatedly looking up
the user's information (which, depending on the setup can be a costly operation).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Commit f32731f902 fixed a potential panic
when an error was returned while trying to get existing credentials.
However, other code paths currently use the result of `GetDefaultAuthConfig()`
even in an error condition; this resulted in a panic, because a `nil` was
returned.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: 75b288015a...c1f2f97bff
relevant changes:
- pkcs12: document that we use the wrong PEM type
- pkcs12: drop PKCS#12 attributes with unknown OIDs
- ocsp: Improve documentation for ParseResponse and ParseResponseForCert
other changes (not in vendor);
- ssh: improve error message for KeyboardInteractiveChallenge
- ssh: remove slow unnecessary diffie-hellman-group-exchange primality check
- ssh/terminal: replace with a golang.org/x/term wrapper
- Deprecates ssh/terminal in favor of golang.org/x/term
- ssh/terminal: add support for zos
- ssh/terminal: bump x/term dependency to fix js/nacl
- nacl/auth: use Size instead of KeySize for Sum output
- sha3: remove go:nocheckptr annotation
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Will display when user types `docker help` or `docker --help`, but not for `docker run --help`.
Signed-off-by: Guillaume Tardif <guillaume.tardif@gmail.com>
This hack was added in an attempt to continue supporting the experimental
(non-buildkit) `--platform` option, by dynamically updating the API version
required if buildkit isn't enabled.
This hack didn't work, however, because at the moment the override is
added, the command is not yet attached to the "root" (`docker`) command,
and because of that, the command itself is the `root` command;
`cmd.Root()` returned the `build` command.
As a result, validation steps defined as `PersistentPreRunE` on the root
command were not executed, causing invalid flags/options to not producing
an error.
Attempts to use an alternative approach (for example, cobra supports both
a `PersistentPreRun` and `PersistentPreRunE`) did not work either, because
`PersistentPreRunE` takes precedence over `PersistentPreRun`, and only one
will be executed.
Now that `--platform` should be supported for other cases than just for
experimental (LCOW), let's remove the 'experimental' check, and just assume
it's supported for API v1.32 and up.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
While performance will be worse, we can safely ignore the --stream
option when used, and print a deprecation warning instead of failing
the build.
With this patch:
echo -e "FROM scratch\nLABEL foo=bar" | docker build --stream -
DEPRECATED: The experimental --stream flag has been removed and the build context
will be sent non-streaming. Enable BuildKit instead with DOCKER_BUILDKIT=1
to stream build context, see https://docs.docker.com/go/buildkit/
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM scratch
--->
Step 2/2 : LABEL foo=bar
---> Running in 99e4021085b6
Removing intermediate container 99e4021085b6
---> 1a7a41be241f
Successfully built 1a7a41be241f
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The CLI disabled experimental features by default, requiring users
to set a configuration option to enable them.
Disabling experimental features was a request from Enterprise users
that did not want experimental features to be accessible.
We are changing this policy, and now enable experimental features
by default. Experimental features may still change and/or removed,
and will be highlighted in the documentation and "usage" output.
For example, the `docker manifest inspect --help` output now shows:
EXPERIMENTAL:
docker manifest inspect is an experimental feature.
Experimental features provide early access to product functionality. These features
may change between releases without warning or can be removed entirely from a future
release. Learn more about experimental features: https://docs.docker.com/go/experimental/
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
All output of the usage / --help output uses spaces, and having a tab
in the output can be somewhat cumbersome (e.g. our YAML docs generator
doesn't like them, and copy/pasing the output in iTerm produces a warning).
This patch changes the output to use two spaces instead.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When initializing the API client, the User-Agent was added to any custom
HTTPHeaders that were configured. However, because the map was not properly
dereferenced, the original map was modified, causing the User-Agent to also
be saved to config.json after `docker login` and `docker logout`:
Before this change;
$ cat ~/.docker/config.json
cat: can't open '/root/.docker/config.json': No such file or directory
$ docker login -u myusername
Password:
...
Login Succeeded
$ cat ~/.docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "<base64 auth>"
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/19.03.12 (linux)"
}
}
$ docker logout
{
"auths": {},
"HttpHeaders": {
"User-Agent": "Docker-Client/19.03.12 (linux)"
}
}
After this change:
$ cat ~/.docker/config.json
cat: can't open '/root/.docker/config.json': No such file or directory
$ docker login -u myusername
Password:
...
Login Succeeded
$ cat ~/.docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "<base64 auth>"
}
}
}
$ docker logout
Removing login credentials for https://index.docker.io/v1/
$ cat ~/.docker/config.json
{
"auths": {}
}
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This implements a special "RESET" value that can be used to reset the
list of capabilities to add/drop when updating a service.
Given the following service;
| CapDrop | CapAdd |
| -------------- | ------------- |
| CAP_SOME_CAP | |
When updating the service, and applying `--cap-drop RESET`, the "drop" list
is reset to its default:
| CapDrop | CapAdd |
| -------------- | ------------- |
| | |
When updating the service, and applying `--cap-drop RESET`, combined with
`--cap-add CAP_SOME_CAP` and `--cap-drop CAP_SOME_OTHER_CAP`:
| CapDrop | CapAdd |
| -------------- | ------------- |
| CAP_FOO_CAP | CAP_SOME_CAP |
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Adding/removing capabilities when updating a service is considered a tri-state;
- if the capability was previously "dropped", then remove it from "CapabilityDrop",
but do NOT add it to "CapabilityAdd". However, if the capability was not yet in
the service's "CapabilityDrop", then simply add it to the service's "CapabilityAdd"
- likewise, if the capability was previously "added", then remove it from
"CapabilityAdd", but do NOT add it to "CapabilityDrop". If the capability was
not yet in the service's "CapabilityAdd", then simply add it to the service's
"CapabilityDrop".
In other words, given a service with the following:
| CapDrop | CapAdd |
| -------------- | ------------- |
| CAP_SOME_CAP | |
When updating the service, and applying `--cap-add CAP_SOME_CAP`, the previously
dropped capability is removed:
| CapDrop | CapAdd |
| -------------- | ------------- |
| | |
When updating the service a second time, applying `--cap-add CAP_SOME_CAP`,
capability is now added:
| CapDrop | CapAdd |
| -------------- | ------------- |
| | CAP_SOME_CAP |
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When creating and updating services, we need to avoid unneeded service churn.
The interaction of separate lists to "add" and "drop" capabilities, a special
("ALL") capability, as well as a "relaxed" format for accepted capabilities
(case-insensitive, `CAP_` prefix optional) make this rather involved.
This patch updates how we handle `--cap-add` / `--cap-drop` when _creating_ as
well as _updating_, with the following rules/assumptions applied:
- both existing (service spec) and new (values passed through flags or in
the compose-file) are normalized and de-duplicated before use.
- the special "ALL" capability is equivalent to "all capabilities" and taken
into account when normalizing capabilities. Combining "ALL" capabilities
and other capabilities is therefore equivalent to just specifying "ALL".
- adding capabilities takes precedence over dropping, which means that if
a capability is both set to be "dropped" and to be "added", it is removed
from the list to "drop".
- the final lists should be sorted and normalized to reduce service churn
- no validation of capabilities is handled by the client. Validation is
delegated to the daemon/server.
When deploying a service using a docker-compose file, the docker-compose file
is *mostly* handled as being "declarative". However, many of the issues outlined
above also apply to compose-files, so similar handling is applied to compose
files as well to prevent service churn.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The tabwriter was configured to have a min-width for columns of 20 positions.
This seemed quite wide, and caused smaller columns to be printed with a large
gap between.
Before:
docker container stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
29184b3ae391 amazing_shirley 0.00% 800KiB / 1.944GiB 0.04% 1.44kB / 0B 0B / 0B 1
403c101bad56 agitated_swartz 0.15% 34.31MiB / 1.944GiB 1.72% 10.2MB / 206kB 0B / 0B 51
0dc4b7f6c6be container2 0.00% 1.012MiB / 1.944GiB 0.05% 12.9kB / 0B 0B / 0B 5
2d99abcc6f62 container99 0.00% 972KiB / 1.944GiB 0.05% 13kB / 0B 0B / 0B 5
9f9aa90173ac foo 0.00% 820KiB / 1.944GiB 0.04% 13kB / 0B 0B / 0B 5
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
29184b3ae391 docker-cli-dev "ash" 4 hours ago Up 4 hours amazing_shirley
403c101bad56 docker-dev:master "hack/dind bash" 3 days ago Up 3 days agitated_swartz
0dc4b7f6c6be nginx:alpine "/docker-entrypoint.…" 4 days ago Up 4 days 80/tcp container2
2d99abcc6f62 nginx:alpine "/docker-entrypoint.…" 4 days ago Up 4 days 80/tcp container99
9f9aa90173ac nginx:alpine "/docker-entrypoint.…" 4 days ago Up 4 days 80/tcp foo
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker-cli-dev latest 5f603caa04aa 4 hours ago 610MB
docker-cli-native latest 9dd29f8d387b 4 hours ago 519MB
docker-dev master 8132bf7a199e 3 days ago 2.02GB
docker-dev improve-build-errors 69e208994b3f 11 days ago 2.01GB
docker-dev refactor-idtools 69e208994b3f 11 days ago 2.01GB
After:
docker container stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
29184b3ae391 amazing_shirley 0.14% 5.703MiB / 1.944GiB 0.29% 1.44kB / 0B 0B / 0B 10
403c101bad56 agitated_swartz 0.15% 56.97MiB / 1.944GiB 2.86% 10.2MB / 206kB 0B / 0B 51
0dc4b7f6c6be container2 0.00% 1016KiB / 1.944GiB 0.05% 12.9kB / 0B 0B / 0B 5
2d99abcc6f62 container99 0.00% 956KiB / 1.944GiB 0.05% 13kB / 0B 0B / 0B 5
9f9aa90173ac foo 0.00% 980KiB / 1.944GiB 0.05% 13kB / 0B 0B / 0B 5
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
29184b3ae391 docker-cli-dev "ash" 12 minutes ago Up 12 minutes amazing_shirley
403c101bad56 docker-dev:master "hack/dind bash" 3 days ago Up 3 days agitated_swartz
0dc4b7f6c6be nginx:alpine "/docker-entrypoint.…" 4 days ago Up 4 days 80/tcp container2
2d99abcc6f62 nginx:alpine "/docker-entrypoint.…" 4 days ago Up 4 days 80/tcp container99
9f9aa90173ac nginx:alpine "/docker-entrypoint.…" 4 days ago Up 4 days 80/tcp foo
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker-cli-dev latest 5f603caa04aa 4 hours ago 610MB
docker-cli-native latest 9dd29f8d387b 4 hours ago 519MB
docker-dev master 8132bf7a199e 3 days ago 2.02GB
docker-dev improve-build-errors 69e208994b3f 11 days ago 2.01GB
docker-dev refactor-idtools 69e208994b3f 11 days ago 2.01GB
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The vanity domain is down, and the project has moved
to a new location.
vendor check started failing because of this:
Collecting initial packages
Download dependencies
unrecognized import path "vbom.ml/util" (https fetch: Get https://vbom.ml/util?go-get=1: dial tcp: lookup vbom.ml on 169.254.169.254:53: no such host)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When using `docker rm` / `docker container rm` with the `-f` / `--force` option, attempts to remove non-existing containers should print a warning, but should return a zero exit code ("successful").
Currently, a non-zero exit code is returned, marking the removal as "failed";
$ docker rm -fv 798c9471b695
Error: No such container: 798c9471b695
$ echo $?
1
The command should match the behavior of `rm` / `rm -f`, with the exception that
a warning is printed (instead of silently ignored):
Running `rm` with `-f` silences output and returns a zero exit code:
touch some-file && rm -f no-such-file some-file; echo exit code: $?; ls -la
# exit code: 0
# total 0
# drwxr-xr-x 2 sebastiaan staff 64 Aug 14 12:17 .
# drwxr-xr-x 199 sebastiaan staff 6368 Aug 14 12:13 ..
mkdir some-directory && rm -rf no-such-directory some-directory; echo exit code: $?; ls -la
# exit code: 0
# total 0
# drwxr-xr-x 2 sebastiaan staff 64 Aug 14 12:17 .
# drwxr-xr-x 199 sebastiaan staff 6368 Aug 14 12:13 ..
Note that other reasons for a delete to fail should still result in a non-zero
exit code, matching the behavior of `rm`. For instance, in the example below,
the `rm` failed because directories can only be removed if the `-r` option is used;
touch some-file && mkdir some-directory && rm -f some-directory no-such-file some-file; echo exit code: $?; ls -la
# rm: some-directory: is a directory
# exit code: 1
# total 0
# drwxr-xr-x 3 sebastiaan staff 96 Aug 14 14:15 .
# drwxr-xr-x 199 sebastiaan staff 6368 Aug 14 12:13 ..
# drwxr-xr-x 2 sebastiaan staff 64 Aug 14 14:15 some-directory
This patch updates the `docker rm` / `docker container rm` command to not produce
an error when attempting to remove a missing containers, and instead only print
the error, but return a zero (0) exit code.
With this patch applied:
docker create --name mycontainer busybox \
&& docker rm nosuchcontainer mycontainer; \
echo exit code: $?; \
docker ps -a --filter name=mycontainer
# df23cc8573f00e97d6e948b48d9ea7d75ce3b4faaab4fe1d3458d3bfa451f39d
# mycontainer
# Error: No such container: nosuchcontainer
# exit code: 0
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Combining `-add` and `-rm` flags on `docker service update` should
be usable to explicitly replace existing options. The current order
of processing did not allow this, causing the `-rm` flag to remove
properties that were specified in `-add`. This behavior was inconsistent
with (for example) `--host-add` and `--host-rm`.
This patch updates the behavior to first remove properties, then
add new properties.
Note that there's still some improvements to make, to make the removal
more granulas (e.g. to make `--label-rm label=some-value` only remove
the label if value matches `some-value`); these changes are left for
a follow-up.
Before this change:
-----------------------------
Create a service with two env-vars
```bash
docker service create --env FOO=bar --env BAR=baz --name=test nginx:alpine
docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Env }}' test | jq .
[
"FOO=bar",
"BAR=baz"
]
```
Update the service, with the intent to replace the value of `FOO` for a new value
```bash
docker service update --env-rm FOO --env-add FOO=updated-foo test
docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Env }}' test | jq .
[
"BAR=baz"
]
```
Create a service with two labels
```bash
docker service create --label FOO=bar --label BAR=baz --name=test nginx:alpine
docker service inspect --format '{{json .Spec.Labels }}' test | jq .
{
"BAR": "baz",
"FOO": "bar"
}
```
Update the service, with the intent to replace the value of `FOO` for a new value
```bash
docker service update --label-rm FOO --label-add FOO=updated-foo test
docker service inspect --format '{{json .Spec.Labels }}' test | jq .
{
"BAR": "baz"
}
```
Create a service with two container labels
```bash
docker service create --container-label FOO=bar --container-label BAR=baz --name=test nginx:alpine
docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Labels }}' test | jq .
{
"BAR": "baz",
"FOO": "bar"
}
```
Update the service, with the intent to replace the value of `FOO` for a new value
```bash
docker service update --container-label-rm FOO --container-label-add FOO=updated-foo test
docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Labels }}' test | jq .
{
"BAR": "baz",
}
```
With this patch applied:
--------------------------------
Create a service with two env-vars
```bash
docker service create --env FOO=bar --env BAR=baz --name=test nginx:alpine
docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Env }}' test | jq .
[
"FOO=bar",
"BAR=baz"
]
```
Update the service, and replace the value of `FOO` for a new value
```bash
docker service update --env-rm FOO --env-add FOO=updated-foo test
docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Env }}' test | jq .
[
"BAR=baz",
"FOO=updated-foo"
]
```
Create a service with two labels
```bash
docker service create --label FOO=bar --label BAR=baz --name=test nginx:alpine
docker service inspect --format '{{json .Spec.Labels }}' test | jq .
{
"BAR": "baz",
"FOO": "bar"
}
```
Update the service, and replace the value of `FOO` for a new value
```bash
docker service update --label-rm FOO --label-add FOO=updated-foo test
docker service inspect --format '{{json .Spec.Labels }}' test | jq .
{
"BAR": "baz",
"FOO": "updated-foo"
}
```
Create a service with two container labels
```bash
docker service create --container-label FOO=bar --container-label BAR=baz --name=test nginx:alpine
docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Labels }}' test | jq .
{
"BAR": "baz",
"FOO": "bar"
}
```
Update the service, and replace the value of `FOO` for a new value
```bash
docker service update --container-label-rm FOO --container-label-add FOO=updated-foo test
docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Labels }}' test | jq .
{
"BAR": "baz",
"FOO": "updated-foo"
}
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When doing `docker service inspect --pretty` on services without
`TaskTemplate.Resources` or `TaskTemplate.Resources.Limits`, the command
fails. This is due to a missing check on ResourceLimitPids().
This bug has been introduced by 395a6d560d
and produces following error message:
```
Template parsing error: template: :139:10: executing "" at <.ResourceLimitPids>: error calling ResourceLimitPids: runtime error: invalid memory address or nil pointer dereference
```
Signed-off-by: Albin Kerouanton <albin@akerouanton.name>
Both libaries provide similar functionality. We're currently using
Google Shlex in more places, so prefering that one for now, but we
could decide to switch to mattn/go-shellwords in future if that
library is considered better (it looks to be more actively maintained,
but that may be related to it providing "more features").
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
In situations where `~/.docker/config.json` was a symlink, saving
the file would replace the symlink with a file, instead of updating
the target file location;
mkdir -p ~/.docker
touch ~/real-config.json
ln -s ~/real-config.json ~/.docker/config.json
ls -la ~/.docker/config.json
# lrwxrwxrwx 1 root root 22 Jun 23 12:34 /root/.docker/config.json -> /root/real-config.json
docker login
# Username: thajeztah
# Password:
# Login Succeeded
ls -la ~/.docker/config.json
-rw-r--r-- 1 root root 229 Jun 23 12:36 /root/.docker/config.json
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The wrapping made the code harder to read (and in some cases destracted
from the actual code flow).
Some of these functions take too many arguments; instead of hiding that,
it probably better to make it apparent that something needs to be done
(and fix it :-)).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- change `validateResolveImageFlag()` to only perform _validation_,
and not combine it with modifying the option.
- use a `switch` instead of `if` in `validateResolveImageFlag()`
- `deployServices()`: break up some `switch` cases to make them
easier to read/understand the logic.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- TestParseRunAttach: use subtests to reduce cyclomatic complexity
- TestParseRunWithInvalidArgs: use subtests, and check if the expected
error is returned.
- Removed parseMustError() as it was mostly redundant
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
These tests failed when running natively on macOS;
unknown server OS: darwin
Skipping them, like we do on Windows
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this change, a warning would be printed if the `~/.docker/config.json`
file was empty:
mkdir -p ~/.docker && touch ~/.docker/config.json
docker pull busybox
WARNING: Error loading config file: /root/.docker/config.json: EOF
Using default tag: latest
....
Given that we also accept an empty "JSON" file (`{}`), it should be
okay to ignore an empty file, as it's effectively a configuration file
with no custom options set.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
I'm not sure if this fixes anything, however I have seen some weird
behavior on Windows where temp config files are left around and there
doesn't seem to be any errors reported.
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Previously, if a registry AuthInfo was not present in the CLI config file, docker logout could not be used
to ask the credential helper to forget about it. It causes problem for people working with
multiple alternative config files, and it causes problems for cases like Docker Desktop w/ WSL 2, as
it uses the same win32 credential helper as the Windows CLI, but a different config file, leading to
bugs where I cannot logout from a registry from wsl2 if I logged in from Windows and vice-versa.
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
There's no need to perform an `os.Stat()` first, because
`os.Open()` also returns the same errors if the file does
not exist, or couldn't be opened for other reasons.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This prevents inconsistent errors when using a symlink, or when renaming
the binary;
Before this change;
ln -s $(which docker) toto
./toto rune
docker: 'rune' is not a docker command.
./toto run daslkjadslkjdaslkj
Unable to find image 'adslkjadslakdsj:latest' locally
./toto: Error response from daemon: pull access denied for adslkjadslakdsj, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.
After this change:
ln -s $(which docker) toto
./toto rune
docker: 'rune' is not a docker command.
./toto run daslkjadslkjdaslkj
Unable to find image 'adslkjadslakdsj:latest' locally
docker: Error response from daemon: pull access denied for adslkjadslakdsj, repository does not exist or may require 'docker login': denied: requested access to the resource is den>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Previously we only set the platform when performing a pull, which is
only initiated if pull always is set, or if the image reference does not
exist in the daemon.
The daemon now supports specifying which platform you wanted on
container create so it can validate the image reference is the platform
you thought you were getting.
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This is not currently used by the CLI, but can be used by
docker compose to bring parity on this feature with the
compose v2.4 schema.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This adds the currently selected "docker context" to the output
of "docker version", which allows users to see which context
is selected to produce the version output, and can be used (for
example), to set the prompt to the currently selected context:
(in `~/.bashrc`):
```bash
function docker_context_prompt() {
PS1="context: $(docker version --format='{{.Client.Context}}')> "
}
PROMPT_COMMAND=docker_context_prompt
```
After reloading the `~/.bashrc`, the prompt now shows the currently selected
`docker context`:
```bash
$ source ~/.bashrc
context: default> docker context create --docker host=unix:///var/run/docker.sock my-context
my-context
Successfully created context "my-context"
context: default> docker context use my-context
my-context
Current context is now "my-context"
context: my-context> docker context use default
default
Current context is now "default"
context: default>
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This flag type was not yet merged upstream, so instead of
using a fork of spf13/pflag, define the type locally, so that
we can vendor the upstream package again.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* Added two new modes accepted by the `--mode` flag
* `replicated-job` creates a replicated job
* `global-job` creates a global job.
* When using `replicated-job` mode, the `replicas` flag sets the
`TotalCompletions` parameter of the job. This is the total number of
tasks that will run
* Added a new flag, `max-concurrent`, for use with `replicated-job`
mode. This flag sets the `MaxConcurrent` parameter of the job, which
is the maximum number of replicas the job will run simultaneously.
* When using `replicated-job` or `global-job` mode, using any of the
update parameter flags will result in an error, as jobs cannot be
updated in the traditional sense.
* Updated the `docker service ls` UI to include the completion status
(completed vs total tasks) if the service is a job.
* Updated the progress bars UI for service creation and update to
support jobs. For jobs, there is displayed a bar covering the overall
progress of the job (the number of tasks completed over the total
number of tasks to complete).
* Added documentation explaining the use of the new flags, and of jobs
in general.
Signed-off-by: Drew Erny <derny@mirantis.com>
These packages are now living in their own repository. Updating
docker/docker to replace the dependencies.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This patch changes the package to lazily obtain the user's home-
directory on first use, instead of when initializing the package.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
67ebcd6dcf added an exception for
the "host-gateway" magic value to the validation rules, but didn't
add thise value to any of the tests.
This patch adds the magic value to tests, to verify the validation
is skipped for this magic value.
Note that validation on the client side is "optional" and mostly
done to provide a more user-friendly error message for regular
values (IP-addresses).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- Perform feature detection when actually needed, instead of during
initializing
- Version negotiation is performed either when making an API request,
or when (e.g.) running `docker help` (to hide unsupported features)
- Use a 2 second timeout when 'pinging' the daemon; this should be
sufficient for most cases, and when feature detection failed, the
daemon will still perform validation (and produce an error if needed)
- context.WithTimeout doesn't currently work with ssh connections (connhelper),
so we're only applying this timeout for tcp:// connections, otherwise
keep the old behavior.
Before this change:
time sh -c 'DOCKER_HOST=tcp://42.42.42.41:4242 docker help &> /dev/null'
real 0m32.919s
user 0m0.370s
sys 0m0.227s
time sh -c 'DOCKER_HOST=tcp://42.42.42.41:4242 docker context ls &> /dev/null'
real 0m32.072s
user 0m0.029s
sys 0m0.023s
After this change:
time sh -c 'DOCKER_HOST=tcp://42.42.42.41:4242 docker help &> /dev/null'
real 0m 2.28s
user 0m 0.03s
sys 0m 0.03s
time sh -c 'DOCKER_HOST=tcp://42.42.42.41:4242 docker context ls &> /dev/null'
real 0m 0.13s
user 0m 0.02s
sys 0m 0.02s
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `docker network prune` command removes unused custom networks,
but built-in networks won't be removed. This patch updates the
message to mention that it's only removing custom networks.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The trust tests were not resetting the environment after they
ran, which could result in tests following those tests to fail.
While at it, I also updated some other tests to use gotest.tools
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this change, this would cause a panic:
docker run -it --rm -v 1:/1 alpine
panic: runtime error: index out of range
goroutine 1 [running]:
github.com/docker/cli/cli/compose/loader.isFilePath(0xc42027e058, 0x1, 0x557dcb978c20)
...
After this change, a correct error is returned:
docker run -it --rm -v 1:/1 alpine
docker: Error response from daemon: create 1: volume name is too short, names should be at least two alphanumeric characters.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When printing services' tasks with `docker service ps` command, tasks are grouped only by task slot.
This leads to interleaving tasks from different services when `docker service ps` is called with multiple services.
Besides this, global services do not have slots at all and printing tasks for them doesn't group and
doesn't properly indent tasks with \_.
With this patch all tasks are grouped by service ID, slot and node ID (relevant only for global services) and it fixes issue 533.
Before this patch:
```console
docker service ps a b c
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
xbzm6ed776yw c.j1afavbqqhr21jvnid3nnfoyt nginx:alpine docker-desktop Running Running 5 seconds ago
4mcsovp8ckwn \_ c.j1afavbqqhr21jvnid3nnfoyt nginx:alpine docker-desktop Shutdown Shutdown 6 seconds ago
qpcgdsx1r21a b.1 nginx:alpine docker-desktop Running Running 2 seconds ago
kfjo1hly92l4 a.1 nginx:alpine docker-desktop Running Running 5 seconds ago
pubrerosvsw5 b.1 nginx:alpine docker-desktop Shutdown Shutdown 3 seconds ago
fu08gfi8tfyv a.1 nginx:alpine docker-desktop Shutdown Shutdown 7 seconds ago
pu6qmgyoibq4 b.2 nginx:alpine docker-desktop Running Ready 1 second ago
tz1n4hjne6pk \_ b.2 nginx:alpine docker-desktop Shutdown Shutdown less than a second ago
xq8dogqcbxd2 a.2 nginx:alpine docker-desktop Running Running 44 seconds ago
rm40lofzed0h a.3 nginx:alpine docker-desktop Running Starting less than a second ago
sqqj2n9fpi82 b.3 nginx:alpine docker-desktop Running Running 5 seconds ago
prv3gymkvqk6 \_ b.3 nginx:alpine docker-desktop Shutdown Shutdown 6 seconds ago
qn7c7jmjuo76 a.3 nginx:alpine docker-desktop Shutdown Shutdown less than a second ago
wi9330mbabpg a.4 nginx:alpine docker-desktop Running Running 2 seconds ago
p5oy6h7nkvc3 \_ a.4 nginx:alpine docker-desktop Shutdown Shutdown 3 seconds ago
```
After this patch:
```console
docker service ps a b c
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
kfjo1hly92l4 a.1 nginx:alpine docker-desktop Running Running 32 seconds ago
fu08gfi8tfyv \_ a.1 nginx:alpine docker-desktop Shutdown Shutdown 34 seconds ago
3pam0limnn24 a.2 nginx:alpine docker-desktop Running Running 23 seconds ago
xq8dogqcbxd2 \_ a.2 nginx:alpine docker-desktop Shutdown Shutdown 24 seconds ago
rm40lofzed0h a.3 nginx:alpine docker-desktop Running Running 26 seconds ago
qn7c7jmjuo76 \_ a.3 nginx:alpine docker-desktop Shutdown Shutdown 27 seconds ago
wi9330mbabpg a.4 nginx:alpine docker-desktop Running Running 29 seconds ago
p5oy6h7nkvc3 \_ a.4 nginx:alpine docker-desktop Shutdown Shutdown 30 seconds ago
qpcgdsx1r21a b.1 nginx:alpine docker-desktop Running Running 29 seconds ago
pubrerosvsw5 \_ b.1 nginx:alpine docker-desktop Shutdown Shutdown 30 seconds ago
pu6qmgyoibq4 b.2 nginx:alpine docker-desktop Running Running 26 seconds ago
tz1n4hjne6pk \_ b.2 nginx:alpine docker-desktop Shutdown Shutdown 27 seconds ago
sqqj2n9fpi82 b.3 nginx:alpine docker-desktop Running Running 32 seconds ago
prv3gymkvqk6 \_ b.3 nginx:alpine docker-desktop Shutdown Shutdown 33 seconds ago
xbzm6ed776yw c.j1afavbqqhr21jvnid3nnfoyt nginx:alpine docker-desktop Running Running 32 seconds ago
4mcsovp8ckwn \_ c.j1afavbqqhr21jvnid3nnfoyt nginx:alpine docker-desktop Shutdown Shutdown 33 seconds ago
```
Signed-off-by: Andrii Berehuliak <berkusandrew@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `docker search --automated` and `docker search --stars` options were
deprecated in release v1.12.0, and scheduled for removal in v17.09.
This patch removes the deprecated flags, in favor of their equivalent
`--filter` options (`docker search --filter=is-automated=<true|false>` and
`docker search --filter=stars=...`).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This is required for supporting some Kubernetes distributions such as
rancher/k3s.
It comes with a test case validating correct parsing of a k3s kubeconfig
file
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
The `docker push` command up until [v0.9.1](https://github.com/moby/moby/blob/v0.9.1/api/client.go#L998)
always pushed all tags of a given image, so `docker push foo/bar` would push (e.g.)
all of `foo/bar:latest`, `foo:/bar:v1`, `foo/bar:v1.0.0`.
Pushing all tags of an image was not desirable in many case, so docker v0.10.0
enhanced `docker push` to optionally specify a tag to push (`docker push foo/bar:v1`)
(see https://github.com/moby/moby/issues/3411 and the pull request that implemented
this: https://github.com/moby/moby/pull/4948).
This behavior exists up until today, and is confusing, because unlike other commands,
`docker push` does not default to use the `:latest` tag when omitted, but instead
makes it push "all tags of the image"
For example, in the following situation;
```
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
thajeztah/myimage latest b534869c81f0 41 hours ago 1.22MB
```
Running `docker push thajeztah/myimage` seemingly does the expected behavior (it
pushes `thajeztah/myimage:latest` to Docker Hub), however, it does not so for the
reason expected (`:latest` being the default tag), but because `:latest` happens
to be the only tag present for the `thajeztah/myimage` image.
If another tag exists for the image:
```
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
thajeztah/myimage latest b534869c81f0 41 hours ago 1.22MB
thajeztah/myimage v1.0.0 b534869c81f0 41 hours ago 1.22MB
```
Running the same command (`docker push thajeztah/myimage`) will push _both_ images
to Docker Hub.
> Note that the behavior described above is currently not (clearly) documented;
> the `docker push` reference documentation (https://docs.docker.com/engine/reference/commandline/push/)
does not mention that omitting the tag will push all tags
This patch changes the default behavior, and if no tag is specified, `:latest` is
assumed. To push _all_ tags, a new flag (`-a` / `--all-tags`) is added, similar
to the flag that's present on `docker pull`.
With this change:
- `docker push myname/myimage` will be the equivalent of `docker push myname/myimage:latest`
- to push all images, the user needs to set a flag (`--all-tags`), so `docker push --all-tags myname/myimage:latest`
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Added transforms for when merging compose overrides to preserve the
functionality that was broken by bumping mergo to v1.3.8
This includes:
- Special transform for ulimits so single overrides both soft/hard and
the reverse
- Special transform for service network configs so the override replaces
all aliases
Signed-off-by: Nick Adcock <nick.adcock@docker.com>
Before this patch:
docker push --quiet nosuchimage
docker.io/library/nosuchimage
echo $?
0
With this patch applied:
docker push --quiet nosuchimage:latest
An image does not exist locally with the tag: nosuchimage
echo $?
1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Comments should have a leading space unless the comment is
for special purposes (go:generate, nolint:)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Comments should have a leading space unless the comment is
for special purposes (go:generate, nolint:)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Refactor code to allow mixed notation with -p flag.
Signed-off-by: Aleksander Piotrowski <apiotrowski312@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Reverses the order long-form port options when converted to short-form
to correctly match the documentation and `docker service create`.
Post change `-p published=8111,target=8112` is the equivalent of
`8111:8112`
Signed-off-by: Nick Adcock <nick.adcock@docker.com>
Update the list of overrides for table headers so that columns using split or
join will produce the correct table header.
Before this patch:
docker ps --format='table {{split .Names "/"}}'
[NAMES]
[unruffled_mclean]
[eloquent_meitner]
[sleepy_grothendieck]
With this patch applied:
docker ps --format='table {{split .Names "/"}}'
NAMES
[unruffled_mclean]
[eloquent_meitner]
[sleepy_grothendieck]
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this patch, using a template that used templating functions (such as
`lower` or `json`) caused the command to fail in the pre-processor step (in
`buildContainerListOptions`):
docker ps --format='{{upper .Names}}'
template: :1:8: executing "" at <.Names>: invalid value; expected string
This problem was due to the pre-processing using a different "context" type than
was used in the actual template, and custom functions to not be defined when
instantiating the Go template.
With this patch, using functions in templates works correctly:
docker ps --format='{{upper .Names}}'
MUSING_NEUMANN
ELOQUENT_MEITNER
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Move the remaining test with the others, and rename it from
`TestBuildContainerListOptions` to `TestContainerListBuildContainerListOptions`,
so that it has the same prefix as the other tests.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When running `docker login` or `docker logout`, the CLI updates
the configuration file by creating a temporary file, to replace
the old one (if exists).
When using `sudo`, this caused the file to be created as `root`,
making it inaccessible to the current user.
This patch updates the CLI to fetch permissions and ownership of
the existing configuration file, and applies those permissions
to the new file, so that it has the same permissions as the
existing file (if any).
Currently, only done for "Unix-y" systems (Mac, Linux), but
can be implemented for Windows in future if there's a need.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
These subcommands were created to allow upgrading a Docker Community
engine to Docker Enterprise, but never really took off.
This patch removes the `docker engine` subcommands, as they added
quite some complexity / additional code.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The top-level `docker deploy` command (using the "Docker Application Bundle"
(`.dab`) file format was introduced as an experimental feature in Docker 1.13 /
17.03, but superseded by support for Docker Compose files.
With no development being done on this feature, and no active use of the file
format, support for the DAB file format and the top-level `docker deploy` command
(hidden by default in 19.03), is removed in this patch, in favour of `docker stack deploy`
using compose files.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Anca Iordache <anca.iordache@docker.com>
Possible approach for client info
- split ClientInfo() into ClientInfo() and loadClientInfo()
- split ConfigFile() into ConfigFile() and loadConfigFile()
- ConfigFile() and ClientInfo() call their corresponding loadXX function
if it has not yet been loaded; this allows them to be used before
Initialize() was called.
- Initialize() *always* (re-)loads the configuration; this makes sure
that the correct configuration is used when actually calling commands.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/stack/kubernetes/convert_test.go:199:35: Using the variable on range scope `c` in function literal (scopelint)
conv, err := NewStackConverter(c.version)
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/container/create_test.go:120:20: Using the variable on range scope `c` in function literal (scopelint)
defer func() { c.ResponseCounter++ }()
^
cli/command/container/create_test.go:121:12: Using the variable on range scope `c` in function literal (scopelint)
switch c.ResponseCounter {
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/stack/kubernetes/watcher_test.go:44:20: Using a reference for the variable on range scope `obj` (scopelint)
if err := o.Add(&obj); err != nil {
^
cli/command/stack/kubernetes/watcher_test.go:49:20: Using a reference for the variable on range scope `obj` (scopelint)
if err := o.Add(&obj); err != nil {
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/manifest/store/store_test.go:97:29: Using the variable on range scope `testcase` in function literal (scopelint)
actual, err := store.Get(testcase.listRef, testcase.manifestRef)
^
cli/manifest/store/store_test.go:98:7: Using the variable on range scope `testcase` in function literal (scopelint)
if testcase.expectedErr != "" {
^
cli/manifest/store/store_test.go:99:26: Using the variable on range scope `testcase` in function literal (scopelint)
assert.Error(t, err, testcase.expectedErr)
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/compose/template/template_test.go:279:31: Using the variable on range scope `tc` in function literal (scopelint)
actual := ExtractVariables(tc.dict, defaultPattern)
^
cli/compose/template/template_test.go:280:41: Using the variable on range scope `tc` in function literal (scopelint)
assert.Check(t, is.DeepEqual(actual, tc.expected))
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/cli_test.go:157:15: Using the variable on range scope `testcase` in function literal (scopelint)
pingFunc: testcase.pingFunc,
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/trust/key_load_test.go:121:27: Using the variable on range scope `keyID` in function literal (scopelint)
testLoadKeyFromPath(t, keyID, keyBytes)
^
cli/command/trust/key_load_test.go:176:32: Using the variable on range scope `keyBytes` in function literal (scopelint)
testLoadKeyTooPermissive(t, keyBytes)
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/context/create_test.go:270:31: Using the variable on range scope `c` in function literal (scopelint)
Name: c.name,
^
cli/command/context/create_test.go:271:31: Using the variable on range scope `c` in function literal (scopelint)
Description: c.description,
^
cli/command/context/create_test.go:272:31: Using the variable on range scope `c` in function literal (scopelint)
DefaultStackOrchestrator: c.orchestrator,
cli/command/context/create_test.go:346:31: Using the variable on range scope `c` in function literal (scopelint)
Name: c.name,
^
cli/command/context/create_test.go:347:31: Using the variable on range scope `c` in function literal (scopelint)
Description: c.description,
^
cli/command/context/create_test.go:348:31: Using the variable on range scope `c` in function literal (scopelint)
DefaultStackOrchestrator: c.orchestrator,
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/compose/loader/merge.go:64:41: Using a reference for the variable on range scope `overrideService` (scopelint)
if err := mergo.Merge(&baseService, &overrideService, mergo.WithAppendSlice, mergo.WithOverride, mergo.WithTransformers(specials)); err != nil {
^
cli/compose/loader/loader_test.go:1587:28: Using the variable on range scope `testcase` in function literal (scopelint)
config, err := loadYAML(testcase.yaml)
^
cli/compose/loader/loader_test.go:1590:58: Using the variable on range scope `testcase` in function literal (scopelint)
assert.Check(t, is.DeepEqual(config.Services[0].Init, testcase.init))
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/config/config_test.go:590:11: Using the variable on range scope `tc` in function literal (scopelint)
SetDir(tc.dir)
^
cli/config/config_test.go:591:19: Using the variable on range scope `tc` in function literal (scopelint)
f, err := Path(tc.path...)
^
cli/config/config_test.go:592:23: Using the variable on range scope `tc` in function literal (scopelint)
assert.Equal(t, f, tc.expected)
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/formatter/container_test.go:315:17: Error return value of `ContainerWrite` is not checked (errcheck)
ContainerWrite(context.context, containers)
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/cli_test.go:297:11: Error return value of `cli.Apply` is not checked (errcheck)
cli.Apply(
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/context/store/store_test.go:156:2: SA5001: should check returned error before deferring f.Close() (staticcheck)
defer f.Close()
^
cli/context/store/store_test.go:189:2: SA5001: should check returned error before deferring f.Close() (staticcheck)
defer f.Close()
^
cli/context/store/store_test.go:240:2: SA5001: should check returned error before deferring f.Close() (staticcheck)
defer f.Close()
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
cli/command/image/build.go:434:32: SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)
fmt.Fprintf(dockerCli.Out(), imageID)
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/utils.go:81:20: SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)
fmt.Fprintf(outs, message)
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/trust/key_generate.go:91:30: SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)
fmt.Fprintf(streams.Out(), err.Error())
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/service/update_test.go:31:16: SA1012: do not pass a nil Context, even if a function permits it; pass context.TODO if you are unsure about which Context to use (staticcheck)
updateService(nil, nil, flags, spec)
^
cli/command/service/update_test.go:535:16: SA1012: do not pass a nil Context, even if a function permits it; pass context.TODO if you are unsure about which Context to use (staticcheck)
updateService(nil, nil, flags, spec)
^
cli/command/service/update_test.go:540:16: SA1012: do not pass a nil Context, even if a function permits it; pass context.TODO if you are unsure about which Context to use (staticcheck)
updateService(nil, nil, flags, spec)
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Running `docker stack services <STACK> --orchestrator swarm would yield
the message "Noting found in stack: asdf" with an exit code 0. The same
command with kubernetes orchestrator would yield "nothing found in
stack: adsf" (note the lower-case "nothing") and a non-zero exit code.
This change makes the `stack services` command uniform for both
orchestrators. The logic of getting and printing services is split to
reuse the same formatting code.
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
API v1.41 adds a new option to get the number of desired
and running tasks when listing services. This patch enables
this functionality, and provides a fallback mechanism when
the ServiceStatus is not available, which would be when
using an older API version.
Now that the swarm.Service struct captures this information,
the `ListInfo` type is no longer needed, so it is removed,
and the related list- and formatting functions have been
modified accordingly.
To reduce repetition, sorting the services has been moved
to the formatter. This is a slight change in behavior, but
all calls to the formatter performed this sort first, so
the change will not lead to user-facing changes.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This patch:
- Adds new GlobalService and ServiceStatus options
- Makes the NodeList() function functional
- Minor improvment to the `newService()` function to allow passing options
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This test was intending to run all tests, but didn't, which was
caught by golangci-lint;
cli/compose/loader/windows_path_test.go:46:17: SA4010: this result of append is never used, except maybe in other appends (staticcheck)
tests := append(isabstests, winisabstests...)
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/container/opts.go:700:37: Using a reference for the variable on range scope `n` (scopelint)
if err := applyContainerOptions(&n, copts); err != nil {
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
```
cli/command/service/update.go:1007:43: Using a reference for the variable on range scope `entry` (scopelint)
if _, ok := portSet[portConfigToString(&entry)]; !ok {
^
cli/command/service/update.go:1008:32: Using a reference for the variable on range scope `entry` (scopelint)
portSet[portConfigToString(&entry)] = entry
^
cli/command/service/update.go:1034:44: Using a reference for the variable on range scope `port` (scopelint)
if _, ok := portSet[portConfigToString(&port)]; ok {
^
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This case was in a test in the engine repository, where
it is being removed, so add it to the list of existing
tests here.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
In c2626a82 homedir logic got extremely simplified to only
checking HOME environment variable on UNIX systems.
Although this should work well enough in traditional environments,
this could break minimal containerized environments.
This patch reverts to using github.com/docker/docker/pkg/homedir
that was recently updated to have less dependencies.
Signed-off-by: Tibor Vass <tibor@docker.com>
Before this patch:
```
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
Options:
--add-host list Add a custom host-to-IP mapping (host:ip)
--build-arg list Set build-time variables
--cache-from strings Images to consider as cache sources
--cgroup-parent string Optional parent cgroup for the container
--cpu-period int Limit the CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit the CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight)
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--disable-content-trust Skip image verification (default true)
-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
--force-rm Always remove intermediate containers
--iidfile string Write the image ID to the file
--isolation string Container isolation technology
--label list Set metadata for an image
-m, --memory bytes Memory limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--network string Set the networking mode for the RUN instructions during build (default "default")
--no-cache Do not use cache when building the image
-o, --output stringArray Output destination (format: type=local,dest=path)
--platform string Set platform if server is multi-platform capable
--progress string Set type of progress output (auto, plain, tty). Use plain to show container output (default "auto")
--pull Always attempt to pull a newer version of the image
-q, --quiet Suppress the build output and print image ID on success
--rm Remove intermediate containers after a successful build (default true)
--secret stringArray Secret file to expose to the build (only if BuildKit enabled): id=mysecret,src=/local/secret
--security-opt strings Security options
--shm-size bytes Size of /dev/shm
--squash Squash newly built layers into a single new layer
--ssh stringArray SSH agent socket or keys to expose to the build (only if BuildKit enabled) (format: default|<id>[=<socket>|<key>[,<key>]])
-t, --tag list Name and optionally a tag in the 'name:tag' format
--target string Set the target build stage to build.
--ulimit ulimit Ulimit options (default [])
```
With this patch applied:
```
DOCKER_BUILDKIT=1 docker build --help
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
Options:
--add-host list Add a custom host-to-IP mapping (host:ip)
--build-arg list Set build-time variables
--cache-from strings Images to consider as cache sources
--disable-content-trust Skip image verification (default true)
-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
--iidfile string Write the image ID to the file
--isolation string Container isolation technology
--label list Set metadata for an image
--network string Set the networking mode for the RUN instructions during build (default "default")
--no-cache Do not use cache when building the image
-o, --output stringArray Output destination (format: type=local,dest=path)
--platform string Set platform if server is multi-platform capable
--progress string Set type of progress output (auto, plain, tty). Use plain to show container output (default "auto")
--pull Always attempt to pull a newer version of the image
-q, --quiet Suppress the build output and print image ID on success
--secret stringArray Secret file to expose to the build (only if BuildKit enabled): id=mysecret,src=/local/secret
--squash Squash newly built layers into a single new layer
--ssh stringArray SSH agent socket or keys to expose to the build (only if BuildKit enabled) (format: default|<id>[=<socket>|<key>[,<key>]])
-t, --tag list Name and optionally a tag in the 'name:tag' format
--target string Set the target build stage to build.
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
--stream was always experimental and this patch removes the functionality.
Users should enable BuildKit with DOCKER_BUILDKIT=1
Signed-off-by: Tibor Vass <tibor@docker.com>
This is currently just a copy of the v3.8 schema, in preparation
of new features to be added in the new schema.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The State field allows printing the container state without
additional information about uptime, healthcheck, etc.
With this patch, the container's state can be printed independently:
```bash
docker ps -a --format '{{.State}}'
running
paused
exited
created
```
```bash
docker ps -a --format 'table {{.Names}}\t{{.State}}\t{{.Status}}'
NAMES STATE STATUS
elastic_burnell running Up About a minute
pausie paused Up 5 minutes (Paused)
peaceful_stonebraker exited Exited (0) 10 hours ago
vigilant_shaw created Created
```
```bash
docker ps -a --format 'raw'
container_id: 0445f73f3a71
image: docker-cli-dev
command: "ash"
created_at: 2019-07-12 11:16:11 +0000 UTC
state: running
status: Up 2 minutes
names: elastic_burnell
labels:
ports:
container_id: 1aff69a3912c
image: nginx:alpine
command: "nginx -g 'daemon of ..."
created_at: 2019-07-12 11:12:10 +0000 UTC
state: paused
status: Up 6 minutes (Paused)
names: pausie
labels: maintainer=NGINX Docker Maintainers <docker-maint@nginx.com>
ports: 80/tcp
container_id: d48acf66c318
image: alpine:3.9.3
command: "id -u"
created_at: 2019-07-12 00:52:17 +0000 UTC
state: exited
status: Exited (0) 10 hours ago
names: peaceful_stonebraker
labels:
ports:
container_id: a0733fe0dace
image: b7b28af77ffe
command: "/bin/sh -c '#(nop) ..."
created_at: 2019-07-12 00:51:29 +0000 UTC
state: created
status: Created
names: vigilant_shaw
labels:
ports:
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When deploying a stack using a relative path as bind-mount
source in the compose file, the CLI converts the relative
path to an absolute path, relative to the location of the
docker-compose file.
This causes a problem when deploying a stack that uses
an absolute Windows path, because a non-Windows client will
fail to detect that the path (e.g. `C:\somedir`) is an absolute
path (and not a relative directory named `C:\`).
The existing code did already take Windows clients deploying
a Linux stack into account (by checking if the path had a leading
slash). This patch adds the reverse, and adds detection for Windows
absolute paths on non-Windows clients.
The code used to detect Windows absolute paths is copied from the
Golang filepath package;
1d0e94b1e1/src/path/filepath/path_windows.go (L12-L65)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This partially reverts e0b59ab52b,
and does not automatically disable proxying signals in TTY-mode
Before this change:
------------------------------------
Start a container with a TTY in one shell:
```
docker run -it --init --name repro-28872 busybox sleep 30
```
then, in another shell, kill the docker cli:
```
kill `pgrep -f repro-28872`
```
Notice that the CLI was killed, but the signal not forwarded to the container;
the container continues running
```
docker container inspect --format '{{ .State.Status }}' repro-28872
running
docker container rm -f repro-28872
```
After this change:
------------------------------------
Start a container with a TTY in one shell:
```
docker run -it --init --name repro-28872 busybox sleep 30
```
then, in another shell, kill the docker cli:
```
kill `pgrep -f repro-28872`
```
Verify that the signal was forwarded to the container, and the container exited
```
docker container inspect --format '{{ .State.Status }}' repro-28872
exited
docker container rm -f repro-28872
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This code was attempting to check Linux file permissions
to determine if the key was accessible by other users, which
doesn't work, and therefore prevented users on Windows
to load keys.
Skipping this check on Windows (correspinding tests
were already skipped).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
For backward compatibility: if no custom options are provided for the network,
and only a single network is specified, omit the endpoint-configuration
on the client (the daemon will still create it when creating the container)
This fixes an issue on older versions of legacy Swarm, which did not support
`NetworkingConfig.EndpointConfig`.
This was introduced in 5bc09639cc (#1767)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Adds capabilities to import a .zip file with importZip.
Detects the content type of source by checking bytes & DetectContentType.
Adds LimitedReader reader, a fork of io.LimitedReader,
was needed for better error messaging instead of just getting back EOF.
We are using limited reader to avoid very big files causing memory issues.
Adds a new file size limit for context imports,
this limit is used for the main file for .zip & .tar and individual compressed
files for .zip.
Added TestImportZip that will check the import content type
Then will assert no err on Importing .zip file
Signed-off-by: Goksu Toprak <goksu.toprak@docker.com>
This is less of a layering violation and removes some ugly hardcoded
`"kubernetes"` strings which were needed to avoid an import loop.
Signed-off-by: Ian Campbell <ijc@docker.com>
This removes the need for the core context code to import
`github.com/docker/cli/cli/context/kubernetes` which in turn reduces the
transitive import tree in this file to not pull in all of Kubernetes.
Note that this means that any calling code which is interested in the
kubernetes endpoint must import `github.com/docker/cli/cli/context/kubernetes`
itself somewhere in order to trigger the dynamic registration. In practice
anything which is interested in Kubernetes must import that package (e.g.
`./cli/command/context.list` does for the `EndpointFromContext` function) to do
anything useful, so this restriction is not too onerous.
As a special case a small amount of Kubernetes related logic remains in
`ResolveDefaultContext` to handle error handling when the stack orchestrator
includes Kubernetes. In order to avoid a circular import loop this hardcodes
the kube endpoint name.
Similarly to avoid an import loop the existing `TestDefaultContextInitializer`
cannot continue to unit test for the Kubernetes case, so that aspect of the
test is carved off into a very similar test in the kubernetes context package.
Lastly, note that the kubernetes endpoint is now modifiable via
`WithContextEndpointType`.
Signed-off-by: Ian Campbell <ijc@docker.com>
These are needed by any dynamically registered (via
`RegisterDefaultStoreEndpoints`) endpoint type to write a useful/sensible unit
test.
Signed-off-by: Ian Campbell <ijc@docker.com>
Previously an endpoint registered using `RegisterDefaultStoreEndpoints` would
not be taken into consideration by `resolveDefaultContext` and so could not
provide any details.
Resolve this by passing a `store.Config` to `resolveDefaultContext` and using
it to iterate over all registered endpoints. Any endpoint can ensure that their
type implements the new `EndpointDefaultResolver` in order to provide a default.
The Docker and Kubernetes endpoints are special cased, shortly the Kubernetes
one will be refactored to be dynamically registered.
Signed-off-by: Ian Campbell <ijc@docker.com>
This reverts commit 59defcb34d which caused #1892
since the timeout applied not only to the dial phase but to everything, so it
would kill `docker logs -f ...` if the container was not chatty enough.
Signed-off-by: Ian Campbell <ijc@docker.com>
The comment on `github.com/docker/cli/kubernetes.NewKubernetesConfig` said:
// Deprecated: Use github.com/docker/compose-on-kubernetes/api.NewKubernetesConfig instead
By making this switch in `github.com/docker/cli/context/kubernetes/load.go` we
break a vendoring chain:
`github.com/docker/cli/cli/command`
→ `vendor/github.com/docker/cli/cli/context/kubernetes/load.go`
→ `vendor/github.com/docker/cli/kubernetes`
→ `github.com/docker/compose-on-kubernetes/api/compose/...`
This means that projects which just want `github.com/docker/cli/cli/command`
(which is itself pulled in transitively by
`github.com/docker/cli/cli-plugins/plugin`) which do not themselves need the
compose-on-kubernetes API avoid a huge pile of transitive dependencies.
On one of my private projects the diff on the vendor dir is:
280 files changed, 21 insertions(+), 211346 deletions(-)
and includes dropping:
* `github.com/docker/compose-on-kubernetes/api/compose/{clone,impersonation}`
* `github.com/docker/compose-on-kubernetes/api/compose/{v1alpha3,v1beta1,v1beta2,v1beta3}`
* `github.com/google/btree`
* `github.com/googleapis/gnostic`
* `github.com/gregjones/httpcache`
* `github.com/peterbourgon/diskv`
* `k8s.io/api/*` (_lots_ of subpackages)
* `k8s.io/client-go/{discovery,kubernetes/scheme}`
and I've gone from:
$ du -sh vendor/k8s.io/
8.1M vendor/k8s.io/
to:
$ du -sh vendor/k8s.io/
2.1M vendor/k8s.io/
(overall I went from 36M → 29M of vendor dir for this particular project)
The change to `cli/command/system/version.go` is just for consistency and
allows us to drop the now unused alias.
Signed-off-by: Ian Campbell <ijc@docker.com>
Refactor `RunCreate` slightly so that all three paths always produce the same
output, namely the name of the new context of `stdout` (for scripting) and the
success log message on `stderr`.
Validate by extending the existing unit tests to always check the output is as
expected.
Signed-off-by: Ian Campbell <ijc@docker.com>
This partially mitigates #1739 ("Docker commands take 1 minute to timeout if
context endpoint is unreachable") and is a simpler alternative to #1747 (which
completely defers the client connection until an actual call is attempted).
Note that the previous 60s delay was the culmination of two separate 30s
timeouts since the ping is tried twice. This with this patch the overall
timeout is 20s. https://github.com/moby/moby/pull/39206 will remove the second
ping and once that propagates to this tree the timeout will be 10s.
Signed-off-by: Ian Campbell <ijc@docker.com>
- Follows the proposal on issue [#34394](https://github.com/moby/moby/issues/34394)
- Maintains current behavior as default (Pull image if missing)
- Adds tristate flag allowing modification (PullMissing, PullAlways, PullNever)
Signed-off-by: Zander Mackie <zmackie@gmail.com>
With this patch it is possible to alias an existing allowed command.
At the moment only builder allows an alias.
This also properly puts the build command under builder, instead of image
where it was for historical reasons.
Signed-off-by: Tibor Vass <tibor@docker.com>
This is to make it easier to implement support for exporting contexts in
3rd party code, or to create mocks in tests.
2 exemples where it simplify things:
- docker-app desktop-specific context decorator (which rewrites parts of
the docker context to simplify UX when using on Docker Desktop contexts)
- ucp for including a context in the connection bundle
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
This change refines the warning message returned during docker login to
only warn for unencrypted storage when the users password is being stored.
If the remote registry supports identity tokens, omit the warning,
since those tokens can be independently managed and revoked.
Signed-off-by: Daniel Hiltgen <daniel.hiltgen@docker.com>
The github.com/flynn-archive/go-shlex package is a fork of Google/shlex,
and the repository is now archived, so let's switch to the maintained
version.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Adds tests for setting and updating swarm service CredentialSpecs,
especially when using a Config as a credential spec.
Signed-off-by: Drew Erny <drew.erny@docker.com>
Updates the CredentialSpec handling code for services to allow using
swarm Configs.
Additionally, fixes a bug where the `--credential-spec` flag would not
be respected on service updates.
Signed-off-by: Drew Erny <drew.erny@docker.com>
This regroup all Kubernetes extra fields for compose-on-kubernetes
v1alpha3 in a single x-kubernetes object.
Also use the same naming scheme as cap_add etc. for fiels inside this
object.
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
On the server v0.4.21 has introduced a better way of dealing with
intra-stack networking: if the user can specify a list of endpoints
exposed internally, we now can setup a ClusterIP for this to avoid the
pitfalls of DNS-based load balancing.
This exposes the feature using the "Expose" compose field, and adds an
extra x-internal-service-type field to explicitly define how intra-stack
networking is handled on a service.
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
For clarity, on `docker context use` or `docker context ls`, this adds a
warning if the DOCKER_HOST variable is set because it overrides the
active context.
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
This allows setting the ip/ipv6 address as an option in the
advanced `--network` syntax;
```
docker run --network name=mynetwork,ip=172.20.88.22,ip6=2001:db8::8822
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This refactors the way networking options are parsed, and makes the
client able to pass options for multiple networks. Currently, the
daemon does not yet accept multiple networks when creating a container,
and will produce an error.
For backward-compatibility, the following global networking-related
options are associated with the first network (in case multiple
networks are set);
- `--ip`
- `--ip6`
- `--link`
- `--link-local-ip`
- `--network-alias`
Not all of these options are supported yet in the advanced notation,
but for options that are supported, setting both the per-network option
and the global option will produce a "conflicting options" error.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The commit contains cli changes to support driver options for a network in
docker run and docker network connect cli's. The driver-opt, aliases is now
supported in the form of csv as per network option in service commands in
swarm mode since docker/cli#62 . This commit extends this support to docker
run command as well.
For docker connect command `--driver-opt` is added to pass driver specific
options for the network the container is connecting to.
Signed-off-by: Abhinandan Prativadi <abhi@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
--from creates a context from a named context.
By default `context create` will create a context from the current context.
Replaced "from-current=" docker/kubernetes option with "from=" to allow specifying which context to copy the settings from.
Signed-off-by: Nick Adcock <nick.adcock@docker.com>
Old selector was wrong (it watched for the label we applied to child
resources when reconciling the stack, instead of the stack itself)
This should be back-ported to older version of the CLI
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
bump required:
- replacing vendor ghodss/yaml with sigs.k8s.io/yaml
- adding vendor k8s.io/klog and github.com/evanphx
- compose-on-kubernetes
removed 'IncludeUninitialized' from watch as it have been removed from k8s
Signed-off-by: Nick Adcock <nick.adcock@docker.com>
Instead of using an `if else if else`, switch to a sequence of independent
`if` blocks containing a `return`.
Instead of defining a return variable and updating it in the `if` blocks
and returning at the end, make each `if` block return the desired value
independenly.
Signed-off-by: David Scott <dave.scott@docker.com>
Previously if the Docker engine was not running the behaviour of
commands would vary depending on whether the --debug flag was provided.
For example, consider `docker logout`:
$ docker logout
Not logged in to
-- note the missing server URL
$ docker --debug logout
Warning: failed to get default registry endpoint from daemon (Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?). Using system default: https://index.docker.io/v1/
Not logged in to https://index.docker.io/v1/
-- note the server URL is present
This patch makes only the debug printing conditional on the `--debug` flag,
not the return value.
Signed-off-by: David Scott <dave.scott@docker.com>
In the initial implementation I thought it would be good to not pass on the
deprecation to plugins (since they are new). However it turns out this causes
`docker helloworld -h` to print a spurious "pflag: help requested" line:
$ docker helloworld -h
pflag: help requested
See 'docker helloworld --help'.
Usage: docker helloworld [OPTIONS] COMMAND
A basic Hello World plugin for tests
...
Compared with:
$ docker ps -h
Flag shorthand -h has been deprecated, please use --help
Usage: docker ps [OPTIONS]
This is in essence because having the flag undefined hits a different path
within cobra, causing `c.execute()` to return early due to getting an error
(`flag.ErrHelp`) from `c.ParseFlags`, which launders the error through our
`FlagErrorFunc` which wraps it in a `StatusError` which in turn defeats an `if
err == flag.ErrHelp` check further up the call chain. If the flag is defined we
instead hit a path which returns a bare `flag.ErrHelp` without wrapping it.
I considered updating our `FlagErrorFunc` to not wrap `flag.ErrHelp` (and then
following the chain to the next thing) however while doing that I realised that
the code for `-h` (and `--help`) is deeply embedded into cobra (and its flags
library) such that actually using `-h` as a plugin argument meaning something
other than `help` is basically impossible/impractical. Therefore we may as well
have plugins behave identically to the monolithic CLI and support (deprecated)
the `-h` argument.
With this changed the help related blocks of `SetupRootCommand` and
`SetupPluginRootCommand` are now identical, so consolidate into
`setupCommonRootCommand`.
Tests are updated to check `-h` in a variety of scenarios, including the happy
case here.
Signed-off-by: Ian Campbell <ijc@docker.com>
As pointed out in #1459, docker cli fails to detect that the input is a tarball,
in case it is generated by `git archive --format=tgz`.
This happens because `git archive` adds some metadata to the initial tar header,
and so it is more than 1 block (of 512 bytes) long, while we only provide 1 block
to archive/tar.Next() and it fails.
To fix, give it 2 blocks :)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This adds validation to `docker container run` / `docker container create`;
Validation of labels provided through flags was removed in 31dc5c0a9a,
after the validation was changed to fix labels without values, and to prevent
labels from being expanded with environment variables in 2b17f4c8a8
However, now empty label names from _files_ (`--label-file`) followed different
validation rules than labels passed through `--label`.
This patch adds back minimal validation for labels passed through the command-line
Before this patch:
```bash
docker container create \
--name label \
--label==with-leading-equal-sign \
--label=without-value \
--label=somelabel=somevalue \
--label " = " \
--label=with-quotes-in-value='{"foo"}' \
--label='with"quotes"in-key=test' \
busybox
docker container inspect --format '{{json .Config.Labels}}' label
```
```json
{
"": "with-leading-equal-sign",
" ": " ",
"somelabel": "somevalue",
"with\"quotes\"in-key": "test",
"with-quotes-in-value": "{\"foo\"}",
"without-value": ""
}
```
After this patch:
```bash
docker container create \
--name label \
--label==with-leading-equal-sign \
--label=without-value \
--label=somelabel=somevalue \
--label " = " \
--label=with-quotes-in-value='{"foo"}' \
--label='with"quotes"in-key=test' \
busybox
invalid argument "=with-leading-equal-sign" for "-l, --label" flag: invalid label format: "=with-leading-equal-sign"
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This patch fixes a bug where labels use the same behavior as `--env`, resulting
in a value to be copied from environment variables with the same name as the
label if no value is set (i.e. a simple key, no `=` sign, no value).
An earlier pull request addressed similar cases for `docker run`;
2b17f4c8a8, but this did not address the
same situation for (e.g.) `docker service create`.
Digging in history for this bug, I found that use of the `ValidateEnv`
function for labels was added in the original implementation of the labels feature in
abb5e9a077 (diff-ae476143d40e21ac0918630f7365ed3cR34)
However, the design never intended it to expand environment variables,
and use of this function was either due to either a "copy/paste" of the
equivalent `--env` flags, or a misunderstanding (the name `ValidateEnv` does
not communicate that it also expands environment variables), and the existing
`ValidateLabel` was designed for _engine_ labels (which required a value to
be set).
Following the initial implementation, other parts of the code followed
the same (incorrect) approach, therefore leading the bug to be introduced
in services as well.
This patch:
- updates the `ValidateLabel` to match the expected validation
rules (this function is no longer used since 31dc5c0a9a),
and the daemon has its own implementation)
- corrects various locations in the code where `ValidateEnv` was used instead of `ValidateLabel`.
Before this patch:
```bash
export SOME_ENV_VAR=I_AM_SOME_ENV_VAR
docker service create --label SOME_ENV_VAR --tty --name test busybox
docker service inspect --format '{{json .Spec.Labels}}' test
{"SOME_ENV_VAR":"I_AM_SOME_ENV_VAR"}
```
After this patch:
```bash
export SOME_ENV_VAR=I_AM_SOME_ENV_VAR
docker service create --label SOME_ENV_VAR --tty --name test busybox
docker container inspect --format '{{json .Config.Labels}}' test
{"SOME_ENV_VAR":""}
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This maps the `--template-driver` flag on secret and config creation.
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The warning, printed before running `docker system prune` was printing the
filters in JSON format.
This patch attempts to make the output human readable;
- updating the code, and template to print filters individually
- reducing the indentation (which was quite deep)
Before this patch was applied;
```
docker system prune --filter until=24h --filter label=hello-world --filter label!=foo=bar --filter label=bar=baz
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
- Elements to be pruned will be filtered with:
- label={"label":{"bar=baz":true,"hello-world":true},"label!":{"foo=bar":true},"until":{"24h":true}}
Are you sure you want to continue? [y/N]
```
With this patch applied;
```
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
Items to be pruned will be filtered with:
- label!=foo=bar
- label!=never=remove-me
- label=bar=baz
- label=hello-world
- label=remove=me
- until=24h
Are you sure you want to continue? [y/N]
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The warning, printed before runing docker system prune was missing any filter
that was set in the configuration file. In addition, the warning prefixes the
filters with `label=`, which is no longer accurate, now that the prune command
also supports "until" as a filter.
Before this change, only the filters set on the command-line were shown,
and any filter set in the configuration file was missing;
```
mkdir -p ./test-config
echo '{"pruneFilters": ["label!=never=remove-me", "label=remove=me"]}' > test-config/config.json
docker --config=./test-config system prune --filter until=24h --filter label=hello-world --filter label!=foo=bar --filter label=bar=baz
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
- Elements to be pruned will be filtered with:
- label={"label":{"bar=baz":true,"hello-world":true},"label!":{"foo=bar":true},"until":{"24h":true}}
Are you sure you want to continue? [y/N]
```
With this patch applied, both options from the commandline and options set
in the configuration file are shown;
```
mkdir -p ./test-config
echo '{"pruneFilters": ["label!=never=remove-me", "label=remove=me"]}' > test-config/config.json
docker --config=./test-config system prune --filter until=24h --filter label=hello-world --filter label!=foo=bar --filter label=bar=baz
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
- Elements to be pruned will be filtered with:
- filter={"label":{"bar=baz":true,"hello-world":true,"remove=me":true},"label!":{"foo=bar":true,"never=remove-me":true},"until":{"24h":true}}
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- when using "--context default" parameter
- when printing the list of contexts
- when exporting the default context to a tarball
Signed-off-by: Jean-Christophe Sirot <jean-christophe.sirot@docker.com>
(+1 squashed commit)
Squashed commits:
[20670495] Fix CLI initialization for the `docker stack deploy --help` command and ensure that the dockerCli.CurrentContext() always returns a non empty context name (default as a fallback)
Remove now obsolete code handling empty string context name
Minor code cleanup
Signed-off-by: Jean-Christophe Sirot <jean-christophe.sirot@docker.com>
This makes things more idempotent, rather than relying on undoing the
interspersed settings.
Note that the underlying `Flag`s remain shared, it's just the `FlagSet` which
is duplicated.
Signed-off-by: Ian Campbell <ijc@docker.com>
The issue with plugin options clashing with globals is that when cobra is
parsing the command line and it comes across an argument which doesn't start
with a `-` it (in the absence of plugins) distinguishes between "argument to
current command" and "new subcommand" based on the list of registered sub
commands.
Plugins breaks that model. When presented with `docker -D plugin -c foo` cobra
parses up to the `plugin`, sees it isn't a registered sub-command of the
top-level docker (because it isn't, it's a plugin) so it accumulates it as an
argument to the top-level `docker` command. Then it sees the `-c`, and thinks
it is the global `-c` (for AKA `--context`) option and tries to treat it as
that, which fails.
In the specific case of the top-level `docker` subcommand we know that it has
no arguments which aren't `--flags` (or `-f` short flags) and so anything which
doesn't start with a `-` must either be a (known) subcommand or an attempt to
execute a plugin.
We could simply scan for and register all installed plugins at start of day, so
that cobra can do the right thing, but we want to avoid that since it would
involve executing each plugin to fetch the metadata, even if the command wasn't
going to end up hitting a plugin.
Instead we can parse the initial set of global arguments separately before
hitting the main cobra `Execute` path, which works here exactly because we know
that the top-level has no non-flag arguments.
One slight wrinkle is that the top-level `PersistentPreRunE` is no longer
called on the plugins path (since it no longer goes via `Execute`), so we
arrange for the initialisation done there (which has to be done after global
flags are parsed to handle e.g. `--config`) to happen explictly after the
global flags are parsed. Rather than make `newDockerCommand` return the
complicated set of results needed to make this happen, instead return a closure
which achieves this.
The new functionality is introduced via a common `TopLevelCommand` abstraction
which lets us adjust the plugin entrypoint to use the same strategy for parsing
the global arguments. This isn't strictly required (in this case the stuff in
cobra's `Execute` works fine) but doing it this way avoids the possibility of
subtle differences in behaviour.
Fixes#1699, and also, as a side-effect, the first item in #1661.
Signed-off-by: Ian Campbell <ijc@docker.com>
This happens on Windows when dialing a named pipe (a path which is used by CLI
plugins), in that case some debugging shows:
DEBU[0000] conn is a *winio.win32MessageBytePipe
DEBU[0000] conn is a halfReadCloser: false
DEBU[0000] conn is a halfWriteCloser: true
the raw stream connection does not implement halfCloser
In such cases we can simply wrap with a nop function since closing for read
isn't too critical.
Signed-off-by: Ian Campbell <ijc@docker.com>