docker build --call outline .
TARGET: binary
BUILD ARG VALUE DESCRIPTION
BASE_VARIANT alpine
ALPINE_VERSION 3.21 sets the version of the alpine base image to use, including for the golang image.
GO_VERSION 1.24.5
XX_VERSION 1.6.1
GOVERSIONINFO_VERSION v1.4.1
GO_LINKMODE static defines if static or dynamic binary should be produced
GO_BUILDTAGS defines additional build tags
GO_STRIP strips debugging symbols if set
CGO_ENABLED manually sets if cgo is used
VERSION sets the version for the produced binary
PACKAGER_NAME sets the company that produced the windows binary
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
client.ContainerDiff already validates the given container name/ID, and
produces an error when empty, so we don't have to check for this;
abba330bbf/client/container_diff.go (L13-L16)
While updating, also;
- remove the diffOptions type, as there were no other options, and make
the container name/ID a string argument.
- fix camelCase nameing of dockerCLI
Before this patch:
docker diff ""
Container name cannot be empty
With this patch:
docker diff ""
invalid container name or ID: value is empty
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
It was the only utility we consumed from the package, and it's trivial
to implement, so let's create local copies of it.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This utility was only used for testing, and to generate a random
suffix for Dockerfiles. As we don't need the same contract as
pkg/stringid.GenerateRandomID() (not allow all-numeric IDs as they
would not be usable for hostnames), we can use a local test-utility,
and local implementation for the random suffix instead.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
We were depending on pkg/stringid to truncate IDs for presentation. While
traditionally, we used a fixed length for "truncated" IDs, this is not
a strict requirement (any ID-prefix should work, but conflicts may
happen on shorter IDs).
This patch adds a local `TruncateID()` utility in the formatter package;
it's currently using the same implementation and length as the
`stringid.TruncateID` function, but may diverge in future.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `AllowOverwriteDirWithFile` option was added when reimplementing the
CLI using the API Client lib in [moby@1b2b91b]. Before that refactor, the
`noOverwriteDirNonDir` query argument [would be set unconditionally][1]
by the CLI, with no options to control the behavior.
It's unclear why the `noOverwriteDirNonDir` was implemented as opt-in (not
opt-out), as overwriting a file with a directory (or vice-versa) would
generally be unexpected behavior.
We're considering making `noOverwriteDirNonDir` unconditional on the daemon
side, and to deprecate the `AllowOverwriteDirWithFile` option. This patch
removes its use, as it was set to the default either way, and there's no
options to configure it from the CLI.
[1]: 8c9ad7b818/api/client/cp.go (L345-L346)
[moby@1b2b91b]: 1b2b91ba43
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Make the test slightly more permissive; we're looking for a trailing
newline, not necessarily an empty line.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- https://github.com/golang/go/issues?q=milestone%3AGo1.24.5+label%3ACherryPickApproved
- full diff: https://github.com/golang/go/compare/go1.24.4...go1.24.5
This minor releases include 1 security fixes following the security policy:
- cmd/go: unexpected command execution in untrusted VCS repositories
Various uses of the Go toolchain in untrusted VCS repositories can result in
unexpected code execution. When using the Go toolchain in directories fetched
using various VCS tools (such as directly cloning Git or Mercurial repositories)
can cause the toolchain to execute unexpected commands, if said directory
contains multiple VCS configuration metadata (such as a '.hg' directory in a Git
repository). This is due to how the Go toolchain attempts to resolve which VCS
is being used in order to embed build information in binaries and determine
module versions.
The toolchain will now abort attempting to resolve which VCS is being used if it
detects multiple VCS configuration metadata in a module directory or nested VCS
configuration metadata (such as a '.git' directoy in a parent directory and a
'.hg' directory in a child directory). This will not prevent the toolchain from
building modules, but will result in binaries omitting VCS related build
information.
If this behavior is expected by the user, the old behavior can be re-enabled by
setting GODEBUG=allowmultiplevcs=1. This should only be done in trusted
repositories.
Thanks to RyotaK (https://ryotak.net) of GMO Flatt Security Inc for reporting
this issue.
This is CVE-2025-4674 and https://go.dev/issue/74380.
View the release notes for more information:
https://go.dev/doc/devel/release#go1.24.5
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
I noticed this in a ticket in the compose issue tracker; with debug logging
enabled, the OTEL error-logger may be logging even if there's no error;
DEBU[0000] Executing bake with args: [bake --file - --progress rawjson --metadata-file /tmp/compose-build-metadataFile-1203980021.json --allow fs.read=/home/user/dev/project --allow fs.read=/home/user/dev/project --allow fs.read=/home/user/dev/project/nginx --allow fs.read=/home/user/dev/project]
TRAC[0000] Plugin server listening on @docker_cli_d8df486f78df3b7357995be71bf0cef6
DEBU[0005] otel error error="<nil>"
^CTRAC[0055] Closing plugin server
TRAC[0055] Closing plugin server
DEBU[0055] otel error error="<nil>"
DEBU[0055] otel error error="<nil>"
Update the error-handler to not log if there's no error.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Make it a hidden file. From the [CodeCov docs][1]:
> Can I name the file .codecov.yml?
>
> Yes, you can name the file `codecov.yml` or `.codecov.yml`. However, the
> file must still be located in the repository root, `dev/`, or `.github/`
> directories
[1]: https://docs.codecov.com/docs/codecov-yaml#can-i-name-the-file-codecovyml
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The strslice.StrSlice type is a string-slice with a custom JSON Unmarshal
function to provide backward-compatibility with older API requests (see
[moby@17d6f00] and [moby@ea4a067]).
Given that the type is assigned implicitly through the fields on HostConfig,
we can just use a regular []string instead.
[moby@17d6f00]: 17d6f00ec2
[moby@ea4a067]: ea4a06740b
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Adding image tags that follow the semver major and minor versions (e.g., `28`
and `28.3`) for the moby-bin images.
This makes it easier for users to reference the latest build within a
major or minor version series without having to know the exact
minor/patch version.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
When connecting to a remote daemon through an ssh:// connection,
the CLI connects with the remote host using ssh, executing the
`docker system dial-stdio` command on the remote host to connect
to the daemon API's unix socket.
By default, the `docker system dial-stdio` command connects with the
daemon using the default location (/var/run/docker.sock), or the
location as configured on the remote host.
Commit 25ebf0ec9c (included in docker
CLI v24.0.0-rc.2 and higher) introduced a feature to allow the location
of the socket to be specified through the host connection string, for
example:
DOCKER_HOST='ssh://example.test/run/custom-docker.sock'
The custom path is included as part of the ssh command executed from
the client machine to connect with the remote host. THe example above
would execute the following command from the client machine;
ssh -o ConnectTimeout=30 -T -- example.test docker --host unix:///run/custom-docker.sock system dial-stdio
ssh executes remote commands in a shell environment, and no quoting
was in place, which allowed for a connection string to include additional
content, which would be expanded / executed on the remote machine.
For example, the following example would execute `echo hello > /hello.txt`
on the remote machine;
export DOCKER_HOST='ssh://example.test/var/run/docker.sock $(echo hello > /hello.txt)'
docker info
# (output of docker info from the remote machine)
While this doesn't allow the user to do anything they're not already
able to do so (by directly using the same SSH connection), the behavior
is not expected, so this patch adds quoting to prevent such URLs from
resulting in expansion.
This patch updates the cli/connhelper and cli/connhelper/ssh package to
quote parameters used in the ssh command to prevent code execution and
expansion of variables on the remote machine. Quoting is also applied to
other parameters that are obtained from the DOCKER_HOST url, such as username
and hostname.
- The existing `Spec.Args()` method inthe cli/connhelper/ssh package now
quotes arguments, and returns a nil slice when failing to quote. Users
of this package should therefore check the returned arguments before
consuming. This method did not provide an error-return, and adding
one would be a breaking change.
- A new `Spec.Command` method is introduced, which (unlike the `Spec.Args()`
method) provides an error return. Users are recommended to use this new
method instead of the `Spec.Args()` method.
Some minor additional changes in behavior are included in this patch;
- Connection URLs with a trailing slash (e.g. `ssh://example.test/`)
would previously result in `unix:///` being used as custom socket
path. After this patch, the trailing slash is ignored, and no custom
socket path is used.
- Specifying a remote command is now required. When passing an empty
remote command, `Spec.Args()` now results in a `nil` value to be
returned (or an `no remote command specified` error when using
`Spec.Comnmand()`.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
cli/connhelper/internal/syntax/parser.go:31:2: Duplicate words (the) found (dupword)
// Note that it shares some features with Bash, due to the the shared
^
cli/connhelper/internal/syntax/quote.go:48:1: cyclomatic complexity 35 of func `Quote` is high (> 16) (gocyclo)
func Quote(s string, lang LangVariant) (string, error) {
^
cli/connhelper/internal/syntax/quote.go:103:3: shadow: declaration of "offs" shadows declaration at line 56 (govet)
offs := 0
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This was introduced in 9b54d860cd,
which added `docker container remove` as alias for `docker container rm`.
However, due to the `NewRmCommand` being used both for adding the top-level
`docker rm` command and for adding the `docker container rm` command, it
also introduced a (hidden) top-level `docker remove` command;
docker remove --help | head -n1
Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]
The command was not documented, and did not appear in `--help` output,
nor was auto-complete provided;
docker --help | grep remove
docker r<TAB>
rename (Rename a container) rm (Remove one or more containers) run (Create and run a new container from an image)
restart (Restart one or more containers) rmi (Remove one or more images)
This patch adds a dedicated, non-exported `newRemoveCommand` to add sub-
commands for `docker container`, taking a similar approach as was done in
[moby@b993609d5a] for `docker image rm`.
With this patch applied, the hidden command is no longer there, but
the `docker rm`, `docker container rm`, and `docker container remove`
commands stay functional as intended;
docker remove foo
docker: unknown command: docker remove
Run 'docker --help' for more information
docker rm --help | head -n1
Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]
docker container rm --help | head -n1
Usage: docker container rm [OPTIONS] CONTAINER [CONTAINER...]
docker container remove --help | head -n1
Usage: docker container rm [OPTIONS] CONTAINER [CONTAINER...]
[moby@b993609d5a]: b993609d5a
Reported-by: Lorenzo Buero <138243046+LorenzoBuero@users.noreply.github.com>
Co-authored-by: Lorenzo Buero <138243046+LorenzoBuero@users.noreply.github.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When pulling or pushing images, the CLI could prompt for a password
if the push/pull failed and the registry returned a 401 (Unauthorized)
Ironically, this feature did not work when using Docker Hub (and possibly
other registries using basic auth), due to some custom error handling added
in [moby@19a93a6e3d42], which also discards the registry's status code,
changing it to a 404;
curl -v -XPOST --unix-socket /var/run/docker.sock 'http://localhost/v1.50/images/create?fromImage=docker.io%2Fexample%2Fprivate&tag=latest'
...
< HTTP/1.1 404 Not Found
< Content-Type: application/json
...
{"message":"pull access denied for example/private, repository does not exist or may require 'docker login'"}
And due to a bug, other registries (not using basic auth) returned a generic
error, which resulted in a 500 Internal Server Error. That bug was fixed in
docker 28.2, now returning the upstream status code and trigger an interactive
prompt;
docker pull icr.io/my-ns/my-image:latest
Please login prior to pull:
Username:
This prompt would be triggered unconditionally, also if the CLI was run
non-interactively and no TTY attached;
docker pull icr.io/my-ns/my-image:latest < /dev/null
Please login prior to pull:
Username:
With this PR, no prompt is shown ;
# without STDIN attached
docker pull icr.io/my-ns/my-image:latest < /dev/null
Error response from daemon: error from registry: Authorization required. See https://cloud.ibm.com/docs/Registry?topic=Registry-troubleshoot-auth-req - Authorization required. See https://cloud.ibm.com/docs/Registry?topic=Registry-troubleshoot-auth-req
For now, the prompt is still shown otherwise;
docker pull icr.io/my-ns/my-image:latest
Login prior to pull:
Username: ^C
[moby@19a93a6e3d42]: 19a93a6e3d
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Currently, image tree visualization doesn't properly detect chips for
parent images, only looking at child images. This patch fixes the issue
by checking both parent and child images when determining which chips to
display in the tree view.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This patch enables the CLI to natively pick up the `DOCKER_AUTH_CONFIG`
environment variable and use it as a credential store.
The `DOCKER_AUTH_CONFIG` value should be a JSON object and must store
the credentials in a base64 encoded string under the `auth` key.
Specifying additional fields will cause the parser to fail.
For example:
`printf "username:pat" | openssl base64 -A`
`export DOCKER_AUTH_CONFIG='{
"auths": {
"https://index.docker.io/v1/": {
"auth": "aGk6KTpkY2tyX3BhdF9oZWxsbw=="
}
}
}'`
Credentials stored in `DOCKER_AUTH_CONFIG` would take precedence over any
credential stored in the file store (`~/.docker/config.json`) or native store
(credential helper).
Destructive actions, such as deleting a credential would result in a noop if
found in the environment credential. Credentials found in the file or
native store would get removed.
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
This field was added in [moby@5130fe5d38837302e], which
added it for use as intermediate struct when parsing CLI flags (through
`runconfig.ParseExec`) in [moby@c786a8ee5e9db8f5f].
Commit [moby@9d9dff3d0d9e92adf] rewrote the CLI to use
Cobra, and as part of this introduced a separate `execOptions` type in
`api/client/container`, however the ExecOptions.Detach field was still
used as intermediate field to store the flag's value.
Given that the client doesn't use this field, let's remove its use to
prevent giving the impression that it's used anywhere.
[moby@5130fe5d38837302e]: 5130fe5d38
[moby@c786a8ee5e9db8f5f]: c786a8ee5e
[moby@9d9dff3d0d9e92adf]: 9d9dff3d0d
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The RegistryAuthenticationPrivilegedFunc has some conditional logic to
add additional hints when logging in to the default (Docker Hub) registry.
Commit 9f4165ccb8 inadvertently passed the
wrong variable to PromptUserForCredentials, which caused it to show the
additional hints for Docker Hub.
Before this patch, hints were printed for the default (docker hub) registry;
docker pull icr.io/my-ns/my-image:latest
Login prior to pull:
Log in with your Docker ID or email address to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com/ to create one.
You can log in with your password or a Personal Access Token (PAT). Using a limited-scope PAT grants better security and is required for organizations using SSO. Learn more at https://docs.docker.com/go/access-tokens/
Username:
With this patch, those hints are omitted;
docker pull icr.io/my-ns/my-image:latest
Login prior to pull:
Username:
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This file is only used as default if no version is specified. We
should probably get rid of this, but let's update it to better
reflect the version that developer builds are building.
d48fb9f9f7/docker.Makefile (L22)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Image config fields like Cmd, Entrypoint, Env, etc. will be omitted from
/images/{name}/json response when empty, starting in v29.0.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
- https://github.com/golang/go/issues?q=milestone%3AGo1.24.4+label%3ACherryPickApproved
- full diff: https://github.com/golang/go/compare/go1.24.3...go1.24.4
This release includes 3 security fixes following the security policy:
- net/http: sensitive headers not cleared on cross-origin redirect
Proxy-Authorization and Proxy-Authenticate headers persisted on cross-origin redirects potentially leaking sensitive information.
Thanks to Takeshi Kaneko (GMO Cybersecurity by Ierae, Inc.) for reporting this issue.
This is CVE-2025-4673 and Go issue https://go.dev/issue/73816.
- os: inconsistent handling of O_CREATE|O_EXCL on Unix and Windows
os.OpenFile(path, os.O_CREATE|O_EXCL) behaved differently on Unix and Windows systems when the target path was a dangling symlink. On Unix systems, OpenFile with O_CREATE and O_EXCL flags never follows symlinks. On Windows, when the target path was a symlink to a nonexistent location, OpenFile would create a file in that location.
OpenFile now always returns an error when the O_CREATE and O_EXCL flags are both set and the target path is a symlink.
Thanks to Junyoung Park and Dong-uk Kim of KAIST Hacking Lab for discovering this issue.
This is CVE-2025-0913 and Go issue https://go.dev/issue/73702.
- crypto/x509: usage of ExtKeyUsageAny disables policy validation
Calling Verify with a VerifyOptions.KeyUsages that contains ExtKeyUsageAny unintentionally disabledpolicy validation. This only affected certificate chains which contain policy graphs, which are rather uncommon.
Thanks to Krzysztof Skrzętnicki (@Tener) of Teleport for reporting this issue.
This is CVE-2025-22874 and Go issue https://go.dev/issue/73612.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This change eliminates the automatic creation of image tags in the
format `dockereng/cli-bin:sha-ad132f5` for every push.
They're not too useful, produce noise and use a lot of space.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
Support for API versions lower than v1.24 was removed in v26.0.
The DOCKER_MIN_API_VERSION environment-variable is still present
in the docker daemon, but can currently only be used to raise the
minimum version.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The daemon still has migration code in place, but no longer accepts
the option for new containers, so marking it as "removed";
49ec488036
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
These fields have been removed in v26.0 (API v1.45 and up), and are always
omitted when using the containerd image store;
03cddc62f4
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This functionality, was removed and the DOCKERD_DEPRECATED_GRAPHDRIVER_PLUGINS
no longer can be used in v28.0;
42ca9154e9
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- use filepath.EvalSymlink instead of check with filepath.IsAbs
- allow for dangling symlinks
- extract path from error when NotExist error occurs
Co-authored-by: Paweł Gronowski <me@woland.xyz>
Co-authored-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Will Wang <willww64@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
IsAutomated was deprecated in 4fc3f0e6f6
(docker v25.0), and marked for removal in docker 26.0 (which we missed).
This removes it.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
docker ps --format 'table {{.ID}}\t{{.Image}}{{.Command}}\t{{.RunningFor}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}\t{{.Platform}}'
CONTAINER ID IMAGECOMMAND CREATED STATUS PORTS NAMES PLATFORM
e422855eac55 docker-cli-dev"/bin/bash" 12 minutes ago Up 12 minutes strange_jennings linux/arm64
Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The WithInitializeClient looks redundant altogether, so let's
rewrite this function to not depend on it.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The labels are stored as a map, causing the output to be randomized.
This patch sorts the result to get a consistent output.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This file is only used as default if no version is specified. We
should probably get rid of this, but let's update it to better
reflect the version that developer builds are building.
d48fb9f9f7/docker.Makefile (L22)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this patch:
mkdir -p ./tempconfig && touch ./tempconfig/ca.pem ./tempconfig/cert.pem ./tempconfig/key.pem
DOCKER_TLS_VERIFY=1 DOCKER_CONFIG=./tempconfig DOCKER_HOST=unix:///var/run/docker.sock docker info
Failed to initialize: failed to retrieve context tls info: ca.pem seems invalid
With this patch:
DOCKER_TLS_VERIFY=1 DOCKER_CONFIG=./tempconfig DOCKER_HOST=unix:///var/run/docker.sock docker info
Client:
Version: 28.1.1-25-g2dfe7b558.m
Context: default
...
Note that the above is just to illustrate; there's still parts in context-
related code that will check for, and load TLS-related files ahead of time.
We should make some of that code lazy-loading (i.e., don't load these until
we're actually gonna make an API connection). For example, if the TLS files
are missing;
rm ./tempconfig/*.pem
DOCKER_TLS_VERIFY=1 DOCKER_CONFIG=./tempconfig DOCKER_HOST=unix:///var/run/docker.sock docker info
Failed to initialize: unable to resolve docker endpoint: open tempconfig/ca.pem: no such file or directory
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When attaching to a container, hijack puts the terminal in raw mode,
and local echo is disabled. In normal cases, the terminal is restored
once the container detaches;
6f856263c2/cli/command/container/hijack.go (L40-L44)
However, when the CLI is forced to exit (after 3 signals), we `os.Exit(1)`,
which causes defers to not be executed, and because of this, the terminal
not being restored.
For example; start a container that's attached;
docker run -it --rm --sig-proxy=false alpine sleep 20
In another terminal send a SIGINT 3 times to force terminate;
kill -sINT $(pgrep -af docker\ run)
kill -sINT $(pgrep -af docker\ run)
kill -sINT $(pgrep -af docker\ run)
The first terminal shows that the docker cli was terminated;
got 3 SIGTERM/SIGINTs, forcefully exiting
However, the terminal was not restored, so local echo is disabled, and
typing any command in the terminal does not show output (a manual `stty echo`
is needed to restore).
With this patch, the terminal is restored before we forcefully exit the
docker CLI. Restoring is a no-op if there's no previous state, so we
can unconditionally execute this.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `--platform` flag originally was added for the experimental LCOW
feature and only accepted the target operating system. Current versions
of Docker allow passing both OS and Architecture, so updating the
documentation to reflect this.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- Put the content related to `--changes` under a heading with the correct
anchor, so that it will be linked from the "options" table.
- Move note about `sudo` to be under the right example.
- Update some examples to directly read from a file instead of piping.
- Add heading for the `--message` flag.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Produce an error if the `--type` flag was set, but an empty value
was passed.
Before this patch:
docker inspect --type "" foo
# json output
docker inspect --type unknown foo
"unknown" is not a valid value for --type
With this patch:
docker inspect --type "" foo
type is empty: must be one of "config", "container", "image", "network", "node", "plugin", "secret", "service", "task", "volume"
docker inspect --type unknown foo
unknown type: "unknown": must be one of "config", "container", "image", "network", "node", "plugin", "secret", "service", "task", "volume"
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this patch:
docker inspect --help | grep '\-\-type'
--type string Return JSON for specified type
With this patch:
docker inspect --help | grep '\-\-type'
--type string Only inspect objects of the given type
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this patch, flags and arguments would complete using filenames
from the current directory;
docker inspect --type <TAB>
AUTHORS CONTRIBUTING.md docs/ Makefile SECURITY.md
...
docker inspect <TAB>
With this patch, no completion is provided;
docker inspect --type <TAB>
# no results
docker inspect <TAB>
# no results
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When generating our docs, flag-descriptions are currently expected
to be under the "examples" section for them to be linked correctly.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `-i` and `-t` options are not needed, as the `pwd` command does not require a TTY nor an interactive session. Drop them to simplify the example and avoid causing unnecessary confusion to the reader.
Signed-off-by: 林博仁(Buo-ren Lin) <buo.ren.lin@gmail.com>
Before this change, some errors could be ambiguous as they did not
distinguish a flag to be omitted, or set, but with an empty value.
For example, if a user would try to loging but with an empty username,
the error would suggest that the `--username` flag was not set (which
it was);
I don't have `MY_USERNAME` set in this shell;
printenv MY_USERNAME || echo 'variable not set'
variable not set
Now, attempting to do a non-interactive login would result in an
ambiguous error;
echo "supersecret" | docker login --password-stdin --username "$MY_USERNAME"
Must provide --username with --password-stdin
With this patch applied, the error indicates that the username was empty,
or not set;
echo "supersecret" | docker login --password-stdin --username "$MY_USERNAME"
username is empty
echo "supersecret" | docker login --password-stdin
the --password-stdin option requires --username to be set
echo "supersecret" | docker login --password-stdin --password "supersecret"
conflicting options: cannot specify both --password and --password-stdin
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `GetSlice()` function is part of cobra's [cobra.SliceValue] interface,
and duplicates the older `GetAll()` method. This patch deprecates the
`GetAll()` method in favor of `GetSlice()`.
[cobra.SliceValue]: https://pkg.go.dev/github.com/spf13/cobra@v1.9.1#SliceValue
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This function was parsing the same URL twice; first to detect the
scheme, then again (through ssh.ParseURL) to construct a ssh.Spec.
Change the function to use the URL that's parsed, and use ssh.NewSpec
instead.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `GetSlice()` function is part of cobra's [cobra.SliceValue] interface,
and duplicates the older `GetAll()` method. This patch changes our use
of the `GetAll()` method with the intent to deprecated it in future.
[cobra.SliceValue]: https://pkg.go.dev/github.com/spf13/cobra@v1.9.1#SliceValue
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Cobra's shell completion has specific rules to decide whether a flag can
be accepted multiple times. If a flag does not meet that rule, it only
completes the flag name once; some of those rules depend on the "type"
of the option to end with "Array" or "Slice", which most of our options
don't.
Starting with Cobra 1.9, it also checks whether an option implements
the [cobra.SliceValue] interface (see [spf13/cobra 2210]).
This patch implements the [cobra.SliceValue] interface on ListOpts, so
that these options can be completed multiple times.
In a follow-up, we can update our code to replace our uses of `GetAll()`,
which is identical with the `GetSlice()` method, and potentially deprecate
the old method.
Before this patch, ListOpts would only be completed once when completing
flag names. For example, the following would show the `--label` flag the
first time, but omit it if a `--label` flag was already set;
docker run--l<TAB>
--label (Set meta data on a container) --link-local-ip (Container IPv4/IPv6 link-local addresses)
--label-file (Read in a line delimited file of labels) --log-driver (Logging driver for the container)
--link (Add link to another container) --log-opt (Log driver options)
docker run --label hello --l<TAB>
--label-file (Read in a line delimited file of labels) --link-local-ip (Container IPv4/IPv6 link-local addresses) --log-opt (Log driver options)
--link (Add link to another container) --log-driver (Logging driver for the container)
With this patch, the completion script correctly identifies the `--label`
flag to be accepted multiple times, and also completes it when already
set;
docker run --label hello --l<TAB>
--label (Set meta data on a container) --link-local-ip (Container IPv4/IPv6 link-local addresses)
--label-file (Read in a line delimited file of labels) --log-driver (Logging driver for the container)
--link (Add link to another container) --log-opt (Log driver options)
[cobra.SliceValue]: https://pkg.go.dev/github.com/spf13/cobra@v1.9.1#SliceValue
[spf13/cobra 2210]: https://github.com/spf13/cobra/pull/2210
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this patch, `docker stack deploy` would not validate the image
reference on the client side, depending on the daemon to return an error,
which was not always easy to interpret;
docker stack deploy -c docker-compose.yaml mystack
Creating service mystack_myservice
failed to create service mystack_myservice: Error response from daemon: rpc error: code = InvalidArgument desc = ContainerSpec: image reference must be provided
IMAGE_NAME=FOOBAR docker stack deploy -c docker-compose.yaml mystack
Creating service mystack_myservice
failed to create service mystack_myservice: Error response from daemon: rpc error: code = InvalidArgument desc = ContainerSpec: "FOOBAR" is not a valid repository/tag
With this patch, the CLI validates the image-reference for each service,
producing an error if the reference is empty or invalid.
docker stack config -c docker-compose.yaml
invalid service myservice: no image specified
IMAGE_NAME=FOOBAR ~/Projects/cli/build/docker stack deploy -c docker-compose.yaml mystack
invalid image reference for service myservice: invalid reference format: repository name (library/FOOBAR) must be lowercase
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Aligning with where we put this in moby, and contrib is a slightly
more suitable location for this.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- use designated example domains as example value
- swap "expected" and "actual" values in assertions
- add doc / name for each test
- add test-cases for remote commands
- also test the Spec that's produced, not just the args
- merge two test-cases that could be combined
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
With this patch, the `--use-api-socket` flag can obtain credentials from
a validly formatted `DOCKER_AUTH_CONFIG` environment-variable. If the
env-var is not set, or doesn't contain credentials, it falls back to
attempting to read credentials from the CLI's configured credentials
store.
With this patch:
# Make sure there's no auth on disk first
mkdir -p tmpConfig
export DOCKER_CONFIG=$PWD/tmpConfig
rm -f $PWD/tmpConfig/config.json
# no credentials
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
cat: can't open '/run/secrets/docker/config.json': No such file or directory
# pass credentials through DOCKER_AUTH_CONFIG
DOCKER_AUTH_CONFIG='{"auths": {"https://index.docker.io/v1/": {"auth": "am9lam9lOmhlbGxv"}}}' docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "am9lam9lOmhlbGxv"
}
}
}
# credentials from file if no DOCKER_AUTH_CONFIG is set
echo '{"auths": {"https://index.docker.io/v1/": {"auth": "am9lam9lOmhlbGxv"}}}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "am9lam9lOmhlbGxv"
}
}
}
# same if DOCKER_AUTH_CONFIG is set, but doesn't contain credentials
DOCKER_AUTH_CONFIG='{}' docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "am9lam9lOmhlbGxv"
}
}
}
DOCKER_AUTH_CONFIG='{"auths": {}}' docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "am9lam9lOmhlbGxv"
}
}
}
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The "use-api-socket" code got in between, putting a lot of distance
between the declaration and use.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this patch, a valid, but empty set of credentials would still
write a config-file to the container and set `DOCKER_CONFIG`:
mkdir -p tmpConfig
export DOCKER_CONFIG=$PWD/tmpConfig
echo '{}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
{
"auths": {}
}
echo '{"auths": {}}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
{
"auths": {}
}
echo '{"auths": {"https://index.docker.io/v1/": {"auth": "am9lam9lOmhlbGxv"}}}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "am9lam9lOmhlbGxv"
}
}
}
With this patch, the `DOCKER_CONFIG` env-var and config-file are only created
if we have credentials to set;
mkdir -p tmpConfig
export DOCKER_CONFIG=$PWD/tmpConfig
echo '{}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
cat: can't open '/run/secrets/docker/config.json': No such file or directory
echo '{"auths": {}}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
cat: can't open '/run/secrets/docker/config.json': No such file or directory
echo '{"auths": {"https://index.docker.io/v1/": {"auth": "am9lam9lOmhlbGxv"}}}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "am9lam9lOmhlbGxv"
}
}
}
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Go maintainers started to unconditionally update the minimum go version
for golang.org/x/ dependencies to go1.23, which means that we'll no longer
be able to support any version below that when updating those dependencies;
> all: upgrade go directive to at least 1.23.0 [generated]
>
> By now Go 1.24.0 has been released, and Go 1.22 is no longer supported
> per the Go Release Policy (https://go.dev/doc/devel/release#policy).
>
> For golang/go#69095.
This updates our minimum version to go1.23, as we won't be able to maintain
compatibility with older versions because of the above.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
For now, these are not exported and included in the cli/commands/contexts
package; a copy of this also lives in cmd/docker, but we need to find a
good place for these completions, as some of them bring in additional
dependencies.
Commands that accept multiple arguments provide completion, but removing
duplicates:
docker context inspect<TAB>
default desktop-linux (current) production tcd
docker context inspec default<TAB>
desktop-linux (current) production tcd
docker context inspect default tcd<TAB>
desktop-linux (current) production
For "context export", we provide completion for the first argument, after
which file-completion is provided:
# provides context names completion for the first argument
docker context export production<TAB>
default desktop-linux (current) production tcd
# then provides completion for filenames
docker context export desktop-linux<TAB>
build/ man/ TESTING.md
cli/ docker.Makefile go.mod
...
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Using `--platform=linux` or `--platform=windows` is not commonly
used (or recommended). Let's remove these from the list of suggested
platforms.
We should tweak this completion further, and sort the list based
on the daemon's platform (putting linux first for a Linux daemon,
and windows first on a Windows daemon), possibly with the correct
architecture (and os-version) included, but we don't yet provide
that information in `/_ping`.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Adds a flag to the create and run command, `--use-api-socket`, that can
be used to start a container with the correctly configured parameters to
ensure that accessing the docker socket will work with out managing bind
mounts and authentication injection.
The implementation in this PR resolves the tokens for the current
credential set in the client and then copies it into a container at the
well know location of /run/secrets/docker/config.json, setting
DOCKER_CONFIG to ensure it is resolved by existing tooling. We use a
compose-compatible secret location with the hope that the CLI and
compose can work together seamlessly.
The bind mount for the socket is resolved from the current context,
erroring out if the flag is set and the provided socket is not a unix
socket.
There are a few drawbacks to this approach but it resolves a long
standing pain point. We'll continue to develop this as we understand
more use cases but it is marked as experimental for now.
Signed-off-by: Stephen Day <stephen.day@docker.com>
The existing approach had some issues with how the control-chars
were escaped; also switching to use Dockerfile here-doc to make
it a bit more readable, and add some comments to the `.bashrc`.
Also make sure the MOTD isn't printed multiple times, and only
for interactive shells, and slightly tweak it with some colors.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
31d6292458 mistakenly changed the `ToSpec`
function to set all certs passed via `external-ca` to empty strings.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
- G306 # G306:Expect WriteFile permissions to be 0600 or less (too restrictive; also flags "0o644" permissions)
- G307 # G307:Deferring unsafe method "*os.File" on type "Close" (also EXC0008); (TODO: evaluate these and fix where needed: G307: Deferring unsafe method "*os.File" on type "Close")
govet:
enable:
- shadow
settings:
shadow:
strict:true
lll:
line-length:200
nakedret:
# Disallow naked returns if func has more lines of code than this setting.
# FIXME(thaJeztah): Disable `os.Chdir()` detections; should be automatically disabled on Go < 1.24; see https://github.com/docker/cli/pull/5835#issuecomment-2665302478
os-chdir:false
# FIXME(thaJeztah): Disable `context.Background()` detections; should be automatically disabled on Go < 1.24; see https://github.com/docker/cli/pull/5835#issuecomment-2665302478
context-background:false
# FIXME(thaJeztah): Disable `context.TODO()` detections; should be automatically disabled on Go < 1.24; see https://github.com/docker/cli/pull/5835#issuecomment-2665302478
context-todo:false
issues:
# The default exclusion rules are a bit too permissive, so copying the relevant ones below
exclude-use-default:false
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-issues-per-linter:0
# This option has been defined when Go modules was not existed and when the
# golangci-lint core was different, this is not something we still recommend.
exclude-dirs-use-default:false
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues:0
exclude:
- parameter .* always receives
formatters:
enable:
- gofumpt # Detects whether code was gofumpt-ed.
- goimports
exclude-files:
- cli/compose/schema/bindata.go
- .*generated.*
exclusions:
generated:strict
exclude-rules:
# We prefer to use an "exclude-list" so that new "default" exclusions are not
linters:
enable:
- asasalint # Detects "[]any" used as argument for variadic "func(...any)".
- bodyclose
- copyloopvar # Detects places where loop variables are copied.
- depguard
- dogsled # Detects assignments with too many blank identifiers.
- dupword # Detects duplicate words.
- durationcheck # Detect cases where two time.Duration values are being multiplied in possibly erroneous ways.
- errcheck
- errchkjson # Detects unsupported types passed to json encoding functions and reports if checks for the returned error can be omitted.
- exhaustive # Detects missing options in enum switch statements.
- exptostd # Detects functions from golang.org/x/exp/ that can be replaced by std functions.
- fatcontext # Detects nested contexts in loops and function literals.
- forbidigo
- gocheckcompilerdirectives# Detects invalid go compiler directive comments (//go:).
- gocritic # Metalinter; detects bugs, performance, and styling issues.
- gocyclo
- gosec # Detects security problems.
- govet
- iface # Detects incorrect use of interfaces. Currently only used for "identical" interfaces in the same package.
- importas # Enforces consistent import aliases.
- ineffassign
- makezero # Finds slice declarations with non-zero initial length.
- mirror # Detects wrong mirror patterns of bytes/strings usage.
- misspell # Detects commonly misspelled English words in comments.
- nakedret # Detects uses of naked returns.
- nilnesserr # Detects returning nil errors. It combines the features of nilness and nilerr,
- nosprintfhostport # Detects misuse of Sprintf to construct a host with port in a URL.
- nolintlint # Detects ill-formed or insufficient nolint directives.
- perfsprint # Detects fmt.Sprintf uses that can be replaced with a faster alternative.
- prealloc # Detects slice declarations that could potentially be pre-allocated.
- predeclared # Detects code that shadows one of Go's predeclared identifiers
- reassign # Detects reassigning a top-level variable in another package.
- revive # Metalinter; drop-in replacement for golint.
- spancheck # Detects mistakes with OpenTelemetry/Census spans.
- staticcheck
- thelper # Detects test helpers without t.Helper().
- tparallel # Detects inappropriate usage of t.Parallel().
- unconvert # Detects unnecessary type conversions.
- unparam
- unused
- usestdlibvars # Detects the possibility to use variables/constants from the Go standard library.
- usetesting # Reports uses of functions with replacement inside the testing package.
- G306 # G306:Expect WriteFile permissions to be 0600 or less (too restrictive; also flags "0o644" permissions)
- G307 # G307:Deferring unsafe method "*os.File" on type "Close" (also EXC0008); (TODO: evaluate these and fix where needed: G307: Deferring unsafe method "*os.File" on type "Close")
govet:
enable:
- shadow
settings:
shadow:
strict:true
lll:
line-length:200
importas:
# Do not allow unaliased imports of aliased packages.
no-unaliased:true
alias:
# Enforce alias to prevent it accidentally being used instead of our
os-chdir: false # FIXME(thaJeztah):Disable `os.Chdir()` detections; should be automatically disabled on Go < 1.24; see https://github.com/docker/cli/pull/5835#issuecomment-2665302478
context-background: false # FIXME(thaJeztah):Disable `context.Background()` detections; should be automatically disabled on Go < 1.24; see https://github.com/docker/cli/pull/5835#issuecomment-2665302478
context-todo: false # FIXME(thaJeztah):Disable `context.TODO()` detections; should be automatically disabled on Go < 1.24; see https://github.com/docker/cli/pull/5835#issuecomment-2665302478
exclusions:
# We prefer to use an "linters.exclusions.rules" so that new "default" exclusions are not
# automatically inherited. We can decide whether or not to follow upstream
# defaults when updating golang-ci-lint versions.
# Unfortunately, this means we have to copy the whole exclusion pattern, as
# (unlike the "include" option), the "exclude" option does not take exclusion
# ID's.
#
# These exclusion patterns are copied from the default excluses at:
// TODO should we error if _any_ advanced option is used? (i.e. forbid to combine advanced notation with the "old" flags (`--network-alias`, `--link`, `--ip`, `--ip6`)?
iflen(n.Aliases)>0&&copts.aliases.Len()>0{
returnerrdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --network-alias and per-network alias"))
returninvalidParameter(errors.New("conflicting options: cannot specify both --network-alias and per-network alias"))
}
iflen(n.Links)>0&&copts.links.Len()>0{
returnerrdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --link and per-network links"))
returninvalidParameter(errors.New("conflicting options: cannot specify both --link and per-network links"))
}
ifn.IPv4Address!=""&&copts.ipv4Address!=""{
returnerrdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --ip and per-network IPv4 address"))
returninvalidParameter(errors.New("conflicting options: cannot specify both --ip and per-network IPv4 address"))
}
ifn.IPv6Address!=""&&copts.ipv6Address!=""{
returnerrdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --ip6 and per-network IPv6 address"))
returninvalidParameter(errors.New("conflicting options: cannot specify both --ip6 and per-network IPv6 address"))
}
ifn.MacAddress!=""&&copts.macAddress!=""{
returnerrdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --mac-address and per-network MAC address"))
returninvalidParameter(errors.New("conflicting options: cannot specify both --mac-address and per-network MAC address"))
t.Errorf("Wrong UNC long path returned. Original = %s ; Long = %s",c,longC)
}
}
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.