Compare commits

...
1744 Commits
Author SHA1 Message Date
Sebastiaan van StijnandGitHub d072fe407f Merge pull request #7234 from vvoland/update-dco
docs: Update DCO identity guidance
2026-08-24 12:16:16 +02:00
Paweł Gronowski 3fe73079aa docs: Clarify DCO identity guidance
The DCO policy used here appears to have been derived from the Linux
kernel's guidance. In 2023, that guidance changed to relax the "real
name" requirement to a "known identity".

The DCO sign-off identifies the person certifying that they have the
right to submit a contribution. The previous wording required a "real
name" and rejected pseudonyms, which could discourage contributors
whose preferred or community name is the identity by which they can be
known.

The requirement is not anonymity: the identity in the sign-off must be
known enough for the project to follow up about the contribution if a
question arises. It does not require a legal name or a government-issued
identity. Use the clarified wording from the Linux kernel so known
pseudonyms and preferred names remain acceptable while anonymous
contributions remain excluded.

This also reflects concerns raised in the CNCF community about whether
"real name" means a legal name, a government-issued identity, or a
public identity that is sufficient to identify and contact a
contributor. The discussion emphasized that attribution and future
accountability do not require publishing a legal identity, and that
strict public-name rules can exclude people who cannot safely contribute
under that name.

Source: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d4563201f33a022fc035

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-08-24 11:41:24 +02:00
Paweł GronowskiandGitHub 28f756087e Merge pull request #7224 from vvoland/update-go
update to go1.26.7
2026-08-20 12:38:49 +02:00
Paweł Gronowski 387b8e2af8 update to go1.26.7
This release includes a fix to address a breakage affecting unencrypted
HTTP/2 (h2c) connections caused by a security patch included in last
patch release.

See go.dev/issue/80876 for details.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-08-19 20:23:24 +02:00
Paweł GronowskiandGitHub 55e4a7eef5 Merge pull request #7222 from thaJeztah/bump_logrus
vendor: github.com/sirupsen/logrus v1.10.1
2026-08-19 12:34:56 +02:00
Sebastiaan van Stijn 58d9cdd2d9 vendor: github.com/sirupsen/logrus v1.10.1
Notable changes:

- Add bidirectional `log/slog` integration with a Logrus hook and `slog.Handler`.
- Add minimal, composable logging interfaces for individual log levels.
- Fix reentrant logging deadlocks and improve concurrency safety around formatters, hooks, and entries.
- Fix generic `Log`, `Logf`, `Logln`, and `LogFn` methods unexpectedly panicking at `PanicLevel`.
- Allow `Entry.Caller` to be set explicitly and preserved across derived entries.
- Improve `TextFormatter` performance and reduce allocations significantly.
- Improve common Logger and Entry hot paths and caller-reporting performance.
- Update `TextFormatter` handling for `[]byte`, debug/trace colors, and Windows ANSI terminals.
- Raise the minimum supported Go version to Go 1.23.
- Deprecate `Entry.HasCaller` and `MutexWrap`.

release-notes: https://github.com/sirupsen/logrus/releases/tag/v1.10.0
release-notes: https://github.com/sirupsen/logrus/releases/tag/v1.10.1
full diff: https://github.com/sirupsen/logrus/compare/v1.9.4...v1.10.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-08-19 11:34:53 +02:00
Sebastiaan van StijnandGitHub 8659aa5d4c Merge pull request #7185 from thaJeztah/duplicate_normalize
cli/command/manifest: remove redundant normalization
2026-08-14 18:42:04 +02:00
Paweł GronowskiandGitHub 8d08c75e81 Merge pull request #7191 from thaJeztah/bump_go
update to go1.26.6
2026-08-14 14:52:56 +02:00
Sebastiaan van Stijn 24af004cbf update to go1.26.6
This release includes 10 security fixes following the security policy:

- x/mod/sumdb/tlog: fix transparency log tile verification bypass

    A malicious GOPROXY was previously capable of forging
    up to two sumdb tiles that allow for a requested module
    to bypass the GOSUMDB check and persist attacker-controlled
    module content to a local Go module cache.

    This attack allows for a malicious GOPROXY to serve
    malicious module content that cannot be detected
    by evaluating the transparency log.

    All tiles are now correctly verified against their parents.

    In order to determine if you have been affected:

    rm -r go.sum go.work.sum vendor/ && go mod tidy

    Thanks to Filippo Valsorda (Geomys) for reporting this issue.

    This is CVE-2026-56865 and Go issue https://go.dev/issue/80744.

- x/mod/sumdb: ignore unrelated, unauthenticated hashes in Lookup

    A malicious GOSUMDB was capable of serving arbitrary
    module content not contained within the transparency
    log.

    This attack allows for a coordinating GOPROXY and
    GOSUMDB to serve a client malicious module content
    that cannot be detected by evaluating the transparency
    log.

    In order to determine if you have been affected:

    rm -r go.sum go.work.sum vendor/ && go mod tidy

    Thanks to mundur for reporting this issue.

    This is CVE-2026-56864 and Go issue https://go.dev/issue/80745.

- encoding/xml: add recursion depth guard during decode

    Previously, DecodeElement would reset the depth counter
    causing it to never fire; this could lead to stack
    exhaustion.

    This is CVE-2026-56859 and Go issue https://go.dev/issue/80481.

 net/http: apply ReadHeaderTimeout when doing unencrypted HTTP/2 check

    When a server is configured to support unencrypted HTTP/2, it reads a
    few bytes from each new connection to see if they contain the HTTP/2
    client preface. Previously, this was being done with no timeout applied.
    ReadHeaderTimeout is now applied for this.

    This is CVE-2026-56853 and Go issue https://go.dev/issue/80205.

- net/url: avoid quadratic complexity in resolvePath

    Previously, resolving relative paths containing parent directory (..) segments performed string conversions and buffer rewrites on each step, resulting in quadratic time complexity and high memory allocation overhead.

    Now, path resolution operates on a byte buffer using index-based backtracking for .. segments, eliminating the quadratic time complexity and significantly reducing memory allocations.

    This is CVE-2026-56860 and Go issue https://go.dev/issue/80494.

- golang.org/x/net/dns/dnsmessage: panic when parsing invalid SVCB record

    Parsing an invalid SVCB or HTTPS RR can panic when
    the size of a parameter value overflows the message buffer.

    Thanks to Mundur (https://github.com/M0nd0R) for reporting this issue.

    This is CVE-2026-46600 and Go issue https://go.dev/issue/79795.

- crypto/tls: limit handshake messages we are willing to accept post-handshake

    Previously, we always counted handshake messages, such as KeyUpdate, as
    state-advancing, regardless of whether a handshake has been completed or
    not. As a result, a malicious client can keep sending KeyUpdate messages
    to force the server to keep performing key derivation operations
    indefinitely.

    Thanks to Qi Deng of Aurascape.ai for reporting this issue.

    This is CVE-2026-56862 and Go issue https://go.dev/issue/80528.

- html/template: fix Javascript regexp context tracking

    Previously, pathological inputs could close an
    unescaped / early, allowing for attack-controlled
    data to inject arbitrary content, potentially
    leading to XSS.

    Thanks to Ali Sherif for reporting this issue.

    This is CVE-2026-56858 and Go issue https://go.dev/issue/80435.

- x/net/idna: failure to reject ASCII-only Punycode-encoded labels

    The ToASCII and ToUnicode functions incorrectly accepted Punycode-encoded labels
    that decode to an ASCII-only label. For example, ToUnicode("xn--example-.com")
    incorrectly returned the name "example.com" rather than an error.

    The idna package implements the processing algorithm from UTS 46.
    Older versions of UTS 46 included a specification bug which permitted
    multiple ASCII labels to decode to the same Unicode label.
    UTS 46 revision 33 fixed the specification bug.
    The idna package now implements the updated specification.

    This behavior can lead to privilege escalation in programs using the idna package.
    For example, a program which performs privilege checks on the ASCII hostname
    may reject "example.com" but permit "xn--example-.com". If that program subsequently
    converts the ASCII hostname to Unicode, it will inadvertently permits access
    to the Unicode name "example.com".

    Thanks to KC1zs4 (https://github.com/KC1zs4) for reporting this issue.

    This is CVE-2026-39821 and Go issue https://go.dev/issue/78760.

- encoding/asn1: enforce maximum recursion depth

    Enforce a recursion limit in Unmarshal to prevent stack exhaustion
    when parsing deeply-nested, recursive structures.

    Thanks to Marwan Atia (marwans...@gmail.com) for reporting this issue.

    This is CVE-2026-33818 and Go issue https://go.dev/issue/80405.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-08-14 14:02:40 +02:00
Sebastiaan van StijnandGitHub eb68ed19d2 Merge pull request #7157 from docker/dependabot/github_actions/codeql-actions-8417568871
build(deps): bump the codeql-actions group across 1 directory with 3 updates
2026-08-13 22:42:40 +02:00
dependabot[bot]andGitHub 8a375034e2 build(deps): bump the codeql-actions group across 1 directory with 3 updates
Bumps the codeql-actions group with 3 updates in the / directory: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/autobuild](https://github.com/github/codeql-action) and [github/codeql-action/analyze](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.37.3 to 4.37.6
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...5595ccaf912efad79be6eef63a5619ff05969be3)

Updates `github/codeql-action/autobuild` from 4.37.3 to 4.37.6
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...5595ccaf912efad79be6eef63a5619ff05969be3)

Updates `github/codeql-action/analyze` from 4.37.3 to 4.37.6
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...5595ccaf912efad79be6eef63a5619ff05969be3)

---
updated-dependencies:
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-actions
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.37.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-actions
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-13 08:46:20 +00:00
Sebastiaan van Stijn a7c0741fa7 cli/command/manifest: remove redundant normalization
commit 55fcffe743 added normalization
in config/configfile, so it's no longer needed to normalize here as
well.

updates 55fcffe743

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-08-12 16:38:26 +02:00
Sebastiaan van StijnandGitHub 12892075d2 Merge pull request #7180 from docker/dependabot/github_actions/docker-actions-ebe691cc85
build(deps): bump docker/github-builder/.github/workflows/bake.yml from 1.15.0 to 1.16.0 in the docker-actions group
2026-08-12 15:37:56 +02:00
dependabot[bot]andGitHub e1f9b284df build(deps): bump docker/github-builder/.github/workflows/bake.yml
Bumps the docker-actions group with 1 update: [docker/github-builder/.github/workflows/bake.yml](https://github.com/docker/github-builder).


Updates `docker/github-builder/.github/workflows/bake.yml` from 1.15.0 to 1.16.0
- [Release notes](https://github.com/docker/github-builder/releases)
- [Commits](https://github.com/docker/github-builder/compare/27ade872c1e2296e62ef15ab3b10d37665e57cf7...a492c6d04fd3315f67230809b44d60cc0acd50b3)

---
updated-dependencies:
- dependency-name: docker/github-builder/.github/workflows/bake.yml
  dependency-version: 1.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: docker-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-12 08:43:00 +00:00
Sebastiaan van StijnandGitHub 4f84911bfe Merge pull request #7144 from hirehamir/fix/ps-port-sort
cli/command/formatter: sort published ports numerically by IP
2026-08-06 15:50:28 +02:00
Paweł GronowskiandGitHub 228f29e810 Merge pull request #7159 from thaJeztah/version_29.8
VERSION: 29.8.0
2026-08-06 15:47:41 +02:00
Sebastiaan van Stijn d8c3543407 VERSION: 29.8.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-08-06 15:34:41 +02:00
Hamir 2dd7b7e15b cli/command/formatter: sort published ports numerically by IP
`comparePorts` compared host IPs with `i.IP.String() < j.IP.String()`, which
sorts them lexicographically, so "10.0.0.2" ordered before "9.0.0.1" in
`docker ps` output.

This also avoids formatting both addresses as strings on every comparison.

ports    before               after
64       1540 allocs/op       394 allocs/op
256      5364 allocs/op       1548 allocs/op

That's a ~74% (3.9x) reduction in allocations.

Signed-off-by: Hamir <hirehamir@gmail.com>
2026-08-05 11:38:20 -07:00
Paweł GronowskiandGitHub a7dcaa6fdb Merge pull request #7151 from vvoland/update-archive
vendor: github.com/moby/go-archive v0.3.3
2026-08-05 19:34:15 +02:00
Paweł Gronowski 400b45f682 vendor: github.com/moby/go-archive v0.3.3
full diff: https://github.com/moby/go-archive/compare/v0.3.2...v0.3.3

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-08-05 19:11:05 +02:00
Sebastiaan van StijnandGitHub 38887ec4ed Merge pull request #7145 from winklemad/fix-service-duplicate-removal-panic
cli/command/service: fix panic when removing duplicate values
2026-08-05 19:10:29 +02:00
Sebastiaan van StijnandGitHub 904aef7f69 Merge pull request #7147 from docker/dependabot/github_actions/docker-actions-269857e486
build(deps): bump docker/docker-agent-action/.github/workflows/review-pr.yml from 2.0.2 to 2.0.3 in the docker-actions group across 1 directory
2026-08-04 13:11:45 +02:00
dependabot[bot]andGitHub f08e60eb09 build(deps): bump docker/docker-agent-action/.github/workflows/review-pr.yml
Bumps the docker-actions group with 1 update in the / directory: [docker/docker-agent-action/.github/workflows/review-pr.yml](https://github.com/docker/docker-agent-action).


Updates `docker/docker-agent-action/.github/workflows/review-pr.yml` from 2.0.2 to 2.0.3
- [Release notes](https://github.com/docker/docker-agent-action/releases)
- [Commits](https://github.com/docker/docker-agent-action/compare/774b6e0e60d6c648b0f2dc43bd5221377a0a7420...baf90543d81f5de59751dfd10e6cf45e21a5a982)

---
updated-dependencies:
- dependency-name: docker/docker-agent-action/.github/workflows/review-pr.yml
  dependency-version: 2.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: docker-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-04 08:42:59 +00:00
Paweł GronowskiandGitHub abfd89157d Merge pull request #7149 from vvoland/update-docker
VERSION: 29.7.2
2026-08-03 18:24:10 +02:00
Paweł Gronowski 519eb45d03 VERSION: 29.7.2
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-08-03 18:18:56 +02:00
Madan Kumar 8717af7168 cli/command/service: fix panic when removing duplicate values
Both makeEnv and updateHosts removed elements from a slice while ranging
over that same slice. The range expression is evaluated once, so after a
removal the loop keeps using the original length: it reads stale elements
that shifted down, skips a live element, and can slice past the end of the
shrunken slice, which panics.

In makeEnv, the "no update required" continue also applied to the inner
loop instead of skipping the re-append, so an env-var passed twice with
the same value was stored twice. A third occurrence with a different value
then tried to remove both entries and panicked:

    docker service create --env A=1 --env A=1 --env A=2 --name repro nginx
    panic: runtime error: slice bounds out of range [2:1]

The same happens with an env-file that lists a variable twice, and the
panic occurs before any API call, so no daemon is needed to hit it.

updateHosts has the same problem when a hostname is listed more than once
in a single entry: --host-rm either leaves a copy behind or panics with
"slice bounds out of range". That needs a spec written through the API or
swarmkit directly, as the CLI does not produce such entries itself, so it
is less likely to be hit in practice.

Use slices.DeleteFunc for both, which removes every match in one pass, and
add tests for makeEnv, which had no coverage.

Signed-off-by: Madan Kumar <winklemad@outlook.com>
2026-08-02 07:13:16 +05:30
Paweł GronowskiandGitHub e9452d6e78 Merge pull request #7142 from thaJeztah/bump_go_archive_0.3.2
vendor: github.com/moby/go-archive v0.3.2
2026-07-31 19:03:37 +02:00
Sebastiaan van Stijn a6014a702b vendor: github.com/moby/go-archive v0.3.2
full diff: https://github.com/moby/go-archive/compare/v0.3.1...v0.3.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-31 18:53:47 +02:00
Paweł GronowskiandGitHub 2465fca604 Merge pull request #7140 from thaJeztah/bump_go_archive_0.3.1
vendor: github.com/moby/go-archive v0.3.1
2026-07-31 18:33:04 +02:00
Sebastiaan van StijnandGitHub 52b15cc571 Merge pull request #7141 from thaJeztah/bump_version2
update version to 29.7.1
2026-07-31 18:20:09 +02:00
Sebastiaan van Stijn 13590921a4 update version to 29.7.1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-31 18:11:45 +02:00
Sebastiaan van Stijn 0b50545471 vendor: github.com/moby/go-archive v0.3.1
full diff: https://github.com/moby/go-archive/compare/v0.3.0...v0.3.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-31 18:10:04 +02:00
Paweł GronowskiandGitHub c1eba931e3 Merge pull request #7086 from mickael-docker/docs-authz-decoding
docs(authz): clarify daemon parsing semantics
2026-07-30 22:16:32 +02:00
Paweł GronowskiandGitHub 1a305be376 Merge pull request #7084 from thaJeztah/prompt_cleans
cli/command: PromptUserForCredentials: don't mutate cli
2026-07-30 22:15:34 +02:00
Sebastiaan van StijnandGitHub 4c1c648df1 Merge pull request #7129 from docker/dependabot/github_actions/codeql-actions-f42a4cd18a
build(deps): bump the codeql-actions group across 1 directory with 3 updates
2026-07-30 21:56:12 +02:00
Sebastiaan van StijnandGitHub ee046d35c0 Merge pull request #7134 from hirehamir/fix/flaky-client-hangs
cli/command: fix flaky TestInitializeFromClientHangs
2026-07-30 21:54:54 +02:00
Sebastiaan van StijnandGitHub d70c3fd5e7 Merge pull request #7139 from thaJeztah/vendor_go_archive
vendor: github.com/moby/go-archive v0.3.0
2026-07-30 21:49:42 +02:00
Sebastiaan van Stijn f6d6bede46 vendor: github.com/moby/go-archive v0.3.0
full diff: https://github.com/moby/go-archive/compare/v0.2.1...v0.3.0

v0.3.0

This release fixes CVE-2026-17106 / GHSA-hfg8-hc9c-6c3h, where a crafted
tar archive could use links to cause extraction operations to create or
overwrite files outside the intended destination directory.

The issue affected Unpack, UnpackLayer, Untar, UntarUncompressed, and the
ApplyLayer helpers. Users should upgrade and avoid extracting untrusted
archives with earlier versions.

What's Changed

* archive: harden tar extraction against path traversal
* archive: do not follow reparse points in chtimes
* archive: fix creation time updates on Windows
* archive: minor cleanups and godoc touch-up
* archive: RebaseArchiveEntries: fix archive path rebasing

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-30 19:17:27 +02:00
Sebastiaan van StijnandGitHub b47659808a Merge pull request #7026 from vvoland/fix-hostname
cli/file_store: Go 1.26 compatibility
2026-07-30 15:51:46 +02:00
dependabot[bot]andGitHub af626e1ed7 build(deps): bump the codeql-actions group across 1 directory with 3 updates
Bumps the codeql-actions group with 3 updates in the / directory: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/autobuild](https://github.com/github/codeql-action) and [github/codeql-action/analyze](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.37.1 to 4.37.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81)

Updates `github/codeql-action/autobuild` from 4.37.1 to 4.37.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81)

Updates `github/codeql-action/analyze` from 4.37.1 to 4.37.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81)

---
updated-dependencies:
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-actions
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.37.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-actions
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-30 08:46:12 +00:00
Sebastiaan van StijnandGitHub 6d35de4601 Merge pull request #7137 from crazy-max/bin-image-github-builder
ci: use docker github builder to build bin image
2026-07-29 16:58:14 +02:00
CrazyMaxandCrazyMax ad8dce1012 ci: use docker github builder to build bin image
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-07-29 16:32:49 +02:00
Hamir 844210bd0f cli/command: fix flaky TestInitializeFromClientHangs
Signed-off-by: Hamir <hirehamir@gmail.com>
2026-07-28 15:06:53 -07:00
Paweł GronowskiandGitHub bd719d6703 Merge pull request #7131 from vvoland/build-oidc
gha/build: Use OIDC for Docker Hub login
2026-07-28 17:10:00 +02:00
Paweł Gronowski 52b1160c85 gha: bump docker/login-action from 4.4.0 to 4.5.0
OIDC login requires docker/login-action v4.5.0 or newer

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-07-28 15:38:23 +02:00
Paweł Gronowski 5ff2ff6311 gha/build: Use OIDC for Docker Hub login
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-07-28 14:28:40 +02:00
Paweł GronowskiandGitHub 775dd50364 Merge pull request #7111 from thaJeztah/bump_go_archive
vendor: github.com/moby/go-archive main / v0.3.0-dev
2026-07-27 22:13:35 +02:00
Paweł GronowskiandGitHub 3320996718 Merge pull request #7122 from thaJeztah/bump_x_deps
vendor: update golang.org/x/* dependencies
2026-07-27 22:13:17 +02:00
Sebastiaan van StijnandGitHub 4b02fd04b0 Merge pull request #7124 from JessThrysoee/completion-swarm-filters
completion: add completion for swarm "--filter" flags
2026-07-27 21:30:07 +02:00
Sebastiaan van Stijn 487686142c vendor: golang.org/x/net v0.57.0
Relevant changes (in vendor):

- bpf: add security considerations to package docs
- http2: initialize Transport on NewClientConn
  fixes: x/net/http2: zero Transport not ready for use
- idna: reject all-ASCII xn-- labels on all Go versions
  fixes x/net/idna: ToUnicode accepts Punycode labels encoding pure ASCII labels

full diff: https://github.com/golang/net/compare/v0.56.0...v0.57.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-27 21:28:05 +02:00
Sebastiaan van Stijn e03b83ef06 vendor: golang.org/x/text v0.40.0
- unicode/norm: avoid infinite loop on invalid input

full diff: https://github.com/golang/text/compare/v0.38.0...v0.40.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-27 21:28:05 +02:00
Sebastiaan van Stijn 8dfca49e6b vendor: golang.org/x/mod v0.38.0
full diff: https://github.com/golang/mod/compare/v0.37.0...v0.38.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-27 21:28:05 +02:00
Sebastiaan van Stijn 808405b67d vendor: golang.org/x/term v0.45.0
full diff: https://github.com/golang/term/compare/v0.44.0...v0.45.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-27 21:28:05 +02:00
Sebastiaan van Stijn 3f5a7b50ab vendor: golang.org/x/sys v0.47.0
- cpu: handle vendor suffixes in parseRelease
- unix: update glibc to 2.43
- unix: use epoll_pwait rather than epoll_wait
- windows: avoid length overflow in NewNTString
- windows: document safe usage of TrusteeValue

full diff: https://github.com/golang/sys/compare/v0.46.0...v0.47.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-27 21:28:05 +02:00
Sebastiaan van Stijn 40c63db4c8 vendor: golang.org/x/sync v0.22.0
semaphore: panic on negative weights

full diff: https://github.com/golang/sync/compare/v0.21.0...v0.22.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-27 21:28:03 +02:00
Sebastiaan van StijnandGitHub 977f88900e Merge pull request #7121 from thaJeztah/bump_go_connections
vendor: github.com/docker/go-connections v0.8.0
2026-07-27 21:26:50 +02:00
Sebastiaan van Stijn f6dfb40875 vendor: github.com/moby/go-archive main / v0.3.0-dev
full diff: https://github.com/moby/go-archive/compare/v0.2.0...2ff9bfb8b2ee

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-27 21:24:52 +02:00
Sebastiaan van StijnandGitHub a9ac44ea6b Merge pull request #7128 from vvoland/update-docker
vendor: github.com/moby/moby/client v0.5.1
2026-07-27 21:21:13 +02:00
Sebastiaan van StijnandGitHub 358f0135e3 Merge pull request #7127 from vvoland/win-unix
docs: Document Unix socket support on Windows
2026-07-27 21:20:26 +02:00
Paweł Gronowski aa610f321d vendor: github.com/moby/moby/client v0.5.1
full diff: https://github.com/moby/moby/compare/client/v0.5.0...client/v0.5.1

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-07-27 21:15:05 +02:00
Paweł Gronowski 0d32eed829 docs: Document Unix socket support on Windows
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-07-27 20:29:50 +02:00
Paweł GronowskiandGitHub be7865c09e Merge pull request #7123 from thaJeztah/bump_grpc
vendor: google.golang.org/grpc v1.82.1
2026-07-27 17:00:54 +02:00
Paweł GronowskiandGitHub 186b7283e1 Merge pull request #7126 from thaJeztah/bump_yaml
vendor: go.yaml.in/yaml/v3 v3.0.5
2026-07-27 16:59:57 +02:00
Sebastiaan van Stijn 9f4301e8f5 vendor: go.yaml.in/yaml/v3 v3.0.5
removes transitive dependencies on gopkg.in/check.v1

full diff: https://github.com/yaml/go-yaml/compare/v3.0.4...v3.0.5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-27 14:43:56 +02:00
Jess Thrysoee 89e882a808 completion: add completion for swarm "--filter" flags
The migration to the generated (V2) shell completions dropped the
"--filter" key/value suggestions that the legacy bash completion used to
provide for the swarm commands, so e.g. "docker service ps <service>
--filter <TAB>" no longer completed anything.

Register filter completions for "docker service ps", "docker service
ls", and "docker node ps", following the same approach as the existing
completion for "docker events --filter".

Signed-off-by: Jess Thrysoee <jess@thrysoee.dk>
2026-07-26 15:52:58 +02:00
Sebastiaan van Stijn 4e6e8fe5c8 vendor: github.com/docker/go-connections v0.8.0
- sockets: set socket permissions without overriding umask
- sockets: improve abstract Unix socket handling
- sockets: InmemSocket: add DialContext
- sockets: remove double error decoration
- sockets: test-enhancements and improve coverage

full diff: https://github.com/docker/go-connections/compare/v0.7.0...v0.8.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-25 19:47:59 +02:00
Sebastiaan van StijnandGitHub 5b21d378b0 Merge pull request #7118 from docker/dependabot/github_actions/codeql-actions-15f4d34eb1
build(deps): bump the codeql-actions group with 3 updates
2026-07-25 04:05:04 +02:00
Sebastiaan van Stijn 532dcc37f5 vendor: google.golang.org/grpc v1.82.1
Fixes xDS RBAC and HTTP/2 Vulnerabilities: GHSA-hrxh-6v49-42gf

full diff: https://github.com/grpc/grpc-go/compare/v1.81.1...v1.82.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-25 03:59:22 +02:00
Sebastiaan van StijnandGitHub 19a0ee3926 Merge pull request #7113 from nikolauspschuetz/test-device-opts-validators
opts: add tests for weight/throttle device opts validators
2026-07-25 02:16:11 +02:00
Sebastiaan van StijnandGitHub c700ac42b6 Merge pull request #7103 from hirehamir/fix/stray-pipe-in-docker-create-help-message
fix: stray `|` pipe in `docker create --help`
2026-07-25 02:01:52 +02:00
Sebastiaan van StijnandGitHub 03b45495db Merge pull request #7116 from docker/dependabot/github_actions/actions/setup-go-7.0.0
build(deps): bump actions/setup-go from 6.5.0 to 7.0.0
2026-07-25 01:51:41 +02:00
Sebastiaan van StijnandGitHub 8061c90dcd Merge pull request #7110 from HajimohammadiNet/fix-container-rm-force-output
container rm: suppress forced not found errors
2026-07-25 01:50:41 +02:00
Sebastiaan van StijnandGitHub 80698fa987 Merge pull request #7120 from docker/dependabot/github_actions/actions/checkout-7.0.1
build(deps): bump actions/checkout from 7.0.0 to 7.0.1
2026-07-25 01:41:59 +02:00
AmirHossein HajiMohammadi ee4c249cc2 container rm: suppress forced not found errors
Signed-off-by: AmirHossein HajiMohammadi <a.hajimohammadi@rahkar.team>
2026-07-24 17:38:57 +03:30
Sebastiaan van StijnandGitHub 9391c9889c Merge pull request #7119 from thaJeztah/bump_go_archive_0.2.1
vendor: github.com/moby/go-archive v0.2.1
2026-07-24 12:11:36 +02:00
dependabot[bot]andGitHub 90d14d3e7e build(deps): bump actions/checkout from 7.0.0 to 7.0.1
Bumps [actions/checkout](https://github.com/actions/checkout) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0...3d3c42e5aac5ba805825da76410c181273ba90b1)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 08:43:24 +00:00
Sebastiaan van Stijn 349fad1635 vendor: github.com/moby/go-archive v0.2.1
full diff: https://github.com/moby/go-archive/compare/v0.2.0...v0.2.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-23 23:05:30 +02:00
dependabot[bot]andGitHub a3ea9a43e0 build(deps): bump the codeql-actions group with 3 updates
Bumps the codeql-actions group with 3 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/autobuild](https://github.com/github/codeql-action) and [github/codeql-action/analyze](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.37.0 to 4.37.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a)

Updates `github/codeql-action/autobuild` from 4.37.0 to 4.37.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a)

Updates `github/codeql-action/analyze` from 4.37.0 to 4.37.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-actions
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.37.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-23 08:46:14 +00:00
dependabot[bot]andGitHub fd78fdc62d build(deps): bump actions/setup-go from 6.5.0 to 7.0.0
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.5.0 to 7.0.0.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/924ae3a1cded613372ab5595356fb5720e22ba16...b7ad1dad31e06c5925ef5d2fc7ad053ef454303e)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-22 08:46:48 +00:00
Nikolaus Schuetz 8f3477fca1 Add tests for weight/throttle device opts validators
opts/weightdevice.go and opts/throttledevice.go had no tests, unlike the
sibling opts. Add table-driven coverage for ValidateWeightDevice,
ValidateThrottleBpsDevice, ValidateThrottleIOpsDevice and the Set/GetList
paths, including boundary (weight 0/10/1000/overflow) and error cases.

Signed-off-by: Nikolaus Schuetz <nikolauspschuetz@gmail.com>
2026-07-20 13:47:09 -07:00
Paweł GronowskiandGitHub 7a54334eb0 Merge pull request #7082 from thaJeztah/prompt_cleans_step1
internal/prompt: Confirm: don't wrap stdIn
2026-07-20 17:29:42 +02:00
Sebastiaan van StijnandGitHub 617d772fcc Merge pull request #7112 from vvoland/makesocket
docker.Makefile: Use active context socket
2026-07-17 17:52:07 +02:00
Paweł Gronowski 7aef4c8479 docker.Makefile: Use active context socket
The development and e2e containers hard-code /var/run/docker.sock, so
rootless and other local contexts cannot expose their daemon socket.
Resolve the active context's Docker endpoint and strip the unix scheme
before using it as the bind source.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-07-17 15:33:12 +02:00
Paweł GronowskiandGitHub dc997612d0 Merge pull request #7007 from lohitkolluri/e2e/private-registry-pull-push-5965
e2e: add private registry pull/push regression test
2026-07-16 14:18:00 +02:00
Sebastiaan van StijnandGitHub 7ea9e2158c Merge pull request #7107 from docker/dependabot/github_actions/codeql-actions-e021b9f00e
build(deps): bump the codeql-actions group with 3 updates
2026-07-16 02:01:21 +02:00
dependabot[bot]andGitHub 3519704227 build(deps): bump the codeql-actions group with 3 updates
Bumps the codeql-actions group with 3 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/autobuild](https://github.com/github/codeql-action) and [github/codeql-action/analyze](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.36.3 to 4.37.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/54f647b7e1bb85c95cddabcd46b0c578ec92bc1a...99df26d4f13ea111d4ec1a7dddef6063f76b97e9)

Updates `github/codeql-action/autobuild` from 4.36.3 to 4.37.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/54f647b7e1bb85c95cddabcd46b0c578ec92bc1a...99df26d4f13ea111d4ec1a7dddef6063f76b97e9)

Updates `github/codeql-action/analyze` from 4.36.3 to 4.37.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/54f647b7e1bb85c95cddabcd46b0c578ec92bc1a...99df26d4f13ea111d4ec1a7dddef6063f76b97e9)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: codeql-actions
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: codeql-actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: codeql-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-15 08:46:00 +00:00
Hamir 0133bfa4fd fix: stray | pipe in docker create --help
Signed-off-by: Hamir <hirehamir@gmail.com>
2026-07-10 17:38:18 -07:00
Sebastiaan van StijnandGitHub 09754bc280 Merge pull request #7100 from docker/dependabot/github_actions/docker-actions-4dfd9f9ba8
build(deps): bump docker/login-action from 4.3.0 to 4.4.0 in the docker-actions group
2026-07-10 19:47:32 +02:00
Paweł GronowskiandGitHub 48370883e0 Merge pull request #7102 from vvoland/sync-master
gha/sync-release-branch: Use actions write permission
2026-07-10 19:35:02 +02:00
Paweł Gronowski 18d4f4ff6d gha/sync-release-branch: Use actions write permission
`workflows` is not a supported GITHUB_TOKEN permission key, so GitHub
rejects the workflow definition. Use the valid `actions` permission
for both jobs.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-07-10 17:06:49 +02:00
Sebastiaan van StijnandGitHub 1423089969 Merge pull request #7101 from vvoland/sync-master
sync-release-branch: Run from master against selected release
2026-07-10 15:22:02 +02:00
Paweł Gronowski 5853360a94 gha/sync-release-branch: Add workflows write permission
Without it GitHub rejects the push:

```
refusing to allow a GitHub App to create or update workflow `.github/workflows/build.yml` without `workflows` permission
```

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-07-10 13:49:45 +02:00
Paweł Gronowski f816d5c003 sync-release-branch: Run from master against selected release
The workflow previously inferred its target from the dispatch ref,
requiring operators to always sync the release branch with the
workflow/scripts on master.

Accept the release branch as an input, keep the dispatched master
checkout as the script source, and merge in a detached worktree at the
selected release revision.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-07-10 13:49:45 +02:00
Paweł GronowskiandGitHub 25a1d41669 Merge pull request #7094 from thaJeztah/rm_go_reportcard
README: remove Go Report Card badge
2026-07-10 12:27:07 +02:00
dependabot[bot]andGitHub 45d1a6cccf build(deps): bump docker/login-action in the docker-actions group
Bumps the docker-actions group with 1 update: [docker/login-action](https://github.com/docker/login-action).


Updates `docker/login-action` from 4.3.0 to 4.4.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/c99871dec2022cc055c062a10cc1a1310835ceb4...af1e73f918a031802d376d3c8bbc3fe56130a9b0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: docker-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-10 08:46:40 +00:00
Sebastiaan van StijnandGitHub ba55f0c3b1 Merge pull request #7096 from docker/dependabot/github_actions/docker-actions-c21f7ea42a
build(deps): bump the docker-actions group with 3 updates
2026-07-10 08:39:04 +02:00
Sebastiaan van StijnandGitHub 9c1b7fc671 Merge pull request #7095 from docker/dependabot/github_actions/codeql-actions-920a780463
build(deps): bump the codeql-actions group with 3 updates
2026-07-10 08:37:26 +02:00
Sebastiaan van StijnandGitHub a8ddac1a8e Merge pull request #7098 from vvoland/sync-editor
scripts/sync-branch: Fix non-interactive merge
2026-07-10 08:31:05 +02:00
mickael emirkanian 2d978b80ae docs(authz): clarify daemon parsing semantics
Signed-off-by: mickael emirkanian <mickael.emirkanian@docker.com>
2026-07-09 13:36:32 -04:00
Paweł Gronowski f57e528457 scripts/sync-branch: Fix non-interactive merge
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-07-09 16:51:33 +02:00
Sebastiaan van StijnandGitHub 9ba113bc5d Merge pull request #7091 from vvoland/gha-sync-release
gha: Add release branch sync workflow
2026-07-09 14:29:42 +02:00
dependabot[bot]andGitHub cd79c7ebfc build(deps): bump the docker-actions group with 3 updates
Bumps the docker-actions group with 3 updates: [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action), [docker/login-action](https://github.com/docker/login-action) and [docker/metadata-action](https://github.com/docker/metadata-action).


Updates `docker/setup-buildx-action` from 4.1.0 to 4.2.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5...bb05f3f5519dd87d3ba754cc423b652a5edd6d2c)

Updates `docker/login-action` from 4.2.0 to 4.3.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/650006c6eb7dba73a995cc03b0b2d7f5ca915bee...c99871dec2022cc055c062a10cc1a1310835ceb4)

Updates `docker/metadata-action` from 6.1.0 to 6.2.0
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9...dc802804100637a589fabce1cb79ff13a1411302)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: docker-actions
- dependency-name: docker/login-action
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: docker-actions
- dependency-name: docker/metadata-action
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: docker-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-09 08:47:18 +00:00
dependabot[bot]andGitHub 042528819a build(deps): bump the codeql-actions group with 3 updates
Bumps the codeql-actions group with 3 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/autobuild](https://github.com/github/codeql-action) and [github/codeql-action/analyze](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.36.2 to 4.36.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...54f647b7e1bb85c95cddabcd46b0c578ec92bc1a)

Updates `github/codeql-action/autobuild` from 4.36.2 to 4.36.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...54f647b7e1bb85c95cddabcd46b0c578ec92bc1a)

Updates `github/codeql-action/analyze` from 4.36.2 to 4.36.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...54f647b7e1bb85c95cddabcd46b0c578ec92bc1a)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.36.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-actions
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.36.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.36.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-09 08:46:24 +00:00
Sebastiaan van Stijn 8c9e2f353e README: remove Go Report Card badge
The project was sunset;

> After more than a decade of serving the ecosystem, the time
> has come to sunset Go Report Card. Following the loss of our
> primary infrastructure sponsor, maintaining the web app is
> no longer sustainable.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-09 01:03:31 +02:00
Sebastiaan van StijnandGitHub a86b9aa542 Merge pull request #7090 from docker/dependabot/go_modules/cmd/docker-trust/go_modules-a3c8a40308
build(deps): bump golang.org/x/crypto from 0.50.0 to 0.52.0 in /cmd/docker-trust in the go_modules group across 1 directory
2026-07-08 23:31:27 +02:00
Paweł Gronowski 182f56fe8c gha: Add release branch sync workflow
Add a manually dispatched workflow for maintainers to sync a Docker
release branch to a selected release tag.

The sync-release-branch job checks out the release branch, computes
the list of unmerged tags up to the requested tag via
scripts/unmerged-tags, merges them in order via scripts/sync-branch
using git merge --no-ff (resolving conflicts by taking the tag's
content), then pushes the result to a temporary branch.

The push-release-branch job runs after manual approval via the
docker-releases environment. It verifies that neither the release
branch nor the temporary branch moved since the sync job ran before
force-advancing the release branch and deleting the temporary branch.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-07-08 20:22:22 +02:00
Sebastiaan van StijnandGitHub e5c424fd70 Merge pull request #7092 from docker/dependabot/github_actions/docker-actions-78c0e55afe
build(deps): bump the docker-actions group with 2 updates
2026-07-08 15:00:29 +02:00
dependabot[bot]andGitHub 145e7f83cd build(deps): bump the docker-actions group with 2 updates
Bumps the docker-actions group with 2 updates: [docker/bake-action](https://github.com/docker/bake-action) and [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action).


Updates `docker/bake-action` from 7.2.0 to 7.3.0
- [Release notes](https://github.com/docker/bake-action/releases)
- [Commits](https://github.com/docker/bake-action/compare/6614cfa25eff9a0b2b2697efb0b6159e7680d584...d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b)

Updates `docker/setup-qemu-action` from 4.1.0 to 4.2.0
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/06116385d9baf250c9f4dcb4858b16962ea869c3...96fe6ef7f33517b61c61be40b68a1882f3264fb8)

---
updated-dependencies:
- dependency-name: docker/bake-action
  dependency-version: 7.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: docker-actions
- dependency-name: docker/setup-qemu-action
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: docker-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-08 10:20:16 +00:00
Paweł GronowskiandGitHub e8ded3fce7 Merge pull request #7085 from thaJeztah/dependabot_group
gha: dependabot: group docker/* and codeql action updates
2026-07-08 12:15:03 +02:00
dependabot[bot]andGitHub 91db63cf5b build(deps): bump golang.org/x/crypto
Bumps the go_modules group with 1 update in the /cmd/docker-trust directory: [golang.org/x/crypto](https://github.com/golang/crypto).


Updates `golang.org/x/crypto` from 0.50.0 to 0.52.0
- [Commits](https://github.com/golang/crypto/compare/v0.50.0...v0.52.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.52.0
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-08 09:15:41 +00:00
Paweł GronowskiandGitHub d4218f26dc Merge pull request #7087 from thaJeztah/update_go1.26.5
update to go1.26.5
2026-07-08 11:14:40 +02:00
Sebastiaan van Stijn 6d245daa91 update to go1.26.5
go1.26.5 (released 2026-07-07) includes security fixes to the crypto/tls
and os packages, as well as bug fixes to the compiler, the runtime, the
go command, and the net, os, and syscall packages. See the Go 1.26.5
milestone on our issue tracker for details;

- https://github.com/golang/go/issues?q=milestone%3AGo1.26.5+label%3ACherryPickApproved
- full diff: https://github.com/golang/go/compare/go1.26.4...go1.26.5

From the security announcement:

We have just released Go versions 1.26.5 and 1.25.12, minor point releases.

These releases include 2 security fixes following the security policy:

- os: Root escape via symlink plus trailing slash

  On Unix systems, opening a file in an os.Root improperly
  followed symlinks to locations outside of the Root when
  the final path component of the a path is a symbolic link
  and the path ends in /.

  For example, root.Open("symlink/") would open "symlink"
  even when "symlink" is a symbolic link pointing outside of the root.

  On Unix, openat(fd, path, O_NOFOLLOW) will follow symlinks
  in path when path ends in a /. Root failed to account for
  this behavior, permitting paths with a trailing / to escape.
  It now properly sanitizes the path parameter provided to openat.

  hanks to Mundur for reporting this issue.

  This is CVE-2026-39822 and Go issue https://go.dev/issue/79005.

- crypto/tls: Encrypted Client Hello privacy leak

  he Encrypted Client Hello implementation would leak the pre-shared key
  dentities during the handshake, allowing a passive network observer who can
  ollect handshakes to de-anonymize the hostname of the server, even when ECH was
  eing used.

  Thanks to Coia Prant (github.com/rbqvq) for reporting this issue.

  This is CVE-2026-42505 and Go issue https://go.dev/issue/79282.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-08 00:01:42 +02:00
Sebastiaan van Stijn 2282b23f02 gha: dependabot: group docker/* and codeql action updates
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-07 15:56:25 +02:00
Sebastiaan van Stijn fd3497683d internal/prompt: Confirm: don't wrap stdIn
This was a remnant from when `PromptForConfirmation` accepted a `InStream`;
it was added in [moby@30b8f08], which got left behind when [cli@37ccc00]
updated its signature to accept a plain `io.Reader`.

While updating, also update the comment to provide more context on the reason
we're unconditionally using `os.Stdin` on Windows.

[moby@30b8f08]: https://github.com/moby/moby/commit/30b8f084436a2a1d5e8523fcd2c5ea64cc805224
[cli@37ccc00]: https://github.com/docker/cli/commit/37ccc00d0e14461bcf29e98669773625dfed2fce

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-07 14:19:44 +02:00
Sebastiaan van Stijn 2abf92e95c cli/command: PromptUserForCredentials: don't mutate cli
PromptUserForCredentials accepted a Cli as argument so that it could swap
the input stream on Windows (cli.SetIn).

Given that we only require this swap for the duration of this function (if
needed at all), we can use a local variable that either uses cli.In() or
os.Stdin (on Windows).

We currently still need to wrap the os.Stdin into a streams.In, but can use
the raw os.Stdin (and/or cli.In().File()) once prompt.DisableInputEcho is
updated.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-07-07 14:19:20 +02:00
Sebastiaan van StijnandGitHub 40a8e8e754 Merge pull request #7081 from vvoland/work-gha
Update docker-agent-action to v2.0.2
2026-07-06 11:43:13 +02:00
Paweł Gronowski da2622ed8e Update docker-agent-action to v2.0.2
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-07-06 11:35:08 +02:00
Sebastiaan van StijnandGitHub c4c704e62b Merge pull request #7079 from derekmisler/fix/pr-review-trigger-concurrency
ci: add concurrency group to pr-review-trigger to prevent duplicate reviews
2026-07-02 16:40:57 +02:00
Derek MislerandDerek Misler 1c742902b6 ci: add concurrency group and remove bot filter in pr-review-trigger
Add a concurrency group keyed on PR number to prevent duplicate reviews
from simultaneous review_requested events.

Remove the sender.type != 'Bot' guard so Dependabot PRs remain
reviewable — per maintainer feedback, those reviews are useful for
catching behavior changes in dependency updates.

Signed-off-by: Derek Misler <derek.misler@docker.com>
2026-07-02 14:26:26 +00:00
Sebastiaan van StijnandGitHub 0f83acece4 Merge pull request #7077 from docker/dependabot/github_actions/actions/setup-go-6.5.0
build(deps): bump actions/setup-go from 6.3.0 to 6.5.0
2026-06-30 20:40:27 +02:00
Paweł GronowskiandGitHub 3edebc433e Merge pull request #7078 from thaJeztah/version
bump VERSION to v29.7.0-dev
2026-06-30 16:58:09 +02:00
Sebastiaan van Stijn 635fed89d2 bump VERSION to v29.7.0-dev
This reverts commit d9c59c9cfe.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-30 16:31:14 +02:00
dependabot[bot]andGitHub 444bab12d9 build(deps): bump actions/setup-go from 6.3.0 to 6.5.0
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.3.0 to 6.5.0.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/4b73464bb391d4059bd26b0524d20df3927bd417...924ae3a1cded613372ab5595356fb5720e22ba16)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: 6.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-30 08:44:46 +00:00
Sebastiaan van StijnandGitHub 8900f1d330 Merge pull request #7074 from thaJeztah/version
version 29.6.1
2026-06-25 22:08:24 +02:00
Sebastiaan van StijnandGitHub 22b8f1396e Merge pull request #7069 from docker-agent/auto/migrate-to-docker-agent-action
chore: migrate cagent-action to docker-agent-action (v2.0.0)
2026-06-25 22:05:29 +02:00
Sebastiaan van Stijn d9c59c9cfe version 29.6.1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-25 22:03:12 +02:00
Sebastiaan van StijnandGitHub 64307515e6 Merge pull request #7073 from thaJeztah/bump_moby_user
vendor: github.com/moby/sys/user v0.4.1
2026-06-25 21:59:18 +02:00
Sebastiaan van Stijn 8fda97b545 vendor: github.com/moby/sys/user v0.4.1
- user: prevent possible DoS via unbounded parsing of user and group
  database files in GHSA-mjcv-p78q-w5fw. This fixes a similar issue
  as CVE-2026-47262 in containerd.
- user: prevent falling back to looking up numeric usernames
  Improve handling of numeric user/group to prevent looking up numeric
  values as usernames. This fixes a similar issue as [CVE-2026-46680] in
  containerd.
- user: update minimum go version to go1.18
- assorted testing and linting fixes.

[CVE-2026-46680]: https://github.com/advisories/GHSA-fqw6-gf59-qr4w

full diff: https://github.com/moby/sys/compare/user/v0.4.0...user/v0.4.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-25 21:31:42 +02:00
Docker Agent f9dc4e413b chore: bump docker-agent-action to v2.0.1
Signed-off-by: Docker Agent <svc-github-docker-agent@docker.com>
2026-06-24 13:32:46 +00:00
Sebastiaan van StijnandGitHub f8a2d2b253 Merge pull request #7070 from docker/dependabot/github_actions/actions/checkout-7.0.0
build(deps): bump actions/checkout from 6.0.3 to 7.0.0
2026-06-24 10:48:34 +02:00
dependabot[bot]andGitHub 7eb15d3454 build(deps): bump actions/checkout from 6.0.3 to 7.0.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.3 to 7.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/df4cb1c069e1874edd31b4311f1884172cec0e10...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-24 08:42:35 +00:00
Sebastiaan van StijnandGitHub 033b0ff9ff Merge pull request #7063 from docker/dependabot/github_actions/crazy-max/dot-github/dot-github/workflows/zizmor.yml-1.10.1
build(deps): bump crazy-max/.github/.github/workflows/zizmor.yml from 1.10.0 to 1.10.1
2026-06-22 16:42:54 +02:00
Sebastiaan van StijnandGitHub 317bfd1231 Merge pull request #7067 from docker/dependabot/github_actions/docker/cagent-action/dot-github/workflows/review-pr.yml-1.5.5
build(deps): bump docker/cagent-action/.github/workflows/review-pr.yml from 1.5.4 to 1.5.5
2026-06-22 16:41:07 +02:00
Sebastiaan van StijnandGitHub 1b4c7d7807 Merge pull request #7068 from thaJeztah/bump_version
bump VERSION to v29.7.0-dev
2026-06-22 16:39:50 +02:00
Sebastiaan van Stijn e45822e51d bump VERSION to v29.7.0-dev
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-22 15:52:40 +02:00
dependabot[bot]andGitHub a97303090d build(deps): bump docker/cagent-action/.github/workflows/review-pr.yml
Bumps [docker/cagent-action/.github/workflows/review-pr.yml](https://github.com/docker/cagent-action) from 1.5.4 to 1.5.5.
- [Release notes](https://github.com/docker/cagent-action/releases)
- [Commits](https://github.com/docker/cagent-action/compare/3f5dc9969f307d3c76acb7e9ccaefdd96bd62f4b...367a30ddb41e0156459d03750f508eac03f3c38a)

---
updated-dependencies:
- dependency-name: docker/cagent-action/.github/workflows/review-pr.yml
  dependency-version: 1.5.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-22 08:43:57 +00:00
dependabot[bot]andGitHub d516a10f93 build(deps): bump crazy-max/.github/.github/workflows/zizmor.yml
Bumps [crazy-max/.github/.github/workflows/zizmor.yml](https://github.com/crazy-max/.github) from 1.10.0 to 1.10.1.
- [Release notes](https://github.com/crazy-max/.github/releases)
- [Commits](https://github.com/crazy-max/.github/compare/716fd1c51a46c5d93a41d44a94b439c9ee802536...46267a6e61cd56aac2fc79943df180152f4c89d6)

---
updated-dependencies:
- dependency-name: crazy-max/.github/.github/workflows/zizmor.yml
  dependency-version: 1.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-19 08:42:27 +00:00
Sebastiaan van StijnandGitHub fb59821d45 Merge pull request #7062 from vvoland/update-docker
vendor: github.com/moby/moby api v1.55.0 and client v0.5.0
2026-06-18 21:53:10 +02:00
Paweł Gronowski ee2f737013 vendor: github.com/moby/moby/client v0.5.0
full diff: https://github.com/moby/moby/compare/client/v0.5.0-rc.1...client/v0.5.0

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-06-18 21:41:38 +02:00
Paweł Gronowski 1f80e23560 vendor: github.com/moby/moby/api v1.55.0
full diff: https://github.com/moby/moby/compare/api/v1.55.0-rc.1...api/v1.55.0

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-06-18 21:39:19 +02:00
Lohit Kolluri d9698edc85 e2e: add private registry pull/push regression test
This adds an e2e regression test for authenticated pull/push against a private registry, covering the auth regression reported in docker/cli#5963.

Includes:
- New privateregistry service in the e2e Compose stack with htpasswd auth on port 5001, and --insecure-registry for the engine container.
- TestPullPushPrivateRepository test that verifies authenticated push/pull and rejects unauthenticated operations.
- Auth config and test credentials in e2e/testdata/registry/.
- 90-second retry loop for transient DNS/container startup races.
- Service health wait loop in scripts/test/e2e/run.
- Increase TestProcessTermination timeout from 10s to 20s for connhelper-ssh + engine 25 combination.
- Connhelper-ssh engine Dockerfile for private registry integration.

Signed-off-by: Lohit Kolluri <lohitkolluri@gmail.com>
2026-06-13 00:22:00 +05:30
Paweł GronowskiandGitHub 1d1562e004 Merge pull request #7029 from agirault/login-password-dash-stdin
cli/registry: support password dash stdin
2026-06-12 19:31:17 +02:00
Sebastiaan van StijnandGitHub 8c2e80070b Merge pull request #7051 from thaJeztah/bump_moby
vendor: github.com/moby/moby/api v1.55.0-rc.1, moby/client v0.5.0-rc.1
2026-06-12 19:07:07 +02:00
Sebastiaan van Stijn 233cd4a643 vendor: github.com/moby/moby/api v1.55.0-rc.1, moby/client v0.5.0-rc.1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-12 18:54:32 +02:00
Paweł GronowskiandGitHub 5b600d015d Merge pull request #7047 from thaJeztah/bump_go_events
vendor: github.com/docker/go-events v0.0.0-20260608200158-dbf6103125a4
2026-06-12 18:44:35 +02:00
Paweł GronowskiandGitHub e6decf4d85 Merge pull request #7048 from thaJeztah/bump_compress
vendor: github.com/klauspost/compress v1.18.6
2026-06-12 18:44:24 +02:00
Paweł GronowskiandGitHub a9284d1161 Merge pull request #7049 from thaJeztah/bump_x_net
vendor: golang.org/x/net v0.56.0
2026-06-12 18:44:11 +02:00
Paweł GronowskiandGitHub e7319c78af Merge pull request #7050 from thaJeztah/update_authors_mailmap
update AUTHORS and mailmap
2026-06-12 18:43:43 +02:00
Sebastiaan van Stijn 0f1dbdea86 update AUTHORS and mailmap
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-12 18:05:12 +02:00
Sebastiaan van Stijn fef3ef83fe vendor: golang.org/x/net v0.56.0
full diff: https://github.com/golang/net/compare/v0.55.0...v0.56.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-12 17:13:23 +02:00
Sebastiaan van Stijn 9eff92c55a vendor: github.com/klauspost/compress v1.18.6
full diff: https://github.com/klauspost/compress/compare/v1.18.5...v1.18.6

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-12 17:11:24 +02:00
Sebastiaan van Stijn 43f745b242 vendor: github.com/docker/go-events v0.0.0-20260608200158-dbf6103125a4
full diff: https://github.com/docker/go-events/compare/605354379745...dbf6103125a4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-12 17:07:53 +02:00
Alexis GiraultandSebastiaan van Stijn 450df790a0 cli/registry: support password dash stdin
Signed-off-by: Alexis Girault <agirault@nvidia.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-12 16:15:23 +02:00
Sebastiaan van StijnandGitHub 0df3977cb3 Merge pull request #7042 from thaJeztah/carry_deprecation
Add a deprecation warning about --link on default nw
2026-06-11 15:07:14 +02:00
Sebastiaan van StijnandGitHub 86cf0a5185 Merge pull request #7043 from docker/dependabot/github_actions/crazy-max/dot-github/dot-github/workflows/zizmor.yml-1.10.0
build(deps): bump crazy-max/.github/.github/workflows/zizmor.yml from 1.8.0 to 1.10.0
2026-06-11 14:44:57 +02:00
Sebastiaan van StijnandGitHub 3b10370c40 Merge pull request #7044 from docker/dependabot/github_actions/github/codeql-action-4.36.2
build(deps): bump github/codeql-action from 4.36.1 to 4.36.2
2026-06-11 14:39:44 +02:00
dependabot[bot]andGitHub a23b1c6770 build(deps): bump github/codeql-action from 4.36.1 to 4.36.2
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.36.1 to 4.36.2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/87557b9c84dde89fdd9b10e88954ac2f4248e463...8aad20d150bbac5944a9f9d289da16a4b0d87c1e)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.36.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-11 08:44:24 +00:00
dependabot[bot]andGitHub 3a197287d2 build(deps): bump crazy-max/.github/.github/workflows/zizmor.yml
Bumps [crazy-max/.github/.github/workflows/zizmor.yml](https://github.com/crazy-max/.github) from 1.8.0 to 1.10.0.
- [Release notes](https://github.com/crazy-max/.github/releases)
- [Commits](https://github.com/crazy-max/.github/compare/9ba6e6f9450baf3b1237f8035c1fdc45932510bd...716fd1c51a46c5d93a41d44a94b439c9ee802536)

---
updated-dependencies:
- dependency-name: crazy-max/.github/.github/workflows/zizmor.yml
  dependency-version: 1.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-11 08:42:57 +00:00
Albin KerouantonandSebastiaan van Stijn aaaeb80ceb Add a deprecation warning about --link on default nw
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-10 20:12:17 +02:00
Sebastiaan van StijnandGitHub 278ac25271 Merge pull request #6039 from thaJeztah/gomod_symlink
scripts/with-go-mod.sh: use symlink instead of -modfile
2026-06-10 16:11:07 +02:00
Sebastiaan van StijnandGitHub 54f330978e Merge pull request #7028 from docker/dependabot/github_actions/docker/setup-qemu-action-4.1.0
build(deps): bump docker/setup-qemu-action from 4.0.0 to 4.1.0
2026-06-10 15:49:05 +02:00
Sebastiaan van StijnandGitHub f4a4c1e2cf Merge pull request #7038 from thaJeztah/bump_runewidth
vendor: github.com/mattn/go-runewidth v0.0.24
2026-06-10 15:48:14 +02:00
Sebastiaan van Stijn deacdc6feb scripts/with-go-mod.sh: simplify symlink comparison
Make sure the symlinks point to the same file; not if both are
identical (absolute or relative symlink); it's only for suppressing
the warning so not critical.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-10 15:44:04 +02:00
Sebastiaan van Stijn c17c247ed4 scripts/with-go-mod.sh: use symlink instead of -modfile
While the "-modfile=vendor.mod" is slightly more correct, using a
symlink allows for most of the go tools to work "as usual", just
without an acual `go.mod` being committed in the repository.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-10 15:44:01 +02:00
Sebastiaan van StijnandGitHub b680c49f57 Merge pull request #7041 from thaJeztah/no_tools
man: remove tools.go in favor of tools directive
2026-06-10 15:40:42 +02:00
Sebastiaan van StijnandGitHub 4748c4e4d3 Merge pull request #7040 from thaJeztah/fix_go_version
scripts/with-go-mod: use correct minimum Go version
2026-06-10 15:37:02 +02:00
Paweł GronowskiandGitHub 9c7701eb48 Merge pull request #7037 from thaJeztah/bump_otels
vendor: go.opentelemetry.io/otel v1.44.0, go.opentelemetry.io/contrib v0.69.0
2026-06-10 12:26:23 +02:00
Paweł GronowskiandGitHub ddc801807d Merge pull request #7036 from thaJeztah/bump_x_deps
vendor: update golang.org/x/* dependencies
2026-06-10 12:26:08 +02:00
Paweł GronowskiandGitHub 83963b759c Merge pull request #7035 from thaJeztah/bump_sequential
vendor: github.com/moby/sys/sequential v0.7.0
2026-06-10 12:25:21 +02:00
Paweł GronowskiandGitHub 2e635d7baf Merge pull request #7032 from thaJeztah/bump_creds_helper
vendor: github.com/docker/docker-credential-helpers v0.9.8
2026-06-10 12:24:02 +02:00
Sebastiaan van Stijn 1c22ca1aac scripts/docs: use "go install tool"
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-10 11:49:33 +02:00
Sebastiaan van Stijn 55016421fd man: remove tools.go in favor of tools directive
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-10 11:37:02 +02:00
Sebastiaan van Stijn 8b2a990843 scripts/with-go-mod: use correct minimum Go version
Follow-up to 8f7dc04070, which updated the
minimum Go version in vendor.mod, but did not adjust this script.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-10 10:23:25 +02:00
Sebastiaan van Stijn a9c82c0a9f vendor: github.com/mattn/go-runewidth v0.0.24
- Optimize EastAsian RuneWidth with precomputed width table

full diff: https://github.com/mattn/go-runewidth/compare/v0.0.23...v0.0.24

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-09 16:58:46 +02:00
Sebastiaan van Stijn 22d7ca46a3 vendor: go.opentelemetry.io/otel v1.44.0, go.opentelemetry.io/contrib v0.69.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-09 16:35:02 +02:00
Sebastiaan van Stijn a721bd651b vendor: google.golang.org/genproto 3dc84a4a5aaa
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-09 16:32:02 +02:00
Sebastiaan van Stijn 51583aec0b vendor: golang.org/x/text v0.38.0
full diff: https://github.com/golang/text/compare/v0.37.0...v0.38.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-09 16:26:28 +02:00
Sebastiaan van Stijn 399c9456a7 vendor: golang.org/x/sync v0.21.0
full diff: https://github.com/golang/sync/compare/v0.20.0...v0.21.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-09 16:25:46 +02:00
Sebastiaan van Stijn de24d1cbc0 vendor: golang.org/x/mod v0.37.0
full diff: https://github.com/golang/mod/compare/v0.36.0...v0.37.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-09 16:25:11 +02:00
Sebastiaan van Stijn 49dc46afed vendor: golang.org/x/term v0.44.0
full diff: https://github.com/golang/term/compare/v0.43.0...v0.44.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-09 16:24:33 +02:00
Sebastiaan van Stijn c72acd0a08 vendor: golang.org/x/sys v0.46.0
full diff: https://github.com/golang/sys/compare/v0.45.0...v0.46.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-09 16:23:59 +02:00
Sebastiaan van Stijn b601b2577a vendor: github.com/moby/sys/sequential v0.7.0
- update minimum go version to 1.24
- use os.OpenFile with O_FILE_FLAG_SEQUENTIAL_SCAN on Go 1.26+

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-09 16:22:14 +02:00
Sebastiaan van StijnandGitHub e8f837ba7f Merge pull request #7034 from docker/dependabot/github_actions/actions/checkout-6.0.3
build(deps): bump actions/checkout from 6.0.2 to 6.0.3
2026-06-09 16:12:57 +02:00
Sebastiaan van StijnandGitHub abba6bb358 Merge pull request #7033 from docker/dependabot/github_actions/github/codeql-action-4.36.1
build(deps): bump github/codeql-action from 4.36.0 to 4.36.1
2026-06-09 16:12:11 +02:00
dependabot[bot]andGitHub 9caec62f25 build(deps): bump actions/checkout from 6.0.2 to 6.0.3
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 6.0.3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...df4cb1c069e1874edd31b4311f1884172cec0e10)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-09 08:44:17 +00:00
dependabot[bot]andGitHub 6d9c126733 build(deps): bump github/codeql-action from 4.36.0 to 4.36.1
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.36.0 to 4.36.1.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/7211b7c8077ea37d8641b6271f6a365a22a5fbfa...87557b9c84dde89fdd9b10e88954ac2f4248e463)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.36.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-09 08:43:54 +00:00
Sebastiaan van Stijn 1aae5d7822 vendor: github.com/docker/docker-credential-helpers v0.9.8
full diff: https://github.com/docker/docker-credential-helpers/compare/v0.9.7...v0.9.8

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-08 20:58:17 +02:00
Paweł GronowskiandGitHub 4ed0e4e65d Merge pull request #7014 from vvoland/work-gha
gha: Add docker cagent PR reviewer workflows
2026-06-05 15:11:37 +02:00
Sebastiaan van StijnandGitHub 90f2f30fd1 Merge pull request #7030 from thaJeztah/refactor_handleAux
cli/command/image: handleAux: avoid using global var
2026-06-04 15:44:14 +02:00
Sebastiaan van Stijn a11beec944 cli/command/image: handleAux: avoid using global var
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-04 15:05:41 +02:00
Sebastiaan van StijnandGitHub b50c369d8b Merge pull request #6957 from WilliamK112/6890-respect-no-color-push
image push: respect NO_COLOR in aux notes
2026-06-04 14:38:54 +02:00
dependabot[bot]andGitHub d788f2d81f build(deps): bump docker/setup-qemu-action from 4.0.0 to 4.1.0
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/ce360397dd3f832beb865e1373c09c0e9f86d70a...06116385d9baf250c9f4dcb4858b16962ea869c3)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-04 01:23:33 +00:00
Ching Wei Kang fe262bc2f9 image/push: respect NO_COLOR in aux notes
Signed-off-by: WilliamK112 <164879897+WilliamK112@users.noreply.github.com>
Signed-off-by: Ching Wei Kang <164879897+WilliamK112@users.noreply.github.com>
2026-06-03 14:57:36 -05:00
Paweł GronowskiandGitHub d1341e7caf Merge pull request #7027 from vvoland/bump-version
VERSION: 29.6.0
2026-06-03 20:25:41 +02:00
Paweł Gronowski 54636c8e2e VERSION: 29.6.0
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-06-03 20:02:59 +02:00
Paweł Gronowski a1cf501956 gha: Add docker cagent PR reviewer workflows
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-06-03 19:18:44 +02:00
Paweł GronowskiandGitHub d1c06ef6b4 Merge pull request #7022 from mickael-docker/docs-request-field
docs/plugins/authz: recommend default deny and clarify requesturi field
2026-06-03 19:16:33 +02:00
Paweł GronowskiandGitHub 7dd053b1d1 Merge pull request #7003 from thaJeztah/logs_links
docs: container logs: add headers for flags
2026-06-03 19:14:10 +02:00
Sebastiaan van StijnandGitHub 37c3d316cc Merge pull request #7024 from thaJeztah/add_zizmor
gha: add zizmor workflow
2026-06-03 18:13:43 +02:00
Paweł GronowskiandGitHub 45f10f226e Merge pull request #7025 from vvoland/update-go
update to go1.26.4
2026-06-03 17:45:58 +02:00
Paweł Gronowski 3cc61496db cli/file_store: Preserve IPv6 URL normalization after Go change
Add a fallback for unbracketed IPv6 literals to preserve behavior.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-06-03 17:40:39 +02:00
Paweł Gronowski 55b88882d7 cli/file_store: Clarify ConvertToHostname
The implementation seems to have diverged already.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-06-03 17:40:39 +02:00
Paweł Gronowski b458dc9e81 update to go1.26.4
This release include 3 security fixes following the security policy:

- mime: quadratic complexity in WordDecoder.DecodeHeader

    Decoding a maliciously-crafted MIME header containing many invalid
    encoded-words could consume excessive CPU.
    The MIME decoder now better handles this case.

    Thanks to p4p3r (https://hackerone.com/p4p3r_hak) for reporting this issue.

    This is CVE-2026-42504 and Go issue https://go.dev/issue/79217.

- net/textproto: arbitrary input are included in errors without any escaping

    When returning errors, functions in the net/textproto package would
    include its input as part of the error, without any escaping. Note that
    said input is often controlled by external parties when using this
    package naturally. For example, a net/http client uses ReadMIMEHeader
    when parsing the headers it receive from a server.

    As a result, an attacker could inject arbitrary content into the error.
    Practically, this can result in an attacker injecting misleading
    content, terminal control bytes, etc. into a victim's output or logs.

    This is CVE-2026-42507 and Go issue https://go.dev/issue/79346

- crypto/x509: split candidate hostname only once

    (*x509.Certificate).VerifyHostname previously called matchHostnames in a loop
    over all DNS Subject Alternative Name (SAN) entries. This caused
    strings.Split(host, ".") to execute repeatedly on the same input hostname.

    With a large DNS SAN list, verification costs scaled quadratically based on the
    number of SAN entries multiplied by the hostname's label count. Because
    x509.Verify validates hostnames before building the certificate chain, this
    overhead occurred even for untrusted certificates.

    Thanks to Jakub Ciolek (https://ciolek.dev) for reporting this issue.

    This is CVE-2026-27145 and https://go.dev/issue/79694.

View the release notes for more information:
https://go.dev/doc/devel/release#go1.26.4

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-06-03 17:07:58 +02:00
Sebastiaan van Stijn 1953194bd5 gha: apply zizmor fixes
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-03 16:45:20 +02:00
Sebastiaan van Stijn ac0419ea90 gha: add zizmor workflow
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-03 12:03:45 +02:00
mickael emirkanian 1aa0416b8a docs: recommend default deny and clarify requesturi field
Signed-off-by: mickael emirkanian <mickael.emirkanian@docker.com>
2026-06-02 15:18:36 -04:00
Paweł GronowskiandGitHub 3a85952984 Merge pull request #7020 from thaJeztah/full_semver
ci: update comments to show full (major.minor.patch) version
2026-06-02 15:18:14 +02:00
Paweł GronowskiandGitHub 8d3fbdf570 Merge pull request #7019 from thaJeztah/dependabot_labels
ci: use "area/ci" label for dependabot actions updates
2026-06-02 11:54:27 +02:00
Sebastiaan van Stijn 69c3f5c7af ci: update comments to show full (major.minor.patch) version
This makes it easier to verify the sha matches the tag, and may help
with dependabot not updating the version-comment correctly.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-01 15:21:54 +02:00
Sebastiaan van Stijn 0ae4aac726 ci: use "area/ci" label for dependabot actions updates
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-06-01 15:02:21 +02:00
Sebastiaan van StijnandGitHub 36edcdf9f3 Merge pull request #7004 from docker/dependabot/github_actions/codecov/codecov-action-6.0.1
build(deps): bump codecov/codecov-action from 6.0.0 to 6.0.1
2026-06-01 14:39:16 +02:00
Sebastiaan van StijnandGitHub 4e815a7e97 Merge pull request #7013 from docker/dependabot/github_actions/docker/metadata-action-6.1.0
build(deps): bump docker/metadata-action from 6.0.0 to 6.1.0
2026-05-29 14:56:40 +02:00
Sebastiaan van StijnandGitHub 32e1269780 Merge pull request #7012 from docker/dependabot/github_actions/github/codeql-action-4.36.0
build(deps): bump github/codeql-action from 4.35.5 to 4.36.0
2026-05-29 14:55:48 +02:00
Sebastiaan van StijnandGitHub 5f09e74d48 Merge pull request #7011 from docker/dependabot/github_actions/docker/login-action-4.2.0
build(deps): bump docker/login-action from 4.1.0 to 4.2.0
2026-05-29 14:55:13 +02:00
Sebastiaan van StijnandGitHub 98df84cf86 Merge pull request #7010 from docker/dependabot/github_actions/docker/setup-buildx-action-4.1.0
build(deps): bump docker/setup-buildx-action from 4.0.0 to 4.1.0
2026-05-29 14:54:33 +02:00
dependabot[bot]andGitHub 20b3bc3f64 build(deps): bump docker/metadata-action from 6.0.0 to 6.1.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 6.0.0 to 6.1.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/030e881283bb7a6894de51c315a6bfe6a94e05cf...80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-29 09:02:12 +00:00
dependabot[bot]andGitHub 8a9d271adf build(deps): bump github/codeql-action from 4.35.5 to 4.36.0
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.5 to 4.36.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/9e0d7b8d25671d64c341c19c0152d693099fb5ba...7211b7c8077ea37d8641b6271f6a365a22a5fbfa)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-29 09:01:52 +00:00
dependabot[bot]andGitHub f4f8ffb9d7 build(deps): bump docker/login-action from 4.1.0 to 4.2.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/4907a6ddec9925e35a0a9e82d7399ccc52663121...650006c6eb7dba73a995cc03b0b2d7f5ca915bee)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-29 09:00:23 +00:00
dependabot[bot]andGitHub 2aeb70a5b9 build(deps): bump docker/setup-buildx-action from 4.0.0 to 4.1.0
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd...d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-29 09:00:12 +00:00
Sebastiaan van StijnandGitHub d476e1d9bf Merge pull request #7009 from docker/dependabot/github_actions/docker/bake-action-7.2.0
build(deps): bump docker/bake-action from 7.1.0 to 7.2.0
2026-05-28 14:47:12 +02:00
dependabot[bot]andGitHub 07bb5e458c build(deps): bump docker/bake-action from 7.1.0 to 7.2.0
Bumps [docker/bake-action](https://github.com/docker/bake-action) from 7.1.0 to 7.2.0.
- [Release notes](https://github.com/docker/bake-action/releases)
- [Commits](https://github.com/docker/bake-action/compare/a66e1c87e2eca0503c343edf1d208c716d54b8a8...6614cfa25eff9a0b2b2697efb0b6159e7680d584)

---
updated-dependencies:
- dependency-name: docker/bake-action
  dependency-version: 7.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-28 09:02:20 +00:00
dependabot[bot]andGitHub 224685e1ea build(deps): bump codecov/codecov-action from 6.0.0 to 6.0.1
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/57e3a136b779b570ffcdbf80b3bdc90e7fab3de2...e79a6962e0d4c0c17b229090214935d2e33f8354)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 12:43:12 +00:00
Sebastiaan van StijnandGitHub 9f16882de4 Merge pull request #7001 from thaJeztah/bump_x_deps
vendor: golang.org/x/sys v0.45.0, golang.org/x/net v0.55.0
2026-05-22 16:03:13 +02:00
Sebastiaan van Stijn 9e098b0f82 docs: container logs: add headers for flags
Add separate headers for each flag, so that they can be linked from
the flag-description table.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-22 14:15:38 +02:00
Paweł GronowskiandGitHub f3f823c78b Merge pull request #7002 from thaJeztah/smaller_size
scripts/build: set grpcnotrace build-tag to reduce binary size
2026-05-22 12:16:45 +02:00
Sebastiaan van StijnandGitHub 02e2c2ecda Merge pull request #7000 from docker/dependabot/github_actions/github/codeql-action-4.35.5
build(deps): bump github/codeql-action from 4.35.4 to 4.35.5
2026-05-22 12:03:35 +02:00
Sebastiaan van Stijn 45fc3b034a scripts/build: set grpcnotrace build-tag to reduce binary size
Reduces the binary size (39810466 - 39289106 => 521360 (521 kb)

We only import google.golang.org/grpc as an indirect dependency, and
do not make gRPC connections.

grpcnotrace avoids importing golang.org/x/net/trace, which in turn enables
dead code elimination, which can yield 10-15% improvements in binary size
when tracing is not needed.

see https://github.com/grpc/grpc-go/blob/v1.81.1/trace_notrace.go#L23-L25

Before:

    ls -l ./build/docker-darwin-arm64
    -rwxr-xr-x  1 thajeztah  staff  39810466 May 22 11:44 ./build/docker-darwin-arm64*
    ls -lh ./build/docker-darwin-arm64
    -rwxr-xr-x  1 thajeztah  staff    38M May 22 11:44 ./build/docker-darwin-arm64*

After:

    ls -l ./build/docker-darwin-arm64
    -rwxr-xr-x  1 thajeztah  staff  39289106 May 22 11:45 ./build/docker-darwin-arm64*
    ls -lh ./build/docker-darwin-arm64
    -rwxr-xr-x  1 thajeztah  staff    37M May 22 11:45 ./build/docker-darwin-arm64*

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-22 11:54:09 +02:00
Sebastiaan van Stijn 20f5e7c08c vendor: golang.org/x/net v0.55.0
security changes (not used in our code)

- html: escape greater-than symbol in doctype identifiers (CVE-2026-25681)
- html: improve Noah's Ark clause performance (CVE-2026-25680)
- html: properly render fostered elements in foreign content (CVE-2026-42502)
- html: properly check namespace in "in body" any other end tag (CVE-2026-42506)
- html: ignore duplicate attributes during tokenization (CVE-2026-27136)

other changes:

- quic: fix appendMaxDataFrame erroneously accumulating sentLimit
- quic: establish a "happened-before" relationship between stream write and read
- quic: fix buffer slicing when handling overlapping stream data
- http2: avoid API changes when built with go1.27

security announce: https://groups.google.com/g/golang-announce/c/iI-mYSI0lu8
full diff: https://github.com/golang/net/compare/v0.54.0...v0.55.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-22 11:27:01 +02:00
Sebastiaan van Stijn 20debc9c01 vendor: golang.org/x/sys v0.45.0
notable changes:

- unix: update to Linux kernel 7.0
- unix: add Readv, Writev, Preadv, Pwritev for OpenBSD
- windows: add NtSetEaFile, NtQueryEaFile and NtQueryInformationFile
- cpu: add LLACQ_SCREL, SCQ, DBAR_HINTS detection for loong64
- cpu: detect zbc extension on riscv64

full diff: https://github.com/golang/sys/compare/v0.44.0...v0.45.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-22 11:25:58 +02:00
dependabot[bot]andGitHub cf5f060b4d build(deps): bump github/codeql-action from 4.35.4 to 4.35.5
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.4 to 4.35.5.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/68bde559dea0fdcac2102bfdf6230c5f70eb485e...9e0d7b8d25671d64c341c19c0152d693099fb5ba)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-22 08:50:13 +00:00
Paweł GronowskiandGitHub 9712e537b9 Merge pull request #6999 from thaJeztah/bump_version
bump VERSION to v29.5.3-dev
2026-05-21 11:12:04 +02:00
Sebastiaan van Stijn d6eded1632 bump VERSION to v29.5.3-dev
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-21 09:54:04 +02:00
Sebastiaan van StijnandGitHub 4494f1af5a Merge pull request #6998 from mickael-docker/docs-clarify-authz
docs: further clarify authz plugins
2026-05-21 09:52:08 +02:00
Paweł GronowskiandGitHub 79eb04c7d8 Merge pull request #3173 from rene-hermenau/patch-1
Update dockerd.md
2026-05-20 16:33:30 +02:00
Sebastiaan van StijnandGitHub 1a3048fe6c Merge pull request #6997 from vvoland/gha-fix
gha: Port validate milestones from Moby
2026-05-20 16:16:35 +02:00
Paweł Gronowski 9177c7fc6b gha: Port validate milestones from Moby
Keep it in sync and also fix the base ref to take the VERSION file from.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-05-20 16:08:41 +02:00
Paweł GronowskiandGitHub 77cb156764 Merge pull request #6994 from thaJeztah/bump_buildx
Dockerfile: update buildx to v0.34.1
2026-05-20 15:57:47 +02:00
Sebastiaan van Stijn 382a92daa8 Dockerfile: update buildx to v0.34.1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-20 13:22:29 +02:00
Paweł GronowskiandGitHub 5c0919a947 Merge pull request #6995 from thaJeztah/bump_version
bump VERSION to v29.5.2-dev
2026-05-20 13:18:43 +02:00
Sebastiaan van Stijn a68dd7a4fb bump VERSION to v29.5.2-dev
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-20 10:55:27 +02:00
mickael emirkanian 066d508bd3 docs: further clarify authz plugins
Signed-off-by: mickael emirkanian <mickael.emirkanian@docker.com>
2026-05-19 15:44:59 -04:00
Sebastiaan van StijnandGitHub 2518b52d94 Merge pull request #6991 from mickael-docker/docs-clarify-authz
docs: clarify authz content type
2026-05-15 20:33:23 +02:00
mickael emirkanian 9f18a0a70c docs: clarify authz content type
update based on the logic in https://github.com/moby/moby/blob/0686f57c3d942ce4440f9ed7f2e955de3687dd4e/pkg/authorization/authz.go#L177

Signed-off-by: mickael emirkanian <mickael.emirkanian@docker.com>
2026-05-15 14:26:36 -04:00
Paweł GronowskiandGitHub 2944fd1daa Merge pull request #6989 from thaJeztah/bump_version
bump VERSION to v29.5.1-dev
2026-05-15 11:24:08 +02:00
René HermenauandSebastiaan van Stijn ae9f429677 Update dockerd.md
daemon.json does not exist on a clean install. The doc should reflect that.

Signed-off-by: René Hermenau <rene-hermenau@users.noreply.github.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-15 00:34:15 +02:00
Sebastiaan van Stijn c41489ac39 bump VERSION to v29.5.1-dev
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-14 23:18:26 +02:00
Paweł GronowskiandGitHub 98f1464960 Merge pull request #6988 from thaJeztah/make_shell
README: simplify instructions for using dev container
2026-05-14 16:33:29 +02:00
Sebastiaan van Stijn 50712c9326 README: simplify instructions for using dev container
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-14 15:44:01 +02:00
Paweł GronowskiandGitHub 653dc8f03d Merge pull request #6485 from paulchen5/6484-update-pull-request-template
PR template: remove outdated contributing guide link
2026-05-14 14:15:44 +02:00
Paweł GronowskiandGitHub 13945822d4 Merge pull request #6987 from thaJeztah/contributing_links
docs: fix stale links in CONTRIBUTING.md
2026-05-14 14:15:25 +02:00
f99747b9e0 docs: fix stale links in CONTRIBUTING.md
Also made some minor touch-ups (more can be done).

Co-authored-by: Philemon Ukane <ukanephilemon@gmail.com>
Co-authored-by: Andrea Grillo <andrea.grillo96@live.com>
Co-authored-by: Mahitha Adapa <mahitha.ada@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-14 13:45:02 +02:00
PaulchenandSebastiaan van Stijn ddac061db7 PR template: remove outdated contributing guide link
update contributing guide link and improve PR template formatting in `.github/PULL_REQUEST_TEMPLATE.md`

Signed-off-by: Paulchen <lukas.23022005@gmail.com>
Signed-off-by: Lukas Michael <lukas.23022005@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-14 13:15:58 +02:00
Paweł GronowskiandGitHub bd55370d2f Merge pull request #6984 from thaJeztah/cleanup_experimental
experimental: sync with actual features gated by experimental
2026-05-14 13:08:32 +02:00
Paweł GronowskiandGitHub f907b27599 Merge pull request #6985 from thaJeztah/rm_builder_stub
docs: remove stub for builder
2026-05-14 13:07:52 +02:00
Paweł GronowskiandGitHub 5201f5894e Merge pull request #6971 from matte1782/docs-authz-64kib-buffer-2026-05
docs: clarify 64 KiB response-body buffer in authz plugin docs
2026-05-14 13:02:31 +02:00
Paweł GronowskiandGitHub 5d48774148 Merge pull request #6986 from thaJeztah/cleanup_docs_readme
docs: remove outdated README
2026-05-14 13:00:30 +02:00
Sebastiaan van Stijn 10b1e87d09 docs: remove outdated README
The instructions in the file were outdated, and after removing them,
nothing really substantial was remaining, so let's just remove the
file for now.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-14 12:36:49 +02:00
Sebastiaan van Stijn e3802b8a0e experimental: sync with actual features gated by experimental
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-14 12:25:35 +02:00
Paweł GronowskiandGitHub 24f630cbe6 Merge pull request #2783 from pmorch/zsh-completion-gitlab-url
Reflect the new github URL for completion/zsh/_docker
2026-05-14 12:20:45 +02:00
Paweł GronowskiandGitHub 6f3c1ad752 Merge pull request #2943 from jimlinntu/add_test_commands_in_README
add commands of how to run the test
2026-05-14 12:05:03 +02:00
Paweł GronowskiandGitHub 33b32585cb Merge pull request #3728 from maxmorozoff/issue-3727
docs: Fix template error in cli example (#3727)
2026-05-14 12:04:13 +02:00
Paweł GronowskiandGitHub 333c580fd3 Merge pull request #4290 from 38tter/fix-tiny-nits
Fix nits
2026-05-14 12:03:43 +02:00
Paweł GronowskiandGitHub d77461c153 Merge pull request #4188 from finalchild/autoremove
Explain the auto-removal of anonymous volumes at the description of 'create --rm' and 'run --rm'
2026-05-14 12:03:24 +02:00
Paweł GronowskiandGitHub 666e4d5100 Merge pull request #6980 from thaJeztah/grammar_fixes
docs: minor grammar fixes
2026-05-14 12:02:45 +02:00
Paweł GronowskiandGitHub d090f98cb7 Merge pull request #4391 from u1735067/patch-1
metrics-addr is not experimental anymore since 20.10
2026-05-14 12:02:11 +02:00
Alexandre LEVAVASSEURandSebastiaan van Stijn 18bd1e7ce0 metrics-addr is not experimental since 20.10
See https://github.com/moby/moby/commit/f337a8d21d9902772a766f57475a5512405c86c5

Signed-off-by: Alexandre LEVAVASSEUR <alexandre+oss@13x.fr>
2026-05-14 11:52:32 +02:00
Sebastiaan van StijnandGitHub c5139f4905 Merge pull request #6982 from docker/dependabot/github_actions/github/codeql-action-4.35.4
build(deps): bump github/codeql-action from 4.35.3 to 4.35.4
2026-05-14 11:48:45 +02:00
Sebastiaan van Stijn 8aa8342502 docs: remove stub for builder
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-14 11:45:02 +02:00
dependabot[bot]andGitHub a6dc278db3 build(deps): bump github/codeql-action from 4.35.3 to 4.35.4
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.3 to 4.35.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e46ed2cbd01164d986452f91f178727624ae40d7...68bde559dea0fdcac2102bfdf6230c5f70eb485e)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-14 08:44:18 +00:00
Max MorozovandSebastiaan van Stijn cc962d598a docs: Fix template error in cli example
Signed-off-by: Max Morozov <max@morozov.page>
Signed-off-by: Max Morozov <gtmax.yo@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-14 03:58:34 +02:00
Sebastiaan van StijnandVicente Jimenez Aguilar e4d651d792 docs: fix config, secret examples
Co-authored-by: Vicente Jimenez Aguilar <googuy@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-14 03:34:23 +02:00
Park JaeonandSebastiaan van Stijn fb09d828e3 document --rm also removing anonymous volumes
Explain the auto-removal of anonymous volumes
at the description of 'create --rm' and 'run --rm'

Signed-off-by: Park Jaeon <me@finalchild.dev>
2026-05-14 03:22:40 +02:00
Sebastiaan van Stijn 88e93954a6 docs, completion: use symlinks instead of symbol(ic) links
Symbolic links is the official term, but more commonly we refer to
them as symlinkx.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-14 03:07:19 +02:00
f550901e65 docs: minor grammar fixes
Co-authored-by: David Schmitt <118179693+DavidS-om@users.noreply.github.com>
Co-authored-by: Callis Ezenwaka <callisezenwaka@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-14 03:06:23 +02:00
Seiya MiyataandSebastiaan van Stijn a6d65ea31d Fix nits
Signed-off-by: Seiya Miyata <odradek38@gmail.com>
2026-05-14 03:00:12 +02:00
Jim LinandSebastiaan van Stijn 80ad53b064 add commands of how to run the test
Signed-off-by: Jim Lin <b04705003@ntu.edu.tw>
2026-05-14 02:20:47 +02:00
Peter Valdemar MørchandSebastiaan van Stijn fe78dc0be6 Reflect the new github URL for completion/zsh/_docker
Signed-off-by: Peter Valdemar Mørch <peter@morch.com>
2026-05-14 01:54:56 +02:00
Paweł GronowskiandGitHub 2ea4dc14aa Merge pull request #6977 from thaJeztah/receiver_name
cli/config/configfile: use more idiomatic receiver name
2026-05-13 14:01:42 +02:00
Paweł GronowskiandGitHub 39e188c5dc Merge pull request #6913 from Mohammed-Thaha/6203-add-healthcheck-format
container/ps: add HealthStatus formatter field
2026-05-13 14:01:16 +02:00
Sebastiaan van Stijn f12fc152a7 cli/config/configfile: use more idiomatic receiver name
Use a shorter name, which is more idiomatic, and prevents accidental
shadowing of types or arguments.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-12 16:44:00 +02:00
Mohammed ThahaandSebastiaan van Stijn 8d8d405dc7 container/ps: add HealthStatus formatter field
Signed-off-by: Mohammed Thaha <mohammedthahacse@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-12 16:14:21 +02:00
Sebastiaan van Stijn 517ca50506 docs: add more space in ps format table
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-12 16:09:46 +02:00
Paweł GronowskiandGitHub bcf36a5083 Merge pull request #6975 from thaJeztah/rm_redundant_test
cli/command/image: rm redundant TestPrintImageTreeNoWarningWhenRedirected
2026-05-11 18:36:08 +02:00
Sebastiaan van Stijn 7cbcd2f720 cli/command/image: rm redundant TestPrintImageTreeNoWarningWhenRedirected
This is already covered by various tests using .golden files.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-11 17:27:19 +02:00
Paweł GronowskiandGitHub ba93f0d1cc Merge pull request #6972 from thaJeztah/decorate_env_file_error
decorate --env-file, --label-file errors
2026-05-11 13:59:56 +02:00
Paweł GronowskiandGitHub ed8c9d7113 Merge pull request #6974 from thaJeztah/bump_x_deps
vendor: update golang.org/x/* dependencies
2026-05-11 13:57:56 +02:00
Paweł GronowskiandGitHub aa1be189b4 Merge pull request #4535 from thaJeztah/restart_policy_more_validate
refactor parsing restart-policies
2026-05-11 13:57:33 +02:00
Sebastiaan van Stijn 970afd5cc4 vendor: golang.org/x/net v0.54.0
full diff: https://github.com/golang/net/compare/v0.53.0...v0.54.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-11 12:22:37 +02:00
Sebastiaan van Stijn 7e07bf127c vendor: golang.org/x/mod v0.36.0
full diff: https://github.com/golang/mod/compare/v0.34.0...v0.36.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-11 12:21:34 +02:00
Sebastiaan van Stijn 5aeb52681b vendor: golang.org/x/text v0.37.0
full diff: https://github.com/golang/time/compare/v0.36.0...v0.37.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-11 12:20:20 +02:00
Sebastiaan van Stijn 644d046721 vendor: golang.org/x/term v0.43.0
full diff: https://github.com/golang/term/compare/v0.42.0...v0.43.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-11 12:18:58 +02:00
Sebastiaan van Stijn a853f40a30 vendor: golang.org/x/sys v0.44.0
full diff: https://github.com/golang/sys/compare/v0.43.0...v0.44.0

- unix: add CPUSetDynamic for systems with more than 1024 CPUs
- unix: avoid nil pointer dereference in Utime
- unix: automatically remove container created by mkall.sh
- cpu: use IsProcessorFeaturePresent to calculate ARM64 on windows
- windows: add GetIfTable2Ex, GetIpInterface{Entry,Table}, GetUnicastIpAddressTable
- windows: avoid uint16 overflow in NewNTUnicodeString

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-11 12:18:14 +02:00
Sebastiaan van Stijn 87f06ec70a refactor parsing restart-policies
- opts.ParseRestartPolicy: use a struct-literal and clarify that this
  function only parses, but does not validate invalid combinations.
- cli/compose/convert: convertRestartPolicy: update doc to be more
  clear on the order of preference and intent.
- cli/compose/convert: convertRestartPolicy: use a switch based on
  known values to allow the exhaustive linter to catch missing options.
- cli/compose/convert: convertRestartPolicy: add validation for negative
  values when converting the legacy service.restart policy.
- cli/compose/convert: convertRestartPolicy: always set MaxAttempts
  and leave validation to the daemon.

opts: ParseRestartPolicy: improve validation of max restart-counts

Use the new container.ValidateRestartPolicy utility to verify if a max-restart-count
is allowed for the given restart-policy.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-11 10:41:13 +02:00
Sebastiaan van Stijn 033f8a1fd2 cli/compose/convert: use test-table for restart-policy tests
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-11 10:40:01 +02:00
Sebastiaan van Stijn 27bee792a0 decorate --env-file, --label-file errors
Before:

    docker run --rm --env-file=./no-such-file alpine
    docker: open ./no-such-file: no such file or directory

    Run 'docker run --help' for more information

After:

    docker run --rm --env-file=./no-such-file alpine
    docker: --env-file: open ./no-such-file: no such file or directory

    Run 'docker run --help' for more information

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-11 10:18:53 +02:00
Matteo Panzeri 6d38b7a71a docs: clarify 64 KiB response-body buffer in authz plugin docs
Adds a "Response body size and partial buffering" subsection to
docs/extend/plugins_authorization.md documenting the 64 KiB
maxBufferSize constant in the daemon's internal responseModifier
(pkg/authorization/response.go in moby/moby) and the practical
implications for plugins that use ResponseBody inspection.

The existing docs (lines 81-87) say streaming endpoints such as
logs and events send only the HTTP request to plugins, but don't
explain the underlying mechanism. Plugin authors building
response-body redaction or content-filtering can be surprised when
the same effect happens on non-listed endpoints whose response is
produced through multiple writes exceeding the buffer or via an
io.WriteFlusher.

The 64 KiB buffer is observable from the public moby source, so
this PR is documentation catching up to existing behavior — not
a contract change.

Signed-off-by: Matteo Panzeri <matteo1782@gmail.com>
2026-05-09 23:00:51 +02:00
Sebastiaan van StijnandGitHub a6d013f4c9 Merge pull request #6840 from vibhuanand/3064-context-use-docs
docs: clarify docker context use affects all terminal sessions
2026-05-08 19:35:37 +02:00
Sebastiaan van StijnandGitHub 247839fb41 Merge pull request #6968 from docker/dependabot/github_actions/github/codeql-action-4.35.3
build(deps): bump github/codeql-action from 4.35.2 to 4.35.3
2026-05-08 16:13:43 +02:00
Paweł GronowskiandGitHub 3d408ee95c Merge pull request #6969 from thaJeztah/bump_creds_helper
vendor: github.com/docker/docker-credential-helpers v0.9.7
2026-05-08 15:46:42 +02:00
Paweł GronowskiandGitHub f66e796147 Merge pull request #6846 from thaJeztah/normalize_authconfig
cli/config/configfile: normalize hostname when resolving auth
2026-05-08 15:46:13 +02:00
Sebastiaan van Stijn 1e1384fae2 vendor: github.com/docker/docker-credential-helpers v0.9.7
no code-changes; only updates go version

full diff: https://github.com/docker/docker-credential-helpers/compare/v0.9.6...v0.9.7

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-08 14:51:12 +02:00
Paweł GronowskiandGitHub e76954974a Merge pull request #6737 from thaJeztah/rm_deprecated_buildutils
cli/command/image/build: remove deprecated utilities and consts
2026-05-08 13:54:28 +02:00
Paweł GronowskiandGitHub f285746704 Merge pull request #6947 from thaJeztah/bump_platforms
vendor: github.com/containerd/platforms v1.0.0-rc.4
2026-05-08 13:26:50 +02:00
Paweł GronowskiandGitHub a3554d6830 Merge pull request #6950 from thaJeztah/plugin_limit_messages
cli-plugins/hooks: limit maximum number of lines / messages
2026-05-08 13:26:33 +02:00
Paweł GronowskiandGitHub ed8f23bffa Merge pull request #6965 from thaJeztah/test_subtests
cli/compose/schema: TestValidatePorts: use subtests
2026-05-08 13:26:00 +02:00
Paweł GronowskiandGitHub 96131c8159 Merge pull request #6966 from thaJeztah/DetectDefaultStore_update_godoc
cli/config/credentials: DetectDefaultStore: update GoDoc
2026-05-08 13:25:47 +02:00
dependabot[bot]andGitHub 976d97dd23 build(deps): bump github/codeql-action from 4.35.2 to 4.35.3
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.2 to 4.35.3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/95e58e9a2cdfd71adc6e0353d5c52f41a045d225...e46ed2cbd01164d986452f91f178727624ae40d7)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-08 08:44:18 +00:00
Sebastiaan van StijnandGitHub a9031f4c84 Merge pull request #6967 from vvoland/update-go
update to go1.26.3
2026-05-08 00:22:25 +02:00
Paweł Gronowski 77435c59ec update to go1.26.3
This release include 11 security fixes:

- cmd/go: malicious module proxy can bypass checksum database

    A malicious module proxy could exploit a flaw in the go command's
    validation of module checksums to bypass checksum database validation.

    This vulnerability affects any user using an untrusted module proxy
    (GOMODPROXY) or checksum database (GOSUMDB).

    A malicious module proxy can serve altered versions of the Go toolchain.
    When selecting a different version of the Go toolchain than the
    currently installed toolchain (due to the GOTOOLCHAIN environment variable,
    or a go.work or go.mod with a toolchain line), the go command will download
    and execute a toolchain provided by the module proxy. A malicious module
    proxy can bypass checksum database validation for this downloaded
    toolchain.

    Since this vulnerability affects the security of toolchain downloads,
    setting GOTOOLCHAIN to a fixed version is not sufficient. You must upgrade
    your base Go toolchain.

    The go tool always validates the hash of a toolchain before executing it,
    so fixed versions will refuse to execute any cached, altered versions of the
    toolchain.

    The go tool trusts go.sum files to contain accurate hashes of the current
    module's dependencies. A malicious proxy exploiting this vulnerability to
    serve an altered module will have caused an incorrect hash to be recorded
    in the go.sum. Users who have configured a non-trusted GOPROXY can determine
    if they have been affected by running "rm go.sum ; go mod tidy ; go mod verify",
    which will revalidate all dependencies of the current module.

    The specific flaw in more detail:

    The go command consults the checksum database to validate downloaded modules,
    when a module is not listed in the go.sum file. It verifies that the module hash
    reported by the checksum database matches the hash of the downloaded module.
    If, however, the checksum database returns a successful response that contains
    no entry for the module, the go command incorrectly permitted validation to succeed.

    A module proxy may mirror or proxy the checksum database, in which case the go
    command will not connect to the checksum database directly. Checksums reported
    by the checksum database are cryptographically signed, so a malicious proxy
    cannot alter the reported checksum for a module. However, a proxy which returns
    an empty checksum response, or a checksum response for an unrelated module,
    could cause the go command to proceed as if a downloaded module has been validated.

    The go command now properly checks checksum database responses to ensure
    that the expected module signature is present, not just that if a signature is
    present it matches the expectation.

    Thanks to Mundur (https://github.com/M0nd0R) for reporting this issue.

    This is CVE-2026-42501 and Go issue https://go.dev/issue/79070.

- net/http/httputil: ReverseProxy forwards queries with more than urlmaxqueryparams parameters

    When used with a Rewrite function, or a Director function which parses query parameters,
    ReverseProxy sanitizes the forwarded request to remove query parameters which are not
    parsed by url.ParseQuery. ReverseProxy did not take ParseQuery's limit on the total number
    of query parameters (controlled by GODEBUG=urlmaxqueryparams=N) into account.
    This could permit ReverseProxy to forward a request containing a query parameter
    that was not visible to the Rewrite function.

    For example, the query "a1=x&a2=x&...&a10000=x&hidden=y" could forward the parameter
    "hidden=y" while hiding it from the proxy's Rewrite function.

    ReverseProxy now avoids forwarding parameters that exceed the ParseQuery limit.

    This is CVE-2026-39825 and Go issue https://go.dev/issue/78948.

- net: panic in Dial and LookupPort when handling NUL byte on Windows

    The Dial and LookupPort functions would panic on Windows when provided
    with an input containing a NUL (0). These functions now return an error
    rather than panicking.

    This is CVE-2026-39836 and Go issue https://go.dev/issue/79006.

- net/mail: quadratic string concatenation in consumePhrase

    Pathological inputs could cause DoS through consumePhrase
    when parsing an email address according to RFC 5322.

    This is CVE-2026-42499 and Go issue https://go.dev/issue/78987.

- net/mail: quadratic string concatentation in consumeComment

    Well-crafted inputs reaching ParseAddress, ParseAddressList,
    and ParseDate were able to trigger excessive CPU exhaustion
    and memory allocations.

    This is CVE-2026-39820 and Go issue https://go.dev/issue/78566.

- cmd/go: "go bug" follows symlinks in predictable temporary filenames

    The "go bug" command wrote to two files with predictable names in
    the system temporary directory (for example, "/tmp").

    An attacker with access to the temporary directory could create a
    symlink in one of these names, causing "go bug" to overwrite the
    target of the symlink.

    The "go bug" command now uses os.MkdirTemp to create a safe
    working directory.

    Thanks to Harshit Gupta (Mr HAX) for reporting this issue.

    This is CVE-2026-39819 and Go issue https://go.dev/issue/78584.

- cmd/go: "go tool pack" does not sanitize output paths

    The "go tool pack" subcommand is a minimal version of the Unix ar utility.
    It is used by the compiler as an internal tool with known-good inputs.

    The "pack" subcommand did not sanitize output filenames.
    When invoked to extract a malicious archive file, it could write
    files to arbitrary locations on the filesystem.

    The "pack" subcommand now refuses to extract files with names
    containing any directory components.

    Thanks to Harshit Gupta (Mr HAX) for reporting this issue.

    This is CVE-2026-39817 and Go issue https://go.dev/issue/78778.

- net/http: infinite loop in HTTP/2 transport when given bad SETTINGS_MAX_FRAME_SIZE

    When processing HTTP/2 SETTINGS frames, transport will enter an infinite loop of
    writing CONTINUATION frames if it receives a SETTINGS_MAX_FRAME_SIZE with a
    value of 0.

    This allows potential DoS against a client by a malicious server. HTTP/2
    transport now properly checks that the received SETTINGS_MAX_FRAME_SIZE is
    valid.

    Thanks to Marwan Atia (marwansamir688@gmail.com) for reporting this issue.

    This is CVE-2026-33814 and Go issue https://go.dev/issue/78476.

- html/template: escaper bypass leads to XSS

    If a trusted template author were to write a
    tag containing an empty type attribute or a type
    attribute with an ASCII whitespace, the execution of
    the template would incorrectly escape any data passed
    into the block.

    Thanks to Mundur (https://github.com/M0nd0R) for reporting this issue.

    This is CVE-2026-39826 and Go issue https://go.dev/issue/78981.

- net: crash when handling long CNAME response

    When using LookupCNAME with the cgo DNS resolver,
    a very long CNAME response could trigger a double-free of C memory
    and a crash. The double-free has been fixed.

    Thanks to hamayanhamayan for reporting this issue.

    This is CVE-2026-33811 and Go issue https://go.dev/issue/78803.

- html/template: bypass of meta content URL escaping causes XSS

    CVE-2026-27142 fixed a vulnerability in which URLs were not
    correctly escaped inside of a tag's attribute.
    If the URL content were to insert ASCII whitespaces around the
    = rune inside of the attribute, the escaper would
    fail to similarly escape it, leading to XSS.

    Dynamic inputs to a tag's attribute are now
    whitespace sanitized prior to escaping.

    Thanks to Samy Ghannad for reporting this issue.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-05-07 19:26:33 +02:00
Sebastiaan van Stijn e93fe9083b cli/config/credentials: DetectDefaultStore: update GoDoc
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-07 17:20:48 +02:00
Sebastiaan van Stijn b7ab63387a cli-plugins/hooks: limit maximum number of lines / messages
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-07 17:09:52 +02:00
VibhuandSebastiaan van Stijn e03b8373c7 docs: clarify docker context use is sticky
Signed-off-by: Vibhu <vibhuanand@outlook.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-07 17:06:02 +02:00
Sebastiaan van Stijn 6f144c6d70 cli/command/image/build: remove deprecated ResolveAndValidateContextPath util
It was deprecated in 0f2f9e9c41

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-07 16:28:34 +02:00
Sebastiaan van Stijn b124c707f0 cli/command/image/build: remove deprecated WriteTempDockerfile util
It was deprecated in 6e1ff0bec1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-07 16:28:34 +02:00
Sebastiaan van Stijn 3dd0c846cd cli/command/image/build: remove deprecated DetectArchiveReader util
It was deprecated in c52fa073cd

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-07 16:28:34 +02:00
Sebastiaan van Stijn 403bebeea2 cli/command/image/build: remove deprecated DefaultDockerfileName const
It was deprecated in f24bb4bc76

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-07 16:28:33 +02:00
Sebastiaan van Stijn 8e7ec44f9f cli/command/image/build: remove deprecated IsArchive utility
It was deprecated in 64be664e85

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-07 16:28:31 +02:00
Sebastiaan van StijnandGitHub 4001288d95 Merge pull request #6754 from MaheshThakur9152/fix/remove-images-redirect-warning
Fix: Remove inconsistent human readability warning from docker images
2026-05-07 14:01:21 +02:00
Sebastiaan van Stijn 55fcffe743 cli/config/configfile: normalize hostname when resolving auth
Previously, normalization was done before calling these functions,
which required implementations to normalize before using.

Move the normalization into the GetAuthConfig, GetCredentialsStore,
so that non-normalized hostnames will be able to resolve the correct
auth.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-07 13:58:11 +02:00
Sebastiaan van Stijn e8a0beb909 cli/compose/schema: TestValidatePorts: use subtests
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-07 13:55:59 +02:00
Paweł GronowskiandGitHub 1fe8d42912 Merge pull request #6964 from thaJeztah/bump_version
bump VERSION to v29.5.0
2026-05-07 13:29:25 +02:00
Sebastiaan van Stijn 9013c33372 bump VERSION to v29.5.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-05-07 13:09:47 +02:00
Sebastiaan van StijnandGitHub 0b459a4b76 Merge pull request #6954 from vvoland/stable-labels
formatter: Sort labels for stable output
2026-04-24 17:27:20 +02:00
Paweł Gronowski 7059ef4c9c formatter: Sort labels for stable output
Several Labels() methods iterated over maps without sorting, producing
non-deterministic output.

In early versions of Go, map iteration order happened to be stable in
practice, so the original code appeared to work correctly.
Since Go 1.12, the runtime intentionally randomizes map iteration order,
making the output unpredictable between runs.

The API response produces sorted labels and the container formatter
already sorted its labels (changed in 5ee17eef).

Apply the same fix to the volume, network, config, and secret
formatters, and update tests to assert exact ordering instead of using
order-independent comparison.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-04-24 16:47:11 +02:00
Paweł GronowskiandGitHub 3928571dac Merge pull request #6953 from thaJeztah/bump_swarmkit
vendor: github.com/moby/swarmkit/v2 v2.1.2
2026-04-24 11:40:39 +02:00
Sebastiaan van Stijn 9bbe02848d vendor: github.com/moby/swarmkit/v2 v2.1.2
full diff: https://github.com/moby/swarmkit/compare/v2.1.1...v2.1.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-23 21:39:53 +02:00
Sebastiaan van StijnandGitHub 977ee838e0 Merge pull request #6951 from docker/dependabot/github_actions/github/codeql-action-4.35.2
build(deps): bump github/codeql-action from 4.35.1 to 4.35.2
2026-04-22 17:24:55 +02:00
dependabot[bot]andGitHub b03176ddff build(deps): bump github/codeql-action from 4.35.1 to 4.35.2
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.1 to 4.35.2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/c10b8064de6f491fea524254123dbe5e09572f13...95e58e9a2cdfd71adc6e0353d5c52f41a045d225)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-22 13:35:46 +00:00
Paweł GronowskiandGitHub e874fdbe83 Merge pull request #6952 from thaJeztah/bump_version
bump VERSION to v29.4.2
2026-04-22 15:22:15 +02:00
Sebastiaan van Stijn 9d8c1e4b70 bump VERSION to v29.4.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-22 15:14:35 +02:00
Paweł GronowskiandGitHub 055a478ea9 Merge pull request #6945 from thaJeztah/bump_moby
vendor: github.com/moby/moby/client v0.4.1, moby/api v1.54.2
2026-04-20 16:57:44 +02:00
Sebastiaan van Stijn d0f5b279e9 cmd/docker-trust: bump moby/client v0.4.1, moby/api v1.54.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 16:50:53 +02:00
Sebastiaan van Stijn b7f37e86da vendor: github.com/moby/moby/client v0.4.1, moby/api v1.54.2
- https://github.com/moby/moby/compare/api/v1.54.1...api/v1.54.2
- https://github.com/moby/moby/compare/client/v0.4.0...client/v0.4.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 16:49:58 +02:00
Paweł GronowskiandGitHub c93d892f0e Merge pull request #6949 from thaJeztah/bump_utils
Dockerfile: update buildx to v0.33.0, compose v5.1.3
2026-04-20 16:26:38 +02:00
Paweł GronowskiandGitHub 3553cafa13 Merge pull request #6948 from thaJeztah/bump_trust_deps
cmd/docker-trust: bump dependencies
2026-04-20 16:26:17 +02:00
Sebastiaan van Stijn 266f039bb5 Dockerfile: update compose to v5.1.3
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 16:13:56 +02:00
Sebastiaan van Stijn d74d3c3b16 Dockerfile: update buildx to v0.33.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 16:12:56 +02:00
Sebastiaan van StijnandGitHub 134c2a0ed6 Merge pull request #6826 from thaJeztah/bump_golangci_lint2
Dockerfile: update golangci-lint to v2.10.1
2026-04-20 16:00:14 +02:00
Paweł GronowskiandSebastiaan van Stijn 58a7c3155b golangci-lint: fix lint failures from v2.10.1 upgrade
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-04-20 15:49:35 +02:00
Sebastiaan van Stijn f37a9e663f Dockerfile: update golangci-lint to v2.10.1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 15:49:32 +02:00
Paweł GronowskiandGitHub 4e25e5cfa9 Merge pull request #6941 from vvoland/milestone-validate
gha: Add milestone validation workflow
2026-04-20 15:32:29 +02:00
Sebastiaan van Stijn ee56098b07 cmd/docker-trust: bump dependencies
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 14:59:01 +02:00
Sebastiaan van StijnandGitHub f31b8b2697 Merge pull request #6946 from thaJeztah/bump_runewidth
vendor: github.com/mattn/go-runewidth v0.0.23
2026-04-20 14:52:27 +02:00
Paweł Gronowski efbbc0c68c gha: Add milestone validation workflow
Ensure PRs have a milestone set and that it matches the next release
version declared in the root VERSION file.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-04-20 14:51:37 +02:00
Paweł GronowskiandGitHub 1546665853 Merge pull request #6942 from thaJeztah/rm_kernel_memory
docs, completion: remove deprecated "--kernel-memory" flags
2026-04-20 14:39:40 +02:00
Paweł GronowskiandGitHub 4e4e8f940b Merge pull request #6943 from thaJeztah/bump_creds_helper
vendor: github.com/docker/docker-credential-helpers v0.9.6
2026-04-20 14:38:45 +02:00
Paweł GronowskiandGitHub 2b65d5943f Merge pull request #6944 from thaJeztah/bump_x_deps
vendor: update golang.org/x/* dependencies
2026-04-20 14:38:27 +02:00
Sebastiaan van Stijn beac1144a6 vendor: github.com/containerd/platforms v1.0.0-rc.4
full diff: https://github.com/containerd/platforms/compare/v1.0.0-rc.2...v1.0.0-rc.4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 14:37:14 +02:00
Sebastiaan van Stijn a75ab98e43 vendor: github.com/mattn/go-runewidth v0.0.23
full diff: https://github.com/mattn/go-runewidth/compare/v0.0.22...v0.0.23

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 14:34:25 +02:00
Sebastiaan van Stijn b9549d3ab5 vendor: golang.org/x/net v0.53.0
full diff: https://cs.opensource.google/go/x/net/+/refs/tags/v0.52.0...refs/tags/v0.53.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 14:22:26 +02:00
Sebastiaan van Stijn 2edf815a80 vendor: golang.org/x/term v0.42.0
full diff: https://cs.opensource.google/go/x/term/+/refs/tags/v0.41.0...refs/tags/v0.42.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 14:21:03 +02:00
Sebastiaan van Stijn 258010c788 vendor: golang.org/x/text v0.36.0
full diff: https://cs.opensource.google/go/x/text/+/refs/tags/v0.35.0...refs/tags/v0.36.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 14:20:06 +02:00
Sebastiaan van Stijn cfa80d8644 vendor: golang.org/x/mod v0.35.0
full diff: https://cs.opensource.google/go/x/mod/+/refs/tags/v0.34.0...refs/tags/v0.35.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 14:18:58 +02:00
Sebastiaan van Stijn c20b2479e0 vendor: golang.org/x/sys v0.43.0
full diff: https://cs.opensource.google/go/x/sys/+/refs/tags/v0.42.0...refs/tags/v0.43.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 14:17:33 +02:00
Sebastiaan van Stijn 573dd31bf7 vendor: github.com/docker/docker-credential-helpers v0.9.6
full diff: https://github.com/docker/docker-credential-helpers/compare/v0.9.5...v0.9.6

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 14:14:22 +02:00
Sebastiaan van Stijn 2988338b99 docs/reference: remove deprecated "--kernel-memory" flag
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 14:06:16 +02:00
Sebastiaan van Stijn 58c7328df6 man: remove deprecated "--kernel-memory" flag
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 14:05:48 +02:00
Sebastiaan van Stijn 5468871a02 contrib/completion: remove deprecated "--kernel-memory" flags
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-20 14:05:10 +02:00
Paweł GronowskiandGitHub 10f16704a3 Merge pull request #6931 from docker/dependabot/github_actions/docker/bake-action-7.1.0
build(deps): bump docker/bake-action from 7.0.0 to 7.1.0
2026-04-20 12:12:09 +02:00
Sebastiaan van StijnandGitHub 89958b190c Merge pull request #6927 from Varun5711/docs/legacy-plugin-links-6880
docs: refresh legacy plugin references
2026-04-17 20:24:32 +02:00
Varun5711 acbbeb3c3a docs: refresh legacy plugin references
Signed-off-by: Varun Hotani <varunhotani@gmail.com>
2026-04-17 21:14:16 +05:30
Paweł GronowskiandGitHub dea3ebaa87 Merge pull request #6936 from thaJeztah/bump_otels
vendor: google.golang.org/grpc v1.80.0, go.opentelemetry.io/otel v1.43.0, go.opentelemetry.io/contrib v0.68.0
2026-04-17 15:41:57 +02:00
Sebastiaan van Stijn 3362ae31d0 vendor: go.opentelemetry.io/contrib v0.68.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-17 14:09:30 +02:00
Sebastiaan van Stijn a1edb22832 vendor: go.opentelemetry.io/otel v1.43.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-17 14:07:46 +02:00
Sebastiaan van Stijn 0a24da3382 vendor: google.golang.org/grpc v1.80.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-17 14:07:39 +02:00
Sebastiaan van Stijn f24c779887 vendor: google.golang.org/genproto/* 9d38bb4040a9
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-17 14:04:40 +02:00
Paweł GronowskiandGitHub 17633b7742 Merge pull request #6935 from docker/dependabot/github_actions/actions/upload-artifact-7.0.1
build(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1
2026-04-17 10:52:20 +02:00
dependabot[bot]andGitHub 99aaff1807 build(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-17 08:43:30 +00:00
dependabot[bot]andSebastiaan van Stijn f3c060c382 build(deps): bump docker/bake-action from 7.0.0 to 7.1.0
Bumps [docker/bake-action](https://github.com/docker/bake-action) from 7.0.0 to 7.1.0.
- [Release notes](https://github.com/docker/bake-action/releases)
- [Commits](https://github.com/docker/bake-action/compare/82490499d2e5613fcead7e128237ef0b0ea210f7...a66e1c87e2eca0503c343edf1d208c716d54b8a8)

---
updated-dependencies:
- dependency-name: docker/bake-action
  dependency-version: 7.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-17 00:41:48 +02:00
Paweł GronowskiandGitHub 792293cc2f Merge pull request #6923 from docker/dependabot/github_actions/docker/login-action-4.1.0
build(deps): bump docker/login-action from 4.0.0 to 4.1.0
2026-04-16 13:10:41 +02:00
Paweł GronowskiandGitHub 2660a496bf Merge pull request #6930 from thaJeztah/bump_go_connections
vendor: github.com/docker/go-connections v0.7.0
2026-04-16 13:10:09 +02:00
Sebastiaan van Stijn b9a052a987 vendor: github.com/docker/go-connections v0.7.0
Changes:

- raise minimum supported Go version to go1.23
- sockets: `ConfigureTransport`: prevent idle connections leaking FDs.
- sockets: implement `WithAdditionalUsersAndGroups` for windows.
- tlsconfig: add ChaCha20-Poly1305 cipher suites to align closer with stdlib defaults.
- nat: SortPortMap: accept `map[Port][]PortBinding` as argument.
- nat: add benchmarks, optimize, and improve errors.
- proxy: check for `net.ErrClosed` instead of string-matching "use of closed network connection".

Breaking changes:

- tlsconfig: deprecate `tlsconfig.SystemCertPool` in favor of stdlib `x509.SystemCertPool`.
- sockets: remove deprecated `DialPipe`, `GetProxyEnv`, `DialerFromEnvironment`

Dependency updates:

- update github.com/Microsoft/go-winio to go v0.6.2
- update golang.org/x/sys to v0.10.0

full diff: https://github.com/docker/go-connections/compare/v0.6.0...v0.7.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-16 00:20:20 +02:00
Sebastiaan van StijnandGitHub 84b357f6b0 Merge pull request #6929 from thaJeztah/stdlib_systempools
use stdlib's x509.SystemCertPool on Windows
2026-04-15 16:32:00 +02:00
Sebastiaan van Stijn 0d32fde8e3 internal/registry: use stdlib's x509.SystemCertPool on Windows
The `tlsconfig.SystemCertPool` utility in go-connections was added in
[docker/go-connections@55aadc3], at which time Go stdlib didn't support
system-pools ([x509.SystemCertPool]) on Windows, so an empty pool was
constructed.

Support for system pools on Windows originally added in Go 1.8 (through
[golang/go@05471e9]), but reverted, and re-implemented in Go 1.18 (through
[golang/go@3544082]).

Go 1.18 and up now implement this, but, unlike Linux, which uses a pure-Go
implementation, certificate validation is handled by the system:

> On macOS and Windows, certificate verification is handled by system APIs,
> but the package aims to apply consistent validation rules across operating
> systems.

On macOS and Windows, x509.SystemCertPool returns an empty Pool, with the
`systemPool` set to `true` (see [loadSystemRoots]). This must be considered
an implementation detail; custom CAs can be appended to this pool, and handled
as usual.

This patch removes the special handling on Windows, removing the dependency
on go-connections for this part.

[docker/go-connections@55aadc3]: https://github.com/docker/go-connections/commit/55aadc3cc561684699edcdd0921b9293c3ee6b49
[golang/go@05471e9]: https://github.com/golang/go/commit/05471e9ee64a300bd2dcc4582ee1043c055893bb
[golang/go@3544082]: https://github.com/golang/go/commit/3544082f75fd3d2df7af237ed9aef3ddd499ab9c
[x509.SystemCertPool]: https://pkg.go.dev/crypto/x509#SystemCertPool
[loadSystemRoots]: https://cs.opensource.google/go/go/+/refs/tags/go1.26.1:src/crypto/x509/root_windows.go;l=15-17

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-15 13:04:15 +02:00
Sebastiaan van Stijn ad641e5d61 cmd/docker-trust: use stdlib's x509.SystemCertPool on Windows
The `tlsconfig.SystemCertPool` utility in go-connections was added in
[docker/go-connections@55aadc3], at which time Go stdlib didn't support
system-pools ([x509.SystemCertPool]) on Windows, so an empty pool was
constructed.

Support for system pools on Windows originally added in Go 1.8 (through
[golang/go@05471e9]), but reverted, and re-implemented in Go 1.18 (through
[golang/go@3544082]).

Go 1.18 and up now implement this, but, unlike Linux, which uses a pure-Go
implementation, certificate validation is handled by the system:

> On macOS and Windows, certificate verification is handled by system APIs,
> but the package aims to apply consistent validation rules across operating
> systems.

On macOS and Windows, x509.SystemCertPool returns an empty Pool, with the
`systemPool` set to `true` (see [loadSystemRoots]). This must be considered
an implementation detail; custom CAs can be appended to this pool, and handled
as usual.

This patch removes the special handling on Windows, removing the dependency
on go-connections for this part.

[docker/go-connections@55aadc3]: https://github.com/docker/go-connections/commit/55aadc3cc561684699edcdd0921b9293c3ee6b49
[golang/go@05471e9]: https://github.com/golang/go/commit/05471e9ee64a300bd2dcc4582ee1043c055893bb
[golang/go@3544082]: https://github.com/golang/go/commit/3544082f75fd3d2df7af237ed9aef3ddd499ab9c
[x509.SystemCertPool]: https://pkg.go.dev/crypto/x509#SystemCertPool
[loadSystemRoots]: https://cs.opensource.google/go/go/+/refs/tags/go1.26.1:src/crypto/x509/root_windows.go;l=15-17

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-15 13:03:39 +02:00
dependabot[bot]andSebastiaan van Stijn 14aa781767 build(deps): bump docker/login-action from 4.0.0 to 4.1.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/b45d80f862d83dbcd57f89517bcf500b2ab88fb2...4907a6ddec9925e35a0a9e82d7399ccc52663121)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-15 11:40:10 +02:00
Paweł GronowskiandGitHub 950401cf07 Merge pull request #6920 from thaJeztah/bump_go1.26.2
update to Go 1.26.2
2026-04-08 12:49:00 +02:00
Sebastiaan van StijnandGitHub 3ba1094cb1 Merge pull request #6915 from docker/dependabot/github_actions/github/codeql-action-4.35.1
build(deps): bump github/codeql-action from 4.34.1 to 4.35.1
2026-04-08 01:03:53 +02:00
Sebastiaan van Stijn d1920f0b2c update to Go 1.26.2
go1.26.2 (released 2026-04-07) includes security fixes to the go command,
the compiler, and the archive/tar, crypto/tls, crypto/x509, html/template,
and os packages, as well as bug fixes to the go command, the go fix command,
the compiler, the linker, the runtime, and the net, net/http, and net/url
packages. See the Go 1.26.2 milestone on our issue tracker for details;

- https://github.com/golang/go/issues?q=milestone%3AGo1.26.2+label%3ACherryPickApproved
- full diff: https://github.com/golang/go/compare/go1.26.1...go1.26.2

From the security announce:

We have just released Go versions 1.26.2 and 1.25.9, minor point releases.

These releases include 10 security fixes following the security policy:

- os: Root.Chmod can follow symlinks out of the root on Linux

  On Linux, if the target of Root.Chmod is replaced with a symlink while
  the chmod operation is in progress, Chmod could operate on the target
  of the symlink, even when the target lies outside the root.

  The Linux fchmodat syscall silently ignores the AT_SYMLINK_NOFOLLOW flag,
  which Root.Chmod uses to avoid symlink traversal. Root.Chmod checks its
  target before acting and returns an error if the target is a symlink
  lying outside the root, so the impact is limited to cases where the
  target is replaced with a symlink between the check and operation.

  On Linux, Root.Chmod now uses the fchmodat2 syscall when available, and
  an workaround using /proc/self/fd otherwise.

  Thanks to Uuganbayar Lkhamsuren for reporting this issue.

  This is CVE-2026-32282 and Go issue https://go.dev/issue/78293.

- html/template: JS template literal context incorrectly tracked

  Context was not properly tracked across template branches for JS template
  literals, leading to possibly incorrect escaping of content when branches were
  used.

  Additionally template actions within JS template literals did not properly
  track
  the brace depth, leading to incorrect escaping being applied.

  These issues could cause actions within JS template literals to be incorrectly
  or improperly escaped, leading to XSS vulnerabilities.

  This only affects templates that use template actions within JS template
  literals.

  This is CVE-2026-32289 and Go issue https://go.dev/issue/78331.

- crypto/x509: excluded DNS constraints not properly applied to wildcard domains

  When verifying a certificate chain containing excluded DNS constraints, these
  constraints are not correctly applied to wildcard DNS SANs which use a
  different
  case than the constraint.

  For example, if a certificate contains the DNS name "*.example.com" and the
  excluded DNS name "EXAMPLE.COM", the constraint will not be applied.

  This only affects validation of otherwise trusted certificate chains, issued
  by
  a root CA in the VerifyOptions.Roots CertPool, or in the system certificate
  pool.

  This issue only affects Go 1.26.

  Thank you to Riyas from Saintgits College of Engineering, k1rnt, @1seal for
  reporting this issue.

  This is CVE-2026-33810 and Go issue https://go.dev/issue/78332.

- cmd/compile: no-op interface conversion bypasses overlap checking

  Previously, the compiler failed to unwrap pointers contained within
  a no-op interface conversion leading to an incorrect determination
  of a non-overlapping move.

  To prevent unsafe move operations, the compiler will now unwrap all
  such conversions before considering a move non-overlapping.

  Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.

  This is CVE-2026-27144 and Go issue https://go.dev/issue/78371.

- cmd/compile: possible memory corruption after bound check elimination

  Previously, slices and arrays accessed using induction variables
  were sometimes incorrectly proved in-bound. If the induction variable
  used for indexing were to overflow or underflow, it could allow access
  to memory beyond the scope of the original slice or array.

  To prevent this behavior, the compiler ensures that any mutated induction
  variable that overflows/underflows with respect to its loop condition
  is not used for bound check elimination.

  Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.

  This is CVE-2026-27143 and Go issue https://go.dev/issue/78333.

- archive/tar: unbounded allocation when parsing old format GNU sparse map

  tar.Reader could allocate an unbounded amount of memory when reading
  a maliciously-crafted archive containing a large number of sparse
  regions encoded in the "old GNU sparse map" format.

  We now limit both the number of old GNU sparse map extension blocks,
  and the total number of sparse file entries, regardless of encoding.

  Thanks to Colin Walters (wal...@verbum.org) who initially reported this issue.
  Thanks also to Uuganbayar Lkhamsuren (https://github.com/uug4na) and Jakub
  Ciolek
  who additionally reported this issue.

  This is CVE-2026-32288 and Go issue https://go.dev/issue/78301.

- crypto/tls: multiple key update handshake messages can cause connection to
  deadlock

  If one side of the TLS connection sends multiple key update messages
  post-handshake in a single record, the connection can deadlock, causing
  uncontrolled consumption of resources. This can lead to a denial of service.

  This only affects TLS 1.3.

  Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.

  This is CVE-2026-32283 and Go issue https://go.dev/issue/78334.

- cmd/go: trust layer bypass when using cgo and SWIG

  A well-crafted SWIG source file could take advantage
  of a file-naming convention used inside the trust
  boundary of the cgo compiler. Doing so could result
  in arbitrary code execution during build time.

  SWIG files are disallowed from using this convention.

  Thank you to Juho Forsén of Mattermost for reporting this issue.

  This is CVE-2026-27140 and Go issue https://go.dev/issue/78335.

- crypto/x509: unexpected work during chain building

  During chain building, the amount of work that is done is not correctly
  limited
  when a large number of intermediate certificates are passed in
  VerifyOptions.Intermediates, which can lead to a denial of service. This
  affects
  both direct users of crypto/x509 and users of crypto/tls.

  Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.

  This is CVE-2026-32280 and Go issue https://go.dev/issue/78282.

- crypto/x509: inefficient policy validation

  Validating certificate chains which use policies is unexpectedly inefficient
  when certificates in the chain contain a very large number of policy mappings,
  possibly causing denial of service.

  This only affects validation of otherwise trusted certificate chains, issued
  by
  a root CA in the VerifyOptions.Roots CertPool, or in the system certificate
  pool.

  Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.

  This is CVE-2026-32281 and Go issue https://go.dev/issue/78281.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-08 00:45:45 +02:00
dependabot[bot]andGitHub b23c1a2d76 build(deps): bump github/codeql-action from 4.34.1 to 4.35.1
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.34.1 to 4.35.1.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/38697555549f1db7851b81482ff19f1fa5c4fedc...c10b8064de6f491fea524254123dbe5e09572f13)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 08:45:04 +00:00
Sebastiaan van StijnandGitHub 9d7ad9ff18 Merge pull request #6911 from thaJeztah/bump_modules
vendor: moby/api v1.54.1, moby/client v0.4.0
2026-04-03 16:24:17 +02:00
Sebastiaan van Stijn c88681f8d8 vendor: moby/api v1.54.1, moby/client v0.4.0
full diffs:

- https://github.com/moby/moby/compare/ef0a1e449505...api/v1.54.1
- https://github.com/moby/moby/compare/ef0a1e449505...client/v0.4.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-03 15:54:11 +02:00
Paweł GronowskiandGitHub 84b884f383 Merge pull request #6909 from thaJeztah/update_authors_mailmap
update AUTHORS and .mailmap
2026-04-03 13:53:21 +02:00
Paweł GronowskiandGitHub d6169a5ea9 Merge pull request #6910 from thaJeztah/update_version
bump version to v29.4.0-dev
2026-04-03 13:46:49 +02:00
Sebastiaan van Stijn 5ddc1553ae bump version to v29.4.0-dev
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.

https://github.com/docker/cli/blob/d48fb9f9f7bdb6e0ef37dbde68612a1704cad46e/docker.Makefile#L22

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-03 13:28:17 +02:00
Sebastiaan van Stijn a347d9e103 update AUTHORS and .mailmap
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-03 13:26:29 +02:00
Sebastiaan van StijnandGitHub 699b029b57 Merge pull request #6908 from thaJeztah/bump_runewidth
vendor: github.com/mattn/go-runewidth v0.0.22
2026-04-03 12:58:59 +02:00
Paweł GronowskiandGitHub 512607a396 Merge pull request #6889 from YoanWai/docs/prune-filter-behavior
docs: clarify multiple --filter behavior in prune commands
2026-04-03 12:53:43 +02:00
Sebastiaan van Stijn 5fca671ef4 vendor: github.com/mattn/go-runewidth v0.0.22
full diff: https://github.com/mattn/go-runewidth/compare/v0.0.21...v0.0.22

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-03 12:53:08 +02:00
Paweł GronowskiandGitHub 753b10228f Merge pull request #6893 from thaJeztah/bump_moby
vendor: moby/client and moby/api master
2026-04-03 12:49:36 +02:00
Sebastiaan van Stijn 42da40a605 vendor: moby/client and moby/api master
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-03 12:44:53 +02:00
Paweł GronowskiandGitHub 7d4f9bd581 Merge pull request #6872 from thaJeztah/link_completions
shell completions: add shell completion for `docker rm --link` and exclude legacy links for container names
2026-04-03 12:37:11 +02:00
Paweł GronowskiandGitHub 2daa2c31e8 Merge pull request #6876 from thaJeztah/stats_optimize
docker stats: assorted fixes and optimizations in rendering
2026-04-03 12:34:04 +02:00
Paweł GronowskiandGitHub d8a85fba27 Merge pull request #6875 from thaJeztah/optimize_formatter
cli/command/formatter: assorted fixes and cleanups
2026-04-03 12:32:39 +02:00
Sebastiaan van StijnandGitHub efddff6549 Merge pull request #6907 from docker/dependabot/github_actions/codecov/codecov-action-6.0.0
build(deps): bump codecov/codecov-action from 5.5.3 to 6.0.0
2026-04-03 12:32:27 +02:00
Paweł GronowskiandGitHub 72beec9840 Merge pull request #6906 from thaJeztah/stream_preserve_file
cli/streams: Out, In: preserve original os.File when available
2026-04-03 12:29:30 +02:00
dependabot[bot]andGitHub 0029d5936a build(deps): bump codecov/codecov-action from 5.5.3 to 6.0.0
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.5.3 to 6.0.0.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/1af58845a975a7985b0beb0cbe6fbbb71a41dbad...57e3a136b779b570ffcdbf80b3bdc90e7fab3de2)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-03 08:44:33 +00:00
Sebastiaan van Stijn e7cbaafa9d cli/command/container: statsFormatWrite: inline render func
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 22:00:04 +02:00
Sebastiaan van Stijn c44a4d9758 cli/command/container: RunStats: avoid bytes to strings conversions
This code is using a `bytes.Buffer` to render the stats, before writing
the results to the CLI's output. Let's try to use bytes where possible
instead of converting to a string;

- Use the buffer's `Write` (and `Out().Write`) to write directly to the
  buffer/writer where possible.
- Use `io.WriteString` instead of `fmt.Printf`
- Use `bytes.SplitSeq` instead of `strings.SplitSeq`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 21:59:49 +02:00
Sebastiaan van Stijn d92d1187fc cli/command/container: RunStats: rename buffer var for brevity
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 21:59:10 +02:00
Sebastiaan van Stijn ee88c60a5e cli/command/container: stats: add snapshot method
Move logic to capture a snapshot of the current stats to the stats struct.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 21:59:05 +02:00
Sebastiaan van Stijn 4c5efd61ea cli/command/container: fix buffer reuse when printing stats
Don't write lines back into the same buffer that's being read from when
clearing lines; add a separate output buffer to construct the output,
then write it to the CLI's output at once (to prevent terminal flicker).

Relates to / introduced in cb2f95ceee.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 21:50:31 +02:00
Sebastiaan van Stijn b309524f60 cli/command/formatter: NewStats: update GoDoc and add TODO
Update the GoDoc to better align with the actual implementation. The
"idOrName" is used for fuzzy-matching the container, which can result
in multiple stats for the same container:

    docker ps --format 'table {{.ID}}\t{{.Names}}'
    CONTAINER ID   NAMES
    b49e6c21d12e   quizzical_maxwell

    docker stats --no-stream quizzical_maxwell b49e6c21d12e b49e6
    CONTAINER ID   NAME                CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O        PIDS
    b49e6c21d12e   quizzical_maxwell   0.10%     140.8MiB / 7.653GiB   1.80%     3.11MB / 13.4kB   115MB / 1.12MB   28
    b49e6c21d12e   quizzical_maxwell   0.10%     140.8MiB / 7.653GiB   1.80%     3.11MB / 13.4kB   115MB / 1.12MB   28
    b49e6c21d12e   quizzical_maxwell   0.10%     140.8MiB / 7.653GiB   1.80%     3.11MB / 13.4kB   115MB / 1.12MB   28

We should resolve the canonical ID once, then use that as reference
to prevent duplicates. Various  parts in the code compare Container
against "ID" only (not considering "name" or "ID-prefix").

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 21:11:48 +02:00
Sebastiaan van Stijn abd2e211b9 cli/command/formatter: add Format.templateString, remove Context.preFormat
The `Context.preFormat` method normalizes the Format as given by the user,
and handles (e.g.) stripping the "table" prefix and replacing the "json"
format for the actual format (`{{json .}}`).

The method used a `finalFormat` field on the Context as intermediate,
and was required to be called before executing the format.

This patch adds a `Format.templateString()` method that returns the
parsed format instead of storing it on the Context. It is currently
not exported, but something we could consider in future.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 21:11:40 +02:00
Sebastiaan van Stijn cb615a9772 cli/command/formatter: Context.postFormat: remove redundant buffer
A tabwriter is backed by a buffer already, because it needs to re-flow columns
based on content written to it. This buffer was added in [moby@ea61dac9e6] as
part of a new feature to allow for custom delimiters; neither the patch, nor
code-review on the PR mention the extra buffer, so it likely was just overlooked.

This patch;

- removes the redundant buffer
- adds an early return for cases where no tabwriter is used.

[moby@ea61dac9e6]: https://github.com/moby/moby/commit/ea61dac9e6d04879445f9c34729055ac1bb15050

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 20:59:30 +02:00
Sebastiaan van Stijn f7a909d56b cli/command/formatter: optimize ContainerContext.Names
Optimize formatting of container name(s);

- Inline `StripNamePrefix` in the loop, so that we don't have to
  construct a new slice with names (in most cases only to pick
  the first one).
- Don't use `strings.Split`, as it allocates a new slice and we only
  used it to check if the container-name was a legacy-link (contained
  slashes).
- Use a string-builder to concatenate names when not truncating instead
  of using an intermediate slice (and `strings.Join`).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 20:59:29 +02:00
Sebastiaan van Stijn 94d4929a04 cli/streams: Out, In: preserve original os.File when available
Preserve the original *os.File, if available, and add a File() method
to return it.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 20:52:30 +02:00
Sebastiaan van StijnandGitHub 2cc9fe1438 Merge pull request #6900 from thaJeztah/cli_stream_cleanups
cli/streams: assorted cleanups
2026-04-02 20:52:06 +02:00
Paweł GronowskiandGitHub 38e44e4125 Merge pull request #6905 from thaJeztah/bump_trust_deps
cmd/docker-trust: bump dependencies
2026-04-02 18:15:34 +02:00
Sebastiaan van Stijn 526dfffc26 cli/streams: simplify CheckTty
This function is very specific to attaching to containers, and probably
helps clarity to inline it where used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 18:11:50 +02:00
Sebastiaan van Stijn 48721c2340 cli/streams: don't depend on embedding
Define explicit wrapper methods instead of depending on the embedded
commonStreams struct.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 17:29:55 +02:00
Sebastiaan van Stijn 39e82e6524 cli/streams: move constructors to the start
It's more idiomatic to define the constructor before methods.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 17:29:55 +02:00
Sebastiaan van Stijn 34805dd013 cli/streams: (In|Out).SetRawTerminal: dry
Move the code to the commonStream type, which is where the actual
state field is kept.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 17:29:55 +02:00
Sebastiaan van Stijn 6e1f03c2e0 cmd/docker-trust: bump dependencies
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 17:06:57 +02:00
Sebastiaan van StijnandGitHub 7639343b30 Merge pull request #6867 from docker/update-swarm-docs
Updated example tokens in swarm docs
2026-04-02 15:42:59 +02:00
87a222158d Updated example tokens in swarm docs
Prevent security scanners from detecting them as eaked secrets.

Co-authored-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
Signed-off-by: Alexandre Vallières-Lagacé <alexandre.valliereslagace@docker.com>
Signed-off-by: Alexandre Vallières-Lagacé <alexandre@vallier.es>
2026-04-02 15:25:16 +02:00
Paweł GronowskiandGitHub fbfb69f7e9 Merge pull request #6873 from thaJeztah/simplify_chips
cli/command/image: getPossibleChips: simplify
2026-04-02 13:51:17 +02:00
Paweł GronowskiandGitHub 424955ddf7 Merge pull request #6904 from thaJeztah/bump_otels
vendor: go.opentelemetry.io/otel v1.42.0, otel/contrib v1.67.0
2026-04-02 13:43:10 +02:00
Paweł GronowskiandGitHub bbb6311c09 Merge pull request #6871 from thaJeztah/completions_no_dups
cli/command/completion: don't provide duplicate completions
2026-04-02 13:41:27 +02:00
Sebastiaan van StijnandGitHub 48afa03bba Merge pull request #6878 from zampani-docker/zampani/fix-plugin-force-exit-race
fix(cmd/docker): prevent race between force-exit goroutine and plugin wait
2026-04-02 12:54:38 +02:00
Sebastiaan van Stijn 98d978df6b vendor: go.opentelemetry.io/otel v1.42.0, otel/contrib v1.67.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 12:51:19 +02:00
Sebastiaan van Stijn a48ff6b591 cli/command/completion: don't provide duplicate completions
When completing for commands that accept multiple arguments, we did
not remove suggestions that were already consumed. This could be
confusing if there was only 1 suggestion, in which case every `<tab>`
would automatically suggest the same name again:

docker rm -fv magical_lumiere magical_lumiere  magical_lumiere

This patch adds a "Unique" helper to wrap a completion func to remove
completion results that are already consumed (i.e., appear in "args").

For example:

    # initial completion: args is empty, so all results are shown
    command <tab>
    one two three

    # "one" is already used so omitted
    command one <tab>
    two three

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 12:46:41 +02:00
Paweł GronowskiandGitHub 12b8ca4406 Merge pull request #6901 from thaJeztah/modernize
cli/command/formatter: modernize
2026-04-02 12:34:14 +02:00
Paweł GronowskiandGitHub dc9b6e553e Merge pull request #6874 from thaJeztah/future_proof_prefix
formatting: only strip "/" prefixes
2026-04-02 11:42:31 +02:00
Paweł GronowskiandGitHub f4d2906b56 Merge pull request #6894 from Rohan5commit/docs/fix-run-following-typo-20260331
docs: fix typo in run reference examples
2026-04-02 11:40:50 +02:00
Paweł GronowskiandGitHub 6998987257 Merge pull request #6866 from thaJeztah/bump_x_deps
vendor: update golang.org/x/* dependencies
2026-04-02 11:39:38 +02:00
Paweł GronowskiandGitHub 5e856302bf Merge pull request #6899 from thaJeztah/bump_compress
vendor: github.com/klauspost/compress v1.18.5
2026-04-02 11:37:51 +02:00
Paweł GronowskiandGitHub 253dc62658 Merge pull request #6903 from thaJeztah/bump_jose
vendor: github.com/go-jose/go-jose/v4 v4.1.4
2026-04-02 11:36:52 +02:00
Paweł GronowskiandGitHub a9ea8b23fa Merge pull request #6825 from thaJeztah/bump_go1.26
update to go1.26.1
2026-04-02 11:32:46 +02:00
Sebastiaan van Stijn 091afa4957 vendor: github.com/go-jose/go-jose/v4 v4.1.4
Fixes CVE-2026-34986 / GHSA-78h2-9frx-2jm8

full diff: https://github.com/go-jose/go-jose/compare/v4.1.3...v4.1.4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 02:39:43 +02:00
Sebastiaan van Stijn 968ad0ea6c vendor: golang.org/x/net v0.52.0
full diff: https://cs.opensource.google/go/x/net/+/refs/tags/v0.50.0...refs/tags/v0.52.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 02:31:42 +02:00
Sebastiaan van Stijn 78fb018754 vendor: golang.org/x/time v0.15.0
full diff: https://cs.opensource.google/go/x/time/+/refs/tags/v0.14.0...refs/tags/v0.15.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 02:29:46 +02:00
Sebastiaan van Stijn 18739a5ef6 vendor: golang.org/x/term v0.41.0
full diff: https://cs.opensource.google/go/x/term/+/refs/tags/v0.40.0...refs/tags/v0.41.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 02:29:45 +02:00
Sebastiaan van Stijn 9b21846cde vendor: golang.org/x/text v0.35.0
full diff: https://cs.opensource.google/go/x/text/+/refs/tags/v0.34.0...refs/tags/v0.35.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 02:29:45 +02:00
Sebastiaan van Stijn c22bf3c77e vendor: golang.org/x/mod v0.34.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 02:29:32 +02:00
Sebastiaan van Stijn d792fc53b7 vendor: golang.org/x/sync v0.20.0
full diff: https://cs.opensource.google/go/x/sync/+/refs/tags/v0.19.0...refs/tags/v0.20.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 02:17:17 +02:00
Sebastiaan van Stijn e9664a72ea vendor: golang.org/x/sys v0.42.0
full diff: https://cs.opensource.google/go/x/sys/+/refs/tags/v0.41.0...refs/tags/v0.42.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 02:17:17 +02:00
Sebastiaan van Stijn fb776458cb update to go1.26.1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 02:12:08 +02:00
Sebastiaan van Stijn 62d80156e1 ci: pin remaining actions
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-02 02:11:26 +02:00
Sebastiaan van StijnandGitHub a3c4d64755 Merge pull request #6897 from thaJeztah/bump_minimum_go
update minimum go version to go1.25
2026-04-01 20:12:45 +02:00
Paweł GronowskiandGitHub eecf81316d Merge pull request #6898 from thaJeztah/bump_patternmatcher
vendor: github.com/moby/patternmatcher v0.6.1
2026-04-01 18:39:33 +02:00
Paweł GronowskiandGitHub e67dba1189 Merge pull request #6896 from thaJeztah/bump_grpc
vendor: google.golang.org/grpc v1.79.3
2026-04-01 18:39:30 +02:00
Paweł GronowskiandGitHub fea2465d65 Merge pull request #4723 from thaJeztah/govalidator
ci: add module compatibility check
2026-04-01 16:37:45 +02:00
Sebastiaan van Stijn ea74248e8e cli/command/formatter: modernize
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-01 15:43:34 +02:00
Sebastiaan van Stijn 5efed5fa30 vendor: github.com/klauspost/compress v1.18.5
- zstd: Fix crash when changing encoder dictionary with same ID

full diff: https://github.com/klauspost/compress/compare/v1.18.4...v1.18.5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-01 00:38:50 +02:00
Sebastiaan van Stijn cd9e5ae84f vendor: github.com/moby/patternmatcher v0.6.1
- fix panic / nil pointer dereference on invalid patterns

full diff: https://github.com/moby/patternmatcher/compare/v0.6.0...v0.6.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-01 00:24:02 +02:00
Sebastiaan van Stijn bf6a1e1fcf cli-plugins/socket: modernize
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-01 00:19:32 +02:00
Sebastiaan van Stijn 8f7dc04070 update minimum go version to go1.25
- drop support for go1.24
- update vendor.mod to go1.25.0
- update //go:build tags to go1.25

The golang.org/x/ dependencies now require go1.25 as a minimum,
so updating our build tags accordingly.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-04-01 00:19:04 +02:00
Sebastiaan van Stijn a14db81c9c vendor: google.golang.org/grpc v1.79.3
fixes [CVE-2026-33186] / [GHSA-p77j-4mvh-x3m3]

full diff: https://github.com/grpc/grpc-go/compare/v1.78.0...v1.79.3

[CVE-2026-33186]: https://www.cve.org/CVERecord?id=CVE-2026-33186
[GHSA-p77j-4mvh-x3m3]: https://github.com/grpc/grpc-go/security/advisories/GHSA-p77j-4mvh-x3m3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-31 09:22:30 +02:00
Codex e660030f3a docs: fix typo in run reference
Signed-off-by: Codex <codex@openai.com>
2026-03-31 10:31:44 +08:00
Sebastiaan van Stijn 58c1585b49 gha: validate gocompat
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-26 17:53:31 +01:00
Sebastiaan van Stijn ea42337d01 implement module compatibility check
This package imports all "importable" packages, i.e., packages that:

- are not applications ("main")
- are not internal
- and that have non-test go-files

We do this to verify that our code can be consumed as a dependency
in "module mode". When using a dependency that does not have a go.mod
(i.e.; is not a "module"), go implicitly generates a go.mod. Lacking
information from the dependency itself, it assumes "go1.16" language
(see [DefaultGoModVersion]). Starting with Go1.21, go downgrades the
language version used for such dependencies, which means that any
language feature used that is not supported by go1.16 results in a
compile error;

    # github.com/docker/cli/cli/context/store
    /go/pkg/mod/github.com/docker/cli@v25.0.0-beta.2+incompatible/cli/context/store/storeconfig.go:6:24: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    /go/pkg/mod/github.com/docker/cli@v25.0.0-beta.2+incompatible/cli/context/store/store.go:74:12: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)

These errors do NOT occur when using GOPATH mode, nor do they occur
when using "pseudo module mode" (the "-mod=mod -modfile=vendor.mod"
approach used in this repository).

As a workaround for this situation, we must include "//go:build" comments
in any file that uses newer go-language features (such as the "any" type
or the "min()", "max()" builtins).

From the go toolchain docs (https://go.dev/doc/toolchain):

> The go line for each module sets the language version the compiler enforces
> when compiling packages in that module. The language version can be changed
> on a per-file basis by using a build constraint.
>
> For example, a module containing code that uses the Go 1.21 language version
> should have a go.mod file with a go line such as go 1.21 or go 1.21.3.
> If a specific source file should be compiled only when using a newer Go
> toolchain, adding //go:build go1.22 to that source file both ensures that
> only Go 1.22 and newer toolchains will compile the file and also changes
> the language version in that file to Go 1.22.

This file is a generated module that imports all packages provided in
the repository, which replicates an external consumer using our code
as a dependency in go-module mode, and verifies all files in those
packages have the correct "//go:build <go language version>" set.

To test this package:

    make shell
    make -C ./internal/gocompat/
    make: Entering directory '/go/src/github.com/docker/cli/internal/gocompat'
    GO111MODULE=off go generate .
    GO111MODULE=on go mod tidy
    GO111MODULE=on go test -v
    # github.com/docker/cli/templates
    ../../templates/templates.go:13:17: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    # github.com/docker/cli/cli/compose/template
    ../../cli/compose/template/template.go:98:45: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/template/template.go:105:27: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/template/template.go:141:28: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    # github.com/docker/cli/cli/compose/types
    ../../cli/compose/types/types.go:53:22: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/types/types.go:86:34: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/types/types.go:105:22: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/types/types.go:137:34: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/types/types.go:211:20: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/types/types.go:343:35: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/types/types.go:442:40: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/types/types.go:469:24: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/types/types.go:490:24: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/types/types.go:587:28: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/types/types.go:442:40: too many errors
    # github.com/docker/cli/cli/context/store
    ../../cli/context/store/storeconfig.go:6:24: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/context/store/store.go:74:12: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/context/store/store.go:75:23: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/context/store/metadatastore.go:43:58: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/context/store/metadatastore.go:48:22: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/context/store/metadatastore.go:80:30: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    # github.com/docker/cli/cli/command/idresolver
    ../../cli/command/idresolver/idresolver.go:6:2: "github.com/docker/docker/api/types" imported and not used
    ../../cli/command/idresolver/idresolver.go:7:2: "github.com/docker/docker/api/types/swarm" imported and not used
    ../../cli/command/idresolver/idresolver.go:9:2: "github.com/pkg/errors" imported and not used
    ../../cli/command/idresolver/idresolver.go:28:49: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/command/idresolver/idresolver.go:58:53: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    # github.com/docker/cli/cli/compose/schema
    ../../cli/compose/schema/schema.go:20:46: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/schema/schema.go:27:53: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/schema/schema.go:45:32: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    ../../cli/compose/schema/schema.go:66:33: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
    FAIL	gocompat [build failed]
    make: *** [Makefile:3: verify] Error 1
    make: Leaving directory '/go/src/github.com/docker/cli/internal/gocompat'

[DefaultGoModVersion]: https://github.com/golang/go/blob/58c28ba286dd0e98fe4cca80f5d64bbcb824a685/src/cmd/go/internal/gover/version.go#L15-L24
[2]: https://go.dev/doc/toolchain

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-26 17:53:31 +01:00
Paweł GronowskiandGitHub 538ee85f39 Merge pull request #6888 from thaJeztah/add_build_tags
cli-plugins/hooks: add missing "go:build" comments
2026-03-26 16:32:44 +01:00
Yoan Wainmann d573c171fe docs: clarify multiple --filter behavior in prune commands
Document how multiple --filter flags interact in prune commands:
different filter keys are ANDed (all conditions must match), while
multiple values for the same key are ORed (any value can match).

This addresses a gap in the documentation where users could not
determine whether multiple filters were combined with AND or OR
logic, which is especially important for prune commands where
the wrong assumption could lead to unintended data removal.

Closes #5899

Signed-off-by: Yoan Wainmann <yoan@mreshet.co.il>
2026-03-25 18:13:49 +02:00
Sebastiaan van Stijn 07bb479a45 cli-plugins/hooks: add missing "go:build" comments
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-25 16:32:18 +01:00
Paweł GronowskiandGitHub 9637f1b364 Merge pull request #6886 from thaJeztah/pin_actions
ci: pin actions to digests
2026-03-25 15:22:16 +01:00
Sebastiaan van Stijn 97b9e04a94 ci: pin actions to digests
As a follow-up, we should use the full version (major.minor.patch).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-25 14:58:57 +01:00
Michael ZampaniandClaude Sonnet 4.6 2bc4307816 fix(cmd/docker): prevent race between force-exit goroutine and plugin wait
When a plugin ignores context cancellation and the user sends 3 SIGINTs,
the CLI kills the plugin with SIGKILL. Previously the signal goroutine
called os.Exit(1) directly; a race existed where plugincmd.Run() could
return first (plugin was SIGKILL'd, so ws.ExitStatus() = -1) and the
main goroutine would call os.Exit(-1) = exit code 255 before the
goroutine reached os.Exit(1).

Fix by moving exit-code ownership to the main goroutine. The signal
goroutine closes forceExitCh before calling Kill(), guaranteeing the
channel is closed before plugincmd.Run() returns (the plugin can only
die after Kill() delivers SIGKILL; Run() only returns after the process
is reaped). The main goroutine checks forceExitCh after Run() returns
and performs the print + os.Exit(1) itself.

Also return from the signal goroutine after the force-kill to prevent
further loop iterations from calling close(forceExitCh) a second time
(which would panic), in case additional signals arrive while the kill
is in flight.

Fixes a flaky failure in TestPluginSocketCommunication/detached/
the_main_CLI_exits_after_3_signals where exit code 255 was observed
instead of 1 on loaded CI runners (RC Docker on Alpine).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Michael Zampani <michael.zampani@docker.com>
2026-03-21 15:31:12 -07:00
Sebastiaan van Stijn 9c117d3c5d cli/command/container: add shell completion for docker rm --link
When linking containers through legacy links, a container can get multiple
names; its own name, and a name for each link it's providing:

    # create two containers with links between them
    docker run -d --name one nginx:alpine
    docker run -d --name two --link one:link1 --link one:link2 --link one:link3 nginx:alpine

    docker rm --link <tab>
    two/link1 two/link2 two/link3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-20 18:24:19 +01:00
Sebastiaan van Stijn df57ff7201 cli/command/completion: ContainerNames: skip legacy link names
Inline StripNamePrefix and skip legacy links for completion.
Legacy links can be removed from a container, but only when
using `docker [container] rm --link <link-name>`.

When linking containers through legacy links, a container can get multiple
names; its own name, and a name for each link it's providing:

    # create two containers with links between them

    docker run -d --name one nginx:alpine
    docker run -d --name two --link one:link1 --link one:link2 --link one:link3 nginx:alpine

    # container "one" now has multiple names
    docker ps --no-trunc --format '{{.Names}}'
    two
    one,two/link1,two/link2,two/link3

    # running `docker rm --link` with a link-name removes a link:

    docker rm --link two/link3
    docker ps --no-trunc --format '{{.Names}}'
    two
    one,two/link1,two/link2

    # but without `--link`, it resolves the linked container and removes it:
    docker rm -fv two/link2
    two/link2
    docker ps --no-trunc --format '{{.Names}}'
    two

Legacy links are deprecated, and this can be confusing, so let's not provide
completion for secondary names.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-20 18:17:43 +01:00
Sebastiaan van Stijn dfda342e51 cli/command/formatter: StripNamePrefix only strip "/" prefix
This code was assuming the API always returns container names with
a "/" prefix. While this is currently correct, we may at some point
stop doing so.

This patch changes the code to only trim "/" as prefix and not any
other character.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-20 17:43:37 +01:00
Sebastiaan van Stijn b5efd66ba6 cli/command/container: stats: make stripping "/" prefix deterministic
This code was assuming the API always returns container names with
a "/" prefix. While this is currently correct, we may at some point
stop doing so.

This patch changes the code to only trim "/" as prefix and not any
other character.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-20 17:43:36 +01:00
Sebastiaan van Stijn 64c8d68045 cli/command/image: getPossibleChips: simplify
Extract the check to a closure that filters in-place, and
run the check in a single loop.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-20 17:33:14 +01:00
Sebastiaan van StijnandGitHub 7922984193 Merge pull request #6863 from thaJeztah/fix_stats
fix: docker stats --all: remove containers when removed
2026-03-19 15:44:15 +01:00
Sebastiaan van StijnandGitHub bcfb717a31 Merge pull request #6859 from thaJeztah/plugin_metadata
cli-plugins: separate hook types from manager and refactor
2026-03-19 14:47:29 +01:00
Sebastiaan van Stijn 4bf4d567bd cli-plugins/hooks: PrintNextSteps: slight cleanup
- skip aec to construct the formatting and use a const instead
- skip fmt.Println and write directly to the writer
- move newlines outside of the "bold" formatting

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-19 12:24:36 +01:00
Sebastiaan van Stijn dd1f7f5856 cli-plugins/hooks: simplify templating formats
This allows for slighly cleaner / more natural placeholders, as it
doesn't require the context (`.`) to be specified;

- `{{command}}` instead of `{{.Command}}` or `{{command .}}`
- `{{flagValue "my-flag"}}` instead of `{{.FlagValue "my-flag"}} or `{{flagValue . "my-flag"}}`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-19 12:24:35 +01:00
Sebastiaan van Stijn 9243240346 cli-plugins/hooks: add commandInfo type for templating
Define a local type for methods to expose to the template, instead of
passing the cobra.Cmd. This avoids templates depending on features
exposed by Cobra that are not part of the contract, and slightly
decouples the templat from the Cobra implementation.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-19 12:24:35 +01:00
Sebastiaan van Stijn 4a1b2ef2c5 cli-plugins/hooks: update godoc
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-19 12:24:35 +01:00
Sebastiaan van Stijn 4142d4026e cli-plugins/hooks: detect if templating is needed
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-19 12:24:35 +01:00
Sebastiaan van Stijn cd053606a6 cli-plugins/hooks: slight tweaks in templates
- use `%q` instead of manually quoting the string
- use `%d` instead of manually converting the number to a string

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-19 12:24:35 +01:00
Sebastiaan van Stijn aadfe6214f cli-plugins/hooks: update tests
- add basic unit-test for the template utilities
- make sure the template parsing tests test both the current
  template produced by the utilities, as well as a fixture
- rewrite the printer test to use fixtures
- use blackbox testing ("hooks_test")

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-19 12:24:34 +01:00
Sebastiaan van Stijn dce201d6ee cli-plugins/hooks: move template utils separate from render code
These utilities are used by CLI-plugins; separate them from the render
code, which is used by teh CLI-plugin manager.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-19 12:24:34 +01:00
Sebastiaan van Stijn e26f94d823 cli-plugins/hooks: add JSON labels, omitzero
Add labels to define the expected casing and don't serialize
empty fields.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-19 12:24:27 +01:00
Sebastiaan van Stijn 0431e4d23c cli-plugins/hooks: rename HookType to ResponseType
Rename the type to match the struct it's used for. Also;

- Fix the type of the NextSteps const
- Don't use iota for values; the ResponseType is used as
  part of the "wire" format, which means that plugins using
  the value can use a different version of the module code;
  using iota increases the risk of (accidentally) changing
  values, which would break the wire format.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-18 12:20:48 +01:00
Sebastiaan van Stijn 607ebfca5d cli-plugins/hooks: rename HookMessage to Response
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-18 12:20:48 +01:00
Sebastiaan van Stijn 60180924e3 cli-plugins/manager: move HookPluginData to hooks.Request
Separate types used by plugins from the manager code.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-18 12:20:48 +01:00
Sebastiaan van Stijn dd91ed3f2d cli-plugins/manager: refactor for easier debugging
Extract the code inside the loop to a closure, so that we can more
easily set up debug-logging.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-18 12:20:42 +01:00
Sebastiaan van Stijn 0501cf8293 cli-plugins/manager: simplify ctx-cancel check
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-18 12:18:46 +01:00
Sebastiaan van Stijn 5343bdc792 cli-plugins/manager: Plugin.RunHook: improve error message
Currently, the error was a plain "exit status 1"; make the error
message more informative if we need it :)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-18 12:18:41 +01:00
Sebastiaan van Stijn 5fb5e0b0da docker stats --all: remove containers when removed
Before this patch, running `docker stats --all` would continue showing
all containers once observed. For example;

    CONTAINER ID   NAME                 CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS
    f2a785b0cd5f   foo1                 0.00%     8.535MiB / 7.653GiB   0.11%     1.12kB / 126B   0B / 12.3kB      11
    fc191b27517f   foo2                 0.00%     8.531MiB / 7.653GiB   0.11%     998B / 126B     0B / 12.3kB      11
    5040185fba53   foo3                 0.00%     8.578MiB / 7.653GiB   0.11%     872B / 126B     0B / 8.19kB      11

WHen removing `foo2`, the container would continue to be listed:

    CONTAINER ID   NAME                 CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS
    f2a785b0cd5f   foo1                 0.00%     8.535MiB / 7.653GiB   0.11%     1.12kB / 126B   0B / 12.3kB      11
    fc191b27517f   foo2                 --        -- / --               --        --              --               --
    5040185fba53   foo3                 0.00%     8.578MiB / 7.653GiB   0.11%     872B / 126B     0B / 12.3kB      11

Starting a new `foo2` container would now produce multiple entries:

    CONTAINER ID   NAME                 CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS
    f2a785b0cd5f   foo1                 0.00%     8.535MiB / 7.653GiB   0.11%     1.25kB / 126B   0B / 12.3kB      11
    fc191b27517f   foo2                 --        -- / --               --        --              --               --
    5040185fba53   foo3                 0.00%     8.578MiB / 7.653GiB   0.11%     998B / 126B     0B / 12.3kB      11
    dba11b9e1ba9   foo2                 0.00%     8.578MiB / 7.653GiB   0.11%     872B / 126B     0B / 8.19kB      11

Repeat that, and the list would continue to grow;

    CONTAINER ID   NAME                 CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS
    f2a785b0cd5f   foo1                 0.00%     8.535MiB / 7.653GiB   0.11%     1.25kB / 126B   0B / 12.3kB      11
    fc191b27517f   foo2                 --        -- / --               --        --              --               --
    5040185fba53   foo3                 0.00%     8.578MiB / 7.653GiB   0.11%     998B / 126B     0B / 12.3kB      11
    dba11b9e1ba9   foo2                 --        -- / --               --        --              --               --
    193a6dcfaa2d   foo2                 --        -- / --               --        --              --               --
    bf50e58085c6   foo2                 0.00%     8.539MiB / 7.653GiB   0.11%     872B / 126B     0B / 8.19kB      11

After this patch, containers are removed when we observe a `destroy` event;

    CONTAINER ID   NAME                 CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS
    f2a785b0cd5f   foo1                 0.00%     8.535MiB / 7.653GiB   0.11%     1.5kB / 126B    0B / 12.3kB      11
    5040185fba53   foo3                 0.00%     8.578MiB / 7.653GiB   0.11%     1.25kB / 126B   0B / 12.3kB      11
    bf50e58085c6   foo2                 0.00%     8.539MiB / 7.653GiB   0.11%     872B / 126B     0B / 12.3kB      11

Containers are added when created, so in the example above, the new `foo2`
is added at the end:

    CONTAINER ID   NAME                 CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS
    f2a785b0cd5f   foo1                 0.00%     8.535MiB / 7.653GiB   0.11%     1.5kB / 126B    0B / 12.3kB      11
    5040185fba53   foo3                 0.00%     8.578MiB / 7.653GiB   0.11%     1.25kB / 126B   0B / 12.3kB      11
    bf50e58085c6   foo2                 0.00%     8.539MiB / 7.653GiB   0.11%     872B / 126B     0B / 12.3kB      11

If a container dies, and `--all` is set, we continue listing it, but stats
are not updated while the container is stopped (we should consider resetting
the stats and show `-- / --` to be more clear that we don't have the container
running).

Here's with `foo3` stopped:

    CONTAINER ID   NAME                 CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS
    f2a785b0cd5f   foo1                 0.00%     8.535MiB / 7.653GiB   0.11%     1.5kB / 126B    0B / 12.3kB      11
    5040185fba53   foo3                 0.00%     0B / 0B               0.00%     0B / 0B         0B / 0B          0
    bf50e58085c6   foo2                 0.00%     8.539MiB / 7.653GiB   0.11%     872B / 126B     0B / 12.3kB      11

Starting the container continues updating its stats:

    CONTAINER ID   NAME                 CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS
    f2a785b0cd5f   foo1                 0.00%     8.535MiB / 7.653GiB   0.11%     1.63kB / 126B   0B / 12.3kB      11
    5040185fba53   foo3                 0.00%     8.496MiB / 7.653GiB   0.11%     872B / 126B     0B / 0B          11
    bf50e58085c6   foo2                 0.00%     8.539MiB / 7.653GiB   0.11%     998B / 126B     0B / 12.3kB      11

When running without `--all`, we continue to remove containers as soon as
possible (`die` events), but with `--all`, those events are ignored with
the expectation that the container might come back.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-17 21:05:44 +01:00
Sebastiaan van StijnandGitHub 743c385f78 Merge pull request #6862 from thaJeztah/update_golangci_lint_config
fix linting and update golangci-lint config
2026-03-17 21:05:01 +01:00
Sebastiaan van StijnandGitHub 434193ff78 Merge pull request #6865 from thaJeztah/cleanup_stats
cli/command/container: RunStats: pass ctx to stats event handlers and refractor to DRY
2026-03-17 21:03:38 +01:00
Sebastiaan van StijnandGitHub adc5466cba Merge pull request #6864 from thaJeztah/bump_runewidth
vendor: github.com/mattn/go-runewidth v0.0.21
2026-03-17 21:02:53 +01:00
Sebastiaan van Stijn 560db7d451 vendor: github.com/mattn/go-runewidth v0.0.21
full diff: https://github.com/mattn/go-runewidth/compare/v0.0.20...v0.0.21

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-17 18:36:02 +01:00
Sebastiaan van Stijn dc4abf8b99 golangci-lint: gocheckcompilerdirectives: ignore "//go:fix"
The linter has not been updated yet to recognize this directive.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-17 18:14:57 +01:00
Sebastiaan van Stijn 7f781688ed golangci-lint: remove outdated exclusion
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-17 18:14:54 +01:00
Sebastiaan van Stijn 21293265b1 cli/command/image/build: use t.Chdir() in tests
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-17 18:14:48 +01:00
Sebastiaan van Stijn 3f51d0a9d2 cli/command/container: RunStats: refactor to DRY
- update setHandler to accept multiple event-types
- pass a logger to the event-handlers with the common fields
  already set.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-17 18:05:33 +01:00
Sebastiaan van Stijn 9645db767a cli/command/container: RunStats: pass ctx to stats event handlers
Wire up the context explicitly instead of capturing it in the closures.
Also pass through the context to `watch` to replace the context.TODO()

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-17 18:05:33 +01:00
Sebastiaan van StijnandGitHub 499a4c50bd Merge pull request #6800 from 4RH1T3CT0R7/master
docker cp: report both content size and transferred size
2026-03-16 17:41:05 +01:00
Paweł GronowskiandGitHub bb0f76343a Merge pull request #6804 from icemc/update-docs-flocker-plugin
Removed EOL Flocker plugin reference from plugin documentations.
2026-03-16 09:40:12 +00:00
4RH1T3CT0R7 2bc66ecbc7 docker cp: report both content size and transferred size
When copying files with `docker cp`, the success message now shows both
the actual content size and the transferred (tar stream) size when they
differ, making it easier to understand compression and overhead:

    Successfully copied 2.01MB (transferred 2.53MB) to ctr:/dir

Extract copySummary helper to keep copyToContainer under the gocyclo
complexity threshold. Add unit tests for copySummary and stdin path.

Signed-off-by: 4RH1T3CT0R7 <iprintercanon@gmail.com>
2026-03-13 21:32:58 +03:00
Sebastiaan van StijnandGitHub 26d4525d46 Merge pull request #6817 from luojiyin1987/fix-plugin-cobra
fix: restore os.Args after plugin completion and fix error return
2026-03-13 15:28:03 +01:00
Ludovic Temgoua AbandaandSebastiaan van Stijn 33790e88d0 docs: use generic myplugin example for plugin documentation
- Removed EOL Flocker plugin reference from plugin documentations.
- docs: use generic myplugin example instead of VolumeDriver

Co-authored-by: Ludovic Temgoua Abanda <abandaludovic500@gmail.com>
Signed-off-by: Ludovic Temgoua Abanda <abandaludovic500@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-13 15:27:02 +01:00
luojiyinandSebastiaan van Stijn 6b1ba1ad84 fix: restore os.Args after plugin completion and fix error return
Signed-off-by: luojiyin <luojiyin@hotmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-13 14:48:45 +01:00
Sebastiaan van StijnandGitHub c3a17b9def Merge pull request #6839 from literally-user/6838-fix-font-representation
scripts/warn-outside-container: fix font representation
2026-03-13 14:36:20 +01:00
Sebastiaan van StijnandGitHub 9ca766c489 Merge pull request #6858 from gounthar/feat/add-riscv64-to-bin-image-cross
Add linux/riscv64 to bin-image-cross release target
2026-03-13 13:13:37 +01:00
Bruno Verachten 300d8231da feat: add linux/riscv64 to bin-image-cross release target
Add linux/riscv64 to the bin-image-cross platforms list so that
official release images include riscv64 binaries.

riscv64 is already present in the _platforms variable (line 38) and
used by the cross, dynbinary-cross, and plugins-cross targets. CI
already builds riscv64 binaries, but they are excluded from the
release image because bin-image-cross has its own platform list.

Closes #6857

Signed-off-by: Bruno Verachten <gounthar@gmail.com>
2026-03-12 10:53:47 +01:00
Sebastiaan van StijnandGitHub 5d8cc2c987 Merge pull request #6854 from thaJeztah/missing_buildtags
cli/command: add missing "go:build" comments
2026-03-10 17:31:48 +01:00
Sebastiaan van StijnandGitHub d0442edbfe Merge pull request #6845 from thaJeztah/cleanup_godoc
cli/config/credentials: ConvertToHostname: update godoc
2026-03-10 17:31:14 +01:00
Sebastiaan van StijnandGitHub 3897d9cc09 Merge pull request #6850 from thaJeztah/update_go1.25.8
update to go1.25.8
2026-03-10 17:30:40 +01:00
Sebastiaan van Stijn 9a471180cb cli/command: add missing "go:build" comments
- commit e8dc2fce32 modernized loops to
  range over int, which requires go1.22 or later.
- commit 85ebca52fd modernized code to
  use stdlib min/max, which requires go1.21 or later.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-10 11:18:58 +01:00
Sebastiaan van StijnandGitHub e2f38c4947 Merge pull request #6848 from docker/dependabot/github_actions/docker/metadata-action-6
build(deps): bump docker/metadata-action from 5 to 6
2026-03-06 16:30:00 +01:00
Sebastiaan van StijnandGitHub 13ec581924 Merge pull request #6847 from docker/dependabot/github_actions/docker/bake-action-7
build(deps): bump docker/bake-action from 6 to 7
2026-03-06 16:29:20 +01:00
Sebastiaan van Stijn f7d83cbae8 update to go1.25.8
go1.25.8 (released 2026-03-05) includes security fixes to the html/template,
net/url, and os packages, as well as bug fixes to the go command, the compiler,
and the os package. See the Go 1.25.8 milestone on our issue tracker for details.

- 1.25.8 https://github.com/golang/go/issues?q=milestone%3AGo1.25.8+label%3ACherryPickApproved
- diff: https://github.com/golang/go/compare/go1.25.7...go1.25.8
- 1.26.1 https://github.com/golang/go/issues?q=milestone%3AGo1.26.1+label%3ACherryPickApproved
- diff: https://github.com/golang/go/compare/go1.26.0...go1.26.1

---

We have just released Go versions 1.26.1 and 1.25.8, minor point releases.

These releases include 5 security fixes following the security policy:

crypto/x509: incorrect enforcement of email constraints

- When verifying a certificate chain which contains a certificate containing
  multiple email address constraints (composed of the full email address) which
  share common local portions (the portion of the address before the '@'
  character) but different domain portions (the portion of the address after the
  '@' character), these constraints will not be properly applied, and only the
  last constraint will be considered.

  This can allow certificates in the chain containing email addresses which are
  either not permitted or excluded by the relevant constraints to be returned by
  calls to Certificate.Verify. Since the name constraint checks happen after chain
  building is complete, this only applies to certificate chains which chain to
  trusted roots (root certificates either in VerifyOptions.Roots or in the system
  root certificate pool), requiring a trusted CA to issue certificates containing
  either not permitted or excluded email addresses.

  This issue only affects Go 1.26.

  Thanks to Jakub Ciolek for reporting this issue.

  This is CVE-2026-27137 and Go issue https://go.dev/issue/77952.

- crypto/x509: panic in name constraint checking for malformed certificates

  Certificate verification can panic when a certificate in the chain has an empty
  DNS name and another certificate in the chain has excluded name constraints.
  This can crash programs that are either directly verifying X.509 certificate
  chains, or those that use TLS.

  Since the name constraint checks happen after chain building is complete, this
  only applies to certificate chains which chain to trusted roots (root
  certificates either in VerifyOptions.Roots or in the system root certificate
  pool), requiring a trusted CA to issue certificates containing malformed DNS
  names.

  This issue only affects Go 1.26.

  Thanks to Jakub Ciolek for reporting this issue.

  This is CVE-2026-27138 and Go issue https://go.dev/issue/77953.

- html/template: URLs in meta content attribute actions are not escaped

  Actions which insert URLs into the content attribute of HTML meta tags are not
  escaped. This can allow XSS if the meta tag also has an http-equiv attribute
  with the value "refresh".

  A new GODEBUG setting has been added, htmlmetacontenturlescape, which can be
  used to disable escaping URLs in actions in the meta content attribute which
  follow "url=" by setting htmlmetacontenturlescape=0.

  This is CVE-2026-27142 and Go issue https://go.dev/issue/77954.

- net/url: reject IPv6 literal not at start of host

  The Go standard library function net/url.Parse insufficiently
  validated the host/authority component and accepted some invalid URLs
  by effectively treating garbage before an IP-literal as ignorable.
  The function should have rejected this as invalid.

  To prevent this behavior, net/url.Parse now rejects IPv6 literals
  that do not appear at the start of the host subcomponent of a URL.

  Thanks to Masaki Hara (https://github.com/qnighy) of Wantedly.

  This is CVE-2026-25679 and Go issue https://go.dev/issue/77578.

- os: FileInfo can escape from a Root

  On Unix platforms, when listing the contents of a directory using
  File.ReadDir or File.Readdir the returned FileInfo could reference
  a file outside of the Root in which the File was opened.

  The contents of the FileInfo were populated using the lstat system
  call, which takes the path to the file as a parameter. If a component
  of the full path of the file described by the FileInfo is replaced with
  a symbolic link, the target of the lstat can be directed to another
  location on the filesystem.

  The impact of this escape is limited to reading metadata provided by
  lstat from arbitrary locations on the filesystem. This could be used
  to probe for the presence or absence of files as well as gleaning
  metadata like file sizes, but does not permit reading or writing files
  outside the root.

  The FileInfo is now populated using fstatat.

  Thank you to Miloslav Trmač of Red Hat for reporting this issue.

  This is CVE-2026-27139 and Go issue https://go.dev/issue/77827.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-06 13:52:18 +01:00
dependabot[bot]andGitHub 39d676c72d build(deps): bump docker/metadata-action from 5 to 6
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-06 08:42:45 +00:00
dependabot[bot]andGitHub 6453c4c3a7 build(deps): bump docker/bake-action from 6 to 7
Bumps [docker/bake-action](https://github.com/docker/bake-action) from 6 to 7.
- [Release notes](https://github.com/docker/bake-action/releases)
- [Commits](https://github.com/docker/bake-action/compare/v6...v7)

---
updated-dependencies:
- dependency-name: docker/bake-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-06 08:42:41 +00:00
Sebastiaan van Stijn eef3c957be cli/config/credentials: ConvertToHostname: update godoc
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-05 19:02:03 +01:00
Davlat Davydov 71db1520de scripts/warn-outside-container: fix font representation
Signed-off-by: Davlat Davydov <literally_user@hotmail.com>

fix CI

review changes
2026-03-05 19:34:01 +03:00
Paweł GronowskiandGitHub 5927d80c76 Merge pull request #6844 from vvoland/update-docker
vendor: github.com/moby/moby/api v1.54.0
2026-03-05 14:22:32 +00:00
Paweł Gronowski 206fc8c165 vendor: github.com/moby/moby/client v0.3.0
full diff: https://github.com/moby/moby/compare/client/v0.2.3-rc.1...client/v0.3.0

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-03-05 15:15:44 +01:00
Paweł Gronowski 874a8df0eb vendor: github.com/moby/moby/api v1.54.0
full diff: https://github.com/moby/moby/compare/api/v1.54.0-rc.1...api/v1.54.0

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-03-05 15:15:04 +01:00
Sebastiaan van StijnandGitHub 964a6d2e98 Merge pull request #6792 from vvoland/bind-create
container/opts: Add bind-create-src mount option
2026-03-05 12:39:04 +01:00
Sebastiaan van StijnandGitHub 210147d3f3 Merge pull request #6843 from docker/dependabot/github_actions/docker/setup-buildx-action-4
build(deps): bump docker/setup-buildx-action from 3 to 4
2026-03-05 11:40:17 +01:00
Sebastiaan van StijnandGitHub 847f547aa1 Merge pull request #6842 from docker/dependabot/github_actions/docker/login-action-4
build(deps): bump docker/login-action from 3 to 4
2026-03-05 11:39:15 +01:00
dependabot[bot]andGitHub 668b3671bd build(deps): bump docker/setup-buildx-action from 3 to 4
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-05 08:42:54 +00:00
dependabot[bot]andGitHub 30a2ace7f2 build(deps): bump docker/login-action from 3 to 4
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-05 08:42:47 +00:00
Nicolas De LoofandPaweł Gronowski 32aa575aff docs/service: Document bind-create-src
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-03-04 18:00:48 +01:00
Paweł Gronowski c747cff9ab container/opts: Add bind-create-src mount option
Add support for the `bind-create-src` option in bind mounts, which
instructs the daemon to create the source mountpoint on the host if it
doesn't exist.

This allows to replace the legacy `-v /src/dir:/dst` with the `--mount`.

Usage:
--mount type=bind,src=/host/path,dst=/container/path,bind-create-src
--mount type=bind,src=/host/path,dst=/container/path,bind-create-src=true

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-03-04 18:00:01 +01:00
Sebastiaan van StijnandGitHub ddb986472a Merge pull request #6794 from derekmisler/cli-hints-for-docker-ai-after-buildcompose-failur
Fix: run plugin hooks on command failure, not just success
2026-03-04 15:14:57 +01:00
Sebastiaan van StijnandGitHub 5348cf8461 Merge pull request #6836 from docker/dependabot/github_actions/docker/setup-qemu-action-4
build(deps): bump docker/setup-qemu-action from 3 to 4
2026-03-04 14:38:24 +01:00
Sebastiaan van StijnandGitHub 30fb480896 Merge pull request #6784 from thaJeztah/login_cleanups
cli/command/registry: preserve all whitespace in secrets
2026-03-04 12:53:19 +01:00
Sebastiaan van StijnandGitHub 6347345783 Merge pull request #6809 from thaJeztah/compose_rm_utils
cli/compose/loader: remove some wrapper utilities and use errors.Join
2026-03-04 12:52:36 +01:00
dependabot[bot]andGitHub ba349f5afd build(deps): bump docker/setup-qemu-action from 3 to 4
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 08:42:48 +00:00
Sebastiaan van StijnandGitHub 0eda6db75b Merge pull request #6833 from docker/dependabot/go_modules/cmd/docker-trust/go_modules-6b971a9d7e
build(deps): bump go.opentelemetry.io/otel/sdk from 1.38.0 to 1.40.0 in /cmd/docker-trust in the go_modules group across 1 directory
2026-03-02 15:28:07 +01:00
Sebastiaan van Stijn e2cafd657e cli/command/registry: preserve all whitespace in secrets
Preserve all whitespace and treat the secret as an opaque value,
leaving it to the registry to (in)validate. We still check for
empty values in some places.

This partially reverts a21a5f4243,
but checks for empty (whitespace-only) passwords without mutating
the value.

This better aligns with [NIST SP 800-63B §5.1.1.2], which describes
that the value should be treated as opaque, preserving any other whitespace,
including newlines. Note that trimming whitespace may still happen elsewhere
(see [NIST SP 800-63B (revision 4) §3.1.1.2]);
> Verifiers **MAY** make limited allowances for mistyping (e.g., removing
> leading and trailing whitespace characters before verification, allowing
> the verification of passwords with differing cases for the leading character)

[NIST SP 800-63B §5.1.1.2]: https://pages.nist.gov/800-63-3/sp800-63b.html#memsecretver
[NIST SP 800-63B (revision 4) §3.1.1.2]: https://pages.nist.gov/800-63-4/sp800-63b.html#passwordver

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-02 15:13:16 +01:00
dependabot[bot]andGitHub 10ebb3b204 build(deps): bump go.opentelemetry.io/otel/sdk
Bumps the go_modules group with 1 update in the /cmd/docker-trust directory: [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go).


Updates `go.opentelemetry.io/otel/sdk` from 1.38.0 to 1.40.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.38.0...v1.40.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-version: 1.40.0
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-01 22:11:09 +00:00
Sebastiaan van StijnandGitHub 694d1a034f Merge pull request #6815 from luojiyin1987/fix-typos
Fix various typos in code and documentation
2026-02-28 20:04:24 +01:00
luojiyin 681f15674c Fix typos in code and documentation
Signed-off-by: luojiyin <luojiyin@hotmail.com>
2026-02-28 08:37:04 +08:00
Paweł GronowskiandGitHub 4e5bc6816d Merge pull request #6832 from vvoland/update-docker
vendor: github.com/moby/moby/api v1.54.0-rc.1 & client v0.2.3-rc.1
2026-02-27 19:43:43 +00:00
Paweł Gronowski 0bf060f777 vendor: github.com/moby/moby/client v0.2.3-rc.1
full diff: https://github.com/moby/moby/client/compare/52dc67c0df94...v0.2.3-rc.1

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-02-27 20:34:37 +01:00
Paweł Gronowski 139b58d7f4 vendor: github.com/moby/moby/api v1.54.0-rc.1
full diff: https://github.com/moby/moby/api/compare/52dc67c0df94...v1.54.0-rc.1

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-02-27 20:34:19 +01:00
Paweł GronowskiandGitHub 851b5b7f78 Merge pull request #6829 from thaJeztah/bump_modules
vendor: moby/api v1.54.0-dev, moby/client v0.2.3-dev
2026-02-27 18:00:07 +00:00
Sebastiaan van Stijn 8eedbdc6a8 vendor: moby/api v1.54.0-dev, moby/client v0.2.3-dev
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-27 18:16:02 +01:00
Paweł GronowskiandGitHub afb3212d5b Merge pull request #6827 from thaJeztah/bump_compose
Dockerfile: update compose to v5.1.0, buildx to v0.31.1, mvdan.cc/gofump to v0.9.2
2026-02-27 16:45:45 +00:00
Paweł GronowskiandGitHub 575793f52f Merge pull request #6828 from thaJeztah/bump_runewidth
vendor: github.com/mattn/go-runewidth v0.0.20
2026-02-27 16:45:32 +00:00
Sebastiaan van Stijn cd070a5ed5 vendor: github.com/mattn/go-runewidth v0.0.20
full diff: https://github.com/mattn/go-runewidth/compare/v0.0.19...v0.0.20

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-27 17:28:18 +01:00
Sebastiaan van Stijn 8c3d05398e Dockerfile: update mvdan.cc/gofump to v0.9.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-27 17:21:04 +01:00
Sebastiaan van Stijn b206927e0c Dockerfile: update buildx to v0.31.1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-27 17:20:06 +01:00
Sebastiaan van Stijn 6b5acd3a6e Dockerfile: update compose to v5.1.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-27 17:18:48 +01:00
Paweł GronowskiandGitHub 9e10dc3dca Merge pull request #6824 from thaJeztah/bump_compress2
vendor: github.com/klauspost/compress v1.18.4
2026-02-27 15:39:27 +00:00
Sebastiaan van StijnandGitHub f8a2176b84 Merge pull request #6823 from thaJeztah/bump_otel
vendor: go.opentelemetry.io/otel v1.40.0, go.opentelemetry.io/contrib v0.65.0
2026-02-27 16:33:52 +01:00
Sebastiaan van StijnandGitHub 3169956851 Merge pull request #6822 from docker/dependabot/github_actions/actions/upload-artifact-7
build(deps): bump actions/upload-artifact from 6 to 7
2026-02-27 15:26:48 +01:00
Sebastiaan van Stijn caa8a50468 vendor: github.com/klauspost/compress v1.18.4
full diff: https://github.com/klauspost/compress/compare/v1.18.3...v1.18.4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-27 15:23:55 +01:00
Sebastiaan van Stijn 5c498778ec vendor: go.opentelemetry.io/contrib v0.65.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-27 15:20:49 +01:00
Sebastiaan van Stijn fbd0e7f7c4 vendor: go.opentelemetry.io/otel v1.40.0
Includes fixes for [GHSA-9h8m-3fm2-qjrq] / [CVE-2026-24051] on macOS

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-27 15:16:34 +01:00
dependabot[bot]andGitHub 95a5a9e709 build(deps): bump actions/upload-artifact from 6 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-27 08:42:37 +00:00
Sebastiaan van StijnandGitHub 419e5d136c Merge pull request #6813 from dvdksn/fix-link-to-redirect
chore: use canonical url for buildx build cli doc
2026-02-23 17:58:13 +01:00
David Karlsson a7b95f228f chore: use canonical url for buildx build cli doc
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2026-02-23 17:39:19 +01:00
Sebastiaan van Stijn 13c993f101 cli/compose/loader: merge: use errors.Join
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-20 00:10:22 +01:00
Sebastiaan van Stijn 8b6f23d18b cli/compose/loader: remove some wrapper utilities
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-20 00:09:23 +01:00
Sebastiaan van StijnandGitHub d62b88939b Merge pull request #6803 from thaJeztah/compose_fixes
cli/compose: assorted fixes and cleanups
2026-02-19 23:00:44 +01:00
Sebastiaan van Stijn b35a2d0837 cli/compose/loader: remove getLoggingDriver
Inline it in mergeLoggingConfig and add some vars, which also
makes it more readable.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-19 22:48:39 +01:00
Sebastiaan van Stijn 42a211162c cli/compose/loader: mergeServices: inline mapByName
It's now only used once; let's inline it to remove some abstraction.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-19 22:48:38 +01:00
Sebastiaan van Stijn 6e1393089b cli/compose/loader: mergeServices: remove intermediate map for overrides
The code was using an intermediate map, indexed by name, for services
per file. Service-names should be unique per-file, so using an intermediate
map would not benefit us (we'd still have to loop over all of them to
produce the map, and again to iterate over the map)

Remove the intermediate map for overrides, and apply all overrides for
a service instead.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-19 22:45:41 +01:00
Sebastiaan van Stijn 78458e11e1 cli/compose/loader: mergeServices: tidy up and modernize
- construct merge-opts as a slice
- remove intermediate var for overrideServices
- use slices.SortFunc for sorting

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-19 22:45:08 +01:00
Sebastiaan van Stijn 09cf89e82e cli/compose/convert: convertEndpointSpec: fix sorting of ports
The existing code only sorted by PublishedPort (host port), and did
not account for multiple ports mapped to the same host-port, but
using a different protocol.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-19 22:45:08 +01:00
Sebastiaan van Stijn db28780976 cli/compose/convert: convertUlimits: modernize
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-19 22:45:05 +01:00
Derek Misler 830d05d16e error-hooks approach
Signed-off-by: Derek Misler <derek.misler@docker.com>
2026-02-19 10:07:57 -05:00
Derek Misler 9bc18993a4 Fix: run plugin hooks on command failure, not just success
Signed-off-by: Derek Misler <derek.misler@docker.com>
2026-02-19 10:07:57 -05:00
Sebastiaan van StijnandGitHub 44ca067062 Merge pull request #6807 from thaJeztah/less_streamformatter
remove redundant uses of streamformatter in tests
2026-02-19 14:32:57 +01:00
Sebastiaan van Stijn fdebf0afae cli/command/container: fix some unhandled errors in test
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-19 09:42:01 +01:00
Sebastiaan van Stijn e47a5c7734 remove redundant uses of streamformatter in tests
The output of this was not used in the tests, and shouldn't be
needed as part of it.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-19 09:41:17 +01:00
Sebastiaan van StijnandGitHub 63158f7ede Merge pull request #6801 from thaJeztah/no_no_netgo
scripts/build/.variables: don't use "netgo" when building Windows binaries
2026-02-16 20:52:31 +01:00
Sebastiaan van Stijn 2fa6b736d0 scripts/build/.variables: don't use "netgo" when building Windows binaries
commit 880ef756b7 fixed static builds with
CGO, which included setting the `netgo` build-tag for static builds.

Starting with go1.19, the Go runtime on Windows now supports the `netgo` build-
flag to use a native Go DNS resolver. Prior to that version, the build-flag
only had an effect on non-Windows platforms. From the go1.19 release notes:
https://go.dev/doc/go1.19#net

> Resolver.PreferGo is now implemented on Windows and Plan 9. It previously
> only worked on Unix platforms. Combined with Dialer.Resolver and Resolver.Dial,
> it's now possible to write portable programs and be in control of all DNS name
> lookups when dialing.
>
> The net package now has initial support for the netgo build tag on Windows.
> When used, the package uses the Go DNS client (as used by Resolver.PreferGo)
> instead of asking Windows for DNS results. The upstream DNS server it discovers
> from Windows may not yet be correct with complex system network configurations,
> however.

This originally caused issues in the daemon, because the pure-go implementation
did not respect file-based resolution (`C:\Windows\System32\Drivers\etc\hosts`),
resulting in `localhost` not being resolvable, and custom entries in `.etc/hosts`
not being used.

That specific problem was resolved in go1.22 (through [golang/go@33d4a51]), but
other limitations may still apply, and resolver ordering may not respect VPN
adaptors (such as Twingate) and queries sent through the local network adapter
instead of the VPN tunnel, resulting in DNS resolution failures;

    Get "https://example.com:2376/v1.52/containers/json": dial tcp: lookup example.com: i/o timeout

This patch unsets the `netgo` option when (cross-)compiling for Windows, similar
to the patch used for the daemon (see [moby/moby@53d1b12]).

[golang/go@33d4a51]: https://github.com/golang/go/commit/33d4a5105cf2b2d549922e909e9239a48b8cefcc
[moby/moby@53d1b12]: https://github.com/moby/moby/commit/53d1b12bc014b4243e9439fc2610eb4ef863659f

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-14 14:42:55 +01:00
Sebastiaan van StijnandGitHub 7b93d61673 Merge pull request #6790 from thaJeztah/bump_x_deps
vendor: update golang.org/x/* dependencies
2026-02-13 13:30:07 +01:00
Sebastiaan van StijnandGitHub fbb9cb3d73 Merge pull request #6797 from thaJeztah/login_stdin_refactor
cli/command/registry: refactor reading from stdin
2026-02-13 13:28:57 +01:00
Paweł GronowskiandGitHub 49eae5c613 Merge pull request #6798 from vvoland/issues-sbxs
github/issues: Add links for Docker Desktop and Sandboxes
2026-02-12 15:46:14 +00:00
Sebastiaan van Stijn 61f03db682 cli/command/registry: refactor reading from stdin
Extract the code as a utility function, and add some GoDoc to
describe the behavior.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-12 14:43:22 +01:00
Paweł Gronowski 74d4554ccd github/issues: Add emojis
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-02-12 14:38:16 +01:00
Paweł Gronowski 2ebd137abc github/issues: Add links for Docker Desktop and Sandboxes
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-02-12 14:38:07 +01:00
Sebastiaan van StijnandGitHub 63ba295ba4 Merge pull request #6788 from thaJeztah/bump_alpine
Dockerfile: update alpine to 3.23
2026-02-12 14:07:57 +01:00
Sebastiaan van StijnandGitHub 2d194dcf5a Merge pull request #6789 from thaJeztah/bump_golangci_lint
Dockerfile: update golangci-lint to v2.9.0 and fix linting
2026-02-12 14:07:29 +01:00
Sebastiaan van StijnandGitHub 9a41c733c4 Merge pull request #6796 from thaJeztah/login_cleanup_tests
cli/command/registry: remove uses of "gotest.tools/v3/fs"
2026-02-12 14:04:16 +01:00
Sebastiaan van Stijn f5b6055bd1 cli/command/registry: add unit test for --password-stdin
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-12 12:51:54 +01:00
Sebastiaan van Stijn b82e30e58d cli/command/registry: remove uses of "gotest.tools/v3/fs"
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-12 12:37:02 +01:00
Sebastiaan van StijnandGitHub e30ce84dfe Merge pull request #6793 from thaJeztah/update_e2e
e2e: use docker v29.x dind as default
2026-02-11 17:17:23 +01:00
Sebastiaan van StijnandGitHub 3d62a7c806 Merge pull request #6791 from thaJeztah/modernize
modernize: various cleanups
2026-02-11 16:41:36 +01:00
Sebastiaan van Stijn c4fd2406e0 e2e: use docker v29.x dind as default
Also remove groupadd which looks to be redundant now.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 15:52:01 +01:00
Sebastiaan van Stijn fddfe63ef9 modernize: fmtappendf
go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
    modernize -fmtappendf -fix ./...

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 13:38:38 +01:00
Sebastiaan van Stijn 6d4b3b5f66 modernize: slicescontains
go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
    modernize -slicescontains -fix ./...

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 13:35:26 +01:00
Sebastiaan van Stijn 835d510b78 modernize: stringsseq
go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
    modernize -stringsseq -fix ./...

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 13:31:11 +01:00
Sebastiaan van Stijn dd73e2df77 modernize: reflecttypefor
go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
    modernize -reflecttypefor -fix ./...

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 13:19:10 +01:00
Sebastiaan van Stijn 7f5bb1e99c modernize: testingcontext
go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
    modernize -testingcontext -fix ./...

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 13:17:36 +01:00
Sebastiaan van Stijn 2875e48024 modernize: stringscut
go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
    modernize -stringscut -fix ./...

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 13:16:13 +01:00
Sebastiaan van Stijn 4c7d40cf77 modernize: mapsloop
go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
    modernize -mapsloop -fix ./...

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 13:14:37 +01:00
Sebastiaan van Stijn 85ebca52fd modernize: minmax
go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
    modernize -minmax -fix ./...

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 13:08:46 +01:00
Sebastiaan van Stijn e8dc2fce32 modernize: rangeint
go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
    modernize -rangeint -fix ./...

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 13:07:01 +01:00
Sebastiaan van Stijn e4f6019e62 vendor: golang.org/x/net v0.50.0
full diff: https://cs.opensource.google/go/x/net/+/refs/tags/v0.49.0...refs/tags/v0.50.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 12:38:03 +01:00
Sebastiaan van Stijn 464e14c68e vendor: golang.org/x/term v0.40.0
full diff: https://cs.opensource.google/go/x/term/+/refs/tags/v0.39.0...refs/tags/v0.40.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 12:36:59 +01:00
Sebastiaan van Stijn 1e31c2825e vendor: golang.org/x/text v0.34.0
full diff: https://cs.opensource.google/go/x/text/+/refs/tags/v0.33.0...refs/tags/v0.34.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 12:36:12 +01:00
Sebastiaan van Stijn 355f7bb602 vendor: golang.org/x/sys v0.41.0
full diff: https://cs.opensource.google/go/x/sys/+/refs/tags/v0.40.0...refs/tags/v0.41.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 12:35:22 +01:00
Sebastiaan van Stijn a934c75de7 Dockerfile: update golangci-lint to v2.9.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 11:30:26 +01:00
Sebastiaan van Stijn ab06aebd4b internal/volumespec: fix prealloc linting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 11:30:26 +01:00
Sebastiaan van Stijn 9a0c78fdc0 cli-plugins/manager: fix prealloc linting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 11:30:26 +01:00
Sebastiaan van Stijn 2e544d6308 cli/command: fix prealloc linting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 11:30:26 +01:00
Sebastiaan van Stijn 12a0b0b7b9 cli/compose: fix prealloc linting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 11:30:26 +01:00
Sebastiaan van Stijn 99cef6f700 opts: fix prealloc linting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 11:30:25 +01:00
Sebastiaan van Stijn 8a8a3e1309 opts/swarmopts: fix prealloc linting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 11:30:25 +01:00
Sebastiaan van Stijn 9d2816c8a5 remove outdated "nolint" comments
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 11:30:25 +01:00
Sebastiaan van Stijn eaba9ecf18 cli/connhelper/ssh: remove outdated "nolint" comment
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-11 11:30:25 +01:00
Paweł GronowskiandGitHub 3e466c88e1 Merge pull request #6787 from thaJeztah/fix_vol_prune_example
docs: fix docker volume prune example
2026-02-11 10:24:13 +00:00
Sebastiaan van Stijn 1f6b319d60 Dockerfile: update alpine to 3.23
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-10 20:41:08 +01:00
Sebastiaan van Stijn b598f8f0b8 docs: fix docker volume prune example
It doesn't remove named volumes by default.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-10 19:11:12 +01:00
Sebastiaan van StijnandGitHub df016a3a95 Merge pull request #6785 from thaJeztah/docs_fixes
docs: fix typos
2026-02-09 19:17:31 +01:00
Sebastiaan van Stijn 5eb91665d1 docs: fix typos
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-08 18:10:21 +01:00
Sebastiaan van StijnandGitHub 727bc3ea5b Merge pull request #6776 from whyvineet/fix-typo
docs: fix typo in dockerd.md for 'replacement'
2026-02-05 14:03:50 +01:00
Sebastiaan van StijnandGitHub b0e1e0995d Merge pull request #6781 from thaJeztah/bake_use_dockerfile_defaults
docker-bake.hcl: use default GO_VERSION from Dockerfile
2026-02-05 13:47:09 +01:00
Sebastiaan van Stijn d6c6bbf574 docker-bake.hcl: use default GO_VERSION from Dockerfile
Use the defaults as specified in the Dockerfile, unless set;
https://docs.docker.com/build/bake/reference/#variable

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-05 13:22:56 +01:00
Sebastiaan van StijnandGitHub 7de3e08796 Merge pull request #6780 from thaJeztah/bump_go1.25.7
update to go1.25.7
2026-02-05 13:08:23 +01:00
Sebastiaan van Stijn 2d5d0842c5 update to go1.25.7
go1.25.7 (released 2026-02-04) includes security fixes to the go command
and the crypto/tls package, as well as bug fixes to the compiler and the
crypto/x509 package. See the Go 1.25.7 milestone on our issue tracker for
details:
https://github.com/golang/go/issues?q=milestone%3AGo1.25.7+label%3ACherryPickApproved

full diff: https://github.com/golang/go/compare/go1.25.6...go1.25.7

From the security mailing list:

> Hello gophers,
>
> We have just released Go versions 1.25.7 and 1.24.13, minor point releases.
>
> These releases include 2 security fixes following the security policy:
>
> - cmd/cgo: remove user-content from doc strings in cgo ASTs
>
>   A discrepancy between how Go and C/C++ comments
>   were parsed allowed for code smuggling into the
>   resulting cgo binary.
>
>   To prevent this behavior, the cgo compiler
>   will no longer parse user-provided doc
>   comments.
>
>   Thank you to RyotaK (https://ryotak.net) of
>   GMO Flatt Security Inc. for reporting this issue.
>
>   This is CVE-2025-61732 and https://go.dev/issue/76697.
>
> - crypto/tls: unexpected session resumption when using Config.GetConfigForClient
>
>   Config.GetConfigForClient is documented to use the original Config's session
>   ticket keys unless explicitly overridden. This can cause unexpected behavior if
>   the returned Config modifies authentication parameters, like ClientCAs: a
>   connection initially established with the parent (or a sibling) Config can be
>   resumed, bypassing the modified authentication requirements.
>
>   If ClientAuth is VerifyClientCertIfGiven or RequireAndVerifyClientCert (on the
>   server) or InsecureSkipVerify is false (on the client), crypto/tls now checks
>   that the root of the previously-verified chain is still in ClientCAs/RootCAs
>   when resuming a connection.
>
>   Go 1.26 Release Candidate 2, Go 1.25.6, and Go 1.24.12 had fixed a similar issue
>   related to session ticket keys being implicitly shared by Config.Clone. Since
>   this fix is broader, the Config.Clone behavior change has been reverted.
>
>   Note that VerifyPeerCertificate still behaves as documented: it does not apply
>   to resumed connections. Applications that use Config.GetConfigForClient or
>   Config.Clone and do not wish to blindly resume connections established with the
>   original Config must use VerifyConnection instead (or SetSessionTicketKeys or
>   SessionTicketsDisabled).
>
>   Thanks to Coia Prant (github.com/rbqvq) for reporting this issue.
>
>   This updates CVE-2025-68121 and Go issue https://go.dev/issue/77217.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-05 12:42:11 +01:00
Vineet Kumar def41fe652 docs: fix typo in dockerd.md for 'replacement'
Signed-off-by: Vineet Kumar <vineetkumar17112004@gmail.com>
2026-02-04 23:20:34 +05:30
Sebastiaan van StijnandGitHub 769e75a0ee Merge pull request #6775 from thaJeztah/bump_xx
Dockerfile: update tonistiigi/xx to v1.9.0
2026-02-04 14:13:33 +01:00
Sebastiaan van Stijn 58413ca113 Dockerfile: update tonistiigi/xx to v1.9.0
full diff: https://github.com/tonistiigi/xx/compare/v1.7.0...v1.9.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-04 12:50:49 +01:00
Paweł GronowskiandGitHub a5c7197d72 Merge pull request #6772 from thaJeztah/cleanup_testfile
cli/command: TestGetDefaultAuthConfig: cleanup test file
2026-02-02 16:33:58 +00:00
Paweł GronowskiandGitHub 435384fa29 Merge pull request #6773 from thaJeztah/improve_mountopts
opts: MountOpt: improve validation, and refactor
2026-02-02 16:22:36 +00:00
Sebastiaan van Stijn df3e9237d7 opts: MountOpt: extract utility functions and don't set empty values
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-02 16:51:51 +01:00
Sebastiaan van Stijn d781df8b53 opts: MountOpt: extract validation to a separate function
This splits the validation code from parsing code, potentially allowing
us to either fully deferring it to the daemon, or to perform validation
separately.

For reference; daemon-side validation currently (docker 29.2.0) produces;

    docker run --rm --mount type=bind,src=/var/run,target=/foo,bind-recursive=writable alpine
    docker: Error response from daemon: mount options conflict: !ReadOnly && BindOptions.ReadOnlyNonRecursive

    docker run --rm --mount type=bind,src=/var/run,target=/foo,bind-recursive=readonly alpine
    docker: Error response from daemon: mount options conflict: !ReadOnly && BindOptions.ReadOnlyForceRecursive

Validation for BindOptions.Propagation is currently missing on the daemon;

    docker run --rm --mount type=bind,src=/var/run,target=/foo,bind-recursive=readonly,readonly alpine
    # no error

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-02 16:51:41 +01:00
Sebastiaan van Stijn f35fb0f5a6 cli/command: TestGetDefaultAuthConfig: cleanup test file
Prevent a `cli/command/filename` file being left behind after running tests.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-02 16:06:52 +01:00
Sebastiaan van Stijn fe1af9206c opts: MountOpt: improve validation of boolean values
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-02 15:29:23 +01:00
Sebastiaan van Stijn 5de99e6726 opts: MountOpt: improve validation for whitespace in values
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-02 15:29:22 +01:00
Sebastiaan van Stijn 9620e4178d opts: MountOpt: improve validation for whitespace in options
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-02 15:29:22 +01:00
Sebastiaan van Stijn e888a6e009 opts: remove outdated comment
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-02 15:29:20 +01:00
Paweł GronowskiandGitHub b22f1aef48 Merge pull request #6771 from thaJeztah/allow_empty_target
opts: MountOpt: relax client-side validation of mount target
2026-02-02 14:15:52 +00:00
Sebastiaan van Stijn bcc14559c9 opts: MountOpt: relax client-side validation of mount target
The daemon already validates the target, so we don't have to validate
if a target is set. Instead, we can ignore empty targets, but produce
an error if a target option was set, but set to an empty value.

With this patch applied, omitting a target option is ignored by the CLI,
but still invalidated by the daemon if the given mount-type requires a
mount target;

    docker run --rm --mount type=bind,src=/var/run/docker.sock alpine
    docker: Error response from daemon: invalid mount config for type "bind": field Target must not be empty

    docker run --rm --mount type=bind,src=/var/run/docker.sock,dst=../foo alpine
    docker: Error response from daemon: invalid mount config for type "bind": invalid mount path: '../foo' mount path must be absolute

When passing a target option (`target`, `dst`, or `destination`), the
CLI produces an error if the value is empty;

    docker run --rm --mount type=bind,src=/var/run/docker.sock,dst= alpine
    invalid argument "type=bind,src=/var/run/docker.sock,dst=" for "--mount" flag: invalid value for 'dst': mount target must be a non-empty value

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-02 15:05:44 +01:00
Paweł GronowskiandGitHub ffd9b407f5 Merge pull request #6770 from thaJeztah/validate_empty
opts: MountOpt: improve error for empty value
2026-02-02 13:13:28 +00:00
Sebastiaan van Stijn defbe23deb opts: MountOpt: improve error for empty value
Before this patch:

    docker run --rm --mount "" busybox
    invalid argument "" for "--mount" flag: EOF

With this patch:

    docker run --rm --mount "" busybox
    invalid argument "" for "--mount" flag: value is empty

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-02 12:28:09 +01:00
Sebastiaan van StijnandGitHub 028eee55fa Merge pull request #6768 from thaJeztah/improve_mountopts_tests
opts: improve and cleanup MountOpt tests
2026-02-02 12:14:43 +01:00
Sebastiaan van Stijn 77e02a92ec opts: MountOpt: add test-coverage for volume options
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-01 15:57:02 +01:00
Sebastiaan van Stijn 2c8bf677f0 opts: MountOpt: remove duplicate test
Setting the source and target paths is not tied to the mount-type,
so these tests where covering the same code.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-01 15:57:02 +01:00
Sebastiaan van Stijn 7ebc2f7c21 opts: MountOpt: rewrite TestMountOptVolumeNoCopy to a table-test
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-01 15:56:58 +01:00
Sebastiaan van Stijn a850b054a8 opts: MountOpt: rewrite TestMountOptDefaultEnableReadOnly to a table-test
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-01 15:56:32 +01:00
Sebastiaan van Stijn f3efc27a1a opts: MountOpt: combine error tests into a test-table
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-01 15:52:33 +01:00
Sebastiaan van StijnandGitHub 0b9d1985db Merge pull request #6764 from vvoland/update-docker
vendor: github.com/moby/moby/api v1.53.0 & github.com/moby/moby/client v0.2.2
2026-01-26 20:20:51 +01:00
Paweł Gronowski 9c9ec73588 vendor: github.com/moby/moby/client v0.2.2
full diff: https://github.com/moby/moby/client/compare/v0.2.2-rc.2...v0.2.2

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-01-26 20:15:30 +01:00
Paweł Gronowski bab3e81e1d vendor: github.com/moby/moby/api v1.53.0
full diff: https://github.com/moby/moby/api/compare/v1.53.0-rc.2...v1.53.0

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-01-26 20:15:02 +01:00
Paweł GronowskiandGitHub 2e64fc162a Merge pull request #6367 from thaJeztah/template_slicejoin
templates: make "join" work with non-string slices and map values
2026-01-26 18:03:25 +00:00
Paweł GronowskiandGitHub 1f2ba2ac9d Merge pull request #6760 from thaJeztah/container_create_fix_error
cli/command/container: make injecting config.json failures a warning
2026-01-26 17:44:42 +00:00
Sebastiaan van Stijn e34a3422cc templates: make "join" work with non-string slices and map values
Add a custom join function that allows for non-string slices to be
joined, following the same rules as "fmt.Sprint", it will use the
fmt.Stringer interface if implemented, or "error" if the type has
an "Error()".

For maps, it joins the map-values, for example:

    docker image inspect --format '{{join .Config.Labels ", "}}' ubuntu
    24.04, ubuntu

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-26 18:35:58 +01:00
Paweł GronowskiandGitHub a86356d42f Merge pull request #6763 from thaJeztah/bump_mapstructure
vendor: github.com/go-viper/mapstructure/v2 v2.5.0
2026-01-26 17:21:29 +00:00
Sebastiaan van Stijn 771660a17e vendor: github.com/go-viper/mapstructure/v2 v2.5.0
full diff: https://github.com/go-viper/mapstructure/compare/v2.4.0...v2.5.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-26 12:32:10 +01:00
Sebastiaan van StijnandGitHub 9cff36b35a Merge pull request #6762 from thaJeztah/bump_x_deps
vendor: update golang.org/x/xxx deps
2026-01-26 12:28:34 +01:00
Sebastiaan van Stijn 08ed2bc6e8 cli/command/container: make injecting config.json failures a warning
Prior to 1a502e91c9, failing to write the
container-ID to a file would return an error. After that change, we could
end up in a situation where the container was created successfully, but
we failed to inject the `config.json`. This failure would be returned as
an error, but the container was created (but no ID returned due to the error).

This patch changes the error to a warning; while not "ideal" (the container
is created, but in a "partial" state), we also shouldn't consider it to be
a hard failure; proceed as normal, to allow the user to either use the
container as-is, or to delete the container and try again.

Alternatively, we could join these errors, but the result will be ambiguous
in either case (container created, but an error occurred after the fact).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-26 12:11:35 +01:00
Sebastiaan van StijnandGitHub 0312e3d379 Merge pull request #6761 from thaJeztah/bump_compress
vendor: github.com/klauspost/compress v1.18.3
2026-01-26 12:07:38 +01:00
Sebastiaan van Stijn e9ceb2f5ad vendor: golang.org/x/net v0.49.0
full diff: https://cs.opensource.google/go/x/net/+/refs/tags/v0.48.0...refs/tags/v0.49.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-26 11:30:51 +01:00
Sebastiaan van Stijn faf8a0836e vendor: golang.org/x/term v0.39.0
full diff: https://cs.opensource.google/go/x/term/+/refs/tags/v0.38.0...refs/tags/v0.39.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-26 11:29:34 +01:00
Sebastiaan van Stijn daa4d4e4aa vendor: golang.org/x/text v0.33.0
full diff: https://cs.opensource.google/go/x/text/+/refs/tags/v0.32.0...refs/tags/v0.33.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-26 11:28:39 +01:00
Sebastiaan van Stijn a4aee9bf54 vendor: golang.org/x/sys v0.40.0
full diff: https://cs.opensource.google/go/x/sys/+/refs/tags/v0.39.0...refs/tags/v0.40.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-26 11:27:40 +01:00
Paweł GronowskiandGitHub 9f774c370f Merge pull request #6759 from thaJeztah/container_create_cleanups
cli/command/container: create: assorted cleanups and linting fixes
2026-01-26 10:25:51 +00:00
Paweł GronowskiandGitHub d0838292e1 Merge pull request #6758 from thaJeztah/cidfile_error
cli/command/container: improve CID-file errors
2026-01-26 10:25:27 +00:00
Sebastiaan van Stijn ce489e0dbb vendor: github.com/klauspost/compress v1.18.3
no changes in vendored code

- fixes / downstream CVE-2025-61728

full diff: https://github.com/klauspost/compress/compare/v1.18.2...v1.18.3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-26 11:22:31 +01:00
Paweł GronowskiandGitHub 931f7a1f22 Merge pull request #6753 from thaJeztah/minor_nits
cli/command/containerd: parseSecurityOpts: remove redundant sprintf
2026-01-26 10:06:15 +00:00
Sebastiaan van Stijn ef08475961 cli/command/container: ignore "not found" error on cidfile.Close
Ignore errors when trying to remove a CID-file that no longer exists;
also remove the path from the custom error as os.Remove already returns
a os.PathError, which includes the path.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-26 09:24:08 +01:00
Sebastiaan van Stijn 16bbf5d07f cli/command/container: cidFile.Write: include CID in error message
Include the container-ID in the error message when failing to write
the ID to a file, so that the user can still find the ID of the container
that was created.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-26 09:02:32 +01:00
Sebastiaan van Stijn ed566e723f cli/command/container: createContainer: remove intermediate vars
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-24 14:33:06 +01:00
Sebastiaan van Stijn cfb71de7db cli/command/container: createContainer: remove redundant closure
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-24 14:17:05 +01:00
Sebastiaan van Stijn adfb40ceb1 cli/command/container: remove outdated TODO
This was addressed in 7bdb4df07d

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-24 14:16:06 +01:00
Sebastiaan van Stijn ceea57b46d cli/command/container: copyDockerConfigIntoContainer: close TarWriter
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-24 14:16:05 +01:00
Sebastiaan van Stijn effdf1b452 cli/command/container: rename vars to use correct camelCase
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-24 14:15:57 +01:00
Mahesh Thakur 02dee5c2d2 Fix: Remove inconsistent human readability warning from docker images
Signed-off-by: Mahesh Thakur <maheshthakur9152@gmail.com>
2026-01-23 08:12:21 +05:30
Sebastiaan van Stijn ccbe206a8c cli/command/containerd: parseSecurityOpts: remove redundant sprintf
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-22 10:26:54 +01:00
Paweł GronowskiandGitHub d5ed037320 Merge pull request #6736 from thaJeztah/bump_modules
vendor: moby/api v1.53.0-rc.2, moby/client v0.2.2-rc.2
2026-01-19 12:00:25 +00:00
Sebastiaan van Stijn c8841ac1b2 vendor: moby/api v1.53.0-rc.2, moby/client v0.2.2-rc.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-19 12:55:39 +01:00
Paweł GronowskiandGitHub 714f5bfae4 Merge pull request #6744 from thaJeztah/registryclient_cleanups
internal/registryclient: minor cleanups
2026-01-16 11:33:23 +00:00
Paweł GronowskiandGitHub 49b7be0146 Merge pull request #6745 from thaJeztah/cleanup_RetrieveAuthTokenFromImage
cli/command: RetrieveAuthTokenFromImage: remove redundant conditions
2026-01-16 11:33:02 +00:00
Sebastiaan van StijnandGitHub 533934c063 Merge pull request #6750 from vvoland/update-go
update to go1.25.6
2026-01-16 10:00:51 +01:00
Paweł Gronowski 7e8457115b update to go1.25.6
This releases includes 6 security fixes following the security policy:

- archive/zip: denial of service when parsing arbitrary ZIP archives

    archive/zip used a super-linear file name indexing algorithm that is invoked the first time a file in an archive is opened. This can lead to a denial of service when consuming a maliciously constructed ZIP archive.

    Thanks to Thanks to Jakub Ciolek for reporting this issue.

    This is CVE-2025-61728 and Go issue https://go.dev/issue/77102.

- net/http: memory exhaustion in Request.ParseForm

    When parsing a URL-encoded form net/http may allocate an unexpected amount of
    memory when provided a large number of key-value pairs. This can result in a
    denial of service due to memory exhaustion.

    Thanks to jub0bs for reporting this issue.

    This is CVE-2025-61726 and Go issue https://go.dev/issue/77101.

- crypto/tls: Config.Clone copies automatically generated session ticket keys, session resumption does not account for the expiration of full certificate chain

    The Config.Clone methods allows cloning a Config which has already been passed
    to a TLS function, allowing it to be mutated and reused.

    If Config.SessionTicketKey has not been set, and Config.SetSessionTicketKeys has
    not been called, crypto/tls will generate random session ticket keys and
    automatically rotate them. Config.Clone would copy these automatically generated
    keys into the returned Config, meaning that the two Configs would share session
    ticket keys, allowing sessions created using one Config could be used to resume
    sessions with the other Config. This can allow clients to resume sessions even
    though the Config may be configured such that they should not be able to do so.

    Config.Clone no longer copies the automatically generated session ticket keys.
    Config.Clone still copies keys which are explicitly provided, either by setting
    Config.SessionTicketKey or by calling Config.SetSessionTicketKeys.

    This issue was discoverd by the Go Security team while investigating another
    issue reported by Coia Prant (github.com/rbqvq).

    Additionally, on the server side only the expiration of the leaf certificate, if
    one was provided during the initial handshake, was checked when considering if a
    session could be resumed. This allowed sessions to be resumed if an intermediate
    or root certificate in the chain had expired.

    Session resumption now takes into account of the full chain when determining if
    the session can be resumed.

    Thanks to Coia Prant (github.com/rbqvq) for reporting this issue.

    This is CVE-2025-68121 and Go issue https://go.dev/issue/77113.

- cmd/go: bypass of flag sanitization can lead to arbitrary code execution

    Usage of 'CgoPkgConfig' allowed execution of the pkg-config
    binary with flags that are not explicitly safe-listed.

    To prevent this behavior, compiler flags resulting from usage
    of 'CgoPkgConfig' are sanitized prior to invoking pkg-config.

    Thank you to RyotaK (https://ryotak.net) of GMO Flatt Security Inc.
    for reporting this issue.

    This is CVE-2025-61731 and go.dev/issue/77100.

- cmd/go: unexpected code execution when invoking toolchain

    The Go toolchain supports multiple VCS which are used retrieving modules and
    embedding build information into binaries.

    On systems with Mercurial installed (hg) downloading modules (e.g. via go get or
    go mod download) from non-standard sources (e.g. custom domains) can cause
    unexpected code execution due to how external VCS commands are constructed.

    On systems with Git installed, downloading and building modules with malicious
    version strings could allow an attacker to write to arbitrary files on the
    system the user has access to. This can only be triggered by explicitly
    providing the malicious version strings to the toolchain, and does not affect
    usage of @latest or bare module paths.

    The toolchain now uses safer VCS options to prevent misinterpretation of
    untrusted inputs. In addition, the toolchain now disallows module version
    strings prefixed with a "-" or "/" character.

    Thanks to splitline (@splitline) from DEVCORE Research Team for reporting this
    issue.

    This is CVE-2025-68119 and Go issue https://go.dev/issue/77099.

- crypto/tls: handshake messages may be processed at the incorrect encryption level

    During the TLS 1.3 handshake if multiple messages are sent in records that span
    encryption level boundaries (for instance the Client Hello and Encrypted
    Extensions messages), the subsequent messages may be processed before the
    encryption level changes. This can cause some minor information disclosure if a
    network-local attacker can inject messages during the handshake.

    Thanks to Coia Prant (github.com/rbqvq) for reporting this issue.

    This is CVE-2025-61730 and Go issue https://go.dev/issue/76443

View the release notes for more information:
https://go.dev/doc/devel/release#go1.25.6

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-01-16 09:46:08 +01:00
Sebastiaan van StijnandGitHub 7d2d923a5f Merge pull request #6746 from thaJeztah/bump_logrus
vendor: github.com/sirupsen/logrus v1.9.4
2026-01-15 18:07:25 +01:00
Paweł GronowskiandGitHub 560c3c8fa3 Merge pull request #6747 from vvoland/daemon-typo
docs: Fix daemon.json typo
2026-01-15 13:20:51 +00:00
Paweł Gronowski 86bd884ac7 docs: Fix daemon.json typo
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-01-15 12:50:14 +01:00
Sebastiaan van StijnandGitHub 5579335b82 Merge pull request #6295 from thaJeztah/less_jsonmessage
internal/jsonstream: TestDisplay use streamformatter
2026-01-15 12:10:19 +01:00
Sebastiaan van Stijn 16873675bd vendor: github.com/sirupsen/logrus v1.9.4
Notable changes:

- go.mod: update minimum supported go version to v1.17.
- go.mod: bump up dependencies.
- Touch-up godoc and add "doc" links.
- README: fix links, grammar, and update examples.
- Add GNU/Hurd support.
- Add WASI wasip1 support.
- Remove uses of deprecated `ioutil` package.
- CI: update actions and golangci-lint.
- CI: remove appveyor, add macOS.

full diff: https://github.com/sirupsen/logrus/compare/v1.9.3...v1.9.4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-15 11:45:03 +01:00
Sebastiaan van Stijn b21139c30f internal/jsonstream: TestDisplay use streamformatter
Similar to 69854c4e08, but for the
internal/jsonstream package.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-15 01:38:24 +01:00
Sebastiaan van Stijn d6cdb71e2b cli/command: RetrieveAuthTokenFromImage: remove redundant conditions
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-15 00:45:50 +01:00
Sebastiaan van StijnandGitHub 32b983a26e Merge pull request #6089 from thaJeztah/man_wrap
man: reformat docker-run.1.md to prevent linting warnings
2026-01-15 00:26:43 +01:00
Sebastiaan van Stijn b13b774e24 man: reformat docker-run.1.md to prevent linting warnings
Before this patch, lintian would complain about some lines being too long:

    lintian ./*.deb
    ...
    W: docker-ce-cli: groff-message troff:<standard input>:642: warning [p 8, 10.2i, div '3tbd1,1', 0.0i]: cannot break line [usr/share/man/man1/docker-run.1.gz:1]

    groff -t -man ./docker-run.1 > /dev/null
    troff:./docker-run.1:602: warning [p 9, 2.8i]: cannot adjust line
    troff:./docker-run.1:669: warning [p 10, 2.5i, div '3tbd1,1', 0.0i]: cannot break line

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-15 00:16:14 +01:00
Sebastiaan van Stijn 816f4556ce internal/registryclient: simplify notFoundError
- remove constructor
- fix mixed pointer/non-pointer receivers
- just embed the error we want to produce

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-15 00:06:14 +01:00
Sebastiaan van Stijn d61519f99c internal/registryclient: allEndpoints: pass through context
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-15 00:06:08 +01:00
Sebastiaan van StijnandGitHub b43d4d8e7f Merge pull request #6742 from thaJeztah/validate_detachkeys
improve validation of "--detach-keys" options
2026-01-14 23:56:07 +01:00
Sebastiaan van Stijn fe3157419c improve validation of "--detach-keys" options
Before this change, the detach-keys were not validated, and the code either
fell back to the default sequence, or returned an obscure error if the
invalid sequence would produce an error on the daemon;

Before this patch:

    docker run -it --rm --detach-keys=shift-a,b busybox
    unable to upgrade to tcp, received 400

With this patch:

    docker run -it --rm --detach-keys=shift-a,b busybox
    invalid detach keys (shift-a,b): Unknown character: 'shift-a'

Note that the "unable to upgrade to tcp, received 400" error is still
something to be looked into; the client currently discards error messages
coming from the daemon.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-14 16:57:38 +01:00
Sebastiaan van StijnandGitHub 8f50791fef Merge pull request #6740 from thaJeztah/add_WithAPIClientOptions
cli/command: add WithAPIClientOptions option
2026-01-14 09:46:57 +01:00
Sebastiaan van Stijn 6a93e78038 cli/command: add WithAPIClientOptions option
This option allows setting custom options to use when constructing
the API client.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-13 16:31:58 +01:00
Sebastiaan van StijnandGitHub 07d7ef19f3 Merge pull request #6738 from thaJeztah/fix_TestSetGoDebug
cli/command: make TestSetGoDebug more predictable
2026-01-13 16:27:35 +01:00
Sebastiaan van StijnandGitHub 6050e2bff9 Merge pull request #6741 from thaJeztah/fix_err_grammar
login: touch-up error for non-TTY
2026-01-13 16:27:01 +01:00
Sebastiaan van StijnandGitHub 5d22eaae4b Merge pull request #6739 from thaJeztah/client_opts
cli/command: DockerCli: store API-client options as field
2026-01-13 16:18:57 +01:00
Sebastiaan van Stijn db762956d1 login: touch-up error for non-TTY
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-13 15:44:04 +01:00
Sebastiaan van Stijn 4b0ec0d4ea cli/command: DockerCli: store API-client options as field
Use a more generic "clientOptions" field to store options to apply
when constructing the API client, instead of a dedicated field for
user-agent.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-13 14:48:17 +01:00
Sebastiaan van Stijn f9f2d822b9 cli/command: make TestSetGoDebug more predictable
Prevent the test from failing if GODEBUG is set in the current
environment.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-13 14:24:33 +01:00
Paweł GronowskiandGitHub bd1b1a1590 Merge pull request #6735 from thaJeztah/bump_creds_helper
vendor: github.com/docker/docker-credential-helpers v0.9.5
2026-01-12 15:09:58 +00:00
Sebastiaan van StijnandGitHub bea585067e Merge pull request #6602 from ahopp/improve-env-vars-description
Improve clarity of environment variables description
2026-01-12 13:01:58 +01:00
Andrew HoppandSebastiaan van Stijn 391acef40f Improve clarity of environment variables description
Changed the environment variables section description from:
"The following list of environment variables are supported by the `docker` command line:"

To:
"The following environment variables control the behavior of the `docker` command-line client:"

This makes it clearer that these variables control Docker's behavior, and uses the more precise term "command-line client" instead of "command line".

Signed-off-by: Andrew Hopp <andrew.hopp@me.com>
2026-01-12 11:20:18 +01:00
Sebastiaan van Stijn a6f8391c9f vendor: github.com/docker/docker-credential-helpers v0.9.5
no code changes; full diff:

https://github.com/docker/docker-credential-helpers/compare/v0.9.4...v0.9.5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-08 18:05:14 +01:00
Sebastiaan van StijnandGitHub debbf2d4f9 Merge pull request #6723 from thaJeztah/bump_go_archive
vendor: github.com/moby/go-archive v0.2.0
2026-01-07 11:09:39 +01:00
Sebastiaan van StijnandGitHub ee0951f0e7 Merge pull request #6724 from thaJeztah/bump_x_deps
vendor: update golang.org/x/xxx dependencies
2026-01-07 11:08:15 +01:00
Paweł GronowskiandGitHub 31c58f18a5 Merge pull request #6725 from thaJeztah/test_denoise
gha: run unit-tests in go modules mode, to prevent traversing nested modules
2026-01-07 09:27:45 +00:00
Paweł GronowskiandGitHub 263562efa8 Merge pull request #6722 from thaJeztah/compose_reflectfor
cli/compose/loader: rewrite with reflect.TypeFor
2026-01-07 09:26:57 +00:00
Sebastiaan van Stijn 14cffdbfab gha: run unit-tests in go modules mode, to prevent traversing nested modules
`go list` expects a module to be valid, which means that dependencies must
either be vendored, or downloaded in the module cache. However, when working
in GOPATH mode, `go.mod` files are ignored, which means that `go list` will
traverse subdirectories, even if those are a separate module, and those modules
may not have their dependencies present.

In our case, we try to exclude those modules from paths to be tested, but
do so based on the _result_ of `go list`, which already produces errors before
we filter.

These errors do not impact out tests, as we don't run tests for those paths,
but do produce noise in CI, which can be confusing;

    go test -coverprofile=/tmp/coverage.txt $(go list ./... | grep -vE '/vendor/|/e2e/|/cmd/docker-trust')
    cmd/docker-trust/internal/trust/trust.go:28:2: cannot find package "github.com/theupdateframework/notary" in any of:
        /go/src/github.com/docker/cli/vendor/github.com/theupdateframework/notary (vendor tree)
        /usr/local/go/src/github.com/theupdateframework/notary (from $GOROOT)
        /go/src/github.com/theupdateframework/notary (from $GOPATH)
    cmd/docker-trust/internal/trust/trust.go:29:2: cannot find package "github.com/theupdateframework/notary/client" in any of:
        /go/src/github.com/docker/cli/vendor/github.com/theupdateframework/notary/client (vendor tree)
        /usr/local/go/src/github.com/theupdateframework/notary/client (from $GOROOT)
        /go/src/github.com/theupdateframework/notary/client (from $GOPATH)

This patch adds a symlink for `go.mod` and `go.sum`, so that listing the
packages happens in go modules mode, and doesn't traverse to other modules,
such as `cmd/docker-trust`.

- updates 06914dd0ff, which attempted to
  exclude the docker-trust plugin
- similar to cee9ea67fc, which made this
  change for the linter.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-24 12:47:59 +01:00
Sebastiaan van Stijn 0cd2c18580 vendor: golang.org/x/net v0.48.0
- trace: fix data race in RenderEvents
- http2, webdav, websocket: fix %q verb uses with wrong type
- http2: don't PING a responsive server when resetting a stream
- http2: support net/http.Transport.NewClientConn

full diff: https://github.com/golang/net/compare/v0.47.0...v0.48.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 22:55:24 +01:00
Sebastiaan van Stijn 647ab775d0 vendor: golang.org/x/term v0.38.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 22:55:15 +01:00
Sebastiaan van Stijn a1799eacdb vendor: golang.org/x/text v0.32.0
full diff: https://github.com/golang/text/compare/v0.31.0...v0.32.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 22:50:11 +01:00
Sebastiaan van Stijn a785333731 vendor: golang.org/x/sync v0.19.0
- errgroup: use consistent read for SetLimit panic

full diff: https://github.com/golang/sync/compare/v0.18.0...v0.19.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 22:49:12 +01:00
Sebastiaan van Stijn e2a368fa4b vendor: golang.org/x/sys v0.39.0
- Revert "cpu: add HPDS, LOR, PAN detection for arm64"
- unix: add IOCTL_MEI_* constants
- unix: fix definition of Statvfs_t for netbsd-arm

full diff: https://github.com/golang/sys/compare/v0.38.0...v0.39.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 22:48:28 +01:00
Sebastiaan van Stijn ab5d4d4f8c cli/compose/loader: rewrite with reflect.TypeFor
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 22:46:54 +01:00
Sebastiaan van StijnandGitHub 874b831c0e Merge pull request #6721 from thaJeztah/less_reflect
reduce some uses of reflect package
2025-12-23 18:42:00 +01:00
Sebastiaan van Stijn 3ce8f1d80c vendor: github.com/moby/go-archive v0.2.0
- remove aliases for deprecated types and functions
- chrootarchive: remove redundant "init" mitigation for CVE-2019-14271
- xattr: Fix OS matching

full diff: https://github.com/moby/go-archive/compare/v0.1.0...v0.2.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 18:11:31 +01:00
Sebastiaan van Stijn 8205124d5b cli/command/node: nodeContext: remove uses of reflect
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 17:54:52 +01:00
Sebastiaan van Stijn 40f052c7e1 cli/command/container: use reflect IsZero
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 17:17:12 +01:00
Sebastiaan van Stijn f28565d173 cli/command/service: replace reflect for gotest.tools assertion
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 17:17:05 +01:00
Sebastiaan van Stijn e715dd5076 cli/command/volume: remove uses of reflect in test
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 15:52:40 +01:00
Sebastiaan van Stijn 3811f24f47 cli/connhelper: replace reflect for gotest.tools assertion
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 15:52:39 +01:00
Sebastiaan van Stijn a89b2e19f5 cli/command/formatter: rewrite some tests with gotest.tools
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 15:52:39 +01:00
Sebastiaan van Stijn 90ae5b8136 cli/command: replace reflect for gotest.tools assertion
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 15:52:39 +01:00
Sebastiaan van StijnandGitHub d20f30c648 Merge pull request #6720 from thaJeztah/build_tags
opts/swarmopts: add missing build-tag
2025-12-23 13:15:25 +01:00
Sebastiaan van Stijn a0e303a0ed opts/swarmopts: add missing build-tag
This was introduced in 9c10a9c9ac, which added
use of the network.ParsePortRange.All method, which uses an iterator and
requires go1.23;

    opts/swarmopts/port.go:172:18: cannot range over pr.All() (value of func type iter.Seq[network.Port]): requires go1.23 or later (-lang was set to go1.16; check go.mod)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-23 12:17:17 +01:00
Sebastiaan van StijnandGitHub 0e38eec554 Merge pull request #6718 from thaJeztah/archive_rm_deprecated
remove uses of deprecated go-archive consts
2025-12-19 19:51:48 +01:00
Sebastiaan van Stijn 03dfab4013 remove uses of deprecated go-archive consts
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-19 18:39:13 +01:00
Austin VazquezandGitHub 06818193c7 Merge pull request #6717 from thaJeztah/bump_cdi
vendor: tags.cncf.io/container-device-interface v1.1.0
2025-12-19 08:49:08 -06:00
Sebastiaan van Stijn dd6d0cd801 vendor: tags.cncf.io/container-device-interface v1.1.0
no changes in vendored files

full diff: https://github.com/cncf-tags/container-device-interface/compare/v1.0.1...v1.1.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-18 22:49:32 +01:00
Sebastiaan van StijnandGitHub 60f06cb2df Merge pull request #6716 from vvoland/yamldocs-tty
Makefile/yamldocs: Don't require TTY
2025-12-18 17:48:48 +01:00
Paweł Gronowski 4743d1d894 Makefile/yamldocs: Don't require TTY
Make it work in GHA

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-18 17:38:14 +01:00
Sebastiaan van StijnandGitHub 55d80cca36 Merge pull request #6714 from thaJeztah/fix_api_versions
cli/command/service: fix API version for memory-swap, memory-swappiness
2025-12-18 13:54:21 +01:00
Sebastiaan van StijnandGitHub 7c38d6b59c Merge pull request #6713 from thaJeztah/remove_legacy_plugin_path
cli-plugins/manager: remove legacy system-wide cli-plugin path
2025-12-18 13:53:55 +01:00
Sebastiaan van StijnandGitHub f13565257e Merge pull request #6715 from vvoland/work-docs
docs/container: Fix dead docs reference
2025-12-18 13:41:02 +01:00
Paweł Gronowski 4851066797 docs/container: Update dead link
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-18 13:18:19 +01:00
Sebastiaan van Stijn 226af68141 cli/command/service: fix API version for memory-swap, memory-swappiness
These flags were added in 71828f2792, but
copy/pasted the annotation from `--limit-pids`.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-18 12:21:52 +01:00
Sebastiaan van Stijn 13759330b1 cli-plugins/manager: remove legacy system-wide cli-plugin path
commit 4d3a76d71e updated the list of directories
for discovering CLI plugins, adding `%ProgramFiles%\Docker\cli-plugins` for
system-wide plugins.

For backward compatibility, the `%PROGRAMDATA%\Docker\cli-plugins` was kept,
however, this location is no longer used, and not generally recommended for
storing non-data content (such as CLI plugin binaries). From the [ProgramData]
documentation:

> ProgramData specifies the path to the program-data folder (normally C:\ProgramData).
> Unlike the Program Files folder, this folder can be used by applications to store
> data for standard users, because it does not require elevated permissions.

It also mentions "It can’t contain any serviceable components.", effectively
meaning that these paths should not contain data that is managed (through
updates etc.), making it a poor choice for installing "system wide" CLI plugins.

This patch removes the path from the list, given that this location is no longer
used by Docker Desktop, and the CLI-plugin API is considered an internal
implementation (since 459c6082f8).

[ProgramData]: https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-folderlocations-programdata

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-18 10:23:41 +01:00
Sebastiaan van StijnandGitHub 93fa57bbcd Merge pull request #6711 from vvoland/update-docker
vendor: github.com/moby/moby/api v1.53.0-rc.1
2025-12-17 17:01:14 +01:00
Paweł Gronowski 302498c33c vendor: github.com/moby/moby/client v0.2.2-rc.1
full diff: https://github.com/moby/moby/client/compare/b2d84a3ef5a9...v0.2.2-rc.1

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-17 16:45:43 +01:00
Paweł Gronowski def847be9a vendor: github.com/moby/moby/api v1.53.0-rc.1
full diff: https://github.com/moby/moby/api/compare/b2d84a3ef5a9...v1.53.0-rc.1

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-17 16:45:23 +01:00
Sebastiaan van StijnandGitHub b9095d09ab Merge pull request #6710 from robmry/nri-info
Include NRI in "info" output
2025-12-16 16:33:40 +01:00
Sebastiaan van StijnandGitHub 0e6fee6c52 Merge pull request #6698 from thaJeztah/inline_parseWindowsDevice
cli/command/container: inline parseWindowsDevice, and minor cleanups
2025-12-16 16:33:03 +01:00
Rob Murray 2a903c52d4 Include NRI in info output
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-12-16 13:50:03 +00:00
Rob Murray d8351dbe65 Vendor moby/[api|client] from moby master
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-12-16 13:49:49 +00:00
Sebastiaan van StijnandGitHub 88be58884c Merge pull request #6709 from vvoland/img-list-all-doc
docs: Update --all flag description to clarify it shows dangling images
2025-12-16 12:58:57 +01:00
Paweł Gronowski f7ddc8a7d1 docs: Update --all flag description to clarify it shows dangling images
The --all flag description was misleading by only mentioning
intermediate images, when it actually also controls the visibility of
dangling (untagged) images.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-16 12:27:25 +01:00
Paweł GronowskiandGitHub 00e23cfdb7 Merge pull request #6706 from docker/dependabot/github_actions/actions/upload-artifact-6
build(deps): bump actions/upload-artifact from 5 to 6
2025-12-15 13:08:03 +00:00
dependabot[bot]andGitHub 4d7a8b0fd5 build(deps): bump actions/upload-artifact from 5 to 6
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 08:05:21 +00:00
Sebastiaan van StijnandGitHub f52814d454 Merge pull request #6705 from vvoland/list-fix
image/list: Fix `dangling=false` handling
2025-12-12 15:45:37 +01:00
Paweł Gronowski 0f03c31ab2 image/list: Fix dangling=false handling
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-12 15:36:40 +01:00
Paweł Gronowski 1e259062fc cli/tree: Remove unused all field
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-12 15:36:40 +01:00
Sebastiaan van StijnandGitHub 4d6fc331b9 Merge pull request #6704 from vvoland/list-fix
image: Fix dangling image detection with graphdrivers
2025-12-12 13:25:44 +01:00
Paweł Gronowski 09a46645a0 image/tree: Add golden test
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-12 12:39:26 +01:00
Paweł Gronowski 0d88411f1b image/tree: Remove --all flag check for untagged images in non-expanded view
This reverts part of the logic introduced in 207bf52c27 which
incorrectly gated untagged images behind the --all flag in non-expanded
view.

The original fix was addressing the wrong layer of the problem.

The actual issue was that dangling images were being incorrectly passed
to the tree code in the first place.

This was properly fixed in 67f5e3413 which corrected the dangling image
detection logic to properly filter them out before reaching the tree
display code.

Now that dangling images are correctly filtered upstream, untagged
images that reach the tree view should be displayed regardless of the
--all flag setting.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-12 11:22:47 +01:00
Paweł Gronowski b315983898 image/tree: Fix width calculation for untagged images
When calculating column widths for the tree view, untagged images
weren't being properly accounted for in the width calculation.

This caused layout issues when there were tagged images were shorter
than the `<untagged>` string.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-12 11:18:27 +01:00
Paweł Gronowski 150a25b9ff image/tree: Extract untagged image name to const
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-12 11:17:42 +01:00
Paweł Gronowski 67f5e3413b image: Fix dangling image detection with graphdrivers
The isDangling function was incorrectly identifying images as dangling
when they had no RepoTags but had valid RepoDigests.

This can occur when the graphdrivers are used instead of the containerd
image store.

An image should only be considered dangling if it has no RepoTags,
regardless of whether it has RepoDigests.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-12 11:16:01 +01:00
Sebastiaan van Stijn 2e3425fbd4 cli/command/container: use consistent casing for dockerCLI arg
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-12 09:30:46 +01:00
Sebastiaan van Stijn de098367d0 cli/command/container: inline parseWindowsDevice
It's not parsing anything, so we may as well inline it to be more
clear what's done.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-12 09:24:53 +01:00
Paweł GronowskiandGitHub d96b7869af Merge pull request #6702 from thaJeztah/bump_compress
vendor: github.com/klauspost/compress v1.18.2
2025-12-11 19:50:57 +00:00
Sebastiaan van Stijn 15de6ce8f7 vendor: github.com/klauspost/compress v1.18.2
full diff: https://github.com/klauspost/compress/compare/v1.18.0...v1.18.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-11 19:58:08 +01:00
Paweł GronowskiandGitHub 815be4418f Merge pull request #6701 from thaJeztah/bump_aec2
vendor: github.com/morikuni/aec v1.1.0
2025-12-11 18:14:44 +00:00
Sebastiaan van StijnandGitHub ca0fb174cf Merge pull request #6700 from thaJeztah/fix_validation
docker run, create: don't swallow connection errors during validate
2025-12-11 18:12:13 +01:00
Sebastiaan van Stijn 5c406f5ee4 vendor: github.com/morikuni/aec v1.1.0
full diff: https://github.com/morikuni/aec/compare/v1.0.0...v1.1.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-11 17:30:12 +01:00
Sebastiaan van Stijn a6335c4226 docker run, create: don't swallow connection errors during validate
Some validation steps done by `docker create` (and `docker run`) are platform-
specific, and need to know the daemon's OS.

To get this information, the CLI.ServerInfo() method was used, which
discards connection errors, resulting in an empty OS, which causes
validation to fail with an "unknown server OS" error message.

This patch changes it to use the Client.Ping so that we can error when
failing to connect.

We should look if we can reduce the platform-specific validation and parsing
on the client-side, but at least this change should produce a more useful
error.

Before this patch:

    DOCKER_HOST=tcp://example.invalid docker run -it --rm --device=/dev/dri alpine
    docker: unknown server OS:

    Run 'docker run --help' for more information

With this patch:

    DOCKER_HOST=tcp://example.invalid docker run -it --rm --device=/dev/dri alpine
    failed to connect to the docker API at tcp://example.invalid:2375: lookup example.invalid on 192.168.65.7:53: no such host

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-11 17:03:51 +01:00
Paweł GronowskiandGitHub 91d44d6caf Merge pull request #6697 from thaJeztah/migrate_yaml
vendor: github.com/spf13/cobra v1.10.2, migrate to go.yaml.in/yaml/v3
2025-12-09 15:07:34 +00:00
Sebastiaan van Stijn 49021ad987 vendor: github.com/spf13/cobra v1.10.2, migrate to go.yaml.in/yaml/v3
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-09 15:47:11 +01:00
Sebastiaan van StijnandGitHub 1a1a4fc478 Merge pull request #6685 from thaJeztah/less_nat
remove some uses of go-connections/nat package
2025-12-05 11:06:55 +01:00
Sebastiaan van Stijn 6f75c0c8e2 add TODOs for replacing nat.ParsePortSpecs
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-04 22:07:01 +01:00
Sebastiaan van Stijn 9c10a9c9ac opts/swarmopts: remove use of nat.ParsePortRange
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-04 22:06:57 +01:00
Paweł GronowskiandGitHub 65cf8762d3 Merge pull request #6692 from thaJeztah/rm_FakeStore
internal/test: remove unused FakeStore
2025-12-04 12:36:05 +00:00
Sebastiaan van Stijn 9dfe779abb internal/test: remove unused FakeStore
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-04 00:18:33 +01:00
Sebastiaan van StijnandGitHub dfa98d33ea Merge pull request #6690 from thaJeztah/compose_file_completion
add shell completion for "docker stack deploy --compose-file"
2025-12-03 11:47:52 +01:00
Sebastiaan van Stijn c81e05eed8 add shell completion for "docker stack deploy --compose-file"
With this patch:

    docker stack deploy -c<TAB>
    .codecov.yml       contrib/           e2e/               pkg/
    .git/              build/             debian/            experimental/
    ...

    docker stack deploy -c contrib/otel/<TAB>
    compose.yaml  otelcol.yaml  prom.yaml

Note that filtering for the file-extension only appears to be functional
on bash, but not (currently) working on other shells (at least not on Fish).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-03 11:38:04 +01:00
Sebastiaan van StijnandGitHub 890dcca877 Merge pull request #6688 from vvoland/update-go
update to go1.25.5
2025-12-02 19:58:46 +01:00
Paweł Gronowski d544885316 update to go1.25.5
These releases include 2 security fixes following the security policy:

- crypto/x509: excessive resource consumption in printing error string for host certificate validation

    Within HostnameError.Error(), when constructing an error string, there is no limit to the number of hosts that will be printed out.
    Furthermore, the error string is constructed by repeated string concatenation, leading to quadratic runtime.

    Therefore, a certificate provided by a malicious actor can result in excessive resource consumption.
    HostnameError.Error() now limits the number of hosts and utilizes strings.Builder when constructing an error string.

    Thanks to Philippe Antoine (Catena cyber) for reporting this issue.

    This is CVE-2025-61729 and Go issue https://go.dev/issue/76445.

- crypto/x509: excluded subdomain constraint does not restrict wildcard SANs

    An excluded subdomain constraint in a certificate chain does not restrict the
    usage of wildcard SANs in the leaf certificate. For example a constraint that
    excludes the subdomain test.example.com does not prevent a leaf certificate from
    claiming the SAN *.example.com.

    This is CVE-2025-61727 and Go issue https://go.dev/issue/76442.

View the release notes for more information:
https://go.dev/doc/devel/release#go1.25.5

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-02 18:03:18 +01:00
Paweł GronowskiandGitHub c197aa70ee Merge pull request #6687 from thaJeztah/use_subtests
opts/swarmopts: use sub-tests
2025-12-01 13:08:30 +00:00
Sebastiaan van Stijn ba683d8df3 opts/swarmopts: use sub-tests
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-01 13:01:37 +01:00
Paweł GronowskiandGitHub 0aedba58c2 Merge pull request #6669 from vvoland/29-norc
gha/e2e: Switch to 29 from 29-rc
2025-11-28 12:26:43 +01:00
Paweł Gronowski dd2be022c0 gha/e2e: Switch to rc and 29 latest
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-28 12:22:06 +01:00
Paweł GronowskiandGitHub 360952c8d3 Merge pull request #6680 from thaJeztah/bump_modules
vendor: github.com/moby/moby/client v0.2.1
2025-11-27 17:36:37 +01:00
Sebastiaan van StijnandGitHub 8fc15eaf2c Merge pull request #6579 from dvdksn/doc-daemon-buildc-example
docs: update buildgc example config to use new buildkit v0.17 options
2025-11-27 17:35:32 +01:00
Sebastiaan van Stijn 1abfbf298c vendor: github.com/moby/moby/client v0.2.1
full diff: https://github.com/moby/moby/compare/client/v0.1.0...v0.2.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-27 17:25:03 +01:00
David Karlsson e0d30db115 docs: update buildgc example config to use new buildkit v0.17 options
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2025-11-27 16:24:42 +01:00
Paweł GronowskiandGitHub 5691ade75a Merge pull request #6682 from thaJeztah/bump_dct_deps
cmd/docker-trust: update dependencies
2025-11-27 15:38:49 +01:00
Paweł GronowskiandGitHub 848dcad809 Merge pull request #6681 from thaJeztah/bump_x_deps2
vendor: update various golang.org/x/xxx dependencies
2025-11-27 15:38:16 +01:00
Sebastiaan van Stijn 6a0099bc8a cmd/docker-trust: bump golang.org/x/crypto v0.45.0
Hello gophers,

We have tagged version v0.45.0 of golang.org/x/crypto in order to address two
security issues.

This version fixes a vulnerability in the golang.org/x/crypto/ssh package and a
vulnerability in the golang.org/x/crypto/ssh/agent package which could cause
programs to consume unbounded memory or panic respectively.

SSH servers parsing GSSAPI authentication requests don't validate the number of
mechanisms specified in the request, allowing an attacker to cause unbounded
memory consumption.

Thanks to Jakub Ciolek for reporting this issue.

This is CVE-2025-58181 and Go issue https://go.dev/issue/76363.

SSH Agent servers do not validate the size of messages when processing new
identity requests, which may cause the program to panic if the message is
malformed due to an out of bounds read.

Thanks to Jakub Ciolek for reporting this issue.

This is CVE-2025-47914 and Go issue https://go.dev/issue/76364.

Cheers, Go Security team

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-27 14:38:30 +01:00
Sebastiaan van Stijn c90166ffa6 cmd/docker-trust: update dependencies
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-27 14:37:10 +01:00
Sebastiaan van Stijn ac5e886124 vendor: golang.org/x/net v0.47.0
full diff: https://github.com/golang/net/compare/v0.46.0...v0.47.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-27 14:28:29 +01:00
Sebastiaan van Stijn 3ec414638c vendor: golang.org/x/term v0.37.0
full diff: https://github.com/golang/term/compare/v0.36.0...v0.37.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-27 14:27:21 +01:00
Sebastiaan van Stijn 616e93a0c2 vendor: golang.org/x/text v0.31.0
full diff: https://github.com/golang/text/compare/v0.30.0...v0.31.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-27 14:24:45 +01:00
Sebastiaan van Stijn 1202f8a642 vendor: golang.org/x/sync v0.18.0
full diff: https://github.com/golang/sync/compare/v0.17.0...v0.18.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-27 14:23:31 +01:00
Sebastiaan van Stijn b67055c963 vendor: golang.org/x/sys v0.38.0
- cpu: add HPDS, LOR, PAN detection for arm64
- cpu: also use MRS instruction in getmmfr1
- cpu: use MRS instruction to read arm64 system registers
- unix: add consts for ELF handling
- unix: add SetMemPolicy and its mode/flag values
- unix: add SizeofNhmsg and SizeofNexthopGrp
- windows: add iphlpapi routing functions

full diff: https://github.com/golang/sys/compare/v0.37.0...v0.38.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-27 14:22:32 +01:00
Sebastiaan van StijnandGitHub eee3e3d015 Merge pull request #6671 from docker/dependabot/github_actions/actions/checkout-6
build(deps): bump actions/checkout from 5 to 6
2025-11-27 10:42:16 +01:00
Paweł GronowskiandGitHub 3247a5aae3 Merge pull request #6675 from vvoland/img-list-noellipsis
image/tree: Allow image names to overflow instead of truncating
2025-11-24 21:35:37 +00:00
Paweł Gronowski 4759615835 image/tree: Allow image names to overflow instead of truncating
Users were experiencing poor UX when image names were truncated in the
table output.

Instead of cutting off long image names with ellipsis, the names now
wrap to the next line to ensure full visibility.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-24 22:12:37 +01:00
dependabot[bot]andGitHub 3099d4716c build(deps): bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-21 08:04:55 +00:00
Paweł GronowskiandGitHub 511dad69d0 Merge pull request #6667 from thaJeztah/use_format
image ls: allow custom format in cli config
2025-11-20 16:31:07 +00:00
Paweł GronowskiandGitHub 11f24b8458 Merge pull request #6668 from robmry/builttime-format
docker version: restore top-level BuildTime to RFC3339Nano format
2025-11-20 16:21:40 +00:00
Sebastiaan van Stijn d84396d4eb image ls: allow custom format in cli config
Setting a custom format in the cli cofig should still be supported,
and not produce an error when specifying "--tree". Specifyihg both
"--tree" and "--format" still produces an error, but we could consider
allowing "json" format in a future update.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-20 16:20:33 +00:00
Rob Murray 6751cd1690 docker version: restore top-level BuildTime to RFC3339Nano
Introduced by bff56f0 (cli/command/system: define struct for
formatting version).

In the "docker info" result, the Engine component's BuildTime should
be in time.ANSIC format, but the top level BuildTime field should use
time.RFC3339Nano.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-20 15:57:24 +00:00
Sebastiaan van StijnandGitHub 8108357bcb Merge pull request #6662 from dvdksn/doc-update-http-proxy-link
chore: update link/linktext to dockerd proxy config
2025-11-17 11:19:50 +01:00
David Karlsson 3a842587f9 chore: update link/linktext to dockerd proxy config
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2025-11-17 11:00:04 +01:00
Sebastiaan van StijnandGitHub eedd9698e9 Merge pull request #6659 from vvoland/fix-system-version
cli/command/system: Fix missing components in version output
2025-11-13 22:27:39 +01:00
Paweł Gronowski dd2c493825 cli/command/system: Fix missing components in version output
The `Components` weren't actually copied to the output struct.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 21:19:41 +01:00
Paweł GronowskiandGitHub 67cef775fe Merge pull request #6658 from vvoland/img-list-all-dangling
image/tree: Only show untagged images when --all flag is used
2025-11-13 20:53:26 +01:00
Paweł Gronowski 207bf52c27 image/tree: Only show untagged images when --all flag is used
In non-expanded view, untagged images should only be displayed when the
--all flag is explicitly provided by the user.

Previously, untagged images were accidentally always shown in the
non-expanded view regardless of the --all flag setting.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 20:23:42 +01:00
Sebastiaan van StijnandGitHub 2cfd9df568 Merge pull request #6654 from vvoland/img-list-nocolor
image/tree: Respect NO_COLOR env variable
2025-11-13 15:10:10 +01:00
Paweł Gronowski be9e6308f5 image/tree: Respect NO_COLOR env variable
Do not use the fancy colored output if NO_COLOR variable is set to 1
following the https://no-color.org/ convention.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 14:56:27 +01:00
Sebastiaan van StijnandGitHub 88e324150b Merge pull request #6657 from vvoland/img-list-nonexpanded-untagged
image/tree: Fix untagged images in non-expanded view
2025-11-13 13:20:46 +01:00
Sebastiaan van StijnandGitHub 2ae51e2d69 Merge pull request #6656 from vvoland/img-list-notty-width
image/tree: Don't limit name width if non tty
2025-11-13 13:19:30 +01:00
Paweł Gronowski ed281ddf52 image/list: Print legend only if limiting width
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 13:00:02 +01:00
Paweł Gronowski aa5d00a3a4 image/tree: Don't limit name width if non tty
Previously when no terminal was attached the width was assumed to be 80.
This is too short for most image names which truncated the names when
output was redirect (for example to `grep`).

This disabled the name truncation if the terminal width can't be
determined.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 12:59:46 +01:00
Paweł Gronowski b66b93130c image/tree: Fix untagged images in non-expanded view
In the expanded view there is a separate image entry per each tag.

Fix a bug which caused no entry to be added for untagged images.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 12:47:24 +01:00
Sebastiaan van StijnandGitHub c44e8a0727 Merge pull request #6648 from thaJeztah/cli_version_json_format
cli/command/system: define struct for formatting version
2025-11-12 18:09:53 +01:00
Sebastiaan van Stijn bff56f0493 cli/command/system: define struct for formatting version
The client.ServerVersion method in the moby/client module defines
an output struct that's separate from the API response. These output
structs are not designed to be marshaled as JSON, but the CLI depended
on them defining `json` labels, which it used to format the output
as JSON (`docker version --format=json`); as a result, the JSON output
changed in docker v29, as it would now use the naming based on the Go
struct's fields (`APIVersion` instead of `ApiVersion`).

In future, we should consider having a `--raw` (or similar) option for
the CLI to print API responses as-is, instead of using client structs
or CLI structs for this (this would also make sure the JSON output does
not inherit client-side formatting of fields).

For now, let's create a struct for formatting the output, similar to what
we do for the client-side information.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-12 14:57:13 +01:00
Sebastiaan van StijnandGitHub 3d4129b9ea Merge pull request #6644 from thaJeztah/connhelper_nowarn
cli/connhelper/commandcon: remove warn logs
2025-11-10 22:42:38 +01:00
Sebastiaan van Stijn d787e70a14 cli/connhelper/commandcon: remove warn logs
These were originally added in 6f61cf053a,
but at the time, the error wasn't returned. Now that it is, we shouldn't
log _and_ return the error.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-10 22:36:41 +01:00
Paweł GronowskiandGitHub e730f6f0f3 Merge pull request #6643 from thaJeztah/bump_modules2
vendor: github.com/moby/moby/api v1.52.0, moby/client v0.1.0
2025-11-10 22:04:44 +01:00
Paweł GronowskiandGitHub 6ac3f93755 Merge pull request #6578 from thaJeztah/bump_otel_semconv
cli/command: update to semconv v1.37.0, otel v1.38.0
2025-11-10 22:04:29 +01:00
Sebastiaan van Stijn ebc1995f9f vendor: github.com/moby/moby/api v1.52.0, moby/client v0.1.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-10 21:57:40 +01:00
Sebastiaan van StijnandGitHub 31d1a59d07 Merge pull request #6642 from vvoland/swarm-compose-work
swarm: revert compose/stack support for memory swappiness
2025-11-10 19:09:49 +01:00
Paweł Gronowski ad96811f12 swarm: Add memory swap support (no stack/compose support)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-10 17:48:56 +01:00
Paweł Gronowski 6ba06b5fb4 Revert "cli/compose: add schema 3.14 (no changes from 3.13 yet)"
This reverts commit d0c86d39ef.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-10 17:48:55 +01:00
Paweł Gronowski e0716b571f Revert "Add memory swap to swarm"
This reverts commit 71828f2792.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-10 17:48:54 +01:00
Paweł GronowskiandGitHub 179efae8b0 Merge pull request #6641 from thaJeztah/bump_modules
vendor: github.com/moby/moby/api, moby/client master
2025-11-10 17:03:43 +01:00
Sebastiaan van Stijn 4b450f113b vendor: github.com/moby/moby/api, moby/client master
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-10 16:32:05 +01:00
Paweł GronowskiandGitHub ee244f2f44 Merge pull request #6636 from thaJeztah/add_missing_gobuild
cli/command/system: add missing "go:build"
2025-11-07 01:34:14 +01:00
Paweł GronowskiandGitHub 0c101c4aa7 Merge pull request #6635 from thaJeztah/bump_modules
vendor: github.com/moby/moby/api v1.52.0-rc.1, moby/client v0.1.0-rc.1
2025-11-07 01:31:10 +01:00
Sebastiaan van Stijn 1d789e4099 cli/command/system: add missing "go:build"
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-07 01:27:47 +01:00
Sebastiaan van Stijn b3824015d6 vendor: github.com/moby/moby/api v1.52.0-rc.1, moby/client v0.1.0-rc.1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-07 01:26:13 +01:00
Sebastiaan van StijnandGitHub c4f240cc7d Merge pull request #6606 from dvdksn/update-libnetwork-docs-link
docs: update link to libnetwork protocol doc
2025-11-07 01:12:41 +01:00
Sebastiaan van StijnandGitHub 5b443bf269 Merge pull request #6619 from dperny/swarm-memory-swap
Add memory swap to swarm
2025-11-07 01:03:26 +01:00
Sebastiaan van StijnandGitHub eaa6114d9e Merge pull request #6634 from thaJeztah/remove_replace
vendor.mod: remove replace
2025-11-07 00:55:53 +01:00
Sebastiaan van StijnandGitHub c9e6b41293 Merge pull request #6633 from dvdksn/docs-update-dd-documentation-link
chore: update broken link to restrucured docker desktop documentation
2025-11-07 00:34:43 +01:00
Sebastiaan van Stijn d67291026e vendor.mod: remove replace
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-07 00:32:57 +01:00
Austin VazquezandSebastiaan van Stijn 41088ed7d0 vendor: go.opentelemetry.io/auto/sdk v1.2.1
Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-07 00:29:26 +01:00
Austin VazquezandSebastiaan van Stijn 712f569f17 vendor: go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0
Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-07 00:29:26 +01:00
Sebastiaan van Stijn 7736f5e606 vendor: align other otel packages to v1.38.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-07 00:29:24 +01:00
Jonathan A. SternbergandSebastiaan van Stijn d45551dac9 cli/command: update to semconv v1.37.0, otel v1.38.0
Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-07 00:27:34 +01:00
Drew ErnyandSebastiaan van Stijn 71828f2792 Add memory swap to swarm
Adds support for setting memory swap settings on Swarm services

* Adds flags `memory-swap` and `memory-swappiness` to `docker service
create` and `docker service update` commands.
* Adds compose fields `memswap_limit` and `mem_swappiness` for `docker
stack` commands.

Signed-off-by: Drew Erny <derny@mirantis.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-07 00:24:44 +01:00
Sebastiaan van Stijn d0c86d39ef cli/compose: add schema 3.14 (no changes from 3.13 yet)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-07 00:24:44 +01:00
Paweł GronowskiandGitHub 16d2036cde Merge pull request #6620 from austinvazquez/vendor-system-disk-usage-changes
vendor: github.com/moby/moby/api master, moby/client master
2025-11-07 00:20:18 +01:00
Austin Vazquez 5039eee77f vendor: github.com/moby/moby/api master, moby/client master
Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
2025-11-06 17:02:53 -06:00
Sebastiaan van StijnandGitHub cc7275c4e5 Merge pull request #6121 from thaJeztah/trust_plugin
implement `docker trust` as plugin
2025-11-06 20:29:58 +01:00
Sebastiaan van StijnandGitHub f7d6d5bdb3 Merge pull request #6632 from vvoland/update-go
update to go1.25.4
2025-11-06 17:13:16 +01:00
Sebastiaan van Stijn cee9ea67fc lint: run in go-modules mode
Prevent the linter from recursing to other modules (cmd/docker-trust),
which don't have their dependencies vendored.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-06 15:24:49 +01:00
Sebastiaan van Stijn b2aa690b26 scripts/build/binary: remove pkcs11 build tag
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-06 15:24:49 +01:00
Sebastiaan van Stijn c1a53ae7b6 cmd/docker-trust: remove dependency on cli/internal
Create a copy of the registry package to use, so that code used only
for trust can be removed from the cli/internal package.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-06 15:24:49 +01:00
Sebastiaan van Stijn 06914dd0ff make trust-plugin a separate module
skip cmd/docker-trust in tests, as it's a separate module.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-06 15:24:48 +01:00
Sebastiaan van Stijn c9bb291154 implement docker trust as plugin
move the `trust` subcommands to a plugin, so that the subcommands can
be installed separate from the `docker trust` integration in push/pull
(for situations where trust verification happens on the daemon side).

    make binary
    go build -o /usr/libexec/docker/cli-plugins/docker-trust ./cmd/docker-trust

    docker info
    Client:
     Version:    28.2.0-dev
     Context:    default
     Debug Mode: false
     Plugins:
      buildx: Docker Buildx (Docker Inc.)
        Version:  v0.24.0
        Path:     /usr/libexec/docker/cli-plugins/docker-buildx
      trust: Manage trust on Docker images (Docker Inc.)
        Version:  unknown-version
        Path:     /usr/libexec/docker/cli-plugins/docker-trust

    docker trust --help
    Usage:  docker trust [OPTIONS] COMMAND

    Extended build capabilities with BuildKit

    Options:
      -D, --debug   Enable debug logging

    Management Commands:
      key         Manage keys for signing Docker images
      signer      Manage entities who can sign Docker images

    Commands:
      inspect     Return low-level information about keys and signatures
      revoke      Remove trust for an image
      sign        Sign an image

    Run 'docker trust COMMAND --help' for more information on a command.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-06 15:24:46 +01:00
Sebastiaan van StijnandGitHub face4a61be Merge pull request #6631 from thaJeztah/fix_static_builds
Fix static build + CGO
2025-11-06 15:24:18 +01:00
David Karlsson dd70b43bc1 chore: update broken link to restrucured docker desktop documentation
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2025-11-06 14:40:16 +01:00
Paweł Gronowski f2755b02d7 update to go1.25.4
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-06 14:24:03 +01:00
Tianon GraviandSebastiaan van Stijn 880ef756b7 Fix static build + CGO
Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
2025-11-06 12:39:18 +01:00
Paweł GronowskiandGitHub de00f53cb9 Merge pull request #6629 from thaJeztah/bump_x_deps
vendor: golang.org/x/* dependencies
2025-11-06 11:22:48 +01:00
Sebastiaan van Stijn 0976389e14 vendor: golang.org/x/net v0.46.0, golang.org/x/crypto v0.43.0
full diff: https://github.com/golang/net/compare/v0.39.0...v0.46.0
full diff: https://github.com/golang/crypto/compare/v0.39.0...v0.43.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 22:58:37 +01:00
Sebastiaan van Stijn c733cb0532 vendor: golang.org/x/time v0.14.0
full diff: https://github.com/golang/time/compare/v0.11.0...v0.14.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 22:47:59 +01:00
Sebastiaan van Stijn 1f77c6f1c8 vendor: golang.org/x/term v0.36.0
- term: remove duplicate flag and add comment on windows
- term: allow multi-line bracketed paste to not create single line
  with verbatim LFs (fixes "x/term: multi line bracketed paste fails"
  to issue line by line commands

full diff: https://github.com/golang/term/compare/v0.32.0...v0.36.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 22:47:50 +01:00
Sebastiaan van Stijn dcce972f47 vendor: golang.org/x/text v0.30.0
full diff: https://github.com/golang/text/compare/v0.26.0...v0.30.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 22:47:22 +01:00
Sebastiaan van Stijn b11d143cd1 vendor: golang.org/x/sync v0.17.0
full diff: https://github.com/golang/sync/compare/v0.16.0...v0.17.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 22:46:32 +01:00
Sebastiaan van Stijn 0c8ce84a62 vendor: golang.org/x/sys v0.37.0
full diff: https://github.com/golang/sys/compare/v0.33.0...v0.37.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 22:45:52 +01:00
Sebastiaan van StijnandGitHub 1c572a10de Merge pull request #6628 from thaJeztah/swarm_enums
cli/command/service: use enum-consts defined in API
2025-11-05 17:32:30 +01:00
Sebastiaan van Stijn d9f7e4b0c8 cli/command/service: use enum-consts defined in API
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 13:41:04 +01:00
Sebastiaan van StijnandGitHub 1686e45501 Merge pull request #6612 from jo-so/master
completion/zsh: Allow multiple volumes of 'volume rm'
2025-11-05 13:27:15 +01:00
Sebastiaan van StijnandGitHub 050aca80a5 Merge pull request #6627 from thaJeztah/local_parsegeneric_resource
cli/command/service: parse generic resources without protobufs
2025-11-05 12:45:12 +01:00
Paweł GronowskiandGitHub 30b02813f1 Merge pull request #6625 from thaJeztah/bump_golangci_lint
Dockerfile: update golangci-lint to v2.6.1
2025-11-05 12:40:19 +01:00
Sebastiaan van Stijn 774f1d60a1 cli/command/service: parse generic resources without protobufs
This code was using swarmkit's genericresource package as intermediate;
add a local copy of that code that skips the protobufs as intermediate.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 12:26:02 +01:00
Sebastiaan van Stijn 437ed4c1e4 Dockerfile: update golangci-lint to v2.6.1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 12:24:12 +01:00
Paweł GronowskiandGitHub 9fc247e0e5 Merge pull request #6626 from thaJeztah/fix_perfsprint
fix perfsprint (concat-loop) linting
2025-11-05 12:23:06 +01:00
Paweł GronowskiandGitHub 924ed097c5 Merge pull request #6623 from thaJeztah/bump_swarmkit
vendor: github.com/moby/swarmkit/v2 v2.1.1
2025-11-05 12:22:42 +01:00
Paweł GronowskiandGitHub b52826a55e Merge pull request #6622 from thaJeztah/bump_platforms
vendor: github.com/containerd/platforms v1.0.0-rc.2
2025-11-05 12:22:30 +01:00
Paweł GronowskiandGitHub 38d271a8e4 Merge pull request #6617 from thaJeztah/bump_jose
vendor: github.com/go-jose/go-jose/v4 v4.1.3
2025-11-05 12:22:08 +01:00
Paweł GronowskiandGitHub e6d6ddf38d Merge pull request #6616 from thaJeztah/bump_runewidth
vendor: github.com/mattn/go-runewidth v0.0.19
2025-11-05 12:21:51 +01:00
Sebastiaan van Stijn c4a28d0d3c vendor: github.com/go-jose/go-jose/v4 v4.1.3
- remove Go 1.23 support
- removes dependency on golang.org/x/crypto
- reject JWS with an unprotected critical b64 header

full diff: https://github.com/go-jose/go-jose/compare/v4.1.2...v4.1.3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 11:55:19 +01:00
Sebastiaan van StijnandGitHub 5b68e72ad3 Merge pull request #6624 from thaJeztah/bump_go_minimum
update minimum go version to go1.24
2025-11-05 11:47:27 +01:00
Sebastiaan van Stijn f8d0365127 fix perfsprint (concat-loop) linting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 09:27:52 +01:00
Sebastiaan van Stijn 7b624841c4 update minimum go version to go1.24
Various dependencies, including "golang.org/x/.."  started to update
the minimum required version,so we should follow suit for the next
release.

Note that the `//go:build` directives not necesserily have to be
updated, but it's good to keep them in sync until we have a go.mod
to control this.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 08:24:06 +01:00
Sebastiaan van Stijn 82b47c8e57 vendor: github.com/moby/swarmkit/v2 v2.1.1
full diff: https://github.com/moby/swarmkit/compare/v2.1.0...v2.1.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 08:05:32 +01:00
Sebastiaan van Stijn 3a91788135 vendor: github.com/containerd/platforms v1.0.0-rc.2
- Add WS2025 to Windows matcher and code optimizations
- use windowsMatchComparer for OSVersion match order
  Windows OS version should match based on the full OSVersion. When
  sorting a manifest, the entries should be sorted using the `Less`
  function.

full diff: https://github.com/containerd/platforms/compare/v1.0.0-rc.1...v1.0.0-rc.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-05 07:52:02 +01:00
Sebastiaan van StijnandGitHub 0b3c028108 Merge pull request #6618 from thaJeztah/lint_mod
lint: don't disable modules
2025-11-05 07:31:43 +01:00
Sebastiaan van Stijn 61d88c9519 lint: don't disable modules
prevent the linter from traversing the docker-trust plugin module

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-04 14:44:11 +01:00
Sebastiaan van Stijn 9bce085b13 vendor: github.com/mattn/go-runewidth v0.0.19
full diff: https://github.com/mattn/go-runewidth/compare/v0.0.17...v0.0.19

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-04 14:28:14 +01:00
Austin VazquezandGitHub 7414d73fc1 Merge pull request #6615 from thaJeztah/fix_generics
cli/command/container: fix use of generics
2025-11-04 07:26:44 -06:00
Sebastiaan van StijnandGitHub c01696ffde Merge pull request #6603 from thaJeztah/remove_trust_integration
remove support for client-side docker content trust validation
2025-11-04 14:05:39 +01:00
Sebastiaan van StijnandGitHub 8d1525a011 Merge pull request #6614 from vvoland/list-tree-header-ansi
image/tree: Fix table header having escape codes when not tty
2025-11-04 14:02:28 +01:00
Sebastiaan van Stijn e0b1ab68fe cli/command/container: fix use of generics
This was introduced in dad1d367c8, which
did not add a `//go:build` constraint to enable the use of generics (`any`).

Which causes an error when used;

 could not import github.com/docker/cli/cli/command/container (-: # github.com/docker/cli/cli/command/container
 /Users/thajeztah/go/pkg/mod/github.com/docker/cli@v29.0.0-rc.2+incompatible/cli/command/container/stats.go:148:39: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-04 13:56:23 +01:00
Paweł Gronowski e5f46499b3 image/tree: Fix table header having escape codes when not tty
When stdout is redirected to a non-tty there should be no ANSI escape
codes emitted.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-04 13:55:30 +01:00
Paweł Gronowski d5d2ed5baa image/tree: Add test for checking ansi escape output
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-04 13:55:30 +01:00
Paweł Gronowski 1a261e3f50 image/tree: Use streams interface
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-04 13:55:30 +01:00
Jörg Sommer 4893a5d5e3 completion/zsh: Allow multiple volumes of 'volume rm'
It is possible to give more than one volume for `docker volume rm`.

Signed-off-by: Jörg Sommer <joerg@jo-so.de>
2025-11-04 09:36:42 +01:00
Sebastiaan van StijnandGitHub 30d597df10 Merge pull request #6605 from Benehiko/plugins/hidden
Plugin may set itself as hidden
2025-11-03 16:58:57 +01:00
Alano Terblanche 700875b666 Plugin may set itself as hidden
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-11-03 16:36:46 +01:00
Sebastiaan van StijnandGitHub 7e32fdf1b3 Merge pull request #6611 from thaJeztah/skip_hidden_plugin_commands
cli: allManagementSubCommands: improve handling of plugin stubs
2025-11-03 15:34:01 +01:00
Sebastiaan van Stijn ad776d1e10 remove support for client-side docker content trust validation
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-03 14:21:19 +01:00
Sebastiaan van Stijn 259df25a96 cli: allManagementSubCommands: improve handling of plugin stubs
The allManagementSubCommands function is used to present plugin-commands
in the docker --help output; these commands are included in the "management
commands" section, but for plugins we don't know if they have sub-commands.

However, plugin stubs may be hidden (for placeholders that are not yet loaded),
or not be runnable, which was previously ignored.

This patch treats plugin-stubs the same as other commands, with the exception
of checking if they have subcommands (which is not yet known for plugin-stubs).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-03 13:57:01 +01:00
David Karlsson aa62a6a97a docs: update link to libnetwork protocol doc
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2025-11-03 13:32:30 +01:00
Paweł GronowskiandGitHub b5bac44972 Merge pull request #6601 from thaJeztah/bump_modules2
vendor: github.com/moby/moby/api v1.52.0-beta.4, client v0.1.0-beta.3
2025-10-31 19:36:12 +01:00
Sebastiaan van Stijn ef16d82301 vendor: github.com/moby/moby/api v1.52.0-beta.4, client v0.1.0-beta.3
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-31 19:30:20 +01:00
Sebastiaan van StijnandGitHub 73aade19c1 Merge pull request #6566 from vvoland/img-list
image/list: Show collapsed tree by default
2025-10-31 18:22:07 +01:00
Sebastiaan van StijnandGitHub 0f589b35c5 Merge pull request #6565 from thaJeztah/add_29
e2e: add docker v29-rc
2025-10-31 18:16:16 +01:00
Paweł Gronowski 6fa5900339 image/tree: Remove longest->shortest sort
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-31 18:10:19 +01:00
Paweł Gronowski 5836040ec9 Update golden files
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-31 18:10:19 +01:00
Paweł Gronowski f6feef8fe2 image/test: Fix go test args being used by CLI commands
By default cobra inherit the `os.Args` if there's no non-nil Args slice
set.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-31 18:10:19 +01:00
Paweł Gronowski 631f32ee9d images/list: Add print ambiguous warning for tree
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-31 18:10:19 +01:00
Paweł Gronowski c41815f17a image/list: Show collapsed tree by default
Use the new tree view by default and only fallback if format or old
view-related options are used.

The expanded view is shown when `--tree` is passed.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-31 18:10:19 +01:00
Sebastiaan van Stijn 5d599e9322 e2e: add docker v29-rc
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-31 17:56:37 +01:00
Paweł GronowskiandGitHub cdaae144e9 Merge pull request #6600 from thaJeztah/remove_trust_e2e
e2e: remove DCT tests
2025-10-31 17:56:22 +01:00
Paweł GronowskiandGitHub 7fb94dae5b Merge pull request #6599 from vvoland/update-docker
vendor: github.com/moby/moby master
2025-10-31 17:50:18 +01:00
Sebastiaan van Stijn 50598d21c9 skip TestBuildIidFileSquash
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-31 17:45:30 +01:00
Sebastiaan van Stijn cf9e1778d3 Dockerfile: remove notary
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-31 17:45:30 +01:00
Sebastiaan van Stijn c98d9647d3 e2e: remove DCT tests
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-31 17:45:29 +01:00
Sebastiaan van StijnandGitHub f8e871344f Merge pull request #6596 from vvoland/img-list-all-dangling
image/tree: Fix dangling filter condition
2025-10-31 17:42:33 +01:00
Sebastiaan van StijnandGitHub 173808f8b6 Merge pull request #6598 from AkihiroSuda/deprecate-cgroup1
docs: deprecated: deprecate cgroup v1
2025-10-31 17:40:42 +01:00
Paweł Gronowski 8444c911bd vendor: github.com/moby/moby master
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-31 17:38:52 +01:00
Paweł GronowskiandGitHub 96bc39b36d Merge pull request #6597 from thaJeztah/use_pull_for_pull
cli/command/container: use ImagePull instead of ImageCreate
2025-10-31 17:29:13 +01:00
Sebastiaan van StijnandGitHub 918ec8c48a Merge pull request #6595 from vvoland/list-tree-sortby-name
image/tree: Sort image tree by name instead of creation date
2025-10-31 16:55:07 +01:00
Akihiro Suda 7f86de9319 docs: deprecated: deprecate cgroup v1
See
- moby/moby issue 51111
- moby/moby PR    51360

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2025-11-01 00:55:03 +09:00
Sebastiaan van Stijn 7bdb4df07d cli/command/container: use ImagePull instead of ImageCreate
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-31 15:50:18 +01:00
Paweł Gronowski 9e7937746c image/tree: Fix dangling filter condition
The logic for applying the dangling filter when `--all` is not used was
inverted. The filter was being applied when the dangling filter was
present, but it should be applied when the dangling filter is NOT
present.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-31 14:58:02 +01:00
Paweł Gronowski 8e2943c6c5 image/tree: Sort image tree by name instead of creation date
Sort images alphabetically by their repository tags rather than by
creation date.

When an image has multiple tags, they are sorted internally and the
first tag is used as the representative for sorting the image in the
list. Untagged images are placed at the end.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-31 11:30:59 +01:00
Austin VazquezandGitHub 513ee76bac Merge pull request #6593 from thaJeztah/bump_modules
vendor: github.com/moby/moby/api master, moby/client master
2025-10-30 22:45:41 -05:00
Sebastiaan van Stijn 8767904ae8 vendor: github.com/moby/moby/api master, moby/client master
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-31 03:25:19 +01:00
Sebastiaan van Stijn b8b4f54a89 fix typo in TODO comment
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-31 03:15:47 +01:00
Sebastiaan van StijnandGitHub 03fb1df2dd Merge pull request #6577 from docker/dependabot/github_actions/actions/upload-artifact-5
build(deps): bump actions/upload-artifact from 4 to 5
2025-10-31 03:02:22 +01:00
Sebastiaan van StijnandGitHub 58e3de8781 Merge pull request #6594 from thaJeztah/dont_push_me
cli/trust: use local definition for PushResult Aux message
2025-10-31 02:13:01 +01:00
Sebastiaan van Stijn 65496c5557 cli/trust: use local definition for PushResult Aux message
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-30 20:22:25 +01:00
Sebastiaan van StijnandGitHub 3434869388 Merge pull request #6591 from vvoland/update-docker
vendor: github.com/moby/moby master
2025-10-30 00:32:57 +01:00
Sebastiaan van StijnandGitHub 9dde80abd8 Merge pull request #6574 from vvoland/img-dangling
image/list: Hide untagged images without `--all`
2025-10-30 00:24:29 +01:00
Paweł Gronowski e636a2a069 cli/container_rename: Move to API validation
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-30 00:20:47 +01:00
Paweł Gronowski af255accaa vendor: github.com/moby/moby master
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-30 00:02:41 +01:00
Paweł GronowskiandGitHub fcac1d5b2a Merge pull request #6586 from thaJeztah/bump_modules
vendor: github.com/moby/moby/api, moby/moby/client master
2025-10-29 23:53:04 +01:00
Sebastiaan van Stijn 053aa376ea vendor: github.com/moby/moby/api, moby/moby/client master
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-29 23:17:29 +01:00
Sebastiaan van StijnandGitHub 606f1c65d0 Merge pull request #6584 from thaJeztah/bump_modules
vendor: github.com/moby/moby/api, moby/moby/client master
2025-10-28 19:26:27 +01:00
Sebastiaan van Stijn 83319f09f7 cli/command/container: use per-stats OSType if present
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-28 16:27:00 +01:00
Sebastiaan van Stijn 6ed16a2cc1 vendor: github.com/moby/moby/api, moby/moby/client master
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-28 16:26:53 +01:00
Sebastiaan van StijnandGitHub 10281ff5a5 Merge pull request #6583 from thaJeztah/stats_cleanups
cli/command/container: cleanup stats code
2025-10-28 15:17:20 +01:00
Sebastiaan van Stijn 5007c96b0d cli/command/container: collect(): split windows/unix branches
Use separate branches to handle windows/unix results to reduce intermediate
variables, and make it more transparent what's set for each platform.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-28 15:08:05 +01:00
Sebastiaan van Stijn c467ebafd8 cli/command/container: calculateCPUPercentWindows minor cleanup
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-28 15:08:05 +01:00
Sebastiaan van Stijn 689152a804 cli/command/container: calculateCPUPercentUnix: simplify
Pass the whole CPUStats struct instead of deconstructing it to separate
variables.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-28 15:07:58 +01:00
Sebastiaan van StijnandGitHub e809e65ba6 Merge pull request #6582 from thaJeztah/fix_stats_cancellation
cli/command/container: RunStats: simplify, and fix context-cancellation
2025-10-28 14:12:16 +01:00
Sebastiaan van Stijn e01ce69ff9 cli/command/container: collect: handle context-cancellation
construct the decoder inside the go-routine, including closing the body,
and add handling for context-cancellation.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-28 13:29:43 +01:00
Sebastiaan van Stijn 292001a451 cli/command/container: RunStats: early return for non-streaming
We should consider splitting this out to a separate function, but
start with just an early return before we hit the timer-loop.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-28 12:36:14 +01:00
Sebastiaan van Stijn 0b1c7bc0f1 cli/command/container: RunStats: small tweaks on closeChan
Some suggestions from ChatGPT to prevent deadlocks.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-28 12:36:10 +01:00
Sebastiaan van Stijn d309027d58 cli/command/container: RunStats: gracefully handle io.EOF
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-28 12:08:55 +01:00
Sebastiaan van Stijn 15b422b317 cli/command/container: RunStats: handle context-cancellation
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-28 12:08:54 +01:00
Sebastiaan van Stijn 832fc66ca7 cli/command/container: RunStats: simplify stats loop
Use a single select for the ticker and the closeChan; use early returns.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-28 12:08:54 +01:00
Sebastiaan van Stijn dad1d367c8 cli/command/container: move debug logs to call-site
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-28 12:08:54 +01:00
Austin VazquezandGitHub e50c94f21a Merge pull request #6581 from thaJeztah/stats_ostype
cli/command/container: don't depend on result.OSType
2025-10-27 21:43:53 -05:00
Austin VazquezandGitHub 93cd6793b3 Merge pull request #6580 from thaJeztah/no_json
cli/command/image: remove uses of JSON field
2025-10-27 21:42:29 -05:00
Sebastiaan van Stijn f594a7f09b cli/command/image: remove uses of JSON field
The JSON field was added in [moby@9fd2c0f], to address [moby#19177], which
reported an incompatibility with Classic (V1) Swarm, which produced a non-
standard response;

> Make docker load to output json when the response content type is json
> Swarm hijacks the response from docker load and returns JSON rather
> than plain text like the Engine does. This makes the API library to return
> information to figure that out.

A later change in [moby@96d7db6] added additional logic to make sure the
correct content-type was returned, depending on whether the `quiet` option
was set (which produced a non-JSON response). This caused inconsistency in
the API response, and [moby@2f27632] changed the endpoint to always produce
JSON (only skipping the "progress" output if `quiet` was set).

This means that the "load" endpoint ([`imageRouter.postImagesLoad`]) now
unconditionally returns JSON, making the `JSON` field fully redundant.

This patch removes the use of the JSON field, as it's redundant, and the way it handles
the content-type is incorrect because it would not handle correct, but different
formatted response-headers (`application/json; charset=utf-8`), which could
result in malformed output on the client.

[moby@9fd2c0f]: https://github.com/moby/moby/commit/9fd2c0feb0c131d01d727d50baa7183b976c7bdc
[moby#19177]: https://github.com/moby/moby/issues/19177
[moby@96d7db6]: https://github.com/moby/moby/commit/96d7db665b06cc0bbede22d818c69dc5f6921f66
[moby@2f27632]: https://github.com/moby/moby/commit/2f27632cde2f0e514bd3a8de77cc1934e5193a83
[`imageRouter.postImagesLoad`]: https://github.com/moby/moby/blob/7b9d2ef6e5518a3d3f3cc418459f8df786cfbbd1/api/server/router/image/image_routes.go#L248-L255

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-27 21:37:36 +01:00
Sebastiaan van Stijn 4b498addce cli/command/container: don't depend on result.OSType
This field is set for the request as a whole, so can be obtained
from the server-info instead. Docker v29 will provide per-stats
information.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-27 21:35:25 +01:00
Sebastiaan van StijnandGitHub 715467c9d8 Merge pull request #6569 from jsternberg/otel-sdk-lock-version
telemetry: lock the semconv version of the otel sdk
2025-10-27 21:17:09 +01:00
Sebastiaan van StijnandGitHub dafbfc2f7e Merge pull request #6576 from robmry/bump_modules_again
vendor: github.com/moby/moby/api, moby/moby/client master
2025-10-27 20:35:49 +01:00
Rob MurrayandSebastiaan van Stijn 4a608069a7 vendor: github.com/moby/moby/api, moby/moby/client master
Signed-off-by: Rob Murray <rob.murray@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-27 20:26:27 +01:00
Jonathan A. SternbergandSebastiaan van Stijn 153f7f10c9 telemetry: lock the semconv version of the otel sdk
This change prevents changes to the otel version from affecting the otel
sdk version. This is done by copying the telemetry sdk implementation
locally and using our own choice for semconv from within that.

This prevents a schema conflict from happening since the otel version of
the sdk gets implicitly updated whenever the semconv changes while we
have to manually change ours. Now, we manually change both and they're
locked to each other.

Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-27 11:44:59 +01:00
dependabot[bot]andGitHub aef2ef8c77 build(deps): bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 08:30:59 +00:00
Sebastiaan van StijnandGitHub 965a0e3518 Merge pull request #6575 from thaJeztah/bump_modules
vendor: github.com/moby/moby/api, moby/moby/client master
2025-10-26 17:40:19 +01:00
Sebastiaan van Stijn 4afbd6146b implement some ad-hoc mocks for responses
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-25 01:36:38 +02:00
Sebastiaan van Stijn 056e314645 vendor: github.com/moby/moby/api, moby/moby/client master
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-25 00:48:49 +02:00
Paweł Gronowski 64805c2959 image/list: Respect dangling filter when not using --all
Otherwise `docker images --filter dangling=true` won't work without
`--all`.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-24 20:46:41 +02:00
Paweł Gronowski e9a941001c image/list: Hide untagged images without --all
The `--tree` implementation already does this.

Make the behavior consistent for the legacy image list implementation.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-24 20:46:41 +02:00
Sebastiaan van StijnandGitHub f74cd147bb Merge pull request #6571 from thaJeztah/bump_modules
vendor: github.com/moby/moby/api, moby/moby/client master
2025-10-24 16:43:53 +02:00
Sebastiaan van Stijn 4f7c07cfc2 update local code for updated modules
Some tests had to be skipped as there's some issues to address, and
some of the result-types cannot be mocked / stubbed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-24 10:28:54 +02:00
Sebastiaan van Stijn aeb78091a0 vendor: github.com/moby/moby/api, moby/moby/client master
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-24 10:28:26 +02:00
Sebastiaan van StijnandGitHub 7b4cde6967 Merge pull request #6567 from thaJeztah/bump_modules
vendor: github.com/moby/moby/api, moby/moby/client master
2025-10-20 16:52:25 +02:00
Sebastiaan van Stijn 563f5fe335 vendor: github.com/moby/moby/api, moby/moby/client master
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-20 12:30:05 +02:00
Sebastiaan van StijnandGitHub 171a9b70b2 Merge pull request #6564 from vvoland/container-go123
cli/command/container: add go1.23 build constraint for range-over-func
2025-10-14 15:00:57 +02:00
Paweł Gronowski 5ba4c17d78 cli/command/container: Simplify with slices.Contains
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-14 14:47:59 +02:00
Paweł Gronowski d252afa6b0 cli/command/container: add go1.23 build constraint for range-over-func
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-14 14:43:54 +02:00
Paweł GronowskiandGitHub bc2aa4eed1 Merge pull request #6563 from thaJeztah/bump_modules
vendor: github.com/moby/moby/api v1.52.0-beta.2, moby/client v0.1.0-beta.2
2025-10-14 11:35:31 +02:00
Sebastiaan van Stijn 24e95b8682 vendor: github.com/moby/moby/api v1.52.0-beta.2, moby/client v0.1.0-beta.2
full diff:

- https://github.com/moby/moby/compare/0769fe708773...api/v1.52.0-beta.2
- https://github.com/moby/moby/compare/0769fe708773...client/v0.1.0-beta.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-14 10:43:33 +02:00
Sebastiaan van StijnandGitHub c844f92b58 Merge pull request #6562 from vvoland/update-go
update to go1.25.3
2025-10-14 10:28:33 +02:00
Sebastiaan van StijnandGitHub 07a79d68a6 Merge pull request #6561 from thaJeztah/deprecate_builder_utils
cli/command/image/build: deprecate `DefaultDockerfileName`, `DetectArchiveReader`, `WriteTempDockerfile`, `ResolveAndValidateContextPath`
2025-10-14 10:27:52 +02:00
Paweł Gronowski 2bcf047f90 update to go1.25.3
This release addresses breakage caused by a security patch included in
Go 1.25.2 and 1.24.8, which enforced overly restrictive validation on
the parsing of X.509 certificates. We've removed those restrictions
while maintaining the security fix that the initial release addressed.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-14 09:11:31 +02:00
Sebastiaan van Stijn 0f2f9e9c41 cli/command/image/build: deprecate ResolveAndValidateContextPath util
This utility was used internally and will be removed in the next release.
Use `DetectContextType` to detect the context-type, and use `GetContextFromLocalDir`,
`GetContextFromLocalDir`, `GetContextFromGitURL`, or `GetContextFromURL`
instead.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-13 15:42:03 +02:00
Sebastiaan van Stijn 6e1ff0bec1 cli/command/image/build: deprecate WriteTempDockerfile util
It was only used internal in the package.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-13 15:29:08 +02:00
Sebastiaan van Stijn c52fa073cd cli/command/image/build: deprecate DetectArchiveReader util
It was only used internal in the package.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-13 15:28:55 +02:00
Sebastiaan van Stijn f24bb4bc76 cli/command/image/build: deprecate DefaultDockerfileName const
It was only used internal in the package.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-13 15:20:32 +02:00
Paweł GronowskiandGitHub c599e9064e Merge pull request #6556 from thaJeztah/update_go1.25
update to go1.25.2
2025-10-13 12:52:23 +02:00
Paweł GronowskiandGitHub 68ec5bfe20 Merge pull request #6559 from thaJeztah/fix_filteropts_default
opts: FilterOpt: show empty string if no values are set
2025-10-13 12:31:45 +02:00
Sebastiaan van Stijn 130a3f5f87 update to go1.25.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-13 12:12:25 +02:00
Sebastiaan van Stijn e6d150be16 opts: FilterOpt: show empty string if no values are set
follow-up to f81816ef88

We could decide to not initialize a default, and do this only when
setting a value, but this may require more changes, so doing this
as a starting-point.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-13 12:09:26 +02:00
Paweł GronowskiandGitHub ecea0c01b3 Merge pull request #6557 from thaJeztah/bump_golangci_lint
Dockerfile: update golangci-lint to v2.5.0 (for go1.25)
2025-10-13 12:02:34 +02:00
Paweł GronowskiandGitHub 2027349052 Merge pull request #6555 from thaJeztah/remove_ResolveDefaultContext
cli/command: remove deprecated ResolveDefaultContext
2025-10-13 12:02:01 +02:00
Paweł GronowskiandGitHub bb31a8006e Merge pull request #6554 from thaJeztah/bump_goversioninfo
Dockerfile: bump github.com/josephspurrier/goversioninfo to v1.5.0
2025-10-13 12:00:35 +02:00
Paweł GronowskiandGitHub 8ecdfed2af Merge pull request #6552 from thaJeztah/update_gotestsum
Dockerfile: bump gotest.tools/gotestsum v1.13.0
2025-10-13 12:00:02 +02:00
Paweł GronowskiandGitHub 714c82a014 Merge pull request #6558 from thaJeztah/opts_deprecate_delete
opts: deprecate ListOpts.Delete()
2025-10-13 11:59:30 +02:00
Paweł GronowskiandGitHub aec24ba92c Merge pull request #6553 from thaJeztah/update_utils
Dockerfile: update buildx to v0.29.1, compose v2.40.0
2025-10-13 11:52:47 +02:00
Sebastiaan van Stijn 193db8ec41 opts: deprecate ListOpts.Delete()
This method was added as part of a refactor in [moby@1ba1138], at which
time it was used to delete original values for "--host" and "--volume"
after normalizing. This beccame redundant in [moby@6200002], which added
specialized options that used a validate function, which both validated
and normalized inputs.

It's no longer used, so let's mark it deprecated so that we can remove it.

[moby@1ba1138]: https://github.com/moby/moby/commit/1ba11384bf82f824b0efbab31aaca439cfba1b4f
[moby@6200002]: https://github.com/moby/moby/commit/6200002669874f3314856527fecd0c004060913c

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-13 11:47:39 +02:00
Sebastiaan van Stijn 5ad9fbdef7 Dockerfile: update golangci-lint to v2.5.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-13 10:16:14 +02:00
Sebastiaan van Stijn 7abc65bc06 cli/command: remove deprecated ResolveDefaultContext
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-11 00:40:22 +02:00
Sebastiaan van Stijn c2817e2d59 Dockerfile: bump github.com/josephspurrier/goversioninfo to v1.5.0
- Upgrade to Go 1.18 minimum version and remove ioutil references
- Move from Travis to GitHub Actions for CI
- Support multiple icons
- Add options to parse version string

full diff: https://github.com/josephspurrier/goversioninfo/compare/v1.4.1...v1.5.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-11 00:11:08 +02:00
Sebastiaan van Stijn f68d8f1f24 scripts/build/mkversioninfo: use permalink in comment
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-11 00:03:50 +02:00
Sebastiaan van Stijn 830e1d60ab Dockerfile: update compose to v2.40.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-10 23:59:38 +02:00
Sebastiaan van Stijn 9def7748a5 Dockerfile: update buildx to v0.29.1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-10 23:58:35 +02:00
Sebastiaan van Stijn f8b1b8d165 Dockerfile: bump gotest.tools/gotestsum v1.13.0
full diff: https://github.com/gotestyourself/gotestsum/compare/v1.12.3...v1.13.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-10 23:55:52 +02:00
Sebastiaan van StijnandGitHub 01febbc3bb Merge pull request #6551 from thaJeztah/remove_legacy_api_versions
remove API-version compatibility for API < v1.44
2025-10-10 22:53:01 +02:00
Sebastiaan van StijnandGitHub 59d228cd98 Merge pull request #6550 from thaJeztah/deprecate_builder_utils
cli/command/image/build: deprecate IsArchive utility
2025-10-10 22:46:27 +02:00
Sebastiaan van Stijn 5ad91456c7 docs: update some versions in examples
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-10 21:23:30 +02:00
Sebastiaan van Stijn 4c73cefc15 cli/command/container, image: remove addPlatformFlag utility
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-10 21:23:30 +02:00
Sebastiaan van Stijn b8f2b7c678 cli/command/service: remove AppendServiceStatus (API <v1.41)
This function was added in 7405ac5c2d as
a fallback for API < v1.41, which did not include the service status
in the response. Current API versions return this information, so there's
no need to fetch it manually.

It was not gated by API version for some tests (which didn't set API
version), but should not be needed for non-test situations.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-10 21:23:29 +02:00
Sebastiaan van Stijn f046bd371a cli/command/container: rm use of deprecated MacAddress field
This field is no longer in use since API v1.44.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-10 21:23:29 +02:00
Sebastiaan van Stijn d36f16e224 remove API-version compatibility for API < v1.44
Support for API versions < v1.44 was removed in the client in [moby@96b29f5]
and [moby@7652f38], so we can remove fallback-code from the CLI as well,
as it won't be able to use those versions.

[moby@96b29f5]: https://github.com/moby/moby/commit/96b29f5a1f7fc5e5d8b2b4dbd130e215bbb92ae9
[moby@7652f38]: https://github.com/moby/moby/commit/7652f38c289909bc61b1113c0570b9de345bbed9

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-10 21:23:25 +02:00
Sebastiaan van StijnandGitHub a3e954551d Merge pull request #6545 from thaJeztah/bump_engine_take2
vendor: github.com/moby/moby/api, client 0769fe708773 (master)
2025-10-10 19:45:23 +02:00
Sebastiaan van Stijn f81816ef88 vendor: github.com/moby/moby/api, client 0769fe708773 (master)
full diff: https://github.com/moby/moby/compare/4ca8aedf929f...0769fe708773892d6ac399ee137e71a777b35de7

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-10 19:35:00 +02:00
Sebastiaan van Stijn 9e646f6d92 cli/command/image: runBuild: inline vars and minor cleanups
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-10 17:25:04 +02:00
Sebastiaan van Stijn 64be664e85 cli/command/image/build: deprecate IsArchive utility
It was only used internally.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-10 17:23:57 +02:00
Sebastiaan van Stijn 2c539a6530 cli/command/image/build: fix linting, add sub-tests
- fix minor linting issues (unhandled errors)
- rename vars to prevent shadowing
- use sub-tests for tests that already prepared for it

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-10 17:21:57 +02:00
Austin VazquezandGitHub 6ddff81bee Merge pull request #6548 from thaJeztah/improve_TestRemove
e2e/stack: don't run stack deploy "detached"
2025-10-09 14:57:55 -05:00
Sebastiaan van Stijn 85ac71a3fe e2e/stack: don't run stack deploy "detached"
Run stack deploy in "attached" mode, so that progress and errors
can be printed on failure.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-09 17:19:41 +02:00
Austin VazquezandGitHub 41432adc36 Merge pull request #6547 from thaJeztah/deprecate_ValidateMACAddress
opts: deprecate ValidateMACAddress
2025-10-09 09:13:34 -05:00
Sebastiaan van Stijn 17d6a92954 opts: deprecate ValidateMACAddress
It was a wrapper around net.ParseMAC from stdlib, so users should
use that directly.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-09 13:46:33 +02:00
Sebastiaan van StijnandGitHub 94788a3b63 Merge pull request #6546 from thaJeztah/test_improvements
assorted test-improvements
2025-10-09 12:46:00 +02:00
Sebastiaan van Stijn af34b8471a cli/command/network: TestNetworkCreateWithFlags: fix unhandled errs
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-09 12:29:56 +02:00
Sebastiaan van Stijn c8014ec509 cli/command/network: TestNetworkCreateErrors: use sub-tests
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-09 12:22:08 +02:00
Sebastiaan van Stijn 413ee120de cli/command/container: TestParseWithExpose: use sub-tests
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-09 12:13:25 +02:00
Sebastiaan van Stijn 7923f440ed cli/command/container: update todo comment
Provide some context to the TODO

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-09 11:51:07 +02:00
Sebastiaan van StijnandGitHub b1ea4fe9d9 Merge pull request #6543 from docker/dependabot/github_actions/github/codeql-action-4
build(deps): bump github/codeql-action from 3 to 4
2025-10-08 16:22:13 +02:00
dependabot[bot]andGitHub 5483b10e94 build(deps): bump github/codeql-action from 3 to 4
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-08 08:04:23 +00:00
Austin VazquezandGitHub 9f941a49c1 Merge pull request #6540 from vvoland/update-go
update to go1.24.8
2025-10-07 19:47:18 -07:00
Paweł Gronowski e598ea0176 update to go1.24.8
This minor release includes 10 security fixes following the security policy:

- net/mail: excessive CPU consumption in ParseAddress

    The ParseAddress function constructed domain-literal address components through repeated string concatenation. When parsing large domain-literal components, this could cause excessive CPU consumption.

    Thanks to Philippe Antoine (Catena cyber) for reporting this issue.

    This is CVE-2025-61725 and Go issue https://go.dev/issue/75680.

- crypto/x509: quadratic complexity when checking name constraints

    Due to the design of the name constraint checking algorithm, the processing time
    of some inputs scales non-linearly with respect to the size of the certificate.

    This affects programs which validate arbitrary certificate chains.

    Thanks to Jakub Ciolek for reporting this issue.

    This is CVE-2025-58187 and Go issue https://go.dev/issue/75681.

- crypto/tls: ALPN negotiation errors can contain arbitrary text

    The crypto/tls conn.Handshake method returns an error on the server-side when
    ALPN negotation fails which can contain arbitrary attacker controlled
    information provided by the client-side of the connection which is not escaped.

    This affects programs which log these errors without any additional form of
    sanitization, and may allow injection of attacker controlled information into
    logs.

    Thanks to National Cyber Security Centre Finland for reporting this issue.

    This is CVE-2025-58189 and Go issue https://go.dev/issue/75652.

- encoding/pem: quadratic complexity when parsing some invalid inputs

    Due to the design of the PEM parsing function, the processing time for some
    inputs scales non-linearly with respect to the size of the input.

    This affects programs which parse untrusted PEM inputs.

    Thanks to Jakub Ciolek for reporting this issue.

    This is CVE-2025-61723 and Go issue https://go.dev/issue/75676.

- net/url: insufficient validation of bracketed IPv6 hostnames

    The Parse function permitted values other than IPv6 addresses to be included in square brackets within the host component of a URL. RFC 3986 permits IPv6 addresses to be included within the host component, enclosed within square brackets. For example: "http://[::1]/". IPv4 addresses and hostnames must not appear within square brackets. Parse did not enforce this requirement.

    Thanks to Enze Wang, Jingcheng Yang and Zehui Miao of Tsinghua University for reporting this issue.

    This is CVE-2025-47912 and Go issue https://go.dev/issue/75678.

- encoding/asn1: pre-allocating memory when parsing DER payload can cause memory exhaustion

    When parsing DER payloads, memories were being allocated prior to fully validating the payloads.
    This permits an attacker to craft a big empty DER payload to cause memory exhaustion in functions such as asn1.Unmarshal, x509.ParseCertificateRequest, and ocsp.ParseResponse.

    Thanks to Jakub Ciolek for reporting this issue.

    This is CVE-2025-58185 and Go issue https://go.dev/issue/75671.

- net/http: lack of limit when parsing cookies can cause memory exhaustion

    Despite HTTP headers having a default limit of 1 MB, the number of cookies that can be parsed did not have a limit.
    By sending a lot of very small cookies such as "a=;", an attacker can make an HTTP server allocate a large amount of structs, causing large memory consumption.

    net/http now limits the number of cookies accepted to 3000, which can be adjusted using the httpcookiemaxnum GODEBUG option.

    Thanks to jub0bs for reporting this issue.

    This is CVE-2025-58186 and Go issue https://go.dev/issue/75672.

- crypto/x509: panic when validating certificates with DSA public keys

    Validating certificate chains which contain DSA public keys can cause programs
    to panic, due to a interface cast that assumes they implement the Equal method.

    This affects programs which validate arbitrary certificate chains.

    Thanks to Jakub Ciolek for reporting this issue.

    This is CVE-2025-58188 and Go issue https://go.dev/issue/75675.

- archive/tar: unbounded allocation when parsing GNU sparse map

    tar.Reader did not set a maximum size on the number of sparse region data blocks in GNU tar pax 1.0 sparse files. A maliciously-crafted archive containing a large number of sparse regions could cause a Reader to read an unbounded amount of data from the archive into memory. When reading from a compressed source, a small compressed input could result in large allocations.

    Thanks to Harshit Gupta (Mr HAX) - https://www.linkedin.com/in/iam-harshit-gupta/ for reporting this issue.

    This is CVE-2025-58183 and Go issue https://go.dev/issue/75677.

- net/textproto: excessive CPU consumption in Reader.ReadResponse

    The Reader.ReadResponse function constructed a response string through
    repeated string concatenation of lines. When the number of lines in a response is large,
    this could cause excessive CPU consumption.

    Thanks to Jakub Ciolek for reporting this issue.

    This is CVE-2025-61724 and Go issue https://go.dev/issue/75716.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-10-07 21:46:51 +02:00
Austin VazquezandGitHub d17643a675 Merge pull request #6537 from thaJeztah/no_nw_shadow
rename some vars to prevent shadowing imports
2025-10-07 06:31:30 -07:00
Sebastiaan van Stijn 3754fe3c8a rename some vars to prevent shadowing imports
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-06 22:49:02 +02:00
Austin VazquezandGitHub 30ec4c09b3 Merge pull request #6536 from thaJeztah/cleanups
cli/command/container: inline some variables
2025-10-06 13:21:31 -07:00
Austin VazquezandGitHub 6d351158cc Merge pull request #6535 from thaJeztah/remove_localhostDNSWarning
cli/command/container: remove localhostDNSWarning
2025-10-06 13:10:37 -07:00
Sebastiaan van Stijn 6222292566 cli/command/container: inline some variables
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-06 21:26:17 +02:00
Sebastiaan van Stijn c06c08531a cli/command/container: remove localhostDNSWarning
This warning is better handled by the daemon, where applicable, as
the client does not have all information available to determine
if using a localhost / loopback-address for the DNS is possible.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-06 21:23:50 +02:00
Paweł GronowskiandGitHub 74e3520724 Merge pull request #6530 from thaJeztah/bump_macos
gha: add macOS 15, remove macOS 13 (deprecated)
2025-10-03 14:04:10 +00:00
Paweł GronowskiandGitHub 886e041790 Merge pull request #6532 from thaJeztah/bump_creds_helper_0.9.4
vendor: github.com/docker/docker-credential-helpers v0.9.4
2025-10-03 14:02:59 +00:00
Paweł GronowskiandGitHub 9dea52c193 Merge pull request #6527 from thaJeztah/no_WithInitializeClient
cli/command: don't use WithInitializeClient in test
2025-10-03 14:02:37 +00:00
Paweł GronowskiandGitHub 780c427550 Merge pull request #6526 from thaJeztah/no_plugin_load
cmd/docker: setFlagErrorFunc: don't load plugins for invalid flags
2025-10-03 14:02:16 +00:00
Sebastiaan van StijnandGitHub ca6f899a58 Merge pull request #6525 from thaJeztah/rm_client_side_autorm
remove support for AutoRemove (`--rm`) on API < 1.30
2025-10-03 11:58:03 +02:00
Sebastiaan van Stijn 395152ce88 vendor: github.com/docker/docker-credential-helpers v0.9.4
full diff: https://github.com/docker/docker-credential-helpers/compare/v0.9.3...v0.9.4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-02 22:25:45 +02:00
Paweł GronowskiandGitHub f5a7a3c72e Merge pull request #6528 from thaJeztah/deprecate_ResolveDefaultContext
cli/command: deprecate ResolveDefaultContext
2025-10-01 13:25:04 +00:00
Sebastiaan van StijnandGitHub 394ab41696 Merge pull request #6524 from thaJeztah/rm_deprecated_virtualsize
remove VirtualSize formatting options and output
2025-10-01 12:09:25 +02:00
Sebastiaan van Stijn 91d8c0bf62 gha: add macOS 15, remove macOS 13 (deprecated)
The macOS 13 runners are deprecated and will be removed on December 4th,
with brownouts in November;
https://github.blog/changelog/2025-09-19-github-actions-macos-13-runner-image-is-closing-down/

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-01 11:59:56 +02:00
Sebastiaan van Stijn 311a97a210 cli/command: deprecate ResolveDefaultContext
The ResolveDefaultContext function was exported in [cli@f820766] to allow
(unit) testing, but did not document that it was only exported for this
purpose. The only external use of this function is in buildx, which uses
it in a unit test that can be implemented without this function.

This patch deprecates the function so that we can remove it.

[cli@f820766]: https://github.com/docker/cli/commit/f820766f6ac57188d96c9ca377f2b4627e90da28

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-01 11:47:24 +02:00
Sebastiaan van Stijn b375006c3e cli/command: don't use WithInitializeClient in test
It's just a wrapper around WithAPIClient, and not needed for this
test, which validates that "Initialize" properly creates the context
store, even if a client was already set;
3b26cfce8b

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-01 10:12:11 +02:00
Sebastiaan van Stijn b0201c8531 cmd/docker: hideUnsupportedFeatures: remove unused error return
```
70.72 cmd/docker/docker.go:560:74: hideUnsupportedFeatures - result 0 (error) is always nil (unparam)
70.72 func hideUnsupportedFeatures(cmd *cobra.Command, details versionDetails) error {
70.72                                                                          ^
70.72 1 issues:
```

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-01 01:57:59 +02:00
Sebastiaan van Stijn 2b4fd0d750 cmd/docker: setFlagErrorFunc: don't load plugins for invalid flags
On Docker CLI versions before v28.0.0, using an unknown flag would print
the usage output, showing all available top-level flags and commands;

    docker --badopt
    unknown flag: --badopt
    See 'docker --help'.

    Usage:  docker [OPTIONS] COMMAND

    A self-sufficient runtime for containers

    Options:
          --config string      Location of client config files (default "/root/.docker")
    ...

This output did not include plugin-commands, making the usage output
incomplete. That issue was fixed in [cli@40a6cf7], which loaded all
available cli-plugins, so that a stub was created for printing the
plugin commands in the usage output. Similarly, [cli@79a75da] added
code to hide experimental commands and commands not supported by the
daemon.

However, since 28.0.0 (commit [cli@f28fc7f]), the usage output was
removed for this error, so loading plugins is no longer needed;

    docker --badopt
    unknown flag: --badopt

    Usage:  docker [OPTIONS] COMMAND [ARG...]

    Run 'docker --help' for more information

This patch removes the code added in [cli@40a6cf7] and [cli@79a75da].

With this patch, the output is still the same;

    docker --unknown-flag buildx ls --no-such
    unknown flag: --unknown-flag

    Usage:  docker [OPTIONS] COMMAND [ARG...]

    Run 'docker --help' for more information

This function only handles flags defined by the CLI itself; invalid
flags for plugins are handled by the plugin itself, so are not
impacted;

    docker buildx ls --no-such
    unknown flag: --no-such

    Usage:  docker buildx ls

    Run 'docker buildx ls --help' for more information

[cli@f28fc7f]: https://github.com/docker/cli/commit/f28fc7f82fc87d0ed521de452b6227cee76fd956
[cli@40a6cf7]: https://github.com/docker/cli/commit/40a6cf7c477cf328134b0b8dcdbd9a09d02f918b
[cli@79a75da]: https://github.com/docker/cli/commit/79a75da0fd97b02311676028c3406b242c785f7c

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-01 01:15:53 +02:00
Sebastiaan van Stijn 63c5254201 remove support for AutoRemove (--rm) on API < 1.30
Support for daemon-side auto-remove was added in API v1.25; on older
versions of the daemon, the client was responsible for removing the
container after it exited (see [moby@6dd8e10])

On API versions < 1.30, it used the events API for this purpose, and
would wait for a "die", "detach" or "detroy" events to know the container
exited, and could be removed or (when attached, but without a TTY) to
get the container's exit-status. (see [cli@38591f2]).

API version 1.24 (docker 1.12) is 9 Years old (July 29, 2016), and API
1.30 (docker 17.06) is 8 Years old (Jun 20, 2017), and long EOL. While
technically, a CLI could negotiate API 1.30 or older, this would only
be in cases where either API version negotiation failed, or the version
was explicitly overridden through `DOCKER_API_VERSION` for testing.

Either of those cases would be rare, and not worth the technical complexity
to support. This patch removes support for AutoRemove on API < 1.30.

[moby@6dd8e10]: https://github.com/moby/moby/commit/6dd8e10d6ed7a7371c5c1824ad58c4403a7b3bfd
[cli@38591f2]: https://github.com/docker/cli/commit/38591f20d07795aaef45d400df89ca12f29c603b

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-30 18:16:57 +02:00
Sebastiaan van Stijn 1b90a53be2 remove deprecated VirtualSize formatting options and output
The `VirtualSize` field was deprecated in [moby@1261fe6], and omitted / removed
in API v1.44 in [moby@913b0f5], and the corresponding formatting placeholder
was deprecated in [cli@f02301a].

This patch removes the formatting function, which also removes it from the
`docker image ls --format=json` output.

[moby@1261fe6]: https://github.com/moby/moby/commit/1261fe69a3586bb102182aa885197822419c768c
[moby@913b0f5]: https://github.com/moby/moby/commit/913b0f51cab18a56247a950f5f1e75ca79b63039
[cli@f02301a]: https://github.com/docker/cli/commit/f02301ab5d38f98362d3f4c6975580c27fa750aa

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-30 16:31:57 +02:00
Sebastiaan van Stijn c361deb85d docs, man: image ls: remove VirtualSize from examples
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-30 16:26:06 +02:00
Sebastiaan van Stijn adfcb88896 man: inspect: update some inspect examples
remove various deprecated fields from the example

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-30 16:23:19 +02:00
Austin VazquezandGitHub 9c79528489 Merge pull request #6523 from thaJeztah/rm_deprecated
cli/manifest/store: remove deprecated IsNotFound
2025-09-30 05:36:34 -07:00
Austin VazquezandGitHub 9874437110 Merge pull request #6521 from thaJeztah/bump_moby
vendor: github.com/moby/moby/api, moby/client master
2025-09-30 05:35:30 -07:00
Sebastiaan van Stijn 39d9a0cd51 cli/manifest/store: remove deprecated IsNotFound
This was deprecated in f3fb7728c7, which
is part of 28.5.0, and no longer used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-30 12:59:02 +02:00
Sebastiaan van Stijn 9d97363f8f vendor: github.com/moby/moby/api, moby/client master
full diff: https://github.com/moby/moby/compare/9a97f59e6e2d51818f6b8cf8589199fd6714ebc7...4ca8aedf929f726ac68f96482e2fb704a72b1326

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-30 10:43:02 +02:00
Sebastiaan van StijnandGitHub 21e768adb7 Merge pull request #6520 from thaJeztah/bump_moby
vendor: github.com/moby/moby/api, moby/client master
2025-09-30 09:31:05 +02:00
Sebastiaan van StijnandAustin Vazquez cdcf267264 vendor: github.com/moby/moby/api, moby/client master
full diff: https://github.com/moby/moby/compare/e98849831fc4...9a97f59e6e2d51818f6b8cf8589199fd6714ebc7

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-29 18:00:59 -05:00
Austin VazquezandGitHub f8932e916b Merge pull request #6515 from thaJeztah/rm_authconfig_email
cli/config/types: remove deprecated AuthConfig.Email field
2025-09-29 16:00:21 -07:00
Sebastiaan van StijnandAustin Vazquez e9664b9f34 cli/config/types: remove deprecated AuthConfig.Email field
Relates to [cli@27b2797], which forked this type from the Moby API, and
[cli@aab947d], which fixed the deprecation comment.

This field is no longer used since Docker 1.11 (API version 1.23) through
[moby@aee260d] and [engine-api@9a9e468], and the fix of the deprecation
comment was included in the 28.4.0 release.

This patch removes the field.

[cli@27b2797]: https://github.com/docker/cli/commit/27b2797f7deb3ca5b7f80371d825113deb1faca1
[cli@aab947d]: https://github.com/docker/cli/commit/aab947de8f5cd2db3dd9d8ead0f38d3246557750
[moby@aee260d]: https://github.com/moby/moby/commit/aee260d4eb3aa0fc86ee5038010b7bbc24512ae5
[engine-api@9a9e468]: https://github.com/docker-archive-public/docker.engine-api/commit/9a9e468f503eb731d6fdc9d7f98c122e1b397c86

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-29 17:50:54 -05:00
Austin VazquezandGitHub a61ecaf3c7 Merge pull request #6516 from thaJeztah/authconfig_no_direct_cast
cli/command: explicitly map AuthConfig fields instead of a direct cast
2025-09-29 15:49:22 -07:00
Austin VazquezandGitHub 7e8b893952 Merge pull request #6517 from thaJeztah/memstore_notfounderr
cli/config/memorystore: remove unused IsErrValueNotFound
2025-09-29 15:13:24 -07:00
Austin VazquezandGitHub 5a4758f513 Merge pull request #6513 from thaJeztah/manifeststore_notfound
cli/manifest/store: deprecate IsNotFound
2025-09-29 15:11:13 -07:00
Austin VazquezandGitHub 1b467f909c Merge pull request #6512 from thaJeztah/less_trust
remove some uses of trust-specific types
2025-09-29 15:02:31 -07:00
Sebastiaan van Stijn 3c78ac2aad cli/config/memorystore: remove unused IsErrValueNotFound
This utility was added in 9b83d5bbf9, but
was never used. Remove the utility, and rewrite the error returned to
implement the errdefs.NotFound interface, so that it can be detected
using the errdefs.IsNotFound() utility if needed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-29 13:05:08 +02:00
Sebastiaan van Stijn 9f02d9643d cli/command: explicitly map AuthConfig fields instead of a direct cast
Commit [cli@27b2797] forked the AuthConfig type from the API, and changed
existing code to do a direct cast / convert of the forked type to the API
type. This can cause issues if the API types diverges, such as the removal
of the Email field.

This patch explicitly maps each field to the corresponding API type, but
adds some TODOs, because various code-paths only included a subset of the
fields, which may be intentional for fields that were meant to be handled
on the daemon / registry-client only.

We should evaluate these conversions to make sure these fields should
be sent from the client or not (and possibly even removed from the API
type).

[cli@27b2797]: https://github.com/docker/cli/commit/27b2797f7deb3ca5b7f80371d825113deb1faca1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-29 12:57:52 +02:00
Sebastiaan van Stijn f3fb7728c7 cli/manifest/store: deprecate IsNotFound
Deprecate the IsNotFound utility in favor of errdefs.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-26 23:33:01 +02:00
Sebastiaan van Stijn 0dec83f572 cli/command/image: imagePullPrivileged: move to non-trust file
This function is a wrapper around apiClient.ImagePull and not directly
related to docker content trust; it just happens to also be called
when using content trust (through the trustedPull utility).

Move it together with the `runPull` function to separate it from
trust-related code.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-26 20:06:32 +02:00
Sebastiaan van Stijn e58a6ace45 cli/command/image: imagePullPrivileged: don't use ImageRefAndAuth
This function is a wrapper around apiClient.ImagePull; the use of
trust.ImageRefAndAuth was out of convenience because it's also called
when using content trust (through the trustedPull utility).

Let's pull away the layers to separate it from trust code.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-26 20:06:32 +02:00
Sebastiaan van Stijn a6946d0fbf cli/command/image: notaryClientProvider: don't require arguments
This interface is used in tests to provide a dummy notary client,
but none of the tests require any arguments, so let's remove them.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-26 20:06:26 +02:00
Sebastiaan van Stijn c3317b0a43 cli/trust: Server: accept registry hostname
The IndexInfo was only used to detect if the target was an official
image, which we can deduct from the hostname. Adding some normalizing
just in case (but we should only get "docker.io" here).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-26 18:51:32 +02:00
Sebastiaan van StijnandGitHub 75f3c08257 Merge pull request #6505 from thaJeztah/bump_runewidth
vendor: github.com/mattn/go-runewidth v0.0.17
2025-09-26 11:31:18 +02:00
Sebastiaan van StijnandGitHub aaed38f5d5 Merge pull request #6507 from thaJeztah/split_trust_auth
cli/command/image: pushTrustedReference: internalize constructing indexInfo
2025-09-26 11:24:31 +02:00
Paweł GronowskiandGitHub fdf9b43ca8 Merge pull request #6506 from thaJeztah/bump_mapstructure
vendor: github.com/go-viper/mapstructure/v2 v2.4.0
2025-09-26 09:22:38 +00:00
Paweł GronowskiandGitHub 95735d1631 Merge pull request #6504 from thaJeztah/bump_protobuf
vendor: google.golang.org/protobuf v1.36.9
2025-09-26 09:22:29 +00:00
Paweł GronowskiandGitHub 013c41c602 Merge pull request #6508 from thaJeztah/dct_retiring
trust: print deprecation warning when using hub Notary server
2025-09-26 09:16:45 +00:00
Sebastiaan van Stijn 43b03ef2c5 trust: print deprecation warning when using hub Notary server
Docker Hub's Notary service is being retired, and now produces
failures in most cases. Add a warning when attempting to use
it, pending full removal of trust;
https://www.docker.com/blog/retiring-docker-content-trust/

With this PR:

    DOCKER_CONTENT_TRUST=1 docker pull -q hello-world
    WARNING: Docker is retiring DCT for Docker Official Images (DOI).
             For details, refer to https://docs.docker.com/go/dct-deprecation/

    could not validate the path to a trusted root: unable to retrieve valid leaf certificates

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-26 11:09:07 +02:00
Sebastiaan van Stijn 9a6313ed3b cli/command/image: pushTrustedReference: internalize constructing indexInfo
All information needed can be deducted from the image reference, which
is used to create a indexInfo, repoInfo, and to resolve auth-config.

In some situations this may result in resolving the auth-config twice
after it already was resolved to an encoded auth-config.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-26 10:09:12 +02:00
Sebastiaan van Stijn 20e5dc9469 vendor: github.com/go-viper/mapstructure/v2 v2.4.0
full diff: https://github.com/go-viper/mapstructure/compare/v2.2.1...v2.4.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 19:47:12 +02:00
Sebastiaan van Stijn 4287f1d887 vendor: github.com/mattn/go-runewidth v0.0.17
full diff: https://github.com/mattn/go-runewidth/compare/v0.0.16...v0.0.17

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 19:44:27 +02:00
Sebastiaan van Stijn 746d7cb39e vendor: google.golang.org/protobuf v1.36.9
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 19:41:34 +02:00
Sebastiaan van StijnandGitHub 6855d70c52 Merge pull request #6503 from thaJeztah/rm_apply
cli/command: remove deprecated DockerCli.Apply
2025-09-25 18:43:28 +02:00
Sebastiaan van StijnandGitHub 1a80524834 Merge pull request #6502 from thaJeztah/rm_deprecated
cli/command: remove deprecated methods and options
2025-09-25 18:42:48 +02:00
Sebastiaan van StijnandGitHub d719b416ab Merge pull request #6500 from thaJeztah/bump_go_events
vendor: github.com/docker/go-events v0.0.0-20250808211157-605354379745
2025-09-25 18:42:17 +02:00
Sebastiaan van StijnandGitHub 008b2df526 Merge pull request #6499 from thaJeztah/bump_swarmkit
vendor: github.com/moby/swarmkit/v2 v2.1.0
2025-09-25 18:41:50 +02:00
Sebastiaan van StijnandGitHub 96732f858a Merge pull request #6498 from thaJeztah/bump_jose
vendor: github.com/go-jose/go-jose/v4 v4.1.2
2025-09-25 18:41:17 +02:00
Sebastiaan van Stijn 1b085a2b63 cli/command: remove deprecated DockerCli.Apply
The Apply method was added when CLI options for constructing the CLI were
rewritten into functional options in [cli@7f207f3]. There was no mention
in the pull request of this method specifically, and this may have been
related to work being done elsewhere on compose-on-kubernetes or the
compose-cli plugin that may have needed options to modify the CLI config
after it was already initialized.

The CLI itself no longer depends on this method since [cli@133279f], and
there are no known external users. It was deprecated in [cli@24bfedf],
which is included in the 28.5.0 release, so we can remove it for 29.0.

[cli@7f207f3]: https://github.com/docker/cli/commit/7f207f3f957ed3f5129aeb22bef2a429c14caf22
[cli@133279f]: https://github.com/docker/cli/commit/133279fb0d4adea30d27d27eb8789b79405fc82b
[cli@24bfedf]: https://github.com/docker/cli/commit/24bfedf3f88762bcd46e6452d6547d838f780e6b

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 18:16:20 +02:00
Sebastiaan van Stijn b0cb6406ff cli/command: remove Apply from Cli interface
The Apply command was deprecated in 24bfedf3f8,
and has no known external users, but we didn't remove it from the interface.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 18:09:10 +02:00
Sebastiaan van Stijn 782deffe83 cli/command: remove deprecated DockerCli.DefaultVersion
This function was used internally, but is no longer used.

This method was deprecated in 0270b2d6f7,
which was included in the 28.5.0 release, and has no known external users,
so removing it for 29.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 17:51:09 +02:00
Sebastiaan van Stijn e25843bfb6 cli/command: remove deprecated WithContentTrustFromEnv, WithContentTrust
These options were used internally as defaults for the constructor and
only impact commands implemented in the CLI itself.

They were deprecated in 40cdfc0d81, which
was included in the 28.5.0 release, so removing it for 29.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 17:47:51 +02:00
Sebastiaan van Stijn 592afa8c73 cli/command: remove deprecated DockerCli.ContentTrustEnabled
This function was used internally, but is no longer used. Users should check
the value of the `DOCKER_CONTENT_TRUST` environment variable instead.

This method was deprecated in 11d40488dd,
which was included in the 28.5.0 release, and has no known external users,
so removing it for 29.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 17:42:36 +02:00
Sebastiaan van Stijn 6d1c037640 vendor: github.com/docker/go-events v0.0.0-20250808211157-605354379745
full diff: https://github.com/docker/go-events/compare/c867878c5e32...605354379745

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 15:13:31 +02:00
Sebastiaan van Stijn 9cba658e9a vendor: github.com/moby/swarmkit/v2 v2.1.0
full diff: https://github.com/moby/swarmkit/compare/v2.0.0...v2.1.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 15:07:05 +02:00
Sebastiaan van Stijn 57314d42a2 vendor: github.com/go-jose/go-jose/v4 v4.1.2
full diff: https://github.com/go-jose/go-jose/compare/v4.0.5...v4.1.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 14:58:11 +02:00
Sebastiaan van Stijn e922dbefca vendor: golang.org/x/crypto v0.39.0
no changes in vendored files

full diff: https://github.com/golang/crypto/compare/v0.37.0...v0.39.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 14:58:05 +02:00
Sebastiaan van Stijn 286658d7ff vendor: golang.org/x/text v0.26.0
no changes in vendored files

full diff: https://github.com/golang/text/compare/v0.24.0...v0.26.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 14:55:03 +02:00
Sebastiaan van Stijn 90959c40bd vendor: golang.org/x/term v0.32.0
full diff: https://github.com/golang/term/compare/v0.31.0...v0.32.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 14:54:18 +02:00
Paweł GronowskiandGitHub f369c5bcf2 Merge pull request #6496 from thaJeztah/deprecate_apply
cli/command: deprecate DockerCli.Apply
2025-09-25 12:29:19 +00:00
Sebastiaan van Stijn 24bfedf3f8 cli/command: deprecate DockerCli.Apply
The Apply method was added when CLI options for constructing the CLI were
rewritten into functional options in [cli@7f207f3]. There was no mention
in the pull request of this method specifically, and this may have been
related to work being done elsewhere on compose-on-kubernetes or the
compose-cli plugin that may have needed options to modify the CLI config
after it was already initialized.

The CLI itself no longer depends on this method since [cli@133279f], and
the only known consumer (docker compose) no longer needs it since [cli@2711800]
and [cli@048e931].

This patch deprecates the method with the intent to remove it in a future
release.

[cli@7f207f3]: https://github.com/docker/cli/commit/7f207f3f957ed3f5129aeb22bef2a429c14caf22
[cli@133279f]: https://github.com/docker/cli/commit/133279fb0d4adea30d27d27eb8789b79405fc82b
[cli@2711800]: https://github.com/docker/cli/commit/271180043066ec1baaa91351a63f1854667171d4
[cli@048e931]: https://github.com/docker/cli/commit/048e931b422a6baa26d12f818bbb14c501164c09

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 13:27:28 +02:00
Paweł GronowskiandGitHub ef3c19a80b Merge pull request #6494 from thaJeztah/deprecate_ContentTrustEnabled
cli/command: deprecate DockerCli.ContentTrustEnabled
2025-09-25 11:24:05 +00:00
Sebastiaan van Stijn 11d40488dd cli/command: deprecate DockerCli.ContentTrustEnabled
This function was used internally, but is no longer used. Users should check
the value of the `DOCKER_CONTENT_TRUST` environment variable instead.

There are no known external users of this method, so already removing it
from the Cli interface; this method will be removed in the next release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 12:45:13 +02:00
Sebastiaan van Stijn 1bae6aafa8 trust: add internal utility for checking DOCKER_CONTENT_TRUST
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 12:45:08 +02:00
Sebastiaan van Stijn 1ace9aec34 cli/command: don't use DCT status for trust stub-flags
This is a follow-up to 7609dde8d0 and
3f5b1bdd32, which removed support for
DCT for build and plugin commands.

As these flags are just stubs, hidden by default and no longer functional,
they don't have to reflect the current state of DCT.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 12:39:28 +02:00
Paweł GronowskiandGitHub 734328eef9 Merge pull request #6492 from thaJeztah/fix_alpine
e2e: update openssh, openssl to work around openssh bug
2025-09-25 11:39:52 +02:00
Paweł GronowskiandGitHub 9c88b315ef Merge pull request #6488 from thaJeztah/deprecate_dct_opts
cli/command: deprecate WithContentTrustFromEnv, WithContentTrust
2025-09-25 11:31:55 +02:00
Paweł GronowskiandGitHub 04bfe7dc78 Merge pull request #6490 from thaJeztah/deprecate_defaultversion
cli/command: deprecate DockerCli.DefaultVersion
2025-09-25 11:31:27 +02:00
Sebastiaan van Stijn b611f288ee e2e: update openssh, openssl to work around openssh bug
relates to https://gitlab.alpinelinux.org/alpine/aports/-/issues/17547

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 10:57:14 +02:00
Sebastiaan van Stijn 40cdfc0d81 cli/command: deprecate WithContentTrustFromEnv, WithContentTrust
These options were used internally as defaults for the constructor and
only impact commands implemented in the CLI itself.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 09:57:28 +02:00
Sebastiaan van Stijn 0270b2d6f7 cli/command: deprecate DockerCli.DefaultVersion
This function was used internally, but is no longer used. There are
no known users of this method, so already removing it from the Cli
interface.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 09:38:46 +02:00
Austin VazquezandGitHub 903e9b3426 Merge pull request #6453 from thaJeztah/rm_deprecated_template
templates: remove deprecated NewParse function
2025-09-24 10:40:45 -07:00
Paweł GronowskiandGitHub a44144e1db Merge pull request #6479 from thaJeztah/plugin_semverish
cli-plugins/manager: allow schema-versions <= 2.0.0
2025-09-24 19:25:43 +02:00
Paweł GronowskiandGitHub ed7908e4ed Merge pull request #4574 from milas/cli-user-agent
cli/command: add WithUserAgent option
2025-09-24 19:16:38 +02:00
Milas BowmanandSebastiaan van Stijn 048e931b42 cli/command: add WithUserAgent option
Add support to the `cli/command` package to accept a custom User
Agent to pass to the underlying client.

This is used as the `UpstreamClient` portion of the `User-Agent`
when the Moby daemon makes requests.

For example, pushing and pulling images with Compose might result
in the registry seeing a `User-Agent` value of:

```
docker/24.0.7 go/go1.20.10 git-commit/311b9ff kernel/6.5.13-linuxkit os/linux arch/arm64 UpstreamClient(docker-cli-plugin-compose/v2.24.0)
```

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 17:43:41 +02:00
Sebastiaan van Stijn ec912e5524 cli-plugins/manager: allow schema-versions <= 2.0.0
The CLI currently hard-codes the schema-version for CLI plugins to
"0.1.0", which doesn't allow us to expand the schema for plugins.

As there's many plugins that we shipped already, we can't break
compatibility until we reach 2.0.0, but we can expand the schema
with non-breaking changes.

This patch makes the validation more permissive to allow new schema
versions <= 2.0.0. Note that existing CLIs will still invalidate
such versions, so we cannot update the version until such CLIs are
no longer expected to be used, but this patch lays the ground-work
to open that option.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 16:17:33 +02:00
Austin VazquezandGitHub 8fbb70ae56 Merge pull request #6475 from thaJeztah/cli_plugin_options
cli-plugins/plugin: Run: allow customizing the CLI
2025-09-24 07:15:24 -07:00
Paweł GronowskiandGitHub f3687d8a8b Merge pull request #5922 from thaJeztah/ignore_broken_symlinks
cli-plugins/manager: ignore broken symlinks
2025-09-24 15:10:23 +02:00
Sebastiaan van Stijn 9b2f831452 cli-plugins/manager: ignore broken symlinks
Before this patch, a broken symlink would print a warning;

    docker info > /dev/null
    WARNING: Plugin "/Users/thajeztah/.docker/cli-plugins/docker-feedback" is not valid: failed to fetch metadata: fork/exec /Users/thajeztah/.docker/cli-plugins/docker-feedback: no such file or directory

After this patch, such symlinks are ignored:

    docker info > /dev/null

With debug enabled, we don't ignore the faulty plugin, which will
make the warning shown on docker info;

    mkdir -p ~/.docker/cli-plugins
    ln -s nosuchplugin ~/.docker/cli-plugins/docker-brokenplugin
    docker --debug info
    Client:
     Version:    29.0.0-dev
     Context:    default
     Debug Mode: true
     Plugins:
      buildx: Docker Buildx (Docker Inc.)
        Version:  v0.25.0
        Path:     /usr/libexec/docker/cli-plugins/docker-buildx
    WARNING: Plugin "/Users/thajeztah/.docker/cli-plugins/docker-brokenplugin" is not valid: failed to fetch metadata: fork/exec /Users/thajeztah/.docker/cli-plugins/docker-brokenplugin: no such file or directory

    # ...

We should als consider passing a "seen" map to de-duplicate entries.
Entries can be either a direct symlink or in a symlinked path (for
which we can filepath.EvalSymlinks). We need to benchmark the overhead
of resolving the symlink vs possibly calling the plugin (to get their
metadata) further down the line.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 14:32:37 +02:00
Sebastiaan van Stijn 2711800430 cli-plugins/plugin: Run: allow customizing the CLI
Currently, the plugin.Run command constructs the DockerCli using
the default options, assuming plugins run with all the same options
as the CLI itself; to customize the CLI there's a "Apply" option,
but this means mutating the CLI after it's already constructed, which
is not ideal.

This patch adds a variadic ops argument to allow CLI plugins to pass
custom options to use for the CLI, so that there's no need to mutate
its config in most cases.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 14:17:15 +02:00
Sebastiaan van Stijn 84520653d8 templates: remove deprecated NewParse function
This was deprecated in 7ab3e7e774 and
no longer used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 14:08:27 +02:00
Sebastiaan van StijnandGitHub c8600e1cea Merge pull request #6463 from thaJeztah/remove_oauth_escape_hatch
remove DOCKER_CLI_DISABLE_OAUTH_LOGIN escape hatch
2025-09-24 13:43:42 +02:00
Paweł GronowskiandGitHub 4a4043cdb6 Merge pull request #6462 from thaJeztah/rm_deprecated_registryclient
remove deprecated cli/registry/client package
2025-09-24 13:18:58 +02:00
Paweł GronowskiandGitHub 7cc801d93d Merge pull request #6467 from thaJeztah/no_apply
cli/command: NewDockerCli: don't depend on DockerCli.Apply
2025-09-24 13:17:51 +02:00
Paweł GronowskiandGitHub 7afda4c6c5 Merge pull request #6468 from thaJeztah/cli_plugins_touchup
cli-plugins/plugin: Run: touch-up godoc and minor cleanups
2025-09-24 13:17:38 +02:00
Paweł GronowskiandGitHub 550d40f7bc Merge pull request #6466 from thaJeztah/registry_3
e2e: use registry v3
2025-09-24 13:17:23 +02:00
Paweł GronowskiandGitHub 5710de6d9a Merge pull request #6461 from thaJeztah/bump_xx
Dockerfile: update xx to v1.7.0
2025-09-24 13:17:13 +02:00
Paweł GronowskiandGitHub 93bb8a7a0a Merge pull request #6458 from thaJeztah/bump_engine
vendor: github.com/moby/moby/api, github.com/moby/moby/client master
2025-09-24 13:16:39 +02:00
Paweł GronowskiandGitHub b1d45285ba Merge pull request #6464 from thaJeztah/remove_deprecated_experimental
cli/config/configfile: remove deprecated ConfigFile.Experimental field
2025-09-24 13:15:54 +02:00
Paweł GronowskiandGitHub 4c802a1548 Merge pull request #6465 from thaJeztah/rm_23_test
gha: update test-matrix: remove docker 23.x, 26.x, add 25.x
2025-09-24 13:15:27 +02:00
Sebastiaan van Stijn 635a718209 cli-plugins/plugin: Run: touch-up godoc and minor cleanups
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 12:57:42 +02:00
Sebastiaan van Stijn 133279fb0d cli/command: NewDockerCli: don't depend on DockerCli.Apply
The Apply method was added when CLI options for constructing the CLI were
rewritten into functional options in [cli@7f207f3]. There was no mention
in the pull request of this method specifically, and this may have been
related to work being done elsewhere on compose-on-kubernetes or the
compose-cli plugin that may have needed options to modify the CLI config
after it was already initialized.

We should try to remove functions that mutate the CLI configuration after
initialization if possible (and likely remove the `Apply` method); currently
this function is used in docker compose, but as part of a hack that can
probably be avoided.

[cli@7f207f3]: https://github.com/docker/cli/commit/7f207f3f957ed3f5129aeb22bef2a429c14caf22

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 12:10:57 +02:00
Sebastiaan van Stijn daa15c3bfa e2e: use registry v3
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 10:28:42 +02:00
Sebastiaan van Stijn 83e40c39b4 gha: update test-matrix: remove docker 23.x, 26.x, add 25.x
- Mirantis Container Runtime (MCR) 23.0 reached EOL, and the next LTS
  version of MCR is 25.x
- Docker 26.x reached EOL and is no longer maintained

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 10:12:05 +02:00
Sebastiaan van Stijn 71f46056c9 remove DOCKER_CLI_DISABLE_OAUTH_LOGIN escape hatch
This code was added in 846ecf59ff as an
escape hatch in case the new OAuth login flow would cause problems.
We have not received reports where the new flow caused problems, and
searching the internet shows no mentions of the env-var.

This env-var was not documented, so we can remove it.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-23 21:47:30 +02:00
Sebastiaan van Stijn a53e83a3d4 cli/config/configfile: remove deprecated ConfigFile.Experimental field
Configuration options for experimental CLI features were deprecated in
docker 19.03 (3172219932), and enabled by
default since docker 20.10 (977d3ae046).

This field was deprecated in c8f9187157,
which is part of the 28.x release, and is unused. This patch removes
the field.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-23 21:43:14 +02:00
Sebastiaan van Stijn 083e5ce872 cli/command/registry: remove deprecated OauthLoginEscapeHatchEnvVar
This const was added in 846ecf59ff, but
only used internally; commit 18cdc25bb4
deprecated the const, which was included in the 28.4 release.

This patch removes the exported const, as it's unused.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-23 21:31:43 +02:00
Sebastiaan van Stijn 3cf005ec91 remove deprecated cli/registry/client package
This package was deprecated in 13010ba673,
and only used internally. The deprecation was included in the 28.4 release,
and there's no known external users, so we can remove it for v29.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-23 21:21:31 +02:00
Sebastiaan van Stijn c5cbb3e648 vendor: github.com/moby/moby/api, github.com/moby/moby/client master
full diffs:

- https://github.com/moby/moby/compare/api/v1.52.0-beta.1...e98849831fc4e35bdc09ed31b85f91caa87a0103
- https://github.com/moby/moby/compare/client/v0.1.0-beta.0...e98849831fc4e35bdc09ed31b85f91caa87a0103

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-23 21:11:17 +02:00
Sebastiaan van StijnandGitHub e241f53ebc Merge pull request #6460 from thaJeztah/no_pause
deprecate "--pause" flag on docker commit in favor of "--no-pause"
2025-09-23 12:54:15 +02:00
Sebastiaan van Stijn 0f08b55bce Dockerfile: update xx to v1.7.0
full diff: https://github.com/tonistiigi/xx/compare/v1.6.1...v1.7.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-23 10:42:15 +02:00
Sebastiaan van Stijn 3c244d1099 deprecate "--pause" flag on docker commit in favor of "--no-pause"
Commit [moby@17d870b] (API v1.13, docker v1.1.0) changed the default to pause
containers during commit, keeping the behavior opt-in for older API versions.
This version-gate was removed in [moby@1b1147e] because API versions lower
than v1.23 were no longer supported.

This patch deprecates the `--pause` flag in favor of a `--no-pause` flag to
be more explicit on the default. The old `--pause` flag is marked deprecated
but still functional. Using the deprecated flag will print a warning, and an
error is produced when trying to use both the old and new flag;

    docker commit --pause mycontainer
    Flag --pause has been deprecated, and enabled by default. Use --no-pause to disable pausing during commit.

    docker commit --pause=false mycontainer
    Flag --pause has been deprecated, and enabled by default. Use --no-pause to disable pausing during commit.

    docker commit --pause --no-pause mycontainer
    Flag --pause has been deprecated, use --no-pause instead
    conflicting options: --no-pause and --pause cannot be used together

[moby@17d870b]: https://github.com/moby/moby/commit/17d870bed5ef997c30da1e8b9843f4e84202f8d4
[moby@1b1147e]: https://github.com/moby/moby/commit/1b1147e46b732caeaed4ae365cd56ccbfdf40233

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-22 15:41:22 +02:00
Sebastiaan van StijnandGitHub 233322637a Merge pull request #6452 from doringeman/image-list-completions
Enable completion for `docker images`
2025-09-19 10:57:16 +02:00
Sebastiaan van StijnandGitHub 5d8fb335d4 Merge pull request #6455 from thaJeztah/rm_kmem
cli/command/container: fully deprecate --kernel-memory options
2025-09-16 19:40:56 +02:00
Sebastiaan van Stijn f4a433f841 cli/command/container: fully deprecate --kernel-memory options
The `--kernel-memory` flag was still included to allow it to be used with
old API versions, but it's no longer supported by the kernel, and no longer
handled by OCI runtimes, so deprecating the flags.

With this patch, a deprecation warning is now produced when trying to use
the option;

    docker run --kernel-memory 123b busybox
    Flag --kernel-memory has been deprecated, this option is deprecated in the kernel and no longer supported

    docker container create --kernel-memory 123b busybox
    Flag --kernel-memory has been deprecated, and no longer supported by the kernel
    31fb57e2c6434490a2892031602be20d0206d3cf0fc281ea25654c46dcb62bac

Note that cobra does not _fail_ the command when using deprecated options;
we could make this a hard failure instead, but may not be worth the effort.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-16 15:36:45 +02:00
Sebastiaan van Stijn a02902eb78 docs: deprecated: complete deprecation of kernel-memory limit
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-16 13:50:16 +02:00
Dorin Geman 437f1260fd Enable completion for docker images
Signed-off-by: Dorin Geman <dorin.geman@docker.com>
2025-09-15 11:30:40 +03:00
Sebastiaan van StijnandGitHub 4373ce5f8b Merge pull request #6451 from thaJeztah/fix_stats_bounds
cli/command/container: prevent panic during stats on empty event Actor.ID
2025-09-11 17:27:50 +02:00
Sebastiaan van Stijn 9b79e48646 cli/command/container: prevent panic during stats on empty event Actor.ID
This code was missing a check for the ID field before truncating it to a
shorter length for presentation. This would result in a panic if an event
would either have an empty ID field or a shorter length ID;

    panic: runtime error: slice bounds out of range [:12] with length 0

    goroutine 82 [running]:
    github.com/docker/cli/cli/command/container.RunStats.func2({{0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x40001fcba0, 0x9}, {0x40001fcba9, 0x5}, ...})
        /go/src/github.com/docker/cli/cli/command/container/stats.go:146 +0x1d0
    created by github.com/docker/cli/cli/command/container.(*eventHandler).watch in goroutine 6
        /go/src/github.com/docker/cli/cli/command/container/stats.go:363 +0x1c8

We need to look at this code in general; the truncated ID is passed to
NewStats, which uses the ID to propagate the `Container` field in the
`StatsEntry` struct. which is not used in the default format used by
`docker stats` and, having the same content as the `ID` field on the
same struct, doesn't make it very useful, other than being able to
present it under a `CONTAINER` column (instead of `CONTAINER ID`);
we should consider deprecating it; there may be some subtle things
to look into here; the `Container` field originally held the container
name. This was changed in [moby@ef915fd], which introduced separate
`ID` and `Name` fields, renaming the old `Name` field to container.

Looking at [`Stats.SetStatistics()`] and related code in [stats_helpers.go],
the `Container` field is used as the "canonical" reference for the stats
record; this allows the stats _data_ to be refreshed when a new stats
sample arrives for the same container (also see [moby@929a77b], which
moved locking to the `Stats` wrapper struct). This construct allows to
account for intermediate states, where a stats sample was incomplete
or could produce an error; in that case, the reference to the container
for which the stats were sampled is kept to allow removing a container
from the list once the container was removed. We should consider removing
`Container` as a formatting option, and moving the `Container` field to
the outer struct; this makes the outer struct responsible for keeping a
reference to the container, allowing the `StatsEntry` as a whole to be
replaced atomically.

This patch only addresses the panic;

- It changes the logic to preserve the container ID verbatim instead
  of truncating. This allows stats samples to be matched against the
  `Actor.ID` as-is.
- Truncating the `Container` is moved to the presentation logic;
  currently this does not take `--no-trunc` into account to keep
  the existing behavior, but we can (should) consider adding this.
- Logging is improved to use structured logs, and an extra check is
  added to prevent empty IDs from being added as watcher.

[`Stats.SetStatistics()`]: https://github.com/docker/cli/blob/82281087e3e186c5a2eafa0d973e849ff84c357d/cli/command/container/formatter_stats.go#L88-L94
[moby@ef915fd]: https://github.com/moby/moby/commit/ef915fd036d9ea5263f9370dce490ef97ea0618d
[moby@929a77b]: https://github.com/moby/moby/commit/929a77b814dfe9ab7a11bffc2d16eebd27bd903a
[stats_helpers.go]: https://github.com/docker/cli/blob/82281087e3e186c5a2eafa0d973e849ff84c357d/cli/command/container/stats_helpers.go#L26-L51

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-11 14:28:25 +02:00
Sebastiaan van Stijn b9314938b7 cli/command/container: improve TestContainerStatsContext
- Use sub-tests
- Don't use un-named keys
- Add test-cases for 'Name', 'ID' and custom container names

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-11 14:10:54 +02:00
Sebastiaan van Stijn b8cda96d11 cli/command/container: improve TestContainerStatsContext
- Don't use unnamed keys
- Use sub-tests
- Add test-cases for Name and ID fields

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-11 13:58:50 +02:00
Sebastiaan van StijnandGitHub 82281087e3 Merge pull request #6448 from thaJeztah/cleanup_completion
cli/command/completion: change signatures to return a cobra.CompletionFunc
2025-09-10 15:08:18 +02:00
Sebastiaan van StijnandGitHub c3ceba2548 Merge pull request #6447 from thaJeztah/default_completion
cli: disable file-completion by default
2025-09-10 15:07:03 +02:00
Sebastiaan van StijnandGitHub e78f16961d Merge pull request #6449 from thaJeztah/context_name_positional
cli/command/context: split name from options struct
2025-09-10 15:05:43 +02:00
Sebastiaan van StijnandGitHub d391d0fa4a Merge pull request #6445 from thaJeztah/add_plugin_completions
cli/command/plugin: add completion for plugin subcommands
2025-09-10 15:04:43 +02:00
Sebastiaan van StijnandGitHub 2f6abcf3c2 Merge pull request #6446 from thaJeztah/fix_completions
Improve shell completion for `docker secret` and `docker config` subcommands
2025-09-10 14:30:05 +02:00
Sebastiaan van Stijn ea8212ab55 cli/command/context: split name from options struct
Name is a required argument for both "create" and "update", so better
to split it from the options struct.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 12:15:50 +02:00
Sebastiaan van Stijn 3785198c6e cli/command/completion: change FileNames to return a cobra.CompletionFunc
It's adding a slight indirection by constructing a function when called,
but makes the completion functions more consistent, the signature easier
to read, and making the return type a [cobra.CompletionFunc] makes it
more transparent what it's intended for, and helps discovery of functions
that provide completion.

[cobra.CompletionFunc]: https://pkg.go.dev/github.com/spf13/cobra#CompletionFunc

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 12:06:43 +02:00
Sebastiaan van Stijn 531f7e121d cli/command/completion: change Platforms to return a cobra.CompletionFunc
It's adding a slight indirection by constructing a function when called,
but makes the completion functions more consistent, the signature easier
to read, and making the return type a [cobra.CompletionFunc] makes it
more transparent what it's intended for, and helps discovery of functions
that provide completion.

[cobra.CompletionFunc]: https://pkg.go.dev/github.com/spf13/cobra#CompletionFunc

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 12:06:42 +02:00
Sebastiaan van Stijn 810be9fbe9 cli/command/completion: change Platforms to return a cobra.CompletionFunc
It's adding a slight indirection by constructing a function when called,
but makes the completion functions more consistent, the signature easier
to read, and making the return type a [cobra.CompletionFunc] makes it
more transparent what it's intended for, and helps discovery of functions
that provide completion.

[cobra.CompletionFunc]: https://pkg.go.dev/github.com/spf13/cobra#CompletionFunc

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 12:06:42 +02:00
Sebastiaan van Stijn d18af47d0f cli/command/completion: change EnvVarNames to return a cobra.CompletionFunc
It's adding a slight indirection by constructing a function when called,
but makes the completion functions more consistent, the signature easier
to read, and making the return type a [cobra.CompletionFunc] makes it
more transparent what it's intended for, and helps discovery of functions
that provide completion.

[cobra.CompletionFunc]: https://pkg.go.dev/github.com/spf13/cobra#CompletionFunc

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 12:06:39 +02:00
Sebastiaan van Stijn 47b1715d6f cli-plugins: disable file-completion by default
This uses the DefaultShellCompDirective feature which was added
in cobra to override the default (which would complete to use
files for commands and flags).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 11:52:32 +02:00
Sebastiaan van Stijn 78c54646c3 cli: disable file-completion by default
This uses the DefaultShellCompDirective feature which was added
in cobra to override the default (which would complete to use
files for commands and flags).

Note that we set "cobra.NoFileCompletions" for many commands, which
is redundant with this change, so we could remove as well.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 11:52:32 +02:00
Sebastiaan van Stijn 467fcfe4bd cli/command/plugin: add completion for plugin subcommands
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 11:49:16 +02:00
Sebastiaan van Stijn 8325214ccc cli/command: fix completion for secret create, config create
These commands accept two arguments; the first is a custom name,
the second is either a filename or "-" to create from STDIN.

With this patch:

    # does not provide completion
    docker secret create <tab>

    # starts providing completion once a non-empty name is provided
    docker secret create somename<tab>
    file.txt other-file.txt

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 11:45:21 +02:00
Sebastiaan van Stijn 924dd4710b cli/command/secret: fix completion to complete names, not IDs
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 11:45:21 +02:00
Sebastiaan van Stijn d67dad3fb4 cli/command/secret: remove completion for "ls"
This command takes no arguments, so should not provide completion.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 11:40:42 +02:00
Sebastiaan van Stijn 1336f51e6a remove redundant closures around completion functions
These were remnants from some earlier implementation.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 11:40:42 +02:00
Sebastiaan van StijnandGitHub c5467b5556 Merge pull request #6246 from mmorel-35/revive/use-errors-new
ci: enable use-errors-new from revive
2025-09-10 11:38:14 +02:00
Sebastiaan van StijnandGitHub 8b23c2bcb5 Merge pull request #6444 from thaJeztah/inspect_completion
cli/command/system: add shell completion for "docker inspect"
2025-09-10 11:36:23 +02:00
Matthieu MORELandSebastiaan van Stijn 22dda0fc2b ci: enable use-errors-new from revive
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-09-10 11:31:26 +02:00
Sebastiaan van StijnandGitHub 69972b682b Merge pull request #6441 from thaJeztah/stderrs
cli/command: replace remaining uses of pkg/errors for stdlib
2025-09-10 10:20:21 +02:00
Sebastiaan van Stijn 8bb5595f28 cli/command/system: add shell completion for "docker inspect"
The "docker inspect" command can inspect any type of object, which would
require all possible endpoints to be contacted. By default, we don't
provide completion, but if a `--type` is passed, we provide completion
for the given type.

For example, `docker inspect --type container` will complete container
names, `docker inspect --type volume` will complete volume names and
so on.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-10 00:28:08 +02:00
Sebastiaan van Stijn 5245e20866 update vendor
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 19:58:08 +02:00
Sebastiaan van Stijn c0e37dda14 cli/command/container: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 19:58:08 +02:00
Sebastiaan van Stijn b774e75931 cli/command/system: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 19:58:07 +02:00
Sebastiaan van Stijn 9ba1314d3a cli/command/system: fix error formatting (errlint)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 19:58:07 +02:00
Sebastiaan van Stijn c5150177bf cli/command/secret: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 19:58:07 +02:00
Sebastiaan van Stijn 573e0bddef cli/command/service: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 19:58:07 +02:00
Sebastiaan van Stijn b057ab6d98 cli/command/stack: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 19:58:07 +02:00
Sebastiaan van Stijn 0e4934d36c cli/command/swarm: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 19:58:06 +02:00
Sebastiaan van Stijn cd583313ee cli/command/plugin: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 19:58:06 +02:00
Sebastiaan van Stijn 5c8817b1b2 cli/command/node: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 19:58:06 +02:00
Sebastiaan van Stijn bf78331f0c cli/command/container: runUpdate: use struct-literal
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 19:58:06 +02:00
Sebastiaan van Stijn 0c3bb6c0a4 cli/command/container: rename: remove renameOptions
Also remove redundant validation that's already performed by the client
or daemon.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 19:57:42 +02:00
Sebastiaan van Stijn 179dc0228c cli/command/image: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-09 17:23:58 +02:00
Sebastiaan van StijnandGitHub f10041c724 Merge pull request #6439 from thaJeztah/plugin_rm_special_handling
cli/command/plugin: remove special error handling on install, upgrade
2025-09-09 11:59:51 +02:00
Sebastiaan van StijnandGitHub 62d25205e9 Merge pull request #6440 from thaJeztah/use_multierror
use native errors.Join for multi-errors on "docker ps", "docker node ls"
2025-09-09 10:47:23 +02:00
Sebastiaan van Stijn fb3f2da50e cli/command/plugin: remove special error handling on install, upgrade
Similar to 323fbc485e - this code was added
in [moby@c127d96], but used string-matching to detect cases where a user
tried to install an image as plugin. However, this handling no longer matched
any error-strings, so no longer worked:

    docker plugin install busybox
    Error response from daemon: did not find plugin config for specified reference docker.io/library/busybox:latest

[moby@c127d96]: https://github.com/moby/moby/commit/c127d9614f5b30bd73861877f8540a63e7d869e9

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-08 20:37:03 +02:00
Sebastiaan van Stijn 5df02441ca cli/command/containers: runUpdate: use native errors.Join
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-08 20:30:41 +02:00
Sebastiaan van Stijn 935df8a78f cli/command/node: runPs: use native errors.Join
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-08 20:30:41 +02:00
Sebastiaan van StijnandGitHub 183337db9a Merge pull request #6438 from thaJeztah/internalize_loader
cli/command/stack: internalize GetConfigDetails, LoadComposefile, RunDeploy, RunRemove
2025-09-08 17:31:28 +02:00
Sebastiaan van StijnandGitHub d62d370c23 Merge pull request #6435 from thaJeztah/templates_extract_formatJSON
templates: add formatJSON func
2025-09-08 17:30:37 +02:00
Sebastiaan van Stijn 26bb688ed0 cli/command/stack: internalize RunDeploy, RunRemove
These were deprecated in ad6ab189a6 and
were only used internally. Move them back inside the stack package.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-08 16:03:38 +02:00
Sebastiaan van Stijn 73677146f4 cli/command/stack: internalize GetConfigDetails, LoadComposefile
These were deprecated in ad6ab189a6 and
were only used internally. Move them back inside the stack package.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-08 15:24:35 +02:00
Sebastiaan van Stijn c24b62f19c templates: add formatJSON func
Move the function used to format as JSON to a separate function instead
of definining it inline.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-08 12:06:46 +02:00
Sebastiaan van StijnandGitHub be97096566 Merge pull request #6434 from thaJeztah/update_authors
update mailmap and authors
2025-09-06 00:18:07 +02:00
Sebastiaan van Stijn c4a87de3ec update mailmap and authors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-06 00:06:56 +02:00
Paweł GronowskiandGitHub 4df42ef1d9 Merge pull request #6395 from thaJeztah/bump_engine
vendor: github.com/moby/moby/api v1.52.0-beta.1, client v0.1.0-beta.0
2025-09-05 23:39:16 +02:00
Sebastiaan van StijnandAustin Vazquez b55fed5ef6 vendor: github.com/moby/moby/api v1.52.0-beta.1, client v0.1.0-beta.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Co-authored-by: Austin Vazquez <austin.vazquez@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-05 22:41:03 +02:00
Paweł GronowskiandGitHub 9fb049c8b6 Merge pull request #6433 from thaJeztah/bump_cdi
vendor: tags.cncf.io/container-device-interface v1.0.1
2025-09-05 22:27:10 +02:00
Sebastiaan van Stijn 35f5a4313b vendor: tags.cncf.io/container-device-interface v1.0.1
full diff: https://github.com/cncf-tags/container-device-interface/compare/v0.8.1...v1.0.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-05 21:47:23 +02:00
Austin VazquezandGitHub 589f56c345 Merge pull request #6432 from thaJeztah/rm_windows_warning
cli/command/image: build: remove permissions warning on Windows
2025-09-05 09:51:00 -07:00
Sebastiaan van StijnandGitHub fa5b741c9b Merge pull request #6430 from austinvazquez/update-build-cache-prune-options
Set `ReservedSpace` field in preparation of `KeepStorage` deprecation
2025-09-05 16:28:53 +02:00
Sebastiaan van Stijn af65ee4584 cli/command/image: build: remove permissions warning on Windows
This warning was added in [moby@4a8b3ca] to print a warning when building
Linux images from a Windows client. Window's filesystem does not have an
"executable" bit, which mean that, for example, copying a shell script
to an image during build would lose the executable bit. So for Windows
clients, the executable bit would be set on all files, unconditionally.

Originally this was detected in the client, which had direct access to
the API response headers, but when refactoring the client to use a common
library in [moby@535c4c9], this was refactored into a `ImageBuildResponse`
wrapper, deconstructing the API response into an `io.Reader` and a string
field containing only the `OSType` header.

This was the only use and only purpose of the `OSType` field, and now that
BuildKit is the default builder for Linux images, this warning didn't get
printed unless BuildKit was explicitly disabled.

This patch removes the warning, so that we can potentially remove the
field, or the `ImageBuildResponse` type altogether.

[moby@4a8b3ca]: https://github.com/moby/moby/commit/4a8b3cad6096854027151dfbcfb4b2cd8841ad95
[moby@535c4c9]: https://github.com/moby/moby/commit/535c4c9a59b1e58c897677d6948a595cb3d28639

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-05 13:35:07 +02:00
Austin Vazquez 7d85d8fbea Set ReservedSpace field in preparation of KeepStorage deprecation
This change updates the builder prune command to send the `ReservedSpace` parameter in preparation of `KeepStorage` deprecation in API v1.52.

Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
2025-09-04 17:47:42 -05:00
Austin VazquezandGitHub 4ceef7d328 Merge pull request #6429 from thaJeztah/bump_cobra
vendor github.com/spf13/pflag v1.0.10, github.com/spf13/cobra v1.10.1
2025-09-04 15:46:36 -07:00
Austin VazquezandGitHub 3bbb633e5b Merge pull request #6427 from thaJeztah/avoid_client_types_in_opts
don't wrap client options
2025-09-04 15:45:00 -07:00
Sebastiaan van Stijn fef8773bae vendor: github.com/spf13/cobra v1.10.1
full diff: https://github.com/spf13/cobra/compare/v1.9.1...v1.10.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-04 23:13:26 +02:00
Sebastiaan van Stijn aba5962ffb vendor: github.com/spf13/pflag v1.0.10
full diff: https://github.com/spf13/pflag/compare/v1.0.6...v1.0.10

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-04 23:12:13 +02:00
Austin VazquezandGitHub 1f12d795db Merge pull request #6426 from docker/dependabot/github_actions/actions/setup-go-6
build(deps): bump actions/setup-go from 5 to 6
2025-09-04 12:27:51 -07:00
Sebastiaan van Stijn e7d14d905e cli/command: don't wrap client options
We may still change this, but in the client module, the signature
of the client.Opt changed to now include a non-exported type, which
means that we can't construct a custom option that is implemented
using client options:

    #18 16.94 # github.com/docker/cli/cli/context/docker
    #18 16.94 cli/context/docker/load.go:105:29: cannot use withHTTPClient(tlsConfig) (value of type func(*client.Client) error) as client.Opt value in argument to append
    #18 16.94 cli/context/docker/load.go:152:6: cannot use c (variable of type *client.Client) as *client.clientConfig value in argument to client.WithHTTPClient(&http.Client{…})

We can consider exporting the `client.clientConfig` type (but keep its
fields non-exported), but for this use, we don't strictly need it, so
let's change the implementation to not having to depend on that.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-04 18:57:07 +02:00
Sebastiaan van Stijn b0b0e457f0 cli/context/docker: don't wrap client options
We may still change this, but in the client module, the signature
of the client.Opt changed to now include a non-exported type, which
means that we can't construct a custom option that is implemented
using client options:

    #18 16.94 # github.com/docker/cli/cli/context/docker
    #18 16.94 cli/context/docker/load.go:105:29: cannot use withHTTPClient(tlsConfig) (value of type func(*client.Client) error) as client.Opt value in argument to append
    #18 16.94 cli/context/docker/load.go:152:6: cannot use c (variable of type *client.Client) as *client.clientConfig value in argument to client.WithHTTPClient(&http.Client{…})

We can consider exporting the `client.clientConfig` type (but keep its
fields non-exported), but for this use, we don't strictly need it, so
let's change the implementation to not having to depend on that.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-04 18:53:06 +02:00
dependabot[bot]andGitHub 44e66a97a9 build(deps): bump actions/setup-go from 5 to 6
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 11:32:37 +00:00
Paweł GronowskiandGitHub 27b316fc0d Merge pull request #6421 from vvoland/update-go
update to go1.24.7
2025-09-03 21:28:52 +02:00
Paweł Gronowski f64b8a332d update to go1.24.7
This includes 1 security fix:

- net/http: CrossOriginProtection bypass patterns are over-broad

    When passing patterns to CrossOriginProtection.AddInsecureBypassPattern,
    requests that would have redirected to those patterns (e.g. without a trailing
    slash) were also exempted, which might be unexpected.

    Thanks to Marco Gazerro for reporting this issue.

    This is CVE-2025-47910 and Go issue https://go.dev/issue/75054.

View the release notes for more information:
https://go.dev/doc/devel/release#go1.24.7

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-09-03 20:40:59 +02:00
Sebastiaan van StijnandGitHub 06ed23d5fe Merge pull request #6419 from thaJeztah/complete_pull
add completion for docker image pull
2025-09-03 17:34:50 +02:00
Sebastiaan van Stijn 5bf3c6793d add completion for docker image pull
With this patch, completion is provided for images already present
in the local image cache to help pulling the latest version of the
same tag;

    docker pull go<tab>
    golang:1.12    golang:1.18.0  golang:1.21    golang:1.24    gopher:latest
    golang:1.13    golang:1.20    golang:1.23    golang:latest

    docker pull golang:<tab>
    1.12    1.13    1.18.0  1.20    1.21    1.23    1.24    latest

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-03 15:39:41 +02:00
Austin VazquezandGitHub 5bce5e17af Merge pull request #6415 from thaJeztah/plugin_no_regex
cli-plugins/manager: replace pluginNameRe for isValidPluginName utility
2025-09-02 16:48:11 -07:00
Austin VazquezandGitHub 0640306406 Merge pull request #6417 from thaJeztah/context_no_regex
cli/context/store: replace restrictedNamePattern for isValidName utility
2025-09-02 16:45:21 -07:00
Sebastiaan van Stijn ab7018b590 cli/context/store: replace restrictedNamePattern for isValidName utility
The restrictedNamePattern was a basic regular expression. Replace it
with a minimal utility to do the same, without having to use regular
expressions (or the "lazyregexp" package).

Some quick benchmarking (not committed) show that the non-regex approach
is ~18x faster:

    BenchmarkIsValidName_Regex_Valid-10        8516511        119.4   ns/op      0 B/op        0 allocs/op
    BenchmarkIsValidName_Manual_Valid-10     172426240          6.964 ns/op      0 B/op        0 allocs/op

    BenchmarkIsValidName_Regex_Invalid-10     34824540         34.22  ns/op      0 B/op        0 allocs/op
    BenchmarkIsValidName_Manual_Invalid-10   550804021          2.173 ns/op      0 B/op        0 allocs/op

    BenchmarkIsValidName_Regex_Parallel-10    69289900         17.30   ns/op     0 B/op        0 allocs/op
    BenchmarkIsValidName_Manual_Parallel-10 1000000000          0.9296 ns/op     0 B/op        0 allocs/op

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-02 23:09:12 +02:00
Sebastiaan van Stijn 2351f5b915 cli-plugins/manager: replace pluginNameRe for isValidPluginName utility
The pluginNameRe was a basic regular expression, effectively only checking
if the name consisted of lowercase alphanumeric characters. Replace it
with a minimal utility to do the same, without having to use regular
expressions (or the "lazyregexp" package).

Some quick benchmarking (not committed) show that the non-regex approach
is ~25x faster:

    BenchmarkIsValidPluginName_Regex_Valid-10       13956240        81.39  ns/op       0 B/op        0 allocs/op
    BenchmarkIsValidPluginName_Manual_Valid-10     360003060         3.318 ns/op       0 B/op        0 allocs/op

    BenchmarkIsValidPluginName_Regex_Invalid-10     35281794        33.74  ns/op       0 B/op        0 allocs/op
    BenchmarkIsValidPluginName_Manual_Invalid-10   906072663         1.320 ns/op       0 B/op        0 allocs/op

    BenchmarkIsValidPluginName_Regex_Parallel-10    96595677        12.04  ns/op       0 B/op        0 allocs/op
    BenchmarkIsValidPluginName_Manual_Parallel-10  1000000000        0.4541 ns/op      0 B/op        0 allocs/op

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-02 22:58:32 +02:00
Sebastiaan van StijnandGitHub 153bd95158 Merge pull request #6414 from thaJeztah/plugin_rm_deprecated
cli-plugins/manager: remove deprecated types, functions and aliases
2025-09-02 12:17:31 +02:00
Sebastiaan van Stijn ce72a5c28b cli-plugins/manager: remove deprecated metadata aliases
These consts and types were moved to a separate metadata package in commits
292713c887 and 4321293972,
and deprecated in 72f76f2720, 5876b2941c,
and 6fa7d18320.

This removes the deprecated aliases in `cli-plugins/manager` in favor of
their equivalent in `cli-plugins/manager/metadata`:

- `CommandAnnotationPlugin`
- `CommandAnnotationPluginVendor`
- `CommandAnnotationPluginVersion`
- `CommandAnnotationPluginInvalid`
- `CommandAnnotationPluginCommandPath`
- `NamePrefix`
- `MetadataSubcommandName`
- `HookSubcommandName`
- `Metadata`
- `ReexecEnvvar`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-02 11:43:32 +02:00
Sebastiaan van Stijn d54c7f9e63 cli-plugins/manager: remove deprecated IsNotFound
These errors satisfy errdefs.IsNotFound, which can be used instead. This
function was deprecated in 71460215d3 and
is no longer used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-01 18:31:41 +02:00
Paweł GronowskiandGitHub 6ec32660e9 Merge pull request #6412 from thaJeztah/deprecate_OauthLoginEscapeHatchEnvVar
cli/command/registry: deprecate OauthLoginEscapeHatchEnvVar
2025-09-01 17:57:31 +02:00
Paweł GronowskiandGitHub 9e52a2817c Merge pull request #6410 from thaJeztah/deprecate_ReexecEnvvar
cli-plugins/manager: deprecate ReexecEnvvar
2025-09-01 17:56:42 +02:00
Sebastiaan van Stijn 18cdc25bb4 cli/command/registry: deprecate OauthLoginEscapeHatchEnvVar
This const was added in 846ecf59ff, but
only used internally. This patch deprecates the const, to be removed
in the next release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-01 17:43:39 +02:00
Sebastiaan van Stijn 6fa7d18320 cli-plugins/manager: deprecate ReexecEnvvar
This alias was added in 4321293972, which is
part of v28.0, but did not deprecate them. They are no longer used in the
CLI itself, but may be used by cli-plugin implementations.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-01 17:33:32 +02:00
Sebastiaan van StijnandGitHub 89874983c8 Merge pull request #6401 from thaJeztah/check_DisableFlagsInUseLine
verify that DisableFlagsInUseLine is set for all commands
2025-09-01 13:55:57 +02:00
Sebastiaan van StijnandGitHub 88f68273fd Merge pull request #6406 from thaJeztah/rm_GetStacks_StackWrite
cli/command/stack: move GetStacks and StackWrite internal
2025-09-01 13:55:09 +02:00
Sebastiaan van StijnandGitHub a2c886251c Merge pull request #6407 from thaJeztah/rm_exported_context_funcs
cli/command/context: remove deprecated types and functions
2025-09-01 12:58:49 +02:00
Sebastiaan van StijnandGitHub 9a6cbbc586 Merge pull request #6408 from thaJeztah/rm_NoComplete
cli/command/completion: remove deprecated NoComplete
2025-09-01 12:58:20 +02:00
Sebastiaan van Stijn 70915196cb cli/command/completion: remove deprecated NoComplete
This function was an exact duplicate of [cobra.NoFileCompletions], and
was deprecated in 2827d037ba.

[cobra.NoFileCompletions]: https://pkg.go.dev/github.com/spf13/cobra@v1.9.1#NoFileCompletions

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-01 10:27:34 +02:00
Sebastiaan van Stijn 9477941c20 cli/command/context: remove deprecated types and functions
These functions and types are shallow wrappers around the context
store and were intended for internal use as implementation for the
CLI itself.

They were exported in 3126920af1 to be
used by plugins and Docker Desktop. However, there's currently no public
uses of this, and Docker Desktop does not use these functions. These were
deprecated in 95eeafa551 and are no longer
used.

This patch removes the deprecated functions as they were meant to be
implementation specific for the CLI. If there's a need to provide
utilities for manipulating the context-store other than through the
CLI itself, we can consider creating an SDK for that purpose.

This removes:

- `RunCreate` and `CreateOptions`
- `RunExport` and `ExportOptions`
- `RunImport`
- `RunRemove` and `RemoveOptions`
- `RunUpdate` and `UpdateOptions`
- `RunUse`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-01 10:22:28 +02:00
Sebastiaan van Stijn 6647e229be cli/command/stack: move GetStacks and StackWrite internal
These were deprecated in 036d3a6bab and
30774ed1f2, and were originally in the
cli/command/stack package, but moved for the (now deprecated) Compose
on Kubernetes feature in 4d947de292.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-01 09:40:44 +02:00
Sebastiaan van Stijn 0adaf6be3b verify that DisableFlagsInUseLine is set for all commands
This replaces the visitAll recursive function with a test that verifies that
the option is set for all commands and subcommands, so that it doesn't have
to be modified at runtime.

We currently still have to loop over all functions for the setValidateArgs
call, but that can be looked at separately.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-01 09:39:46 +02:00
Sebastiaan van StijnandGitHub ba21666654 Merge pull request #6404 from thaJeztah/deprecate_nocomplete
cli/command/completion: deprecate NoComplete
2025-09-01 09:13:18 +02:00
Sebastiaan van StijnandGitHub 321100e38b Merge pull request #6402 from thaJeztah/deprecate_context_funcs
cli/command/context: deprecate exported types and functions
2025-09-01 09:11:28 +02:00
Sebastiaan van StijnandGitHub 5dd52a9efa Merge pull request #6397 from thaJeztah/compose_clean
cli/compose/convert: split exported AddStackLabel from implementation
2025-09-01 09:10:42 +02:00
Sebastiaan van Stijn 2827d037ba cli/command/completion: deprecate NoComplete
This function was an exact duplicate of [cobra.NoFileCompletions], so
deprecating it in favor of that.

[cobra.NoFileCompletions]: https://pkg.go.dev/github.com/spf13/cobra@v1.9.1#NoFileCompletions

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-30 12:00:34 +02:00
Sebastiaan van Stijn 95eeafa551 cli/command/context: deprecate exported types and functions
These functions and types are shallow wrappers around the context
store and were intended for internal use as implementation for the
CLI itself.

They were exported in 3126920af1 to be
used by plugins and Docker Desktop. However, there's currently no public
uses of this, and Docker Desktop does not use these functions.

This patch deprecates the exported functions as they were meant to be
implementation specific for the CLI. If there's a need to provide
utilities for manipulating the context-store other than through the
CLI itself, we can consider creating an SDK for that purpose.

This deprecates:

- `RunCreate` and `CreateOptions`
- `RunExport` and `ExportOptions`
- `RunImport`
- `RunRemove` and `RemoveOptions`
- `RunUpdate` and `UpdateOptions`
- `RunUse`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-30 01:51:12 +02:00
Rob MurrayandGitHub 81ea282e00 Merge pull request #6398 from thaJeztah/rm_deprecated_stack
cli/command/stack: remove some deprecated functions
2025-08-29 17:23:29 +01:00
Paweł GronowskiandGitHub 0155c264ae Merge pull request #6371 from Benehiko/support-fallback-negative-certs
Add escape hatch for GODEBUG=x509negativeserial
2025-08-29 15:59:24 +02:00
Sebastiaan van Stijn 77205e782a cli/command/stack/swarm: deployServices: use struct-literal for options
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-29 14:52:38 +02:00
Sebastiaan van Stijn 580c3aa218 cli/compose/convert: Networks: use struct-literal for IPAM config
Use a struct-literal for the IPAM config, and combine some of the checks.
Also use the Name field as a default, and only construct a scoped name
if the given name is empty (instead of the reverse).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-29 14:50:49 +02:00
Sebastiaan van Stijn f8d33f4602 cli/compose/convert: split exported AddStackLabel from implementation
This function is currently only used within the package; create a non-exported
version of it, to make it clear it's not used elsewhere. This patch keeps
the exported function for now, but we can decide if we need to keep it
in future.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-29 14:50:46 +02:00
Sebastiaan van Stijn 2066dbcfe8 cli/command/stack/swarm: inline validateResolveImageFlag
It was only used in a single place, and possibly incorrect. Let's inline
it to put the logic where it's used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-29 14:39:06 +02:00
Sebastiaan van Stijn c3be589c16 cli/command/stack/swarm: remove deprecated RunPS and options.PS
These were deprecated in f0e5a0d654 and
036d3a6bab and were only used internally.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-29 14:39:06 +02:00
Sebastiaan van Stijn 2a05951680 cli/command/stack: remove deprecated RunServices and swarm.GetServices
These were deprecated in f0e5a0d654,
036d3a6bab, and
d16c560664 and were only used internally.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-29 14:39:00 +02:00
Alano Terblanche 72f79333e5 return early if GODEBUG set or context is default
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-29 14:31:21 +02:00
Alano Terblanche 6163c03b11 rename function to fit what it is doing
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-29 14:08:15 +02:00
Alano Terblanche 467305fcea Test setAllowNegativex509
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-29 12:15:49 +02:00
Alano Terblanche 65a6c35d90 Cleanup setAllowNegativex509
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-29 12:15:29 +02:00
Sebastiaan van Stijn c4df0d17bb cli/command/stack: remove deprecated RunList and options.List
These were deprecated in f0e5a0d654 and
d16c560664 and were only used internally.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-29 11:46:21 +02:00
Sebastiaan van StijnandGitHub b3cd9d48fe Merge pull request #6393 from thaJeztah/cleanup_stacks
cli/command/stack: cleanups and optimizations
2025-08-29 11:22:11 +02:00
Sebastiaan van Stijn 581cb2b70a cli/command/stack/swarm: GetStacks: don't use pointers for values
These are very small structs, so using pointers doesn't bring much
advantage and makes it slightly more cumbersome to use.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-28 15:44:09 +02:00
Sebastiaan van Stijn 6b86aac02e cli/command/stack/formatter: StackWrite: remove intermediate vars
- inline the closure
- remove newStackContext() constructor and inline it

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-28 15:37:52 +02:00
Sebastiaan van Stijn 8b01d8e74c cli/command/stack: runList: remove intermediate slice
This intermediate slice was a left-over from the "Compose on Kubernetes"
feature, which required some conversions, but that code was removed in
193ede9b12, so the intermediate slice no
longer has a purpose.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-28 15:23:40 +02:00
Sebastiaan van Stijn 047ea37054 cli/command/stack/swarm: pruneServices: fix typo and minor cleanup
- fix typo in argument name
- rename var that shadowed function
- pre-allocate slice

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-28 15:22:16 +02:00
Sebastiaan van Stijn 4f7f42df0e cli/command/stack/swarm: GetStacks: tidy up
Preserve the original order by avoiding the intermediate map[string] and
keeping an index for the first occurrence of a stack; this also avoids
looping multiple times.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-28 15:22:12 +02:00
Sebastiaan van Stijn 5a23ff9b17 cli/command/stack/formatter: TestStackContextWrite: cleanup test
- Include name in test-table
- Don't use un-keyed values in struct
- Simplify test-table to take a format string instead of a whole formatter.Context

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-28 15:21:16 +02:00
Paweł GronowskiandGitHub 8f25f4fb24 Merge pull request #6389 from thaJeztah/deprecate_stack_commands
cli/command/stack/*: deprecate exported functions and types
2025-08-28 13:55:46 +02:00
Sebastiaan van Stijn d16c560664 cli/command/stack: deprecate RunList, RunServices
Functions and types in this package were exported as part of the "compose
on kubernetes" feature, which was deprecated and removed. These functions
are meant for internal use, and will be removed in the next release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-28 10:21:47 +02:00
Sebastiaan van Stijn 036d3a6bab deprecate cli/command/stack/swarm
Functions and types in this package were exported as part of the "compose
on kubernetes" feature, which was deprecated and removed. These functions
are meant for internal use, and will be removed in the next release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-28 10:21:47 +02:00
Sebastiaan van Stijn f0e5a0d654 deprecate cli/command/stack/options
Functions and types in this package were exported as part of the "compose
on kubernetes" feature, which was deprecated and removed. These functions
are meant for internal use, and will be removed in the next release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-28 10:21:47 +02:00
Sebastiaan van Stijn ad6ab189a6 deprecate cli/command/stack/loader
Functions and types in this package were exported as part of the "compose
on kubernetes" feature, which was deprecated and removed. These functions
are meant for internal use, and will be removed in the next release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-28 10:21:47 +02:00
Sebastiaan van Stijn 30774ed1f2 deprecate cli/command/stack/formatter
Functions and types in this package were exported as part of the "compose
on kubernetes" feature, which was deprecated and removed. These functions
are meant for internal use, and will be removed in the next release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-28 10:21:42 +02:00
Austin VazquezandGitHub 306b7445a1 Merge pull request #6377 from thaJeztah/trust_unconvert
cli/command/trust: unconvert
2025-08-27 12:31:52 -07:00
Austin VazquezandGitHub ef0a67551a Merge pull request #6382 from thaJeztah/rm_ParseEnvFile
opts: remove deprecated ParseEnvFile
2025-08-27 12:25:54 -07:00
Austin VazquezandGitHub a7df96501f Merge pull request #6378 from thaJeztah/system_no_deprecated
cli/command/system: don't use deprecated fields in test
2025-08-27 12:21:41 -07:00
Austin VazquezandGitHub 5a2f87f6f6 Merge pull request #6385 from thaJeztah/bump_go_events
vendor: github.com/docker/go-events v0.0.0-20250114142523-c867878c5e32
2025-08-27 11:14:04 -07:00
Sebastiaan van StijnandGitHub b8507d71e8 Merge pull request #6387 from thaJeztah/bump_modules2
vendor: github.com/moby/moby/api, github.com/moby/moby/client master
2025-08-27 17:38:15 +02:00
Sebastiaan van Stijn cdf705ce66 vendor: github.com/moby/moby/api, github.com/moby/moby/client master
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-27 17:12:11 +02:00
Sebastiaan van Stijn 05220c5f19 vendor: github.com/docker/go-events v0.0.0-20250114142523-c867878c5e32
full diff: https://github.com/docker/go-events/compare/e31b211e4f1c...c867878c5e32

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-27 15:51:19 +02:00
Sebastiaan van Stijn 9e331b55d6 opts: remove deprecated ParseEnvFile
This was deprecated in e650803f09 and
no longer used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-27 15:03:34 +02:00
Sebastiaan van StijnandGitHub f40caed86c Merge pull request #6376 from thaJeztah/update_TestEventsFormat
cli/command/system: TestEventsFormat: remove use of deprecated fields
2025-08-27 14:45:44 +02:00
Sebastiaan van Stijn 3d87aa441f cli/command/system: don't use deprecated fields in test
This only impacts the JSON marshaled output; the "regular" output
of `docker info` already ignores these fields.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-27 14:43:37 +02:00
Sebastiaan van Stijn 4d9017d789 cli/command/trust: unconvert
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-27 14:40:56 +02:00
Sebastiaan van StijnandGitHub c558c30056 Merge pull request #6374 from thaJeztah/plugin_errs
cli/command/image: remove special handling for plugin errors on pull
2025-08-27 13:47:39 +02:00
Sebastiaan van Stijn 823c6a75b3 cli/command/system: TestEventsFormat: remove use of deprecated fields
These were just testing JSON marshaling fields that are deprecated, but
may be present in a response; these fields will be removed in future
API versions, so stop testing for them.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-27 13:45:05 +02:00
Sebastiaan van StijnandGitHub 7dfa471387 Merge pull request #6375 from thaJeztah/bump_modules
vendor: github.com/moby/moby/api, github.com/moby/moby/client 62884141100c
2025-08-27 12:14:47 +02:00
Sebastiaan van Stijn 10072c3548 vendor: github.com/moby/moby/api, github.com/moby/moby/client 62884141100c
full diffs:

- https://github.com/moby/moby/compare/7145e7666b8f...62884141100c14533299913efff3ead968ce6c3b

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-27 10:21:32 +02:00
Sebastiaan van Stijn 323fbc485e cli/command/image: remove special handling for plugin errors on pull
This special handling was added in [moby@9b6dcc8], and later updated in
[moby@c127d96], but it fully depended on string-matching, which is brittle.
Testing the original ticket that lead to this handling, it looks like the
string matching no longer works, and the daemon error is returned as-is:

With graphdrivers:

    docker pull tiborvass/no-remove
    Using default tag: latest
    Error response from daemon: Encountered remote "application/vnd.docker.plugin.v0+json"(unknown) when fetching

With containerd snapshotters enabled:

    docker pull tiborvass/no-remove
    Using default tag: latest
    latest: Pulling from tiborvass/no-remove
    cf635291f7c9: Download complete
    failed to unpack image on snapshotter overlayfs: mismatched image rootfs and manifest layers

The error-message for containerd can probably be improved, but as the special
handling in the CLI no longer works, we can remove it.

[moby@9b6dcc8]: https://github.com/moby/moby/commit/9b6dcc8b9d1366d3da3c8f60f89de1a36b087b88
[moby@c127d96]: https://github.com/moby/moby/commit/c127d9614f5b30bd73861877f8540a63e7d869e9

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-26 23:47:17 +02:00
Austin VazquezandGitHub 701b678104 Merge pull request #6255 from thaJeztah/bump_modules
vendor: github.com/moby/moby/api, moby/moby/client 7145e7666b8f (master)
2025-08-26 13:37:06 -07:00
Sebastiaan van Stijn 7118f1fb4b vendor: github.com/moby/moby/api, moby/moby/client 7145e7666b8f (master)
full diff:

- https://github.com/docker/docker/compare/api/v1.52.0-alpha.1...7145e7666b8f
- https://github.com/docker/docker/compare/client/v0.1.0-alpha.0...7145e7666b8f

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

WIP latest

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-26 20:02:30 +02:00
Sebastiaan van StijnandGitHub 212deb412d Merge pull request #6373 from thaJeztah/rm_image_AuthResolver
cli/command/image: remove deprecated AuthResolver utility
2025-08-26 19:27:22 +02:00
Sebastiaan van Stijn 481e792773 cli/command/image: remove deprecated AuthResolver utility
This function was used to share it between "trust" and "image",
but was only a shallow wrapper, so split the implementations where
used.

It was deprecated in 7ad113ccc2 and is
no longer used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-26 17:46:02 +02:00
Sebastiaan van StijnandGitHub 6bc7ed8b65 Merge pull request #6372 from thaJeztah/plugin_simplify_auth
cli/command/plugin: simplify auth
2025-08-26 17:32:23 +02:00
Austin VazquezandGitHub a2198ecd14 Merge pull request #6366 from thaJeztah/fix_email_deprecation
cli/config/types: update deprecation comment for AuthConfig.Email
2025-08-26 08:25:03 -07:00
Sebastiaan van Stijn f2c8b9dfd3 cli/command/plugin: simplify auth
Now that 3f5b1bdd32 removed DCT, which
needed some of the intermediate types (indexInfo), we can simplify the
auth code further and just get the base64-encoded AuthConfig to be set
as header.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-26 16:42:34 +02:00
Sebastiaan van StijnandGitHub cfd7e543fc Merge pull request #6370 from thaJeztah/remove_exported_config_funcs
cli/command/config: remove deprecated types and functions
2025-08-26 16:35:23 +02:00
Alano Terblanche 7d7a7aac4d Add escape hatch for GODEBUG=x509negativeserial
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-26 16:07:47 +02:00
Sebastiaan van Stijn 250e4a564c cli/command/config: remove deprecated types and functions
These were deprecated in a5f4ba08d9 and only
used internally.

This removes the deprecated types and functions:

- `RunConfigCreate` and  `CreateOptions`
- `RunConfigInspect` and `InspectOptions`
- `RunConfigList` and `ListOptions`
- `RunConfigRemove` and `RemoveOptions`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-26 13:17:53 +02:00
Sebastiaan van StijnandGitHub fda64ebc64 Merge pull request #6368 from thaJeztah/deprecate_exported_config_funcs
cli/command/config: deprecate exported types and functions
2025-08-26 13:17:12 +02:00
Sebastiaan van Stijn a5f4ba08d9 cli/command/config: deprecate exported types and functions
These were exported in f60369dfe6 to be
used in docker enterprise, but this never happened, and there's no
known consumers of these, so we should deprecate these. External
consumers can still call the API-client directly, which should've
been the correct thing to do in the first place.

This deprecates:

- `RunConfigCreate` and  `CreateOptions`
- `RunConfigInspect` and `InspectOptions`
- `RunConfigList` and `ListOptions`
- `RunConfigRemove` and `RemoveOptions`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-25 18:54:20 +02:00
Sebastiaan van StijnandGitHub 09cd4ea26c Merge pull request #6362 from thaJeztah/cleanup_formatter
cli/command/formatter: ContainerContext: assorted cleanups, fixes
2025-08-25 16:22:06 +02:00
Sebastiaan van StijnandGitHub a6826de3e2 Merge pull request #6361 from thaJeztah/cli_trust_cleanups
cli/trust: some cleanups
2025-08-25 16:20:56 +02:00
Sebastiaan van StijnandGitHub 5bcb60aaa6 Merge pull request #6356 from thaJeztah/unexport_authresolver_util
cli/command/image: deprecate AuthResolver and un-export
2025-08-25 16:19:45 +02:00
Sebastiaan van StijnandGitHub 1beb3d4d5b Merge pull request #6355 from thaJeztah/rm_image_pull
cli/command/image: remove exported RunPull, PullOptions
2025-08-25 16:00:38 +02:00
Sebastiaan van StijnandGitHub 0395cdbd71 Merge pull request #6353 from thaJeztah/rm_json_deprecated
internal/jsonstream: remove uses of deprecated fields
2025-08-25 15:52:08 +02:00
Sebastiaan van Stijn aab947de8f cli/config/types: update deprecation comment for AuthConfig.Email
Relates to [cli@27b2797], which forked this type from the Moby API, and
[moby@6cfff7e], which made the same change on the API side.

The Email field was originally used to create a new Docker Hub account
through the `docker login` command. The `docker login` command could be
used both to log in to an existing account (providing only username and
password), or to create a new account (providing desired username and
password, and an e-mail address to use for the new account).

This functionality was confusing, because it was implemented when Docker
Hub was the only registry, but the same functionality could not be used
for other registries. This functionality was removed in Docker 1.11 (API
version 1.23) through [moby@aee260d], which also removed the Email field
([engine-api@9a9e468]) as it was no longer used.

However, this caused issues when using a new CLI connecting with an old
daemon, as the field would no longer be serialized, and the deprecation
may not yet be picked up by custom registries, so [engine-api@167efc7]
added the field back, deprecated it, and added an "omitempty". There
was no official "deprecated" format yet at the time, so let's make sure
the deprecation follows the proper format to make sure it gets noticed.

[cli@27b2797]: https://github.com/docker/cli/commit/27b2797f7deb3ca5b7f80371d825113deb1faca1
[moby@6cfff7e]: https://github.com/moby/moby/commit/6cfff7e8803a71b4acb74768b5121e7d17a9e098
[moby@aee260d]: https://github.com/moby/moby/commit/aee260d4eb3aa0fc86ee5038010b7bbc24512ae5
[engine-api@9a9e468]: https://github.com/docker-archive-public/docker.engine-api/commit/9a9e468f503eb731d6fdc9d7f98c122e1b397c86
[engine-api@167efc7]: https://github.com/docker-archive-public/docker.engine-api/commit/167efc72bb24d7ad2bcc91760a9a5d37572e104f

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-25 15:44:04 +02:00
Sebastiaan van StijnandGitHub 5ab12e6262 Merge pull request #6365 from thaJeztah/fix_version_annotations
cli/command/service: fix API annotations for generic resource flags
2025-08-25 13:33:12 +02:00
Sebastiaan van StijnandGitHub 104b07647f Merge pull request #6363 from thaJeztah/image_push_cleanups
cli/command/image: runPush: minor cleanups and linting issues
2025-08-25 11:47:21 +02:00
Sebastiaan van StijnandGitHub 27734fdf4d Merge pull request #6349 from thaJeztah/rm_RegistryAuthenticationPrivilegedFunc
cli/command: remove deprecated RegistryAuthenticationPrivilegedFunc
2025-08-25 11:00:30 +02:00
Sebastiaan van Stijn dcc3d25dc2 cli/command/service: fix API annotations for generic resource flags
These flags were added in 20a6ff32ee, and require
API version v1.32 or up, but they accidentally copied the flag-name from another
flag, so were not setting the annotation correctly.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-25 10:59:47 +02:00
Sebastiaan van Stijn c36e67d7b6 cli/command/image: runPush: minor cleanups and linting issues
- Remove redundant intermediate variables
- Explicitly use an early return on error instead of combining with
  other checks.
- Fix unhandled errors and combine defers
- Remove outstanding TODO that unlikely will be addressed

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-24 19:38:24 +02:00
Sebastiaan van Stijn 4f944e245b cli/command/formatter: ContainerContext.Image: explicitly strip digest
The `reference.TrimNamed` function strips both digests and tags; the
formatter function only wants to remove the digest, but preserve any
tags present.

Update the implementation to only trim the reference if there's a digest
present, otherwise use it as-is.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-24 19:31:47 +02:00
Sebastiaan van Stijn 7ac3e0e0bf cli/command/formatter: ContainerContext.Image: use early returns
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-24 19:31:47 +02:00
Sebastiaan van Stijn 0e7d422e5f cli/command/formatter: TestContainerPsContext: add test-cases
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-24 19:31:46 +02:00
Sebastiaan van Stijn 7cb8147e77 cli/trust: GetNotaryRepository: inline variables
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-24 16:01:08 +02:00
Sebastiaan van Stijn 35a41c39a4 cli/trust: check for Digested, Tagged reference instead of Canonical
The [Canonical] interface defines images that are both [Named] and
[Digested], but in all places where it was used, we were only interested
whether the reference contained a digest. Similarly [NamedTagged] is
a superset of [Tagged], so checking for [Tagged] is sufficient if we're
already dealing with a [Named] reference.

This patch changes those checks to check for [Digested] and [Tagged]
references, as that's what's relevant for these checks.

[Named]: https://pkg.go.dev/github.com/distribution/reference#Named
[NamedTagged]: https://pkg.go.dev/github.com/distribution/reference#NamedTagged
[Canonical]: https://pkg.go.dev/github.com/distribution/reference#Canonical
[Digested]: https://pkg.go.dev/github.com/distribution/reference#Digested

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-24 16:00:54 +02:00
Sebastiaan van StijnandGitHub abe4aa7893 Merge pull request #6360 from hsnabszhdn/add-missing-backticks
docs: add missing backticks in 'run.md'
2025-08-23 14:14:58 +02:00
Sebastiaan van StijnandGitHub 08f876d6e8 Merge pull request #6359 from hsnabszhdn/fix-sentence-structures-in-run-md
docs: fix sentence structures in 'run.md'
2025-08-23 14:14:24 +02:00
Austin VazquezandGitHub 0f875ba9ad Merge pull request #6351 from thaJeztah/avoid_shadowing
cli/command: rename vars for consistency and prevent shadowing
2025-08-23 02:56:49 -07:00
Hossein Abbasi d9cafa759f docs: add missing backticks in 'run.md'
Signed-off-by: Hossein Abbasi <16090309+hsnabszhdn@users.noreply.github.com>
2025-08-23 16:14:53 +10:00
Hossein Abbasi ba2c1c94ab docs: fix sentence structures in 'run.md'
Signed-off-by: Hossein Abbasi <16090309+hsnabszhdn@users.noreply.github.com>
2025-08-23 15:54:56 +10:00
Sebastiaan van Stijn 7ad113ccc2 cli/command/image: deprecate AuthResolver and un-export
This function was exported to share it between "trust" and "image",
but was only a shallow wrapper, so split the implementations where
used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-23 03:46:14 +02:00
Sebastiaan van Stijn 9216f04eb6 cli/command/image: remove exported RunPull, PullOptions
These were exported in 812f113685, but
while the function and options are exported, the option-fields were
all un-exported, so these were not usable.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-23 03:35:51 +02:00
Sebastiaan van Stijn 9fd71c8347 cli/command: rename vars for consistency and prevent shadowing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-23 03:04:36 +02:00
Sebastiaan van Stijn 045ac0b159 internal/jsonstream: remove uses of deprecated fields
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-23 02:17:20 +02:00
Sebastiaan van Stijn 03da6ad2d1 cli/command: remove deprecated RegistryAuthenticationPrivilegedFunc
This function was deprecated in 29263e865b
and is no longer used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-23 00:41:07 +02:00
Sebastiaan van StijnandGitHub 1df8feb2e4 Merge pull request #6345 from thaJeztah/bump_x_sync
vendor: golang.org/x/sync v0.16.0
2025-08-22 21:05:54 +02:00
Sebastiaan van Stijn c7cbac58b3 vendor: golang.org/x/sync v0.16.0
Brings in the errgroup implementation for reverted auto-recover from panics.

full diff: https://github.com/golang/sync/compare/v0.14.0...v0.16.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 14:26:38 +02:00
Sebastiaan van StijnandGitHub e8e4588f64 Merge pull request #6344 from thaJeztah/remove_builder_newprunecommand
cli/command/trust: remove deprecated NewPruneCommand
2025-08-22 12:41:14 +02:00
Sebastiaan van Stijn d317bc30be cli/command/trust: remove deprecated NewPruneCommand
These were deprecated in 7032f5922e, which
is part of the v28.4 release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 12:35:36 +02:00
Sebastiaan van StijnandGitHub 832a3754e5 Merge pull request #6342 from thaJeztah/deprecate_builder_NewPruneCommand
cli/command/builder: deprecate NewPruneCommand
2025-08-22 12:35:08 +02:00
Sebastiaan van StijnandGitHub 4d4533abaa Merge pull request #6338 from thaJeztah/cleanup_formatters
cli/command: inline vars and use struct literals in formatting functions
2025-08-22 12:25:14 +02:00
Sebastiaan van Stijn 7032f5922e cli/command/builder: deprecate NewPruneCommand
This patch deprecates exported NewPruneCommand and moves the
implementation details to an unexported function.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 12:18:27 +02:00
Sebastiaan van StijnandGitHub 2966159873 Merge pull request #6339 from thaJeztah/rm_deprecated_formatting
cli/command/*: remove deprecated formatting-related functions and types
2025-08-22 12:10:26 +02:00
Sebastiaan van StijnandGitHub 65e7ece518 Merge pull request #6337 from thaJeztah/pretty_io
cli/command/system: prettyPrintVersion: accept a plain io.Writer
2025-08-22 11:31:33 +02:00
Sebastiaan van Stijn 5bb8ab4e6f cli/command/trust: remove deprecated formatting functions
These were deprecated in 95c9b1b13b, which
is part of the v28.4 release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:43:27 +02:00
Sebastiaan van Stijn 8969b57500 cli/command/task: remove deprecated formatting functions
These were deprecated in c3ee82fdc3, which
is part of the v28.4 release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:42:53 +02:00
Sebastiaan van Stijn c6f4573153 cli/command/service: remove deprecated formatting functions
These were deprecated in 9f453d3fea, which
is part of the v28.4 release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:42:24 +02:00
Sebastiaan van Stijn 04bcae3a8c cli/command/secret: remove deprecated formatting functions
These were deprecated in f3088e37a0, which
is part of the v28.4 release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:41:52 +02:00
Sebastiaan van Stijn c592932f47 cli/command/registry: remove deprecated formatting functions
These were deprecated in 83371c2014, which
is part of the v28.4 release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:41:11 +02:00
Sebastiaan van Stijn 264080d2fc cli/command/plugin: remove deprecated formatting functions
These were deprecated in bf47419852, which
is part of the v28.4 release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:40:43 +02:00
Sebastiaan van Stijn e5a0fb09a3 cli/command/node: remove deprecated formatting functions
These were deprecated in 123ef81f7d, which
is part of the v28.4 release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:40:09 +02:00
Sebastiaan van Stijn 7b172fcf53 cli/command/network: remove deprecated formatting functions
These were deprecated in e3903a1ac8, which
is part of the v28.4 release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:39:35 +02:00
Sebastiaan van Stijn d223ec3b56 cli/command/image: remove deprecated formatting functions
These were deprecated in 15cf4fa912, which
is part of the v28.4 release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:38:56 +02:00
Sebastiaan van Stijn 206a8da307 cli/command/container: remove deprecated formatting functions
These were deprecated in 907507e22a and
fdc90caeee, which are part of the v28.4
release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:38:09 +02:00
Sebastiaan van Stijn f969adf63f cli/command/config: remove deprecated formatting functions
These were deprecated in e626f778ec, which
is part of the v28.4 release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:36:11 +02:00
Sebastiaan van Stijn e416418e70 cli/command/checkpoint: remove deprecated formatting functions
These were deprecated in d861b78a8a, which
is part of the v28.4 release.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:34:17 +02:00
Sebastiaan van Stijn efd6e7b6e0 cli/command/system: prettyPrintVersion: accept a plain io.Writer
We're only writing to a single stream, so may as well just let it
take an io.writer.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:22:56 +02:00
Sebastiaan van Stijn f72ec26693 cli/command/trust: inline vars and use struct literals
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:19:11 +02:00
Sebastiaan van Stijn 6de2cdd1af cli/command/task: inline vars and use struct literals
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:19:11 +02:00
Sebastiaan van Stijn e308036440 cli/command/service: inline vars and use struct literals
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:19:11 +02:00
Sebastiaan van Stijn 12d30bb50c cli/command/secret: inline vars and use struct literals
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:19:11 +02:00
Sebastiaan van Stijn 863b5633f3 cli/command/registry: inline vars and use struct literals
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:19:11 +02:00
Sebastiaan van Stijn aa39a7e7be cli/command/plugin: inline vars and use struct literals
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:19:10 +02:00
Sebastiaan van Stijn 1a433cdbdb cli/command/node: inline vars and use struct literals
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:19:10 +02:00
Sebastiaan van Stijn 3d2bd97a82 cli/command/config: formatWrite: inline vars and use struct literals
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:19:10 +02:00
Sebastiaan van Stijn 70033b78d4 cli/command/checkpoint: formatWrite: inline vars and use struct literals
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:19:10 +02:00
Sebastiaan van Stijn 8cb8056efa cli/command/image: historyWrite: inline vars and use struct literals
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:19:10 +02:00
Sebastiaan van Stijn 7589722e93 cli/command/network: formatWrite: inline vars and use struct literals
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:19:09 +02:00
Sebastiaan van Stijn e06e758d5f cli/command/system: TestVersionFormat: use table-test and struct literal
- Use a table-test to more easily allow adding test-cases
- Use the test-name itself as name for the golden file
- Use a struct-literal to create the fixture for formatting.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-22 09:11:35 +02:00
Sebastiaan van StijnandGitHub 58bb45c37f Merge pull request #6336 from thaJeztah/internalize_formatters
cli/command/*: deprecate formatting-related functions and types
2025-08-22 08:29:16 +02:00
Sebastiaan van Stijn 95c9b1b13b cli/command/trust: deprecate formatting-related functions and types
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

This deprecates the following types and functions:

- `SignedTagInfo`
- `SignerInfo`
- `NewTrustTagFormat`
- `NewSignerInfoFormat`
- `TagWrite`
- `SignerInfoWrite`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 15:25:26 +02:00
Sebastiaan van Stijn c3ee82fdc3 cli/command/task: deprecate NewTaskFormat, FormatWrite
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 15:25:26 +02:00
Sebastiaan van Stijn 9f453d3fea cli/command/service: deprecate NewFormat, InspectFormatWrite
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 15:25:26 +02:00
Sebastiaan van Stijn f3088e37a0 cli/command/secret: deprecate NewFormat, FormatWrite, InspectFormatWrite
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 15:25:25 +02:00
Sebastiaan van Stijn 83371c2014 cli/command/registry: deprecate NewSearchFormat, SearchWrite
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 15:25:25 +02:00
Sebastiaan van Stijn bf47419852 cli/command/plugin: deprecate NewFormat, FormatWrite
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 15:25:25 +02:00
Sebastiaan van Stijn 123ef81f7d cli/command/node: deprecate NewFormat, FormatWrite, InspectFormatWrite
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 15:25:25 +02:00
Sebastiaan van Stijn e626f778ec cli/command/config: deprecate NewFormat, FormatWrite, InspectFormatWrite
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 15:25:25 +02:00
Sebastiaan van Stijn d861b78a8a cli/command/checkpoint: deprecate NewFormat, FormatWrite
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 15:25:24 +02:00
Sebastiaan van Stijn 15cf4fa912 cli/command/image: deprecate NewHistoryFormat, HistoryWrite
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 15:25:24 +02:00
Sebastiaan van Stijn e3903a1ac8 cli/command/network: deprecate NewFormat, FormatWrite
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 14:31:27 +02:00
Sebastiaan van StijnandGitHub b0d1d94711 Merge pull request #6330 from thaJeztah/internalize_ParseEnvFile
opts: deprecate ParseEnvFile
2025-08-21 13:35:39 +02:00
Sebastiaan van StijnandGitHub 8c0440a653 Merge pull request #6335 from thaJeztah/rm_exported_cobra_funcs
cli/command/*: remove deprecated cobra command constructors
2025-08-21 13:13:19 +02:00
Sebastiaan van StijnandGitHub 40e605a3b2 Merge pull request #6334 from thaJeztah/commands_nolock
internal/commands: remove mutexes / synchronisation and copy
2025-08-21 13:11:17 +02:00
Sebastiaan van Stijn 873609d790 cli/command/*: remove deprecated cobra command constructors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 11:12:28 +02:00
Sebastiaan van Stijn 570a17b3bc internal/commands: RegisterLegacy: remove redundant copy
The RegisterLegacy and Register functions register constructors for
commands, so we should expect them to be a fresh copy that is not
shared, which means that we can mutate the command in-place.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 10:47:26 +02:00
Sebastiaan van Stijn 4405c0bd50 internal/commands: remove mutexes / synchronisation
The Register and RegisterLegacy functions are designed to be used
in package init() functions, which are guaranteed to be run
sequentially.

From the documentation (https://go.dev/ref/mem#init);

> Program initialization runs in a single goroutine, but that goroutine
> may create other goroutines, which run concurrently. If a package `p`
> imports package `q`, the completion of `q`'s `init` functions happens
> before the start of any of `p`'s.
>
> The completion of all `init` functions is synchronized before the
> start of the function `main.main`.

This patch removes the synchonisation as no concurrency should happen
if these functions are used as intended.

As the internal queue is not expected to be mutated after use, we also
don't have to return a copy.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 10:42:02 +02:00
Sebastiaan van StijnandGitHub 942a6c4c76 Merge pull request #6329 from Benehiko/cli/commands
Register CLI commands implicitly
2025-08-21 09:23:30 +02:00
Alano Terblanche 56cab16779 Register CLI commands implicitly
This patch removes the explicit `commands.AddCommands` function and
instead relies upon the `internal/commands` package which registers each
CLI command using `init()` instead.

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-21 07:16:35 +02:00
Sebastiaan van StijnandGitHub 76c405cfdb Merge pull request #6327 from thaJeztah/registryclient_simplify_repositoryEndpoint
internal/registryclient: repositoryEndpoint: memoize repoName
2025-08-20 15:04:16 +02:00
Sebastiaan van Stijn e650803f09 opts: deprecate ParseEnvFile
It was a wrapper around kvfile.Load, which should be used instead.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-20 15:03:05 +02:00
Alano TerblancheandGitHub 4d93a6486e Merge pull request #6328 from Benehiko/command/trust
Unexport trust commands
2025-08-20 12:18:16 +00:00
Alano TerblancheandGitHub d071c29d4a Merge pull request #6326 from Benehiko/command/plugin
Unexport plugin commands
2025-08-20 12:13:18 +00:00
Alano TerblancheandGitHub 8d99b45d4a Merge pull request #6325 from Benehiko/command/swarm
Unexport swarm commands
2025-08-20 12:08:40 +00:00
Alano Terblanche bd8e3e4440 Unexport trust commands
This patch deprecates exported trust commands and moves the implementation
details to an unexported function.

Commands that are affected include:

- trust.NewTrustCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-20 14:07:45 +02:00
Alano Terblanche c6b7268932 Unexport plugin commands
This patch deprecates exported plugin commands and moves the implementation
details to an unexported function.

Commands that are affected include:

- plugin.NewPluginCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-20 14:03:57 +02:00
Sebastiaan van Stijn 2ce94e4fff internal/registryclient: repositoryEndpoint: memoize repoName
- Parse/format the repository name when constructing and store the
  result.
- Remove the Name() accessor, as this type is only used internally,
  and no longer had any special handling.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-20 14:02:26 +02:00
Alano Terblanche bf39340294 Unexport swarm commands
This patch deprecates exported swarm commands and moves the implementation
details to an unexported function.

Commands that are affected include:

- swarm.NewSwarmCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-20 13:59:30 +02:00
Alano TerblancheandGitHub b2b7187244 Merge pull request #6324 from Benehiko/command/registry
Unexport registry commands
2025-08-20 11:43:43 +00:00
Alano TerblancheandGitHub 7dfcb06587 Merge pull request #6322 from Benehiko/command/context
Unexport context command
2025-08-20 11:40:09 +00:00
Alano Terblanche d4588c711c Unexport registry commands
This patch deprecates exported registry commands and moves the implementation
details to an unexported function.

Commands that are affected include:

- registry.NewLoginCommand
- registry.NewLogoutCommand
- registry.NewSearchCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-20 13:39:06 +02:00
Alano TerblancheandGitHub bf9173f383 Merge pull request #6323 from Benehiko/command/stack
Unexport stack commands
2025-08-20 11:36:40 +00:00
Alano Terblanche 630fe430ff Unexport stack commands
This patch deprecates exported stack commands and moves the implementation
details to an unexported function.

Commands that are affected include:

- stack.NewStackCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-20 13:27:11 +02:00
Alano Terblanche 3b0edc794c Unexport context command
This patch deprecates exported context commands and moves the implementation
details to an unexported function.

Commands that are affected include:

- context.NewContextCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-20 13:22:47 +02:00
Alano TerblancheandGitHub 89316e18fc Merge pull request #6321 from Benehiko/command/volume
Unexport volume commands
2025-08-20 11:18:35 +00:00
Alano TerblancheandGitHub 7a50955006 Merge pull request #6320 from Benehiko/command/service
Unexport service commands
2025-08-20 10:57:33 +00:00
Alano Terblanche 9961e39d40 Unexport volume commands
This patch deprecates exported volume commands and moves the implementation
details to an unexported function.

Commands that are affected include:

- volume.NewVolumeCommand
- volume.NewPruneCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-20 12:57:33 +02:00
Alano Terblanche 88178eda32 Unexport service commands
This patch deprecates exported service commands and moves the implementation
details to an unexported function.

Commands that are affected include:

- service.NewServiceCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-20 12:51:55 +02:00
Sebastiaan van StijnandGitHub cd859b33b4 Merge pull request #6318 from Benehiko/command/manifest
Unexport manifest command
2025-08-20 12:51:14 +02:00
Alano TerblancheandGitHub 1d34432676 Merge pull request #6319 from Benehiko/command/secret
Unexport secret commands
2025-08-20 10:49:06 +00:00
Alano Terblanche e00762ed7d Unexport secret commands
This patch deprecates exported secret commands and moves the implementation
details to an unexported function.

Commands that are affected include:

- secrets.NewSecretCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-20 12:45:11 +02:00
Sebastiaan van StijnandGitHub 6b58c4d545 Merge pull request #6317 from Benehiko/command/node
Unexport node commands
2025-08-20 12:43:50 +02:00
Sebastiaan van StijnandGitHub 642adae0c0 Merge pull request #6316 from Benehiko/command/network
Unexport network commands
2025-08-20 12:42:57 +02:00
Alano Terblanche 02fda07211 Unexport manifest command
This patch deprecates exported manifest commands and moves the implementation
details to an unexported function.

Commands that are affected include:

- manifest.NewManifestCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-20 12:40:26 +02:00
Alano Terblanche ab3fcf9f9b Unexport node commands
This patch deprecates exported node commands and moves the implementation
details to an unexported function.

Commands that are affected include:

- node.NewNodeCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-20 12:34:49 +02:00
Alano Terblanche 78a8856c14 Unexport network commands
This patch deprecates exported network commands and moves the
implementation details to an unexported function.

Commands that are affected include:

- network.NewNetworkCommand
- network.NewPruneCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-20 12:32:09 +02:00
Sebastiaan van StijnandGitHub 4643b42e1d Merge pull request #6314 from thaJeztah/auth_cleanups
cli/command: fix godoc links and inline resolveAuthConfigFromImage
2025-08-20 11:57:34 +02:00
Paweł GronowskiandGitHub 86e2a06f1b Merge pull request #6296 from thaJeztah/cli_rm_deprecated_utils
cli: remove deprecated VisitAll, DisableFlagsInUseLine utilities
2025-08-20 11:42:45 +02:00
Sebastiaan van Stijn 4286883b95 cli/command: inline resolveAuthConfigFromImage
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-19 23:42:07 +02:00
Sebastiaan van Stijn 2d3b0b33b4 cli/command: fix godoc links
- Use versioned links to github.com/docker/docker packages
- Fix links to RFC 4648, section 5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-19 23:42:03 +02:00
Sebastiaan van StijnandGitHub c3170f1c81 Merge pull request #6293 from thaJeztah/remove_deprecated_opts
opts: remove deprecated types and functions
2025-08-19 21:03:59 +02:00
Austin VazquezandGitHub 73d88f514b Merge pull request #6306 from thaJeztah/remove_quote_handling
cli/flags: remove special quote handling for `--tlsXXX` flags
2025-08-19 11:36:23 -07:00
Sebastiaan van StijnandGitHub 9ca4ae9e70 Merge pull request #6305 from Benehiko/commands/system
Unexport system commands
2025-08-19 15:27:15 +02:00
Sebastiaan van StijnandGitHub 11a60e871e Merge pull request #6304 from thaJeztah/internalize_registryclient
cli/registry/client: deprecate and move internal
2025-08-19 15:26:10 +02:00
Sebastiaan van StijnandGitHub 57ef7eed46 Merge pull request #6303 from thaJeztah/deprecated_nit
docs: deprecated: fix formatting of deprecated/removed in
2025-08-19 15:23:39 +02:00
Sebastiaan van Stijn 9b9d103b29 cli/flags: remove special quote handling for --tlsXXX flags
This non-standard handling for these options was added in [moby@e4c1f07]
and [moby@abe32de] to work around a regression in Docker 1.13 that caused
`docker-machine` to fail. Preserving quotes in such cases is expected (and
standard behavior), but versions of Docker before 1.13 used a custom "mflag"
package for flag parsing, and that package contained custom handling for
quotes (added in [moby@0e9c40e]).

Given that Docker Machine reached EOL a long time ago and other options,
such as `docker context`, have been added to configure the CLI to connect
to a specific host (with corresponding TLS configuration), we can remove
the special handling for these flags, as it's inconsistent with all other
flags, and not worth maintaining for a tool that no longer exists.

[moby@e4c1f07]: https://github.com/moby/moby/commit/e4c1f0772923c3069ce14a82d445cd55af3382bc
[moby@abe32de]: https://github.com/moby/moby/commit/abe32de6b46825300f612864e6b4c98606a5bb0e
[moby@0e9c40e]: https://github.com/moby/moby/commit/0e9c40eb8243fa437bc6c3e93aaff64a10cb856e

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-19 15:21:17 +02:00
Alano Terblanche cfb8cb91f2 Unexport system commands
This patch deprecates exported system commands and moves the
implementation details to an unexported function.

Commands that are affected include:

- system.NewVersionCommand
- system.NewInfoCommand
- system.NewSystemCommand
- system.NewEventsCommand
- system.NewInspectCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-19 15:17:41 +02:00
Sebastiaan van Stijn 1d571d178d docs: deprecated: fix formatting of deprecated/removed in
- Use sentence-case to follow our docs guidelines.
- Add newlines to prevent these being rendered on a
  single line.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-19 15:04:53 +02:00
Sebastiaan van StijnandGitHub 2e3d021912 Merge pull request #6263 from akerouanton/deprecate-legacy-links-env-vars
docs/deprecated: legacy links env vars
2025-08-19 15:01:18 +02:00
Sebastiaan van Stijn 13010ba673 cli/registry/client: deprecate and move internal
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-19 14:57:00 +02:00
Albin KerouantonandSebastiaan van Stijn 5c76f7f2d8 docs/deprecated: legacy links env vars
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Co-authored-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-19 14:45:53 +02:00
Sebastiaan van StijnandGitHub c2a042e0ed Merge pull request #6301 from Benehiko/commands/image
Unexport image commands
2025-08-19 14:37:12 +02:00
Alano Terblanche e66a1456d3 Unexport image commands
This patch deprecates exported image commands and moves the
implementation details to an unexported function.

Commands that are affected include:

- image.NewBuildCommand
- image.NewPullCommand
- image.NewPushCommand
- image.NewImagesCommand
- image.NewImageCommand
- image.NewHistoryCommand
- image.NewImportCommand
- image.NewLoadCommand
- image.NewRemoveCommand
- image.NewSaveCommand
- image.NewTagCommand
- image.NewPruneCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-19 14:25:15 +02:00
Sebastiaan van StijnandGitHub fcb260df1b Merge pull request #6299 from Benehiko/commands/container
Unexport container commands
2025-08-19 13:03:55 +02:00
Sebastiaan van StijnandGitHub 6e5ce4df55 Merge pull request #6300 from thaJeztah/rm_decodeauthconfig
cli/command: TestRetrieveAuthTokenFromImage: don't decode authconfig
2025-08-19 12:48:50 +02:00
Sebastiaan van Stijn ae1727c41e cli/command: TestRetrieveAuthTokenFromImage: don't decode authconfig
Rewrite the test to not depend on registry.DecodeAuthConfig, which
may be moved internal to the daemon as part of the modules transition.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-19 12:39:10 +02:00
Alano Terblanche 38595fecb6 Unexport container commands
This patch deprecates exported container commands and moves the
implementation details to an unexported function.

Commands that are affected include:
- container.NewRunCommand
- container.NewExecCommand
- container.NewPsCommand
- container.NewContainerCommand
- container.NewAttachCommand
- container.NewCommitCommand
- container.NewCopyCommand
- container.NewCreateCommand
- container.NewDiffCommand
- container.NewExportCommand
- container.NewKillCommand
- container.NewLogsCommand
- container.NewPauseCommand
- container.NewPortCommand
- container.NewRenameCommand
- container.NewRestartCommand
- container.NewRmCommand
- container.NewStartCommand
- container.NewStatsCommand
- container.NewStopCommand
- container.NewTopCommand
- container.NewUnpauseCommand
- container.NewUpdateCommand
- container.NewWaitCommand
- container.NewPruneCommand

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-19 11:12:19 +02:00
Sebastiaan van StijnandGitHub 4c3fa4ac3c Merge pull request #6286 from Benehiko/commands/config
Unexport config command
2025-08-19 10:28:52 +02:00
Sebastiaan van StijnandGitHub 6ad1d4617a Merge pull request #6285 from Benehiko/commands/checkpoint
Unexport checkpoint command
2025-08-19 10:27:49 +02:00
Sebastiaan van StijnandGitHub 2d979220cc Merge pull request #6284 from Benehiko/commands/builder
Unexport the builder and bake stub command
2025-08-19 10:26:25 +02:00
Alano Terblanche cce29da061 Unexport config command
This patch unexports the `config` command.

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-19 08:49:31 +02:00
Alano Terblanche 3265cead1d Unexport checkpoint command
This patch unexports the `checkpoint` command.

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-19 08:49:05 +02:00
Alano Terblanche 1b9d0762a5 Unexport the builder command and bake stub command
This patch unexports the `builder` and `bake` stub command and it adds
deprecation notices on the exported functions.

It also registers the commands using the new `cli/internal/commands`
package when the init function executes.

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-19 08:48:30 +02:00
Austin VazquezandGitHub 6dcf9ac843 Merge pull request #6297 from thaJeztah/plugin_manager_more_deprecations
cli-plugins/manager: deprecate annotation metadata aliases
2025-08-18 20:30:02 -07:00
Sebastiaan van Stijn 72f76f2720 cli-plugins/manager: deprecate annotation metadata aliases
These aliases were added in 292713c887
(part of v28.0), but did not deprecate them. They are no longer used
in the CLI itself, but may be used by cli-plugin implementations.

This deprecates the aliases in `cli-plugins/manager` in favor of
their equivalent in `cli-plugins/manager/metadata`:

- `CommandAnnotationPlugin`
- `CommandAnnotationPluginVendor`
- `CommandAnnotationPluginVersion`
- `CommandAnnotationPluginInvalid`
- `CommandAnnotationPluginCommandPath`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-18 21:50:53 +02:00
Sebastiaan van Stijn f9777d2517 cli: remove deprecated VisitAll, DisableFlagsInUseLine utilities
These were deprecated in 6bd8a4b2b5, and
are no longer used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-18 21:35:05 +02:00
Sebastiaan van Stijn 5934553198 opts: remove deprecated NewNamedListOptsRef, NewNamedMapOpts
These were deprecated in 6f0c66c152 and are
no longer used.

This removes the deprecated:

- `NewNamedListOptsRef`
- `NewNamedMapOpts`
- `NamedListOpts`
- `NamedMapOpts`
- `NamedOption`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-18 18:55:54 +02:00
Sebastiaan van Stijn a056cc6164 opts: remove deprecated ListOpts.GetAll
It's no longer used and replaced by `ListOpts.GetSlice`. It was deprecated
in 5215b1eca4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-18 18:55:50 +02:00
Sebastiaan van Stijn 15f3e910d1 opts: remove deprecated ValidateHost
This function is no longer used, and was deprecated in
d0ac0acff0.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-18 18:40:05 +02:00
Sebastiaan van Stijn 0c07d81a03 opts: remove deprecated QuotedString
This type is no longer used, and was deprecated in
187a942a88

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-18 18:37:15 +02:00
Sebastiaan van StijnandGitHub e0af501e30 Merge pull request #6288 from thaJeztah/deprecate_opts
opts: deprecate NewNamedListOptsRef, NewNamedMapOpts
2025-08-18 18:20:04 +02:00
Sebastiaan van StijnandGitHub 5f5a5e1297 Merge pull request #6290 from thaJeztah/deprecate_quoted_values
Deprecate special handling for quoted values for TLS flags
2025-08-18 18:16:56 +02:00
Sebastiaan van Stijn ee05a71513 Deprecate special handling for quoted values for TLS flags
The `--tlscacert`, `--tlscert`, and `--tlskey` command-line flags had
non-standard behavior for handling values contained in quotes (`"` or `'`).
Normally, quotes are handled by the shell, for example, in the following
example, the shell takes care of handling quotes before passing the values
to the `docker` CLI:

    docker --some-option "some-value-in-quotes" ...

However, when passing values using an equal sign (`=`), this may not happen
and values may be handled including quotes;

    docker --some-option="some-value-in-quotes" ...

This caused issues with "Docker Machine", which used this format as part
of its `docker-machine config` output, and the CLI carried special, non-standard
handling for these flags.

Docker Machine reached EOL, and this special handling made the processing
of flag values inconsistent with other flags used, so this behavior is
deprecated. Users depending on this behavior are recommended to specify
the quoted values using a space between the flag and its value, as illustrated
above.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-18 17:59:16 +02:00
Sebastiaan van Stijn 6f0c66c152 opts: deprecate NewNamedListOptsRef, NewNamedMapOpts
The `NewNamedListOptsRef`, `NewNamedMapOpts` and related `NamedListOpts`,
`NamedMapOpts`, and `NamedOption` interface were added in [moby@677a6b3],
which added support for a `daemon.json` configuration file. That change
required a way to correlate command-line flags with their corresponding
fields in the `daemon.json` to detect conflicting options. At the time,
the CLI and daemon were produced from the same code, and shared packages
for command-line options, but when the CLI was moved to a separate
repository, these options were inherited.

[moby@677a6b3]: https://github.com/moby/moby/commit/677a6b3506107468ed8c00331991afd9176fa0b9

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-18 17:27:02 +02:00
Sebastiaan van StijnandGitHub 5f6dfb00d8 Merge pull request #6287 from thaJeztah/progress_test
cli/command/container: TestRunPullTermination: rewrite with streamformatter
2025-08-18 17:07:32 +02:00
Alano TerblancheandGitHub c06074b22f Merge pull request #6283 from Benehiko/command/registration
Add command registration helpers
2025-08-18 15:02:15 +00:00
Alano Terblanche 4ead8784d0 Add command registration helpers
This patch adds helper methods to the CLI to register cobra commands.

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-08-18 16:56:35 +02:00
Sebastiaan van Stijn 69854c4e08 cli/command/container: TestRunPullTermination: rewrite with streamformatter
This makes the test slightly closer to the actual code in the daemon producing
the progress response;
https://github.com/moby/moby/blob/cd844fd0b2047eff6854600d375545b3ec01de48/daemon/images/image_pull.go#L58-L70
https://github.com/moby/moby/blob/cd844fd0b2047eff6854600d375545b3ec01de48/daemon/internal/distribution/utils/progress.go#L14-L34

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-18 15:21:14 +02:00
Sebastiaan van StijnandGitHub 877a6ef29f Merge pull request #6273 from thaJeztah/cli_internalize_utils
cli: deprecate VisitAll, DisableFlagsInUseLine utilities, remove HasCompletionArg
2025-08-18 11:40:47 +02:00
Sebastiaan van StijnandGitHub 2bcf433605 Merge pull request #6281 from thaJeztah/hosts_regular_stringarray
cli/flags: add "hostVar" to handle --host / -H as a single string
2025-08-18 11:24:10 +02:00
Sebastiaan van Stijn f14eeeb361 cli/flags: add "hostVar" to handle --host / -H as a single string
hostVar is used for the '--host' / '-H' flag to set [ClientOptions.Hosts].
The [ClientOptions.Hosts] field is a slice because it was originally shared
with the daemon config. However, the CLI only allows for a single host to
be specified.

hostVar presents itself as a "string", but stores the value in a string
slice. It produces an error when trying to set multiple values, matching
the check in [getServerHost].

[getServerHost]: https://github.com/docker/cli/blob/7eab668982645def1cd46fe1b60894cba6fd17a4/cli/command/cli.go#L542-L551

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-18 11:01:39 +02:00
Sebastiaan van Stijn 5ee2906e78 cli/flags: use a regular StringArray for the --host / -H flag
The ClientOptions struct and related flags were inherited from the Moby
repository, where originally the CLI and Daemon used the same implementation
and had a "Common" options struct. When the CLI moved to a separate repository,
those structs were duplicated, but some daemon-specific logic remained. For
example, the daemon can be configured to listen on multiple ports and sockets
([moby@dede158]), but the CLI [can only connect to a single host][1]. The
daemon config also had to account for flags conflicting with `daemon.json`,
and use special flag-vars for this ([moby@677a6b3]).

Unfortunately, the `ClientConfig` struct became part of the public API and
is used as argument in various places, but we can remove the use of the
special flag var. This patch replaces the use of `NewNamedListOptsRef`
for a regular `StringArray`.

Unfortunately this changes the flag's type description from `list` to
`stringArray`, but we can look at changing that separately.

[moby@dede158]: https://github.com/moby/moby/commit/dede1585ee00f957e153691c464aab293c2dc469
[1]: https://github.com/moby/moby/blob/0af135e9065562e14a77439e13a29b4f1eb627a0/docker/docker.go#L191-L193
[moby@677a6b3]: https://github.com/moby/moby/commit/677a6b3506107468ed8c00331991afd9176fa0b9

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-16 19:13:27 +02:00
Austin VazquezandGitHub 7eab668982 Merge pull request #6279 from thaJeztah/deprecate_ValidateHost
opts: deprecate ValidateHost utility
2025-08-16 07:21:40 -07:00
Austin VazquezandGitHub ccc1c65859 Merge pull request #6270 from thaJeztah/fix_prune_example
docs: fix output example for docker system prune
2025-08-16 07:20:13 -07:00
Austin VazquezandGitHub 842f8beb00 Merge pull request #6274 from thaJeztah/deprecate_quotedstring
opts: deprecate QuotedString
2025-08-15 13:19:26 -07:00
Sebastiaan van Stijn d0ac0acff0 opts: deprecate ValidateHost utility
The `ValidateHost` option was introduced in [moby@1ba1138] to be used
as validation func for the `--host` flag on the daemon in and CLI in
[moby@5e3f6e7], but is no longer used since [cli@6f61cf0]. which added
support for `ssh://` connections, and required validation elsewhere.

[moby@1ba1138]: https://github.com/moby/moby/commit/1ba11384bf82f824b0efbab31aaca439cfba1b4f
[moby@5e3f6e7]: https://github.com/moby/moby/commit/5e3f6e7023fbd0cfd1233a99c332801755340cfb
[cli@6f61cf0]: https://github.com/docker/cli/commit/6f61cf053afc927379cfef91d241539c36d070f6

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-15 22:16:11 +02:00
Sebastiaan van Stijn 187a942a88 opts: deprecate QuotedString
The `QuotedString` option was added in [moby@e4c1f07] and [moby@abe32de]
to work around a regression in Docker 1.13 that caused `docker-machine`
to fail. `docker-machine` produced instructions on how to set up a cli
to connect to the Machine it produced. These instructions used quotes
around the paths for TLS certificates, but with an `=` for the flag's
values instead of a space; due to this the shell would not handle
stripping quotes, so the CLI would now get the value including quotes.

Preserving quotes in such cases is expected (and standard behavior), but
versions of Docker before 1.13 used a custom "mflag" package for flag
parsing, and that package contained custom handling for quotes (added
in [moby@0e9c40e]).

For other flags, this problem could be solved by the user, but as these
instructions were produced by `docker-machine`'s `config` command, an
exception was made for the `--tls-xxx` flags. From [moby-29761]:

> The flag trimming behaviour is really unusual, and I would say unexpected.
> I think removing it is generally the right idea. Since we have one very
> common case where it's necessary for backwards compatibility we need to
> add a special case, but I don't think we should apply that case to every
> flag.

The `QuotedString` implementation has various limitations, as it doesn't
follow the same handling of quotes as a shell would.

Given that Docker Machine reached EOL a long time ago and other options,
such as `docker context`, have been added to configure the CLI to connect
to a specific host (with corresponding TLS configuration), we should remove
the special handling for these flags, as it's inconsitent with all other
flags, and not worth maintaining for a tool that no longer exists.

This patch deprecates the `QuotedString` option and removes its use. A
temporary, non-exported copy is added, but will be removed in the next
release.

[moby-29761]: https://github.com/moby/moby/issues/29761#issuecomment-270211265
[moby@e4c1f07]: https://github.com/moby/moby/commit/e4c1f0772923c3069ce14a82d445cd55af3382bc
[moby@abe32de]: https://github.com/moby/moby/commit/abe32de6b46825300f612864e6b4c98606a5bb0e
[moby@0e9c40e]: https://github.com/moby/moby/commit/0e9c40eb8243fa437bc6c3e93aaff64a10cb856e
[moby@c79a169]: https://github.com/moby/moby/commit/c79a169a35f8ee0ecb66cfcffab4b0bd2c77f996

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-15 18:58:09 +02:00
Sebastiaan van Stijn 5a38118956 cmd/docker: fix some minor linting issues
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-15 17:45:26 +02:00
Sebastiaan van Stijn 6bd8a4b2b5 cli: deprecate VisitAll, DisableFlagsInUseLine utilities
These utilities were only used internally; create a local copy
where used, and deprecate the ones in cli.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-15 17:45:21 +02:00
Sebastiaan van Stijn 5a99022556 cli: remove HasCompletionArg utility
It was only used in a single place and has no external consumers.
Move it to where it's used to keep things together.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-15 14:21:47 +02:00
Sebastiaan van StijnandRoberto Villarreal bf13010df8 docs: fix output example for docker system prune
The example shows that the `--volumes` option is used, which in current
versions of docker only removes "anonymous" volumes, but preserves named
volume:

    $ docker system prune -a --volumes
    ...
            - all anonymous volumes not used by at least one container
    ...

But the example output showed that a named volume ("named-vol") was
deleted;

    Deleted Volumes:
    named-vol

Co-authored-by: Roberto Villarreal <rrjjvv@yahoo.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-15 12:55:03 +02:00
Sebastiaan van StijnandGitHub 53b6fddced Merge pull request #6261 from vvoland/gha-fix
gha/validate-pr: Replace `continue-on-error`
2025-08-14 14:17:43 +02:00
Paweł Gronowski 4cd9833d7c gha/validate-pr: Replace continue-on-error
The label validation steps now properly fail the workflow when required
labels are missing, instead of continuing with errors.

This change removes the `continue-on-error: true` directives and adds
`always()` conditions to ensure the validation steps run regardless of
previous step outcomes.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-08-14 12:50:00 +02:00
Paweł GronowskiandGitHub 4bff12f476 Merge pull request #6260 from vvoland/gha-changelog-kind
.github/workflows: Add kind label validation to PR workflow
2025-08-14 11:25:41 +02:00
Paweł Gronowski 1456b53e4e .github/workflows: Add kind label validation to PR workflow
The PR validation workflow now enforces that every PR with an 'impact/*'
label must also have a corresponding 'kind/*' label, in addition to the
existing 'area/*' label requirement.

This change helps ensure proper categorization of pull requests by
requiring contributors to specify both the impact area and the kind of
change being made.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-08-14 10:34:07 +02:00
Paweł Gronowski 6d9b06d227 gha/validate-pr: Run on synchronize
Align with moby/moby

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-08-14 10:33:59 +02:00
Sebastiaan van StijnandGitHub e8876edcc2 Merge pull request #6254 from thaJeztah/cp_cleanup
cli/command/container: copyToContainer: improve error-handling
2025-08-13 11:22:30 +02:00
Sebastiaan van Stijn eb5b03a8a3 cli/command/container: copyToContainer: improve error-handling
The logic used in this function was confusing; some errors were ignored,
but responses handled regardless. The intent here is to try to detect
whether the destination exists inside the container and is of the right
"type" (otherwise produce an error).

Failing to "stat" the path in the container means we can't produce a
nice error for the user, but we'll continue the request, which either
would succeed or produce an error returned by the daemon.

While working on this patch, I noticed that some error-handling on the
daemon side is incorrect. This patch does not fix those cases, but
makes the logic slightly easier to follow (we should consider extracting
the "stat" code to a separate function though).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-13 00:24:31 +02:00
Sebastiaan van StijnandGitHub b71a055a11 Merge pull request #6253 from docker/dependabot/github_actions/actions/checkout-5
build(deps): bump actions/checkout from 4 to 5
2025-08-13 00:14:50 +02:00
Sebastiaan van Stijn c5ea9079af cli/command/container: copyToContainer rename error-return
Make it more clearly identifiable where we're dealing with the
named error-return

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-12 18:53:12 +02:00
dependabot[bot]andGitHub f2af519f2e build(deps): bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 16:52:05 +00:00
Sebastiaan van StijnandGitHub bd0546ad5b Merge pull request #6252 from thaJeztah/less_pkg_errors
reduce uses of pkg/errors
2025-08-12 07:44:16 +02:00
Sebastiaan van Stijn 27a7947535 cli/command/image/build/internal/git: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:09 +02:00
Sebastiaan van Stijn 53183396d7 internal/volumespec: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:08 +02:00
Sebastiaan van Stijn 70f1147394 cli/command/trust: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:08 +02:00
Sebastiaan van Stijn a8f11a2fa2 cli/command/formatter: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:08 +02:00
Sebastiaan van Stijn c612e141b5 cli/command/registry: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:08 +02:00
Sebastiaan van Stijn 9b7ee0e201 cli/config: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:08 +02:00
Sebastiaan van Stijn 3b677449d8 cli/context: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:08 +02:00
Sebastiaan van Stijn d38317c781 cli/compose: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:07 +02:00
Sebastiaan van Stijn 2dd462cc36 cli/command/idresolver: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:07 +02:00
Sebastiaan van Stijn 4c89455378 cli/registry/client: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:07 +02:00
Sebastiaan van Stijn adbe04b5fc cli/manifest, cli/command/manifest: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:07 +02:00
Sebastiaan van Stijn 097cc9ca64 cli/trust: use stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:07 +02:00
Sebastiaan van Stijn e069ded4c3 cli: reduce uses of pkg/errors for stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:02 +02:00
Sebastiaan van StijnandGitHub 44eba133d6 Merge pull request #6250 from thaJeztah/bump_go_connections
vendor: github.com/docker/go-connections v0.6.0
2025-08-11 15:56:03 +02:00
Sebastiaan van Stijn 3529651fa7 vendor: github.com/docker/go-connections v0.6.0
- deprecate sockets.GetProxyEnv, sockets.DialerFromEnvironment
- add support for unix sockets on Windows
- remove legacy CBC cipher suites from client config
- align client and server defaults to be the same.
- remove support for encrypted TLS private keys.
- nat: optimize ParsePortSpec

full diff: https://github.com/docker/go-connections/compare/v0.5.0...v0.6.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 15:33:22 +02:00
Sebastiaan van StijnandGitHub 8324b17f9a Merge pull request #6249 from thaJeztah/skip_TestPromptExitCode
e2d skip flaky test: TestPromptExitCode/plugin_upgrade, plugin_install
2025-08-11 15:06:56 +02:00
Sebastiaan van StijnandGitHub d16defd9e2 Merge pull request #6247 from austinvazquez/update-golang-1.24.6
update to go1.24.6
2025-08-08 19:56:53 +02:00
Sebastiaan van Stijn 3035b6685b e2d skip flaky test: TestPromptExitCode/plugin_upgrade, plugin_install
This test was recently rewritten from testing plugin upgrade with
DCT enabled to just "plugin upgrade", but there's a fair amount of
complexity in the e2e tests that set up different daemons and registries.

It's possible that tests are affecting each-other, and some state (config)
is left behind.

Let's skip the test for now, and add a tracking ticket to dig deeper.

    === FAIL: e2e/global TestPromptExitCode/plugin_upgrade (7.55s)
        cli_test.go:205: assertion failed:
            Command:  docker plugin push registry:5000/plugin-upgrade-test:latest
            ExitCode: 1
            Error:    exit status 1
            Stdout:   The push refers to repository [registry:5000/plugin-upgrade-test]
            459089aa5943: Preparing
            adc41078d1d9: Preparing
            d7bff979db13: Preparing
            459089aa5943: Preparing

            Stderr:   error pushing plugin: failed to do request: Head "https://registry:5000/v2/plugin-upgrade-test/blobs/sha256:adc41078d1d937495df2f90444e5414a01db31e5a080f8aa4f163c64d41abd11": http: server gave HTTP response to HTTPS client

            Failures:
            ExitCode was 1 expected 0
            Expected no error

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-08 19:07:00 +02:00
Austin Vazquez 6769f62746 update to go1.24.6
- https://github.com/golang/go/issues?q=milestone%3AGo1.24.6+label%3ACherryPickApproved
- full diff: golang/go@go1.24.5...go1.24.6

These minor releases include 2 security fixes following the security policy:

- os/exec: LookPath may return unexpected paths

If the PATH environment variable contains paths which are executables (rather
than just directories), passing certain strings to LookPath ("", ".", and ".."),
can result in the binaries listed in the PATH being unexpectedly returned.

Thanks to Olivier Mengué for reporting this issue.

This is CVE-2025-47906 and Go issue https://go.dev/issue/74466.

- database/sql: incorrect results returned from Rows.Scan

Cancelling a query (e.g. by cancelling the context passed to one of the query
methods) during a call to the Scan method of the returned Rows can result in
unexpected results if other queries are being made in parallel. This can result
in a race condition that may overwrite the expected results with those of
another query, causing the call to Scan to return either unexpected results
from the other query or an error.

We believe this affects most database/sql drivers.

Thanks to Spike Curtis from Coder for reporting this issue.

This is CVE-2025-47907 and https://go.dev/issue/74831.

View the release notes for more information:
https://go.dev/doc/devel/release#go1.24.6

Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
2025-08-08 10:15:50 -05:00
Sebastiaan van StijnandGitHub ef38d81fdb Merge pull request #6245 from thaJeztah/rm_completion
cli/command/completion: remove deprecated ValidArgsFn
2025-08-07 13:52:04 +02:00
Sebastiaan van Stijn 5052a39915 cli/command/completion: remove deprecated ValidArgsFn
This was deprecated in 9f19820f88, which
is part of v28.x, and unlikely used externally.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-06 23:53:56 +02:00
Sebastiaan van StijnandGitHub 4beddd3e25 Merge pull request #6244 from thaJeztah/remove_trust_flag_helpers
cli/command: remove `AddTrustSigningFlags`, `AddTrustVerificationFlags`, `AddPlatformFlag` utilities
2025-08-06 19:37:36 +02:00
Sebastiaan van Stijn 7026e68a71 cli/command: remove AddPlatformFlag utility
It was only used internally and has no external users. It should not be
used for new uses, because it also adds a minimum API version constraint
and a default from env-var, which must be evaluated for each individual
use of such flags.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-06 17:15:32 +02:00
Sebastiaan van Stijn c0fbbe05ca cli/command: remove AddTrustVerificationFlags
It was only used internally; inline it where used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-06 17:00:25 +02:00
Sebastiaan van Stijn 8c22927978 cli/command: remove AddTrustSigningFlags
it was only used internally in a single location, so inline the
code where it's used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-06 16:55:42 +02:00
Sebastiaan van StijnandGitHub c1cc6b61a3 Merge pull request #6233 from thaJeztah/plugin_no_dct
cli/command/plugin: remove DCT
2025-08-06 14:04:01 +02:00
Sebastiaan van Stijn 3f5b1bdd32 cli/command/plugin: remove DCT
Plugins are not widely used, and there's no known plugins that use
content-trust. We're working on updating the authentication stack
in the CLI, and the trust implementation hinders us in making
changes, so removing parts that are not high-priority (ahead of
full deprecation of DCT).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-06 12:33:27 +02:00
Sebastiaan van StijnandGitHub 845870e669 Merge pull request #6243 from thaJeztah/remove_prompt_utils
cli/command: remove prompt utilities that were for internal use
2025-08-06 12:30:31 +02:00
Sebastiaan van StijnandGitHub 8683664b29 Merge pull request #6238 from thaJeztah/e2e_touchups
e2e: minor cleanups in `TestPromptExitCode`
2025-08-06 12:30:08 +02:00
Sebastiaan van Stijn d3c23a223c e2e/global: TestPromptExitCode: group plugin preparation steps
Use names for the plugin that don't refer to content-trust, as that's
not related to this test.

Make it slightly more clear which steps are preparation and which
are the actual test. The test sometimes fails in the preparation
step, and we could consider moving those separate and XFail the
test if the preparation fails;

        Stderr:   error pushing plugin: failed to do request: Head "https://registry:5000/v2/plugin-content-trust-upgrade/blobs/sha256:af932a31d4df3a2890f900bcf28e16cea87b2b440b8036ba86ab3418f3e50a35": http: server gave HTTP response to HTTPS client

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-06 10:57:01 +02:00
Sebastiaan van Stijn 081add2fc5 e2e/testutils: SetupPlugin: return path of directory
The gotest.tools `fs.NewDir` utility already sets up a `t.Cleanup`,
so we can treat it the same as `t.TempDir()` and let it handle
cleaning up by itself.

We should probably consider replacing some of this with `t.TempDir`.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-06 10:57:01 +02:00
Sebastiaan van Stijn 8972e53ad0 cli/command: remove prompt utilities that were for internal use
- The `DisableInputEcho` and `PromptForInput` utilities were added in
  c15ade0c64 as part of a bug-fix, which
  was part of v28.x. [There are no (publicly visible) users][1] of either.
- The `ErrPromptTerminated` was added in v26.x (originally added in
  10bf91a02d, later updated in commit
  7c722c08d0. [It is not used][2]
- The `PromptForConfirmation` was added in [moby@280c872] (docker v1.13.0)
  as part of the `docker <object> prune` subcommands. It was meant for
  internal use but exported to allow re-using it in the `container`,
  `image` (etc.) packages. However, a breaking change to its signature
  was made in 10bf91a02d. It currently
  does [not appear to have any (public) users][2].

This patch removes the `ErrPromptTerminated`, `DisableInputEcho`,
`PromptForInput`, and `PromptForConfirmation` utilities from the
`cli/command` package. The core functionality of these is still
available in the `internal/prompt` package, which we may make
public at some point, but still needs some refining / decoupling.

[moby@280c872]: https://github.com/moby/moby/commit/280c8723667af385e0807a090ddc5cc57c46807e
[1]: https://grep.app/search?f.lang=Go&regexp=true&q=%5C.%28DisableInputEcho%7CPromptForInput%29%5C%28
[2]: https://grep.app/search?f.lang=Go&q=%5C.ErrPromptTerminated
[3]: https://grep.app/search?f.lang=Go&q=.PromptForConfirmation%28

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-06 10:50:31 +02:00
Sebastiaan van StijnandGitHub f2c64c123f Merge pull request #6241 from thaJeztah/deprecate_bind_nonrecursive
remove deprecated `bind-nonrecursive` option for `--mount`
2025-08-06 10:48:58 +02:00
Sebastiaan van StijnandGitHub 25f95877b5 Merge pull request #6219 from thaJeztah/cleanup_credentialSpecOpt
cli/command/service: credentialSpecOpt: use strings.Cut
2025-08-06 10:09:26 +02:00
Sebastiaan van StijnandGitHub 14ed619736 Merge pull request #6240 from thaJeztah/remove_deprecated
cli/command: remove deprecated CopyToFile, ConfigureAuth utilities
2025-08-06 10:08:33 +02:00
Sebastiaan van StijnandGitHub 7dd9c20cac Merge pull request #6235 from thaJeztah/remove_cli_experimental_remnants
remove some remnants from CLI "experimental" config option
2025-08-06 09:50:27 +02:00
Paweł GronowskiandGitHub 39829affbe Merge pull request #6242 from thaJeztah/bump_mergo
vendor: dario.cat/mergo v1.0.2
2025-08-06 07:33:22 +00:00
Sebastiaan van Stijn a93ed48d06 vendor: dario.cat/mergo v1.0.2
drops gopkg.in/yaml.v3 as dependency

full diff: https://github.com/darccio/mergo/compare/v1.0.1...v1.0.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-06 01:16:17 +02:00
Sebastiaan van StijnandGitHub f1ceb8c55d Merge pull request #6236 from thaJeztah/system_prune_register
system prune: refactor to use "register" functions
2025-08-05 23:25:51 +02:00
Sebastiaan van Stijn abfe4d4629 remove deprecated bind-nonrecursive option for --mount
The `bind-nonrecursive` option was replaced with the [`bind-recursive`]
option (see [cli-4316], [cli-4671]). The option was still accepted, but
printed a deprecation warning:

    bind-nonrecursive is deprecated, use bind-recursive=disabled instead

In the v29.0 release, this warning is removed, and returned as an error.
Users should use the equivalent `bind-recursive=disabled` option instead.

[`bind-recursive`]: https://docs.docker.com/engine/storage/bind-mounts/#recursive-mounts
[cli-4316]: https://github.com/docker/cli/pull/4316
[cli-4671]: https://github.com/docker/cli/pull/4671

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-05 23:23:38 +02:00
Sebastiaan van StijnandGitHub 68fc942fd2 Merge pull request #6232 from thaJeztah/bump_engine
vendor: moby/moby/api v1.52.0-alpha.1, moby/moby/client v0.1.0-alpha.0
2025-08-05 22:42:19 +02:00
Sebastiaan van Stijn f9431e3b35 vendor: moby/moby/api v1.52.0-alpha.1, moby/moby/client v0.1.0-alpha.0
full diff: https://github.com/moby/moby/compare/4faedf2bec36...37d0204d7f23

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-05 22:01:50 +02:00
Sebastiaan van Stijn 22cc0e90ae cli/command: remove deprecated ConfigureAuth utility
It was deprecated in 6e4818e7d6, which
is part of v28.x and backported to v27.x.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-05 21:22:59 +02:00
Sebastiaan van Stijn de54347518 cli/command: remove deprecated CopyToFile utility
It was deprecated in 7cc6b8ebf4, which is
part of v28.x

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-05 21:11:47 +02:00
Sebastiaan van StijnandGitHub b01d359cc9 Merge pull request #6239 from thaJeztah/no_pkg_process
cli/connhelper: remove dependency on pkg/process
2025-08-05 16:57:54 +02:00
Sebastiaan van Stijn 2abcbf842f cli/connhelper: remove dependency on pkg/process
This package will not be included in the api or client modules, and
we're currently only using a single function of it, and only the
unix implementation, so let's fork it for now (although the package
may be moved to moby/sys).

This removes the last dependency on github.com/docker/docker.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-05 16:30:09 +02:00
Sebastiaan van StijnandGitHub fcfaa8daeb Merge pull request #6234 from thaJeztah/ParseRepositoryInfo_no_err_step2
internal/registry: remove RepositoryInfo, add NewIndexInfo
2025-08-04 15:21:49 +02:00
Sebastiaan van StijnandGitHub a629a840a8 Merge pull request #6237 from thaJeztah/plugin_manager_unexport
cli-plugins/manager: various fixes and deprecations
2025-08-04 14:00:21 +02:00
Sebastiaan van Stijn 513ceeec0a cli-plugins/manager: remove deprecated ResourceAttributesEnvvar
This const was deprecated in 9dc175d6ef,
which is part of v28.0, so let's remove it.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 12:26:22 +02:00
Sebastiaan van Stijn 5876b2941c cli-plugins/manager: deprecate metadata aliases
These aliases were added in 4321293972
(part of v28.0), but did not deprecate them. They are no longer used
in the CLI itself, but may be used by cli-plugin implementations.

This deprecates the aliases in `cli-plugins/manager` in favor of
their equivalent in `cli-plugins/manager/metadata`:

- `NamePrefix`
- `MetadataSubcommandName`
- `HookSubcommandName`
- `Metadata`
- `ReexecEnvvar`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 12:26:22 +02:00
Sebastiaan van Stijn 50963accec cli-plugins/manager: wrapAsPluginError: don't special-case nil
This was a pattern inheritted from pkg/errors.Wrapf, which ignored
nil errors for convenience. However, it is error-prone, as it is
not obvious when returning a nil-error.

All call-sites using `wrapAsPluginError` already do a check for
nil errors, so remove this code to prevent hard to find bugs.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 12:26:14 +02:00
Sebastiaan van Stijn d789bac04a cli-plugins/manager: pluginError: remove Causer interface
We no longer depend on this interface and it implements Unwrap for
native handling by go stdlib.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 11:11:52 +02:00
Sebastiaan van Stijn 71460215d3 cli-plugins/manager: deprecate "IsNotFound"
These errors satisfy errdefs.IsNotFound, so make it a wrapper, and
deprecate it.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 11:06:49 +02:00
Sebastiaan van Stijn 1cc698c68f cli-plugins/manager: un-export "NewPluginError"
It is for internal use, and no longer needed for testing, now that
the `Plugin` type handles marshalling errors.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 11:01:24 +02:00
Sebastiaan van Stijn 549d39a89f cli-plugins/manager: fix Plugin marshaling with regular errors
Go does not by default marshal `error` type fields to JSON. The manager
package therefore implemented a `pluginError` type that implements
[encoding.TextMarshaler]. However, the field was marked as a regular
`error`, which made it brittle; assining any other type of error would
result in the error being discarded in the marshaled JSON (as used in
`docker info` output), resulting in the error being marshaled as `{}`.

This patch adds a custom `MarshalJSON()` on the `Plugin` type itself
so that any error is rendered. It checks if the error used already
implements [encoding.TextMarshaler], otherwise wraps the error in
a `pluginError`.

[encoding.TextMarshaler]: https://pkg.go.dev/encoding#TextMarshaler

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 10:55:16 +02:00
Sebastiaan van Stijn 54367b3283 cli-plugins/manager: un-export "Candidate" interface
It is for internal use for mocking purposes, and is not part
of any public interface / signature.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 09:14:13 +02:00
Sebastiaan van Stijn 057f3128b6 cli-plugins/manager: reformat TestValidateCandidate table
Slightly more verbose, but makes it easier to see properties
of each test.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 08:50:07 +02:00
Sebastiaan van Stijn dfbac70efa remove some remnants from CLI "experimental" config option
Experimental is always enabled (977d3ae046),
and the `Experimental` field in plugin metadata was deprecated in
977d3ae046 and removed in commit
6a50c4f700.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 08:48:29 +02:00
Sebastiaan van Stijn 3b6a556533 cli/command: remove exported "RunPrune" functions
These are no longer used, and unlikely to be used externally.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 00:08:03 +02:00
Sebastiaan van Stijn bf8cb43025 system prune: delegate version check
Move the version-check for pruners to the pruner, which can
return a [ErrNotImplemented] error to indicate they won't
be run with the API version that's used.

This helps separating concerns, and doesn't enforce knowledge
about what's supported by each content-type onto the system
prune command.

[ErrNotImplemented]: https://pkg.go.dev/github.com/docker/docker@v28.3.3+incompatible/errdefs#ErrNotImplemented

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 00:08:02 +02:00
Sebastiaan van Stijn a888c4091c system prune: delegate confirmation message and validation
This adds a "dry-run" / "pre-check" option for prune-functions,
which delegates constructing the confirmation message (what is
about to be pruned) and validation of the given options to the
prune-functions.

This helps separating concerns, and doesn't enforce knowledge
about what's supported by each content-type onto the system
prune command.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-04 00:07:54 +02:00
Sebastiaan van Stijn 02d578b637 system prune: use register function for prune functions
Introduce a "prune" package in which we maintain a list of prune
functions that are registered. Known prune "content-types" are
included in a pre-defined order, after which additional content
can be registered.

Using this approach no longer requires the "RunPrune" functions
to be exported, and allows additional content-types to be
introduced without having to import those packages into the
system package, so keeping things more decoupled.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-03 23:52:47 +02:00
Sebastiaan van Stijn 21e8bbc8a2 internal/registry: remove RepositoryInfo, add NewIndexInfo
Most places only use IndexInfo (and may not even need that), so replace
the use of ParseRepositoryInfo for NewIndexInfo, and move the RepositoryInfo
type to the trust package, which uses it as part of its ImageRefAndAuth
struct.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-03 15:32:51 +02:00
Sebastiaan van StijnandGitHub f86ad2ea4c Merge pull request #6228 from thaJeztah/bump_version
bump version to v29.0.0-dev
2025-07-31 18:28:28 +02:00
Sebastiaan van StijnandGitHub a4bf9e78e5 Merge pull request #6227 from thaJeztah/cleanup_swarmopts
opts/swarmopts: minor cleanup and refactor
2025-07-31 18:28:07 +02:00
Sebastiaan van StijnandGitHub a1ea79444b Merge pull request #6230 from robmry/moby29_dockerd_reference
dockerd.md: --firewall-backend and --bridge-accept-fwmark
2025-07-31 18:27:03 +02:00
Sebastiaan van Stijn 066710ba7b opts/swarmopts: minor cleanup and refactor
- Use strong-typed switches for validating options
- Initialize defaults instead of setting them after
  parsing the ports. Each option should be validated
  as part of the parsing, so no invalid (or empty)
  values should be set.
- Put variables closer to where they're used, and
  pre-allocate slices.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-31 18:19:58 +02:00
Sebastiaan van Stijn b8df4abeb5 bump version to v29.0.0-dev
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.

https://github.com/docker/cli/blob/d48fb9f9f7bdb6e0ef37dbde68612a1704cad46e/docker.Makefile#L22

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-31 18:17:29 +02:00
Rob Murray 3f0ccd1b71 dockerd.md: Add --firewall-backend
Related to https://github.com/moby/moby/commit/39ab39327417e1feebbc48a98748579ff8872e45

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-07-31 17:11:47 +01:00
Rob Murray 6176a7686e dockerd.md: add --bridge-accept-fwmark
Related to https://github.com/moby/moby/commit/cf1695bef13b4eeef71d106a979825aaaed8a79f

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-07-31 17:11:47 +01:00
Sebastiaan van StijnandGitHub 66aca29f7d Merge pull request #6226 from thaJeztah/bump_engine
vendor: docker/docker, moby/moby/api and moby/moby/client 4faedf2bec36
2025-07-31 18:10:08 +02:00
Sebastiaan van Stijn f937e62c89 replace direct uses of github.com/docker/go-connections/nat types
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-31 17:37:34 +02:00
Sebastiaan van Stijn bf16dd1251 vendor: docker/docker, moby/moby/api and moby/moby/client 4faedf2bec36
notable changes:

- api: remove deprecated NoBaseImageSpecifier
- api/stdcopy: move to api/pkg/stdcopy
- api/types/container: add aliases for go-connections/nat types
- pkg/progress: move to api/pkg/progress
- pkg/jsonmessage: move JSONError to api/types/jsonstream
- pkg/jsonmessage: move JSONProgress to api/types/jsonstream
- pkg/jsonmessage: move to client/pkg/jsonmessage
- pkg/jsonmessage: remove github.com/morikuni/aec dependency
- pkg/jsonmessage: stop printing deprecated progressDetail, errorDetail,
  remove DisplayJSONMessagesToStream and Stream interface
- pkg/streamformatter: move to api/pkg/streamformatter
- pkg/streamformatter: split from pkg/jsonmessage

full diff: https://github.com/moby/moby/compare/2574c2b2e917...4faedf2bec36

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-31 17:31:01 +02:00
Sebastiaan van StijnandGitHub 2199a05e08 Merge pull request #6212 from carsontham/e2e-test-container-rename
intergration-cli: migrate TestContainerAPIRename to cli e2e test
2025-07-29 20:17:38 +02:00
carsonthamandSebastiaan van Stijn 149503a32c migrate e2e container rename test
Signed-off-by: carsontham <carsontham@outlook.com>
2025-07-29 20:07:15 +02:00
Sebastiaan van Stijn 5c3577ff9f cli/command/service: credentialSpecOpt: use strings.Cut
- Rewrite the function to use strings.Cut instead of checking for,
  and trimming prefixes for each option.
- More explicitly set the value, instead of setting an empty value,
  then propagating the struct.
- Define a "type" to provide a more enum-like construct.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-29 19:55:50 +02:00
Sebastiaan van StijnandGitHub 14203bbc77 Merge pull request #6216 from thaJeztah/bump_engine
vendor: docker/docker, moby/moby/api and moby/moby/client 2574c2b2e917
2025-07-29 19:51:52 +02:00
Sebastiaan van Stijn b6d7ac34be vendor: docker/docker, moby/moby/api and moby/moby/client 2574c2b2e917
notable changes;

- api/types/container: move StateStatus, NewStateStatus internal again
- daemon/server/httputils: remove ContainerDecoder interface
- runconfig: move to daemon/internal/runconfig
- pkg/stack: move to daemon/internal
- remove pkg/stringid as it has moved to the client module
- remove pkg/stdcopy as it has moved to the api module
- pkg/rootless: move to daemon/internal
- move api/types/plugins/logdriver to daemon/internal
- move api/types/plugins/logdriver to daemon/internal
- pkg/system: move to daemon/internal
- remove pkg/fileutils

full diff: https://github.com/moby/moby/compare/25e2b4d48551...2574c2b2e9174688bb78010a1dd8a02017ca5130

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-29 18:56:56 +02:00
Sebastiaan van Stijn 83e507377a vendor: docker/docker, moby/moby/api and moby/moby/client 25e2b4d48551
notable changes:

- api/types/container.StatsResponseReader: move to client
- api/types: move backend types to daemon/server
- runconfig: remove exported errors

full diff: https://github.com/moby/moby/compare/c4afa7715715...25e2b4d48551

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-29 18:48:18 +02:00
Sebastiaan van StijnandGitHub a0ae6e6a5a Merge pull request #6215 from thaJeztah/ParseRepositoryInfo_no_err
internal/registry: ParseRepositoryInfo: remove unused error return
2025-07-29 18:41:18 +02:00
Sebastiaan van Stijn 86b5b528a6 internal/registry: ParseRepositoryInfo: remove unused error return
Removed the error return from the `ParseRepositoryInfo` function.
There are no validation steps inside `ParseRepositoryInfo` which
could cause an error, so we always returned a nil error.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-29 18:32:15 +02:00
Sebastiaan van StijnandGitHub f0030712e9 Merge pull request #6217 from thaJeztah/errdefs_unalias
remove aliases for containerd/errdefs, disallow docker/errdefs
2025-07-28 20:12:39 +02:00
Sebastiaan van Stijn 89d8c8a2a7 remove aliases for containerd/errdefs, disallow docker/errdefs
We transitioned most functionality of docker/errdefs to containerd
errdefs module, and the docker/errdefs package should no longer be
used.

Because of that, there will no longer be ambiguity, so we can remove
the aliases for this package, and use it as "errdefs".

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-28 14:55:43 +02:00
Sebastiaan van StijnandGitHub e2a4e429bc Merge pull request #6211 from thaJeztah/bump_engine
vendor: update docker, api, client to master, consume client/pkg/stringid
2025-07-28 14:25:36 +02:00
Sebastiaan van StijnandGitHub fdc4397906 Merge pull request #6214 from thaJeztah/template_deprecate_newparse
templates: deprecate NewParse()
2025-07-28 11:26:37 +02:00
Sebastiaan van Stijn d63cae6f1c cli/command/formatter: use alias/wrapper for TruncateID
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-28 08:50:15 +02:00
Sebastiaan van Stijn 4bd6b6897f vendor: update docker, api, client to master
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-28 08:50:13 +02:00
Sebastiaan van StijnandGitHub a1035b0796 Merge pull request #6213 from thaJeztah/cleanup_plugins
cli/command/plugin: fix linting issues, and assorted cleanups
2025-07-28 08:49:00 +02:00
Sebastiaan van Stijn 7ab3e7e774 templates: deprecate NewParse()
It it just a chain of `New("sometag").Parse(...)`, and most of our
uses don't use a tag for the template, so can call Parse.

There's no public users of this function, but deprecating it first
just in case.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-28 08:25:02 +02:00
Sebastiaan van Stijn c6f935eba5 cli/command/plugin: fix linting issues, and assorted cleanups
- fix various unhandled errors
- remove some locally defined option-types in favor of option-types
  defined by the client / api
- don't use unkeyed structs in tests, and add docs for some subtests
- fix some values in tests that triggered "spellcheck" warnings
- inline vars / functions that only had a single use.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-26 16:45:04 +02:00
Sebastiaan van StijnandGitHub 2f87a11e96 Merge pull request #6202 from Mewsen/issue/6188
refactor(cli/compose/loader): extract ParseVolume() to its own package
2025-07-25 17:08:54 +02:00
Michael TewsandSebastiaan van Stijn ef7fd8bb67 refactor(cli/compose/loader): extract ParseVolume() to its own package
Moves ParseVolume() to a new internal package to remove the dependency
on cli/compose/loader in cli/command/container/opts.go

refactor to keep types isolated

- rename the package to "volumespec" to reuse the name of the package
  as part of the name (parsevolume.ParseVolume() -> volumespec.Parse())
- move the related compose types to the internal package as well,
  and rename them to be more generic (not associated with "compose");
  - ServiceVolumeConfig -> VolumeConfig
  - ServiceVolumeBind -> BindOpts
  - ServiceVolumeVolume -> VolumeOpts
  - ServiceVolumeImage -> ImageOpts
  - ServiceVolumeTmpfs -> TmpFsOpts
  - ServiceVolumeCluster -> ClusterOpts
- alias the internal types inside cli/compose/types to keep backward
  compatibility (for any external consumers); even though the implementation
  is internal, Go allows aliasing types to use them externally.

Signed-off-by: Michael Tews <michael@tews.dev>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-25 16:56:17 +02:00
Paweł GronowskiandGitHub 3046019d3b Merge pull request #6209 from vvoland/image-tree-nonexp
image/tree: Unmark as experimental, warn when redirected
2025-07-25 12:58:37 +02:00
Sebastiaan van StijnandGitHub 1eeb0cc3e1 Merge pull request #6207 from thaJeztah/fork_registry
add internal fork of docker/docker/registry
2025-07-25 12:57:47 +02:00
Paweł Gronowski 9257cc7f68 image/tree: Unmark as experimental, warn when redirected
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-07-25 12:07:54 +02:00
Paweł Gronowski f214f860b6 image/tree: Remove extra newline after legend
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-07-25 12:04:42 +02:00
Sebastiaan van Stijn f907c7a4b0 internal/registry: fix linting issues (revive)
internal/registry/errors.go:26:43: use-any: since Go 1.18 'interface{}' can be replaced by 'any' (revive)
    func invalidParamf(format string, args ...interface{}) error {
                                              ^
    internal/registry/registry_mock_test.go:52:51: use-any: since Go 1.18 'interface{}' can be replaced by 'any' (revive)
    func writeResponse(w http.ResponseWriter, message interface{}, code int) {
                                                      ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-25 00:08:26 +02:00
Sebastiaan van Stijn cd277a5815 cli/command/system: remove use of Mirrors field in test
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 23:29:48 +02:00
Sebastiaan van Stijn c297770d2d internal/registry: remove pkg/errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 23:29:47 +02:00
Sebastiaan van Stijn 219cfc8b7d internal/registry: define local serviceConfig
The registry.ServiceConfig struct in the API types was meant for the
registry configuration on the daemon side; it has variuos fields we
don't use, defines methods for (un)marshaling JSON, and a custom version
of `net.IPNet`, also to (un)marshal JSON.

None of that is needed, so let's change it to a local type, and implement
a constructor (as we now only have "insecure registries" to care
about).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 23:29:47 +02:00
Sebastiaan van Stijn 2607ba8062 internal/registry: remove ValidateIndexName
It was written to be used as validate-func for command-line flags, which
we don't use it for (which for CLI-flags includes normalizing the value).

The validation itself didn't add much; it only checked the registry didn't
start or end with a hyphen (which would still fail when parsing).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 23:29:36 +02:00
Sebastiaan van Stijn 5322affc9f internal/registry: remove duplicate endpoint methods
now that we no longer need to account for mirrors, these were
identical, so just use a single one.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 23:23:11 +02:00
Sebastiaan van Stijn dc41365b56 internal/registry: remove NewStaticCredentialStore
It was only used in a single place; inline it there.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 23:23:10 +02:00
Sebastiaan van Stijn dad2e67860 internal/registry: remove PingResponseError
It's not matched anywhere, so we can just return a plain error.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 23:23:10 +02:00
Sebastiaan van Stijn 7cf245d2f7 internal/registry: Service.Auth remove unused statusmessage return
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 23:23:10 +02:00
Sebastiaan van Stijn e0b351b3d9 internal/registry: remove code related to mirrors
The CLI does not have information about mirrors, and doesn't
configure them, so we can remove these parts.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 23:23:02 +02:00
Sebastiaan van Stijn 7716219e17 internal/registry: remove dead code
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 22:14:25 +02:00
Sebastiaan van Stijn f6b90bc253 add internal fork of docker/docker/registry
This adds an internal fork of [github.com/docker/docker/registry], taken
at commit [moby@f651a5d]. Git history  was not preserved in this fork,
but can be found using the URLs provided.

This fork was created to remove the dependency on the "Moby" codebase,
and because the CLI only needs a subset of its features. The original
package was written specifically for use in the daemon code, and includes
functionality that cannot be used in the CLI.

[github.com/docker/docker/registry]: https://pkg.go.dev/github.com/docker/docker@v28.3.2+incompatible/registry
[moby@49306c6]: https://github.com/moby/moby/tree/49306c607b72c5bf0a8e426f5a9760fa5ef96ea0/registry

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 19:59:17 +02:00
Sebastiaan van StijnandGitHub 636a4cf2dc Merge pull request #6208 from thaJeztah/bump_moby
vendor: github.com/docker/docker master
2025-07-24 19:45:06 +02:00
Sebastiaan van Stijn 20181d4363 vendor: github.com/docker/docker master
forgot to update this dependency (only updated the api and client)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 18:12:28 +02:00
Paweł GronowskiandGitHub d29d719c42 Merge pull request #6204 from thaJeztah/bump_engine
vendor: docker/docker, moby/api, and moby/client master
2025-07-24 17:25:47 +02:00
Sebastiaan van Stijn fa169b6933 vendor: docker/docker, moby/api, and moby/client master
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 16:06:08 +02:00
Paweł GronowskiandGitHub 1ca6c946d5 Merge pull request #6126 from ctalledo/fix-for-moby-48759
Add support for multiple platform options in image load and save
2025-07-24 11:48:11 +02:00
Sebastiaan van StijnandGitHub c2586d68cf Merge pull request #6206 from thaJeztah/remove_RepoNameForReference
cli/registry/client: remove deprecated RepoNameForReference
2025-07-24 11:35:03 +02:00
Sebastiaan van Stijn a87bde0068 cli/registry/client: remove deprecated RepoNameForReference
This was deprecated in 6f46cd2f4b,
which is part of v28.x, and no longer used, so we can remove it.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-24 01:33:55 +02:00
Sebastiaan van StijnandGitHub df9950aa06 Merge pull request #6201 from thaJeztah/bump_engine
vendor: docker/docker, moby/api, moby/client to latest
2025-07-23 13:40:13 +02:00
Sebastiaan van Stijn 323ef1997f vendor: docker/docker, moby/api, moby/client to latest
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-23 09:45:51 +02:00
Sebastiaan van StijnandGitHub 80be02c72b Merge pull request #6200 from thaJeztah/search_no_registrypkg
cli/command/registry: remove uses of registry.ParseSearchIndexInfo
2025-07-22 23:01:28 +02:00
Sebastiaan van Stijn e504faf6da cli/command/registry: remove uses of registry.ParseSearchIndexInfo
This utility was only used in the CLI, but the implementation was
based on it being used on the daemon side, so included resolving
the host's IP-address, mirrors, etc.

The only reason it's used in the CLI is to provide credentials for
the registry that's being searched, so reduce it to just that.

There's more cleaning up to do in this area, so to make our lives
easier, it's implemented locally as non-exported functions; likely
to be replaced with something else.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-22 22:13:38 +02:00
Sebastiaan van StijnandGitHub 03ff54b8ba Merge pull request #6193 from thaJeztah/bump_engine
vendor: github.com/docker/docker master (v29.0-dev)
2025-07-22 09:19:13 +02:00
Sebastiaan van Stijn 644dc16b16 vendor: github.com/docker/docker master (v29.0-dev)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-21 23:04:50 +02:00
Sebastiaan van StijnandGitHub 2a2748a94c Merge pull request #6195 from thaJeztah/build_no_dct
build: remove DCT support for classic builder
2025-07-21 22:03:46 +02:00
Sebastiaan van Stijn 7609dde8d0 build: remove DCT support for classic builder
Docker Content Trust is currently only implemented for the classic
builder, but is known to not work with multi-stage builds, and
requires rewriting the Dockerfile, which is brittle because the
Dockerfile syntax evolved with the introduction of BuildKit as
default builder.

Given that the classic builder is deprecated, and only used for
Windows images, which are not verified by content trust;

    # docker pull --disable-content-trust=false mcr.microsoft.com/windows/servercore:ltsc2025
    Error: remote trust data does not exist for mcr.microsoft.com/windows/servercore: mcr.microsoft.com does not have trust data for mcr.microsoft.com/windows/servercore

With content trust not implemented in BuildKit, and not implemented
in docker compose, this resulted in an inconsistent behavior.

This patch removes content-trust support for "docker build". As this
is a client-side feature, users who require this feature can still
use an older CLI to to start the build.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-21 19:05:38 +02:00
Sebastiaan van StijnandGitHub 71bc8ab3ea Merge pull request #6186 from thaJeztah/remove_more_aliases
opts: minor cleanup in tests, and remove some import aliases
2025-07-17 17:18:15 +02:00
Sebastiaan van StijnandGitHub 6cf2c023f8 Merge pull request #6187 from thaJeztah/container_unexport
cli/command/container: deprecate NewDiffFormat, DiffFormatWrite
2025-07-17 17:09:50 +02:00
Sebastiaan van StijnandGitHub 73604b8c36 Merge pull request #6192 from thaJeztah/trust_no_api_const
cli/command/image: remove use of api.NoBaseImageSpecifier
2025-07-17 15:59:06 +02:00
Sebastiaan van Stijn e2cab2c64c cli/command/image: remove use of api.NoBaseImageSpecifier
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-17 14:28:13 +02:00
Sebastiaan van StijnandGitHub 74042f5ffa Merge pull request #6191 from robmry/info_firewall_backend
Include FirewallBackend in docker info output
2025-07-17 11:52:35 +02:00
Sebastiaan van StijnandGitHub 8c317ad3fd Merge pull request #6190 from thaJeztah/fork_remotecontext
add local fork of github.com/docker/docker/builder/remotecontext
2025-07-17 01:34:55 +02:00
Sebastiaan van Stijn 64f33cd463 TestCloneArgsSmartHttp: fix unhandled error
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 22:21:46 +02:00
Rob Murray a3bea24086 Include FirewallBackend in docker info output
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-07-16 17:17:27 +00:00
Sebastiaan van Stijn b05aa464a6 Dockerfile: install git-daemon for use in tests
gitutils_test.go:210: git-http-backend: git: 'http-backend' is not a git command. See 'git --help'.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 16:48:40 +02:00
Sebastiaan van Stijn e34616574f fix linting issues
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 16:27:27 +02:00
Sebastiaan van Stijn 8d2ccc128a add local fork of github.com/docker/docker/builder/remotecontext
Adds a local fork of this package for use in the classic builder.

Code was taken at commit [d33d46d01656e1d9ee26743f0c0d7779f685dd4e][1].

Migration was done using the following steps:

    # install filter-repo (https://github.com/newren/git-filter-repo/blob/main/INSTALL.md)
    brew install git-filter-repo

    # create a temporary clone of docker
    cd ~/Projects
    git clone https://github.com/docker/docker.git build_context_temp
    cd build_context_temp

    # commit taken from
    git rev-parse --verify HEAD
    d33d46d01656e1d9ee26743f0c0d7779f685dd4e

    git filter-repo --analyze

    # remove all code, except for the remotecontext packages, and move to build/internal docs and previous locations of it
    git filter-repo \
      --path 'builder/remotecontext/git' \
      --path 'builder/remotecontext/urlutil' \
      --path-rename builder/remotecontext:cli/command/image/build/internal

    # go to the target repository
    cd ~/go/src/github.com/docker/cli

    # create a branch to work with
    git checkout -b fork_remotecontext

    # add the temporary repository as an upstream and make sure it's up-to-date
    git remote add build_context_temp ~/Projects/build_context_temp
    git fetch build_context_temp

    # merge the upstream code
    git merge --allow-unrelated-histories --signoff -S build_context_temp/master

[1]: https://github.com/docker/docker/d33d46d01656e1d9ee26743f0c0d7779f685dd4e

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 16:18:51 +02:00
Sebastiaan van StijnandGitHub b5a939268b Merge pull request #6189 from thaJeztah/cleanup_build_context
cli/command/image: move build-context detection to build
2025-07-16 15:57:58 +02:00
Sebastiaan van Stijn 260f1dbebb cli/command/image: move build-context detection to build
Removes direct imports of github.com/docker/docker/builder in
the image package, to be moved later.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 15:50:32 +02:00
Sebastiaan van Stijn e95d133612 remove some redundant import aliases
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 13:56:49 +02:00
Sebastiaan van Stijn 3dec3879c8 opts: minor cleanup in tests
- use consistent name for MountOpt vars
- cleanup some comments and make them a GoDoc
- remove import alias
- use subtests for tests that were prepared for it.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 13:56:49 +02:00
Sebastiaan van Stijn fdc90caeee cli/command/container: deprecate DiffFormatWrite
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 13:52:04 +02:00
Sebastiaan van Stijn 0db7b9f774 cli/command/container: newDiffContext: use struct-literal
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 13:50:31 +02:00
Sebastiaan van Stijn 239b727834 cli/command/container: DiffFormatWrite: remove intermediate var
Also rename "ctx" argument; we shouldn't use this as name for things
that are not a context.Context.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 13:45:09 +02:00
Sebastiaan van Stijn 907507e22a cli/command/container: deprecate NewDiffFormat
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 13:45:05 +02:00
Sebastiaan van StijnandGitHub d8089e7d1b Merge pull request #6184 from Benehiko/deprecate-prompt-privilege-func
cli/command: deprecate RegistryAuthenticationPrivilegedFunc
2025-07-16 13:26:12 +02:00
Alano TerblancheandSebastiaan van Stijn 29263e865b cli/command: remove usages of RegistryAuthenticationPrivilegedFunc
This patch deprecates the unused `RegistryAuthenticationPrivilegedFunc`.
The function would prompt the user when the registry returns a 403 after trying
the initial auth value set in `RegistryAuth`.

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-07-16 12:49:19 +02:00
Sebastiaan van StijnandGitHub 6bcc9ce730 Merge pull request #6174 from Benehiko/remove-prompt-privilege-func
cli/command: remove interactive login prompt from docker push/pull
2025-07-16 12:48:25 +02:00
Sebastiaan van StijnandGitHub 46b8679315 Merge pull request #6155 from thaJeztah/bump_alpine
Dockerfile: update to alpine 3.22
2025-07-16 12:47:48 +02:00
Sebastiaan van StijnandGitHub 980b856816 Merge pull request #6183 from thaJeztah/diff_simplify
cli/command/container: diff: remove redundant validation and cleanup
2025-07-16 12:32:48 +02:00
Sebastiaan van Stijn ea4c161067 Dockerfile: update to alpine 3.22
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 12:20:03 +02:00
Sebastiaan van StijnandGitHub 9c256146ac Merge pull request #6181 from thaJeztah/fork_readCloserWrapper
remove uses of github.com/docker/docker/pkg/ioutils ReadCloserWrapper
2025-07-16 12:19:14 +02:00
Sebastiaan van StijnandGitHub bc01f8489d Merge pull request #6182 from thaJeztah/fork_longpath
remove use of github.com/docker/docker/pkg/longpath
2025-07-16 12:18:06 +02:00
Sebastiaan van StijnandGitHub ea2a0c3b8a Merge pull request #6177 from thaJeztah/rm_aliases
cli/command: remove some redundant import-aliases
2025-07-16 12:17:23 +02:00
Sebastiaan van Stijn 3d985799d4 cli/command: remove some redundant import-aliases
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-16 12:12:41 +02:00
Sebastiaan van StijnandGitHub f5f3b027e8 Merge pull request #6178 from thaJeztah/bump_dev_tools
Dockerfile: update Buildx v0.25.0, compose v2.38.2
2025-07-16 12:07:46 +02:00
Sebastiaan van StijnandGitHub 143f36133a Merge pull request #6179 from thaJeztah/bump_gotestsum
Dockerfile: bump gotest.tools/gotestsum v1.12.3 (for go1.25)
2025-07-16 12:07:17 +02:00
Sebastiaan van StijnandGitHub d7181e47e2 Merge pull request #6185 from thaJeztah/alpine_doc
Dockerfile: document ALPINE_VERSION build-arg
2025-07-16 12:06:17 +02:00
Sebastiaan van Stijn 8b6436ecee Dockerfile: document ALPINE_VERSION build-arg
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>
2025-07-16 09:51:14 +02:00
Alano Terblanche 2b56b66b10 cli/command: remove interactive login prompt from docker push/pull
This patch removes the interactive prompts from `docker push/pull`.
The prompt would only execute on a response status code 403 from the registry
after trying the value set in `RegistryAuth`. Docker Hub could return 404
instead or 429, which would never execute the prompt.

The UX regarding the prompt is also questionable since the user might
not actually want to authenticate with a registry and the CLI could fail fast
instead. The user can always run `docker login` or set the `DOCKER_AUTH_CONFIG`
environment variable to get authenticated.

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-07-16 08:43:35 +02:00
Sebastiaan van StijnandGitHub 7d574b816d Merge pull request #6180 from thaJeztah/truncate_id
remove uses of github.com/docker/docker/pkg/stringid
2025-07-15 14:03:18 +02:00
Sebastiaan van Stijn 0f2b709c7c cli/command/container: diff: remove redundant validation and cleanup
client.ContainerDiff already validates the given container name/ID, and
produces an error when empty, so we don't have to check for this;
https://github.com/moby/moby/blob/abba330bbfe10765822b59bb68af99db439736ba/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>
2025-07-15 01:08:29 +02:00
Sebastiaan van StijnandGitHub 7668b683d2 Merge pull request #6176 from thaJeztah/rm_use_AllowOverwriteDirWithFile
cli/command/container: don't set CopyToContainerOptions.AllowOverwriteDirWithFile
2025-07-14 23:17:34 +02:00
Sebastiaan van Stijn 53d02ece89 remove use of github.com/docker/docker/pkg/longpath
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-14 22:34:36 +02:00
Sebastiaan van Stijn 3600ebca76 remove uses of github.com/docker/docker/pkg/ioutils ReadCloserWrapper
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>
2025-07-14 22:09:31 +02:00
Sebastiaan van Stijn 9b047a501f remove uses of pkg/stringid.GenerateRandomID()
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>
2025-07-14 20:11:07 +02:00
Sebastiaan van Stijn e0f4bc699c cli/command/formatter: add TrunateID utility
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>
2025-07-14 20:10:56 +02:00
Sebastiaan van Stijn 1264a59779 Dockerfile: bump gotest.tools/gotestsum v1.12.3 (for go1.25)
full diff: https://github.com/gotestyourself/gotestsum/compare/v1.12.0...v1.12.3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-13 17:50:03 +02:00
Sebastiaan van Stijn e6b8cc1c7d Dockerfile: update buildx to v0.25.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-13 17:45:07 +02:00
Sebastiaan van Stijn 50fa436c21 Dockerfile: update compose to v2.38.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-13 17:43:50 +02:00
Sebastiaan van Stijn 0be687acc0 cli/command/container: don't set CopyToContainerOptions.AllowOverwriteDirWithFile
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]: https://github.com/moby/moby/blob/8c9ad7b818c0a7b1e39f8df1fabba243a0961c2d/api/client/cp.go#L345-L346
[moby@1b2b91b]: https://github.com/moby/moby/commit/1b2b91ba43dc6fa1b4b758fc5a8090ce6cc597ff

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-13 13:48:59 +02:00
Sebastiaan van StijnandGitHub c69d8bde4a Merge pull request #6173 from vvoland/fix-anchor-cdi
docs: fix CDI device configuration anchor
2025-07-11 15:27:46 +02:00
Paweł Gronowski 8eac03d5fa docs: fix CDI device configuration anchor
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-07-11 10:44:29 +02:00
Paweł GronowskiandGitHub 578ccf607d Merge pull request #6170 from thaJeztah/e2e_newline_check
e2e/global: TestPromptExitCode: check for trailing newline
2025-07-09 14:04:02 +02:00
Sebastiaan van Stijn 0c5e258f8a e2e/global: TestPromptExitCode: check for trailing newline
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>
2025-07-09 13:35:17 +02:00
Paweł GronowskiandGitHub 30cad385b6 Merge pull request #6167 from vvoland/update-go
Update to go1.24.5
2025-07-09 01:23:29 +02:00
Paweł Gronowski 9bcc88611f update to go1.24.5
- 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>
2025-07-08 19:23:57 +02:00
Sebastiaan van StijnandGitHub 3302212263 Merge pull request #6163 from Benehiko/env-credential-warn
registry: warn of `DOCKER_AUTH_CONFIG` usage in login and logout
2025-07-08 15:33:07 +02:00
Alano Terblanche ccd5bd8d57 registry: warn of DOCKER_AUTH_CONFIG usage in login and logout
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-07-08 14:07:32 +02:00
Alano Terblanche dec07e6fdf tui/note: add warning note type
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-07-08 14:07:22 +02:00
Sebastiaan van StijnandGitHub 28f19a9d65 Merge pull request #6162 from ArthurFlag/ENGDOCS-2807-cdi-docs-update
docs: cdi isn't experimental
2025-07-07 17:53:48 +02:00
Sebastiaan van StijnandGitHub 219e5ca4f2 Merge pull request #6165 from thaJeztah/bump_engine_28.3.1
vendor: github.com/docker/docker v28.3.1
2025-07-07 17:53:31 +02:00
ArthurFlag 7e040d91ef docs: cdi is not experimental anymore
Signed-off-by: ArthurFlag <arthur.flageul@docker.com>
2025-07-07 16:10:30 +02:00
Sebastiaan van Stijn 76524e7d0e vendor: github.com/docker/docker v28.3.1
no changes in vendored code

full diff: https://github.com/docker/docker/compare/v28.3.0...v28.3.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-07 15:52:29 +02:00
Alano Terblanche 3262107821 cli/config: export const dockerEnvConfig
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-07-04 14:04:38 +02:00
Sebastiaan van StijnandGitHub 8403869122 Merge pull request #6158 from thaJeztah/reduce_strslice
cli/command/container: remove redundant uses of strslice.StrSlice
2025-07-02 17:42:43 +02:00
Sebastiaan van StijnandGitHub 1fc7194554 Merge pull request #6159 from thaJeztah/hide_codecov
rename codecov.yml to .codecov.yml
2025-07-02 17:42:11 +02:00
Sebastiaan van StijnandGitHub fa2a7f1536 Merge pull request #6154 from thaJeztah/bump_engine
vendor: github.com/docker/docker v28.3.0
2025-07-02 17:41:49 +02:00
Sebastiaan van StijnandGitHub 350b3a6e25 Merge pull request #6160 from thaJeztah/fix_otel_debug_logs
cli/debug: fix OTELErrorHandler logging messages if there's no error
2025-07-02 17:41:26 +02:00
Sebastiaan van Stijn 4ea6fbf538 cli/debug: fix OTELErrorHandler logging messages if there's no error
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>
2025-07-02 11:59:05 +02:00
Sebastiaan van StijnandGitHub 74a896f18c Merge pull request #6157 from ndeloof/use_api_socket
mount /var/run/docker.sock for --use-api-socket
2025-07-01 17:00:24 +02:00
Sebastiaan van Stijn 94f097da28 rename codecov.yml to .codecov.yml
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>
2025-07-01 16:20:54 +02:00
Sebastiaan van Stijn e7e238eb4b cli/command/container: remove redundant uses of strslice.StrSlice
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]: https://github.com/moby/moby/commit/17d6f00ec2b8b9636f0bb64c55a5b3855e8f4bae
[moby@ea4a067]: https://github.com/moby/moby/commit/ea4a06740b6d4579f77507c1d7e0897a870fd72d

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-01 10:09:54 +02:00
Nicolas De Loof 2ba7cb8b44 mount /var/run/docker.sock for --use-api-socket
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-30 12:38:15 +02:00
Sebastiaan van Stijn 52e1e4fb21 vendor: github.com/docker/docker v28.3.0
no diff; same commit: https://github.com/docker/docker/compare/v28.3.0-rc.2...v28.3.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-30 09:35:21 +02:00
Sebastiaan van StijnandGitHub 7cbee73f19 Merge pull request #6147 from thaJeztah/connhelper_quote
cli/connhelper: quote ssh arguments to prevent shell injection
2025-06-25 17:21:12 +02:00
Paweł GronowskiandGitHub ae6f8d0021 Merge pull request #6149 from vvoland/gha-tags
gha/bin-image: add major and minor version image tags
2025-06-25 14:35:11 +00:00
Paweł Gronowski 70867e7067 gha/bin-image: add major and minor version image tags
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>
2025-06-24 23:35:10 +02:00
Paweł GronowskiandGitHub 38b7060a21 Merge pull request #6148 from thaJeztah/vendor_rc2
vendor: github.com/docker/docker v28.3.0-rc.2
2025-06-24 15:37:19 +00:00
Sebastiaan van Stijn 2d46d162c1 vendor: github.com/docker/docker v28.3.0-rc.2
no diff; same commit, but tagged;
https://github.com/docker/docker/compare/265f70964794...v28.3.0-rc.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-24 16:35:29 +02:00
Sebastiaan van Stijn 88d1133224 cli/connhelper: quote ssh arguments to prevent shell injection
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>
2025-06-24 16:26:17 +02:00
Sebastiaan van Stijn 82eda48066 cli/connhelper/internal/syntax: fix linting issues
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>
2025-06-24 16:24:34 +02:00
Sebastiaan van Stijn 52d2a9b5ae cli/connhelper/internal/syntax: remove unused code from fork
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-24 16:24:29 +02:00
Sebastiaan van Stijn 64a9a6d0c8 cli/connhelper: add fork of mvdan.cc/sh/v3/syntax v3.10.0
This adds a local fork of the mvdan.cc/sh/v3/syntax package to provide the
Quote function without having to introduce additional (indirect) dependencies
of the mvdan.cc/sh module.

This commit does not compile as it references code not forked.

The following files were included:

- https://raw.githubusercontent.com/mvdan/sh/refs/tags/v3.10.0/syntax/quote.go
- https://raw.githubusercontent.com/mvdan/sh/refs/tags/v3.10.0/syntax/parser.go
- https://raw.githubusercontent.com/mvdan/sh/refs/tags/v3.10.0/LICENSE

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-24 10:02:53 +02:00
Sebastiaan van StijnandGitHub f03fb6c40b Merge pull request #6146 from thaJeztah/bump_docker
vendor: github.com/docker/docker 265f70964794 (v28.3.0-rc.2)
2025-06-20 18:33:20 +02:00
Sebastiaan van Stijn 5bb0d7f70c vendor: github.com/docker/docker 265f70964794 (v28.3.0-rc.2)
full diff: https://github.com/docker/docker/compare/v28.3.0-rc.1...265f709647947fb5a1adf7e4f96f2113dcc377bd

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-20 18:25:22 +02:00
Sebastiaan van Stijn 575d4af72f vendor: github.com/docker/docker v28.3.0-rc.1
no diff: just tagged; https://github.com/docker/docker/compare/6a1fb46d4805...v28.3.0-rc.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-20 17:43:37 +02:00
Sebastiaan van StijnandGitHub 4b202b9e2b Merge pull request #6141 from thaJeztah/login_no_tty
prevent login prompt on registry operations with no TTY attached
2025-06-20 12:40:36 +02:00
Akihiro SudaandGitHub 80d1959ee3 Merge pull request #6144 from thaJeztah/rm_top_level_remove
remove undocumented top-level "docker remove" command
2025-06-20 06:14:15 +09:00
Sebastiaan van StijnandLorenzo Buero 19a5c5c714 remove undocumented top-level "docker remove" command
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]: https://github.com/moby/moby/commit/b993609d5ad4590da72e217bb43786b74aabc183

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>
2025-06-19 15:42:54 +02:00
Sebastiaan van Stijn c88268681e prevent login prompt on registry operations with no TTY attached
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]: https://github.com/moby/moby/commit/19a93a6e3d4213c56583bb0c843cf9e33d379752

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-19 10:25:27 +02:00
Paweł GronowskiandGitHub 747cb4448f Merge pull request #6140 from vvoland/image-tree-used
image/tree: Fix top image chip detection
2025-06-18 20:13:03 +00:00
Paweł Gronowski 23fe9ec244 image/tree: Fix top image chip detection
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>
2025-06-18 20:18:58 +02:00
Paweł GronowskiandGitHub 51025e12e5 Merge pull request #6008 from Benehiko/env-credentials-store
Use `DOCKER_AUTH_CONFIG` env as credential store
2025-06-18 18:07:07 +00:00
Alano Terblanche 9b83d5bbf9 Use DOCKER_AUTH_CONFIG env as credential store
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>
2025-06-18 18:55:42 +02:00
Sebastiaan van StijnandGitHub ab2d683f61 Merge pull request #6137 from thaJeztah/execconfig_detach
cli/command/container: remove use of ExecOptions.Detach as intermediate
2025-06-17 14:22:28 +02:00
Sebastiaan van StijnandGitHub 3664c08b73 Merge pull request #6138 from thaJeztah/bump_swarmkit
vendor: github.com/moby/swarmkit/v2 v2.0.0
2025-06-17 14:21:47 +02:00
Sebastiaan van Stijn cccf6d8cc4 vendor: github.com/moby/swarmkit/v2 v2.0.0
full diff: https://github.com/moby/swarmkit/compare/8c1959736554...v2.0.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-17 13:26:30 +02:00
Sebastiaan van Stijn 50da0ad9df cli/command/container: remove use of ExecOptions.Detach as intermediate
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]: https://github.com/docker/docker/commit/5130fe5d38837302e72bdc5e4bd1f5fa1df72c7f
[moby@c786a8ee5e9db8f5f]: https://github.com/docker/docker/commit/c786a8ee5e9db8f5f609cf8721bd1e1513fb0043
[moby@9d9dff3d0d9e92adf]: https://github.com/docker/docker/commit/9d9dff3d0d9e92adf7c2e59f94c63766659d1d47

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-17 12:53:44 +02:00
Sebastiaan van StijnandGitHub dbb5872b69 Merge pull request #6135 from thaJeztah/fix_login_message
cli/command: RegistryAuthenticationPrivilegedFunc: fix hints for login
2025-06-16 14:35:56 +02:00
Sebastiaan van Stijn e2632c5c4f cli/command: RegistryAuthenticationPrivilegedFunc: fix hints for login
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>
2025-06-16 12:14:53 +02:00
Paweł GronowskiandGitHub f53bb8882f Merge pull request #6131 from vvoland/vendor-docker
vendor: github.com/docker/docker v28.3.0-dev (6a1fb46d4805)
2025-06-13 16:29:11 +00:00
Paweł Gronowski 4cb0695b49 vendor: github.com/docker/docker v28.3.0-dev (6a1fb46d4805)
full diff: https://github.com/docker/docker/compare/v28.2.2...6a1fb46d4805

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-06-13 18:23:51 +02:00
Paweł GronowskiandGitHub 3ce5130af6 Merge pull request #6132 from thaJeztah/replace_evt
cli/command/container: replace uses of deprecated event.Status field
2025-06-13 16:23:08 +00:00
Sebastiaan van Stijn 99d4d1f386 cli/command/container: replace uses of deprecated event.Status field
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-13 18:18:28 +02:00
Paweł GronowskiandGitHub 398fa5aa70 Merge pull request #6130 from thaJeztah/bump_version
bump version to v28.3.0-dev
2025-06-13 13:42:56 +00:00
Sebastiaan van Stijn e225d51919 bump version to v28.3.0-dev
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.

https://github.com/docker/cli/blob/d48fb9f9f7bdb6e0ef37dbde68612a1704cad46e/docker.Makefile#L22

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-13 14:11:56 +02:00
Sebastiaan van StijnandGitHub 9cc2a2bf2d Merge pull request #6129 from vvoland/docs-deprecated
docs: deprecate empty Config fields in image inspect API
2025-06-13 14:10:48 +02:00
Paweł Gronowski 181563ee99 docs: deprecate empty Config fields in image inspect API
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>
2025-06-13 13:48:07 +02:00
Paweł GronowskiandGitHub 082d23d12d Merge pull request #6127 from thaJeztah/bump_deps
vendor: update buildkit and containerd dependencies
2025-06-12 13:20:31 +00:00
Sebastiaan van Stijn 59e34093bc vendor: otel v1.35.0, otel/contrib v0.60.0, grpc v1.72.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-12 14:16:23 +02:00
Sebastiaan van Stijn a76643bca3 vendor: github.com/prometheus/client_golang v1.22.0
full diff: https://github.com/prometheus/client_golang/compare/v1.20.5...v1.22.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-12 14:12:33 +02:00
Sebastiaan van Stijn f6985b7a27 vendor: google.golang.org/protobuf v1.36.6
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-12 14:11:07 +02:00
Sebastiaan van Stijn bab8478ef3 vendor: golang.org/x/sys v0.33.0
full diff: https://github.com/golang/sys/compare/v0.32.0...v0.33.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-12 14:09:24 +02:00
Sebastiaan van Stijn 9f82d4a791 vendor: golang.org/x/sync v0.14.0
full diff: https://github.com/golang/sync/compare/v0.13.0...v0.14.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-12 13:54:57 +02:00
Cesar Talledo 0ba4362d69 Update markdown docs to indicate multi-platform support in image load/save.
Signed-off-by: Cesar Talledo <cesar.talledo@docker.com>
2025-06-10 16:42:39 -07:00
Cesar Talledo 8993f54fc3 Add support for multiple platforms in docker image save
Signed-off-by: Cesar Talledo <cesar.talledo@docker.com>
2025-06-10 16:34:07 -07:00
Cesar Talledo 38b99adc10 Add support for multiple platforms in docker image load.
Signed-off-by: Cesar Talledo <cesar.talledo@docker.com>
2025-06-10 16:34:02 -07:00
Sebastiaan van StijnandGitHub 8b8f558b83 Merge pull request #6124 from vvoland/update-go
update to go1.24.4
2025-06-10 15:12:26 +02:00
Sebastiaan van StijnandGitHub 5487986681 Merge pull request #6123 from ndeloof/pluginserver
only close plugin server if actually created
2025-06-10 15:12:06 +02:00
Nicolas De Loof b9c563a581 only close plugin server if actually created
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-10 14:57:19 +02:00
Paweł Gronowski fe7fc2ff7f update to go1.24.4
- 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>
2025-06-09 16:25:41 +02:00
Sebastiaan van StijnandGitHub 9e506545fd Merge pull request #6120 from thaJeztah/fix_url
docs: fix link to live-restore
2025-06-02 13:02:40 +02:00
Sebastiaan van Stijn 3c1bbfd82f docs: fix link to live-restore
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-02 12:56:04 +02:00
Sebastiaan van StijnandGitHub 0bfd4c9f29 Merge pull request #6119 from thaJeztah/bump_engine
vendor: github.com/docker/docker v28.2.2
2025-06-02 10:15:52 +02:00
Sebastiaan van StijnandGitHub 3b25977f82 Merge pull request #50110 from thaJeztah/remove_import_comments
all: remove // import comments
2025-05-30 20:35:54 +02:00
Sebastiaan van StijnandGitHub d8f09a1b75 Merge pull request #6117 from vvoland/binimage-nosha
gha/bin-image: Don't push sha tags
2025-05-30 17:42:22 +02:00
Sebastiaan van Stijn 473b248260 vendor: github.com/docker/docker v28.2.2
no diff; same commit, but tagged:
https://github.com/docker/docker/compare/45873be4ae3f...v28.2.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-05-30 17:37:57 +02:00
Sebastiaan van Stijn 342f8bca25 builder: remove // import comments
These comments were added to enforce using the correct import path for
our packages ("github.com/docker/docker", not "github.com/moby/moby").
However, when working in go module mode (not GOPATH / vendor), they have
no effect, so their impact is limited.

Remove these imports in preparation of migrating our code to become an
actual go module.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-05-30 15:59:11 +02:00
Paweł Gronowski b2d63d17af gha/bin-image: Don't push sha tags
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>
2025-05-30 12:00:29 +02:00
Sebastiaan van StijnandGitHub 7422403164 Merge pull request #49885 from mmorel-35/fix-staticcheck
fix staticcheck linting issues for golangci-lint v2
2025-05-01 17:08:40 +02:00
Matthieu MORELandSebastiaan van Stijn 09a3c93f96 fix(QF1001): Apply De Morgan’s law
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-05-01 14:16:44 +02:00
Sebastiaan van Stijn a10a1e619b builder/remotecontext: remove unused named and "naked" returns
Also renamed some vars for clarity, renamed a error-returns to prevent
shadowing, and fixed some linter warnings about unhandled errors.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-04-26 15:47:11 +02:00
Sebastiaan van Stijn 75f791d904 builder: use lazyregexp to compile regexes on first use
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-01-02 21:37:32 +01:00
Aleksa Sarai 8d3c0fb6dc tests: migrate to assert.ErrorContains when possible
If we have an error type that we're checking a substring against, we
should really be checking using ErrorContains to indicate the right
semantics to assert.

Mostly done using these transforms:

  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r 'assert.Assert(t, is.ErrorContains(e, s)) -> assert.ErrorContains(t, e, s)'
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r 'assert.Assert(t, is.Contains(err.Error(), s)) -> assert.ErrorContains(t, err, s)'
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r 'assert.Check(t, is.Contains(err.Error(), s)) -> assert.Check(t, is.ErrorContains(err, s))'

As well as some small fixups to helpers that were doing
strings.Contains explicitly.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-11-22 23:59:21 +11:00
Sebastiaan van Stijn 45f09a1504 builder/remotecontext/git: remove redundant capturing of loop vars (copyloopvar)
builder/remotecontext/git/gitutils_test.go:116:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
            tc := tc
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-12 14:02:11 +01:00
Tianon GraviandGitHub ce639151e0 Merge pull request #47109 from whalelines/git-url-regex
Fix isGitURL regular expression
2024-01-18 14:02:57 -08:00
David Dooling 52c62bd13b Fix isGitURL regular expression
Escape period (.) so regular expression does not match any character before "git".

Signed-off-by: David Dooling <david.dooling@docker.com>
2024-01-18 14:14:08 -06:00
Sebastiaan van Stijn 8f865184a6 builder/remotecontext: format code with gofumpt
Formatting the code with https://github.com/mvdan/gofumpt

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-29 00:25:21 +02:00
Tianon GraviandGitHub ee957e144b Merge pull request #44381 from thaJeztah/strings_cut
Replace uses of `strings.Split(N)` with `strings.Cut()`
2022-12-21 09:16:05 -08:00
Sebastiaan van Stijn 6291744fa4 builder/remotecontext/git: use strings.Cut()
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-12-21 11:09:00 +01:00
Sebastiaan van Stijn 60b326f814 builder/remotecontext/gitutils: switch back to os/exec
This is a partial revert of 389ada7188, which
switched from os/exec to the golang.org/x/sys/execabs package to mitigate
security issues (mainly on Windows) with lookups resolving to binaries in the
current directory.

from the go1.19 release notes https://go.dev/doc/go1.19#os-exec-path

> ## PATH lookups
>
> Command and LookPath no longer allow results from a PATH search to be found
> relative to the current directory. This removes a common source of security
> problems but may also break existing programs that depend on using, say,
> exec.Command("prog") to run a binary named prog (or, on Windows, prog.exe) in
> the current directory. See the os/exec package documentation for information
> about how best to update such programs.
>
> On Windows, Command and LookPath now respect the NoDefaultCurrentDirectoryInExePath
> environment variable, making it possible to disable the default implicit search
> of “.” in PATH lookups on Windows systems.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-11-09 12:28:17 +01:00
Sebastiaan van StijnandGitHub aa6ad06304 Merge pull request #44344 from thaJeztah/go1.18_compat
builder/remotecontext/git: allow building on go1.18
2022-10-21 19:38:54 +02:00
Sebastiaan van Stijn 66713384c3 builder/remotecontext/git: allow building on go1.18
cmd.Environ() is new in go1.19, and not needed for this specific case.
Without this, trying to use this package in code that uses go1.18 will fail;

    builder/remotecontext/git/gitutils.go:216:23: cmd.Environ undefined (type *exec.Cmd has no field or method Environ)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-21 17:41:41 +02:00
Cory Snider 5c21ec520e builder: add missing doc comment
Signed-off-by: Cory Snider <csnider@mirantis.com>
2022-10-20 16:47:18 -04:00
Cory Snider 212213e81e builder: fix running git commands on Windows
Setting cmd.Env overrides the default of passing through the parent
process' environment, which works out fine most of the time, except when
it doesn't. For whatever reason, leaving out all the environment causes
git-for-windows sh.exe subprocesses to enter an infinite loop of
access violations during Cygwin initialization in certain environments
(specifically, our very own dev container image).

Signed-off-by: Cory Snider <csnider@mirantis.com>
2022-10-20 16:47:18 -04:00
Cory Snider bcd6c45731 builder: make git config isolation opt-in
While it is undesirable for the system or user git config to be used
when the daemon clones a Git repo, it could break workflows if it was
unconditionally applied to docker/cli as well.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2022-10-20 16:47:18 -04:00
Cory Snider 876fc1dac4 builder: isolate git from local system
Prevent git commands we run from reading the user or system
configuration, or cloning submodules from the local filesystem.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2022-10-20 16:47:18 -04:00
Cory Snider 3bfb30acd7 builder: explicitly set CWD for all git commands
Keep It Simple! Set the working directory for git commands by...setting
the git process's working directory. Git commands can be run in the
parent process's working directory by passing the empty string.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2022-10-20 16:47:18 -04:00
Cory Snider 3f4cc89f64 builder: modernize TestCheckoutGit
Make the test more debuggable by logging all git command output and
running each table-driven test case as a subtest.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2022-10-20 16:47:18 -04:00
Sebastiaan van Stijn a12090d787 gofmt GoDoc comments with go1.19
Older versions of Go don't format comments, so committing this as
a separate commit, so that we can already make these changes before
we upgrade to Go 1.19.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-07-08 19:56:23 +02:00
Sebastiaan van StijnandGitHub f1b0ef127d Merge pull request #43477 from thaJeztah/deprecate_urlutil
pkg/urlutil: deprecate, and move to builder/remotecontext/urlutil
2022-04-13 17:16:15 +02:00
Sebastiaan van Stijn 26a11366a7 builder/remotecontext/urlutil: simplify and improve documentation
Simplify some of the logic, and add documentation about the package,
as well as warnings that this package should not be used as a general-
purpose utility.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-04-12 19:58:09 +02:00
Sebastiaan van Stijn 9e39630a05 pkg/urlutil: deprecate, and move to builder/remotecontext/urlutil
pkg/urlutil (despite its poorly chosen name) is not really intended as a generic
utility to handle URLs, and should only be used by the builder to handle (remote)
build contexts.

- IsURL() only does a very rudimentary check for http(s):// prefixes, without any
  other validation, but due to its name may give incorrect expectations.
- IsGitURL() is written specifically with docker build remote git contexts in
  mind, and has handling for backward-compatibility, where strings that are
  not URLs, but start with "github.com/" are accepted.

Because of the above, this patch:

- moves the package inside builder/remotecontext, close to where it's intended
  to be used (ideally this would be part of build/remotecontext itself, but this
  package imports many other dependencies, which would introduce those as extra
  dependencies in the CLI).
- deprecates pkg/urlutil, but adds aliases as there are some external consumers.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-04-12 19:58:05 +02:00
Eng Zer Jun 6d2a901118 refactor: move from io/ioutil to io and os package
The io/ioutil package has been deprecated in Go 1.16. This commit
replaces the existing io/ioutil functions with their new definitions in
io and os packages.

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2021-08-27 14:56:57 +08:00
Tibor Vass 389ada7188 Use golang.org/x/sys/execabs
Signed-off-by: Tibor Vass <tibor@docker.com>
2021-01-25 19:13:12 +00:00
Tibor VassandGitHub 613477b489 Merge pull request #41606 from thaJeztah/moby_sys_symlink
replace pkg/symlink with github.com/moby/sys/symlink
2020-11-03 09:58:08 -08:00
Sebastiaan van Stijn a4c8c72411 replace pkg/symlink with github.com/moby/sys/symlink
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-11-03 11:17:12 +01:00
Sebastiaan van Stijn 5896d383ca bump gotest.tools v3.0.1 for compatibility with Go 1.14
full diff: https://github.com/gotestyourself/gotest.tools/compare/v2.3.0...v3.0.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-02-11 00:06:42 +01:00
Sebastiaan van Stijn ea850377cd builder/remotecontext: allow ssh:// urls for remote context
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-12-05 21:22:49 +01:00
Sebastiaan van Stijn 2d0d4ce4af builder/remotecontext: use net/url instead of urlutil
urlutil.IsUrl() was merely checking if the url had a http(s)://
prefix, which is just as well handled through using url.Parse()

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-11-05 18:04:01 -08:00
Sebastiaan van Stijn a0d9b0cf0d TestParseRemoteURL: use subtests
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-11-05 14:00:18 -08:00
Yong TangandGitHub b3d0327781 Merge pull request #39668 from thaJeztah/replace_gometalinter
Replace gometalinter with golangci-lint
2019-09-18 07:30:18 -07:00
Sebastiaan van Stijn 70aef9f502 gosec: add ignore comments for reported issues that can be ignored
```
builder/remotecontext/remote.go:48:        G107: Potential HTTP request made with variable url (gosec)
builder/remotecontext/git/gitutils.go:145: G107: Potential HTTP request made with variable url (gosec)
builder/remotecontext/git/gitutils.go:147: G107: Potential HTTP request made with variable url (gosec)
pkg/fileutils/fileutils_test.go:185:       G303: File creation in shared tmp directory without using ioutil.Tempfile (gosec)
pkg/tarsum/tarsum_test.go:7:               G501: Blacklisted import `crypto/md5`: weak cryptographic primitive (gosec)
pkg/tarsum/tarsum_test.go:9:               G505: Blacklisted import `crypto/sha1`: weak cryptographic primitive (gosec)
```

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-09-18 12:57:43 +02:00
Sebastiaan van StijnandGitHub 80dd489f21 Merge pull request #38944 from andrewhsu/gitutils
gitutils: add validation for ref
2019-03-27 02:03:47 +01:00
Tonis TiigiandAndrew Hsu 04e2a24a9e gitutils: add validation for ref
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit 723b107ca4fba14580a6cd971e63d8af2e7d2bbe)
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2019-03-26 22:05:46 +00:00
Vincent DemeesterandGitHub 84c375f430 Merge pull request #37243 from vdemeester/gotestyourself-with-tools
Update gotestyourself to gotest.tools
2018-06-13 16:23:26 +02:00
Vincent Demeester 71672ece9c Update tests to use gotest.tools 👼
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2018-06-13 09:04:30 +02:00
Daniel Nephin db857b5d9c Post migration assertion fixes
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2018-03-16 11:03:46 -04:00
Daniel Nephin 242f176825 Automated migration using
gty-migrate-from-testify --ignore-build-tags

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2018-03-16 11:03:43 -04:00
Daniel Nephin 6ea4877cff Add canonical import comment
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2018-02-05 16:51:57 -05:00
Tonis Tiigi 7bc503344a gitutils: remove checkout directory on error
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2017-12-08 11:58:13 -08:00
Tonis Tiigi e2cc22d076 gitutils: fix checking out submodules
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2017-12-07 14:25:19 -08:00
Andrew He e9831d75e2 Fix shallow git clone in docker-build
If the HEAD request fails, use a GET request to properly test if git
server is smart-http.

Signed-off-by: Andrew He <he.andrew.mail@gmail.com>
2017-07-25 13:20:59 -07:00
Sebastiaan van Stijn 9450481b7e Move IsGitTransport() to gitutils
This function was only used inside gitutils,
and is written specifically for the requirements
there.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-06-26 10:07:04 -07:00
Sebastiaan van Stijn a6cc6cd878 Fix handling of remote "git@" notation
`docker build` accepts remote repositories
using either the `git://` notation, or `git@`.

Docker attempted to parse both as an URL, however,
`git@` is not an URL, but an argument to `git clone`.

Go 1.7 silently ignored this, and managed to
extract the needed information from these
remotes, however, Go 1.8 does a more strict
validation, and invalidated these.

This patch adds a different path for `git@` remotes,
to prevent them from being handled as URL (and
invalidated).

A test is also added, because there were no
tests for handling of `git@` remotes.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-06-26 10:02:12 -07:00
Daniel Nephin e907d54fe6 Move pkg/gitutils to remotecontext/git
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2017-06-02 16:54:50 -04:00
2355 changed files with 140086 additions and 182481 deletions
View File
+9 -3
View File
@@ -1,11 +1,17 @@
blank_issues_enabled: false
contact_links:
- name: "Contributing to Docker"
- name: "🗃️ Docker Sandboxes: report an issue"
about: "Issues with Docker Sandboxes should be filed in the Docker Desktop feedback tracker (not docker/cli)."
url: "https://github.com/docker/desktop-feedback/issues"
- name: "🖥️ Docker Desktop: report an issue"
about: "General Docker Desktop issues (installation, upgrades, UI, networking on macOS/Windows, WSL2, etc.) should be filed in the Docker Desktop feedback tracker (not docker/cli)."
url: "https://github.com/docker/desktop-feedback/issues"
- name: "🧑‍💻 Contributing to Docker"
about: "Read guidelines and tips about contributing to Docker."
url: "https://github.com/docker/cli/blob/master/CONTRIBUTING.md"
- name: "Security and Vulnerabilities"
- name: "🔒 Security and Vulnerabilities"
about: "Report any security issues or vulnerabilities responsibly to the Docker security team. Do not use the public issue tracker."
url: "https://github.com/moby/moby/security/policy"
- name: "General Support"
- name: "💬 General Support"
about: "Get the help you need to build, share, and run your Docker applications"
url: "https://www.docker.com/support/"
+2 -5
View File
@@ -4,9 +4,6 @@ https://github.com/docker/cli/blob/master/CONTRIBUTING.md
** Make sure all your commits include a signature generated with `git commit -s` **
For additional information on our contributing process, read our contributing
guide https://docs.docker.com/opensource/code/
If this is a bug fix, make sure your description includes "fixes #xxxx", or
"closes #xxxx"
@@ -20,6 +17,7 @@ Provide the following information:
**- How to verify it**
**- Human readable description for the release notes**
<!--
Write a short (one line) summary that describes the changes in this
pull request for inclusion in the changelog.
@@ -28,10 +26,9 @@ It must be placed inside the below triple backticks section.
NOTE: Only fill this section if changes introduced in this PR are user-facing.
The PR must have a relevant impact/ label.
-->
```markdown changelog
```markdown changelog
```
**- A picture of a cute animal (not mandatory but encouraged)**
+10 -1
View File
@@ -5,5 +5,14 @@ updates:
schedule:
interval: "daily"
labels:
- "area/testing"
- "area/ci"
- "status/2-code-review"
cooldown:
default-days: 7
groups:
codeql-actions:
patterns:
- "github/codeql-action/*"
docker-actions:
patterns:
- "docker/*"
+39 -47
View File
@@ -35,7 +35,9 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
-
name: Create matrix
id: platforms
@@ -63,10 +65,10 @@ jobs:
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
-
name: Build
uses: docker/bake-action@v6
uses: docker/bake-action@d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b # v7.3.0
with:
targets: ${{ matrix.target }}
set: |
@@ -78,62 +80,50 @@ jobs:
working-directory: ./build
run: |
mkdir /tmp/out
platform=${{ matrix.platform }}
platformPair=${platform//\//-}
platformPair=${PLATFORM//\//-}
tar -cvzf "/tmp/out/docker-${platformPair}.tar.gz" .
if [ -z "${{ matrix.use_glibc }}" ]; then
echo "ARTIFACT_NAME=${{ matrix.target }}-${platformPair}" >> $GITHUB_ENV
else
echo "ARTIFACT_NAME=${{ matrix.target }}-${platformPair}-glibc" >> $GITHUB_ENV
fi
env:
PLATFORM: ${{ matrix.platform }}
-
name: Upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ env.ARTIFACT_NAME }}
path: /tmp/out/*
if-no-files-found: error
bin-image:
runs-on: ubuntu-24.04
if: ${{ github.event_name != 'pull_request' && github.repository == 'docker/cli' }}
steps:
-
name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_CLIBIN_USERNAME }}
password: ${{ secrets.DOCKERHUB_CLIBIN_TOKEN }}
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: dockereng/cli-bin
tags: |
type=semver,pattern={{version}}
type=ref,event=branch
type=ref,event=pr
type=sha
-
name: Build and push image
uses: docker/bake-action@v6
with:
files: |
./docker-bake.hcl
cwd://${{ steps.meta.outputs.bake-file }}
targets: bin-image-cross
push: ${{ github.event_name != 'pull_request' }}
set: |
*.cache-from=type=gha,scope=bin-image
*.cache-to=type=gha,scope=bin-image,mode=max
uses: docker/github-builder/.github/workflows/bake.yml@a492c6d04fd3315f67230809b44d60cc0acd50b3 # v1.16.0
permissions:
contents: read # same as global permission
id-token: write # for signing attestation(s) and authenticating to Docker Hub with GitHub OIDC Token
with:
setup-qemu: true
target: bin-image-cross
cache: true
cache-scope: bin-image
output: image
push: true
vars: |
VERSION=${{ github.ref }}
meta-images: |
dockereng/cli-bin
meta-tags: |
type=semver,pattern={{version}}
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{major}}
type=semver,pattern={{major}}.{{minor}}
registry-identities: |
- type: dockerhub
username: dockereng
connection_id: ${{ vars.DOCKERHUB_OIDC_CONNECTIONID }}
prepare-plugins:
runs-on: ubuntu-24.04
@@ -142,7 +132,9 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
-
name: Create matrix
id: platforms
@@ -164,10 +156,10 @@ jobs:
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
-
name: Build
uses: docker/bake-action@v6
uses: docker/bake-action@d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b # v7.3.0
with:
targets: plugins-cross
set: |
+8 -6
View File
@@ -46,9 +46,10 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 2
persist-credentials: false
# CodeQL 2.16.4's auto-build added support for multi-module repositories,
# and is trying to be smart by searching for modules in every directory,
# including vendor directories. If no module is found, it's creating one
@@ -61,19 +62,20 @@ jobs:
ln -s vendor.sum go.sum
-
name: Update Go
uses: actions/setup-go@v5
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version: "1.24.3"
go-version: "1.26.7"
cache: false
-
name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
with:
languages: go
-
name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
-
name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
with:
category: "/language:go"
+9 -7
View File
@@ -37,14 +37,16 @@ jobs:
- alpine
- debian
engine-version:
- 28 # latest
- 27 # latest - 1
- 26 # github actions default
- 23 # mirantis lts
- rc # latest rc
- 29 # latest
- 28 # latest - 1
- 25 # mirantis lts
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
-
name: Update daemon.json
run: |
@@ -63,7 +65,7 @@ jobs:
docker info
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
-
name: Run ${{ matrix.target }}
run: |
@@ -74,7 +76,7 @@ jobs:
TESTFLAGS: -coverprofile=/tmp/coverage/coverage.txt
-
name: Send to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1
with:
files: ./build/coverage/coverage.txt
token: ${{ secrets.CODECOV_TOKEN }}
+42
View File
@@ -0,0 +1,42 @@
name: PR Review - Trigger
on:
pull_request:
types: [ready_for_review, opened, review_requested]
pull_request_review_comment:
types: [created]
permissions: {}
# Deduplicate simultaneous pull_request events for the same fork PR.
# When reviewers are requested at the same time, GitHub fires multiple
# review_requested events. Without this group each event triggers a
# separate review via workflow_run, producing duplicate reviews.
concurrency:
group: pr-review-trigger-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
save-context:
if: github.event.pull_request.head.repo.fork
runs-on: ubuntu-latest
steps:
- name: Save event context
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
COMMENT_JSON: ${{ toJSON(github.event.comment) }}
run: |
mkdir -p context
printf '%s' "${{ github.event_name }}" > context/event_name.txt
printf '%s' "$PR_NUMBER" > context/pr_number.txt
printf '%s' "$PR_HEAD_SHA" > context/pr_head_sha.txt
if [ "${{ github.event_name }}" = "pull_request_review_comment" ]; then
printf '%s' "$COMMENT_JSON" > context/comment.json
fi
- name: Upload context
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: pr-review-context
path: context/
retention-days: 1
+23
View File
@@ -0,0 +1,23 @@
name: PR Review
on:
issue_comment:
types: [created]
workflow_run:
workflows: ["PR Review - Trigger"]
types: [completed]
permissions:
contents: read
jobs:
review:
uses: docker/docker-agent-action/.github/workflows/review-pr.yml@baf90543d81f5de59751dfd10e6cf45e21a5a982 # v2.0.3
permissions:
contents: read # Read repository files and PR diffs
pull-requests: write # Post review comments
issues: write # Create security incident issues if secrets detected
checks: write # (Optional) Show review progress as a check run
id-token: write # Required for OIDC authentication to AWS Secrets Manager
actions: read # Download artifacts from trigger workflow
with:
trigger-run-id: ${{ github.event_name == 'workflow_run' && format('{0}', github.event.workflow_run.id) || '' }}
+157
View File
@@ -0,0 +1,157 @@
name: Sync Docker release branch
concurrency:
group: ${{ github.workflow }}-${{ inputs.release_branch }}
cancel-in-progress: false
permissions:
contents: read
on:
workflow_dispatch:
inputs:
release_branch:
description: Release branch to sync, for example 29.x
required: true
type: string
tag:
description: Tag to sync from, for example v29.6.0
required: true
type: string
dry_run:
description: Merge but don't push
required: true
default: false
type: boolean
jobs:
sync-release-branch:
runs-on: ubuntu-24.04
permissions:
contents: write
actions: write
outputs:
base_sha: ${{ steps.sync.outputs.base_sha }}
has_changes: ${{ steps.sync.outputs.has_changes }}
temporary_branch: ${{ steps.sync.outputs.temporary_branch }}
temporary_sha: ${{ steps.sync.outputs.temporary_sha }}
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Validate
env:
BRANCH: ${{ github.ref_name }}
RELEASE_BRANCH: ${{ inputs.release_branch }}
run: |
if [ "$BRANCH" != "master" ]; then
echo "::error::This workflow is expected to be run on master, not $BRANCH"
exit 1
fi
if [ "$RELEASE_BRANCH" = "master" ]; then
echo "::error::The release branch must not be master"
exit 1
fi
if ! [[ "$RELEASE_BRANCH" =~ ^[0-9]+\.[x0-9]+$ ]]; then
echo "::error::Invalid release branch name: '$RELEASE_BRANCH'. Expected format: 29.x"
exit 1
fi
- name: Configure git author
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Sync release branch to tag range
id: sync
env:
DRY_RUN: ${{ inputs.dry_run }}
RELEASE_BRANCH: ${{ inputs.release_branch }}
RUN_ATTEMPT: ${{ github.run_attempt }}
RUN_ID: ${{ github.run_id }}
TAG: ${{ inputs.tag }}
run: |
set -o pipefail
base_sha=$(git rev-parse "origin/$RELEASE_BRANCH")
temporary_branch="process/sync-release-branch/$RUN_ID-$RUN_ATTEMPT"
echo "base_sha=$base_sha" >> "$GITHUB_OUTPUT"
echo "temporary_branch=$temporary_branch" >> "$GITHUB_OUTPUT"
# Keep the master checkout unchanged so scripts run from the dispatched revision.
release_worktree="$RUNNER_TEMP/release-branch"
git worktree add --detach "$release_worktree" "$base_sha"
cd "$release_worktree"
tags_file=$(mktemp)
"$GITHUB_WORKSPACE/scripts/unmerged-tags" \
"origin/$RELEASE_BRANCH" \
"$TAG" \
> "$tags_file"
echo >> "$GITHUB_STEP_SUMMARY"
echo "## Tags to sync" >> "$GITHUB_STEP_SUMMARY"
echo >> "$GITHUB_STEP_SUMMARY"
sed 's/^/- /' "$tags_file" >> "$GITHUB_STEP_SUMMARY"
xargs -r "$GITHUB_WORKSPACE/scripts/sync-branch" < "$tags_file" | tee -a "$GITHUB_STEP_SUMMARY"
if [[ "$DRY_RUN" == "true" ]]; then
echo "has_changes=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ $(git rev-parse HEAD) == $(git rev-parse "origin/$RELEASE_BRANCH") ]]; then
echo "has_changes=false" >> "$GITHUB_OUTPUT"
echo "No changes to push"
exit 0
fi
echo "has_changes=true" >> "$GITHUB_OUTPUT"
git push origin "HEAD:refs/heads/$temporary_branch"
echo "temporary_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
push-release-branch:
needs: sync-release-branch
if: ${{ !inputs.dry_run && needs.sync-release-branch.outputs.has_changes == 'true' }}
runs-on: ubuntu-24.04
environment: docker-releases
permissions:
contents: write
actions: write
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Push release branch
env:
BASE_SHA: ${{ needs.sync-release-branch.outputs.base_sha }}
RELEASE_BRANCH: ${{ inputs.release_branch }}
TEMPORARY_BRANCH: ${{ needs.sync-release-branch.outputs.temporary_branch }}
TEMPORARY_SHA: ${{ needs.sync-release-branch.outputs.temporary_sha }}
run: |
git fetch origin "$RELEASE_BRANCH"
current_sha=$(git rev-parse "origin/$RELEASE_BRANCH")
if [[ "$current_sha" != "$BASE_SHA" ]]; then
echo "$RELEASE_BRANCH changed from $BASE_SHA to $current_sha"
exit 1
fi
git fetch origin "$TEMPORARY_BRANCH"
current_temporary_sha=$(git rev-parse FETCH_HEAD)
if [[ "$current_temporary_sha" != "$TEMPORARY_SHA" ]]; then
echo "$TEMPORARY_BRANCH changed from $TEMPORARY_SHA to $current_temporary_sha"
exit 1
fi
git push origin "FETCH_HEAD:$RELEASE_BRANCH"
- name: Delete temporary branch
env:
TEMPORARY_BRANCH: ${{ needs.sync-release-branch.outputs.temporary_branch }}
run: git push origin --delete "$TEMPORARY_BRANCH"
+16 -10
View File
@@ -30,15 +30,15 @@ jobs:
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
-
name: Test
uses: docker/bake-action@v6
uses: docker/bake-action@d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b # v7.3.0
with:
targets: test-coverage
-
name: Send to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1
with:
files: ./build/coverage/coverage.txt
token: ${{ secrets.CODECOV_TOKEN }}
@@ -53,30 +53,36 @@ jobs:
fail-fast: false
matrix:
os:
- macos-13 # macOS 13 on Intel
- macos-14 # macOS 14 on arm64 (Apple Silicon M1)
- macos-14 # macOS 14 on arm64 (Apple Silicon M1)
- macos-15-intel # macOS 15 on Intel
- macos-15 # macOS 15 on arm64 (Apple Silicon M1)
# - windows-2022 # FIXME: some tests are failing on the Windows runner, as well as on Appveyor since June 24, 2018: https://ci.appveyor.com/project/docker/cli/history
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: ${{ env.GOPATH }}/src/github.com/docker/cli
persist-credentials: false
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version: "1.24.3"
go-version: "1.26.7"
cache: false
-
name: Test
run: |
go test -coverprofile=/tmp/coverage.txt $(go list ./... | grep -vE '/vendor/|/e2e/')
# run in go modules mode to prevent traversing to nested modules
ln -s vendor.mod go.mod
ln -s vendor.sum go.sum
go test -coverprofile=/tmp/coverage.txt $(go list ./... | grep -vE '^github.com/docker/cli/e2e/')
go tool cover -func=/tmp/coverage.txt
working-directory: ${{ env.GOPATH }}/src/github.com/docker/cli
shell: bash
-
name: Send to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1
with:
files: /tmp/coverage.txt
working-directory: ${{ env.GOPATH }}/src/github.com/docker/cli
+58
View File
@@ -0,0 +1,58 @@
name: validate-milestone
permissions:
contents: read
pull-requests: read
on:
pull_request:
types: [opened, synchronize, milestoned, demilestoned, edited]
jobs:
validate-milestone:
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
- name: Validate milestone matches VERSION
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
MILESTONE: ${{ github.event.pull_request.milestone.title }}
with:
script: |
const files = await github.paginate(github.rest.pulls.listFiles, {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
});
core.info(`Modified files: ${files.map(f => f.filename).join(', ')}`);
const touchesVersion = files.some(f => f.filename === 'VERSION');
core.info(`Touches VERSION: ${touchesVersion}`);
// Use the PR's version when it bumps the file, base branch otherwise.
// It's fine to trust the author in this case, it's not meant to be
// a security gate, just a helpful check for maintainers.
const ref = touchesVersion
? context.payload.pull_request.head.sha
: context.payload.pull_request.base.ref;
core.info(`Base ref: ${ref}`);
const resp = await github.rest.repos.getContent({
owner: context.repo.owner,
repo: context.repo.repo,
path: 'VERSION',
ref,
});
const expected = Buffer.from(resp.data.content, resp.data.encoding).toString('utf8').trim();
const milestone = process.env.MILESTONE;
if (!milestone) {
core.setFailed(`PR must have a milestone set (expected: ${expected})`);
return;
}
if (milestone !== expected) {
core.setFailed(`Milestone '${milestone}' does not match VERSION '${expected}'`);
return;
}
core.info(`Milestone: ${milestone} ✓`);
+8 -3
View File
@@ -11,18 +11,23 @@ permissions:
on:
pull_request:
types: [opened, edited, labeled, unlabeled]
types: [opened, edited, labeled, unlabeled, synchronize]
jobs:
check-area-label:
check-labels:
runs-on: ubuntu-24.04
timeout-minutes: 120 # guardrails timeout for the whole job
steps:
- name: Missing `area/` label
if: contains(join(github.event.pull_request.labels.*.name, ','), 'impact/') && !contains(join(github.event.pull_request.labels.*.name, ','), 'area/')
if: always() && contains(join(github.event.pull_request.labels.*.name, ','), 'impact/') && !contains(join(github.event.pull_request.labels.*.name, ','), 'area/')
run: |
echo "::error::Every PR with an 'impact/*' label should also have an 'area/*' label"
exit 1
- name: Missing `kind/` label
if: always() && contains(join(github.event.pull_request.labels.*.name, ','), 'impact/') && !contains(join(github.event.pull_request.labels.*.name, ','), 'kind/')
run: |
echo "::error::Every PR with an 'impact/*' label should also have a 'kind/*' label"
exit 1
- name: OK
run: exit 0
+32 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
-
name: Run
uses: docker/bake-action@v6
uses: docker/bake-action@d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b # v7.3.0
with:
targets: ${{ matrix.target }}
@@ -48,7 +48,9 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
-
name: Generate
shell: 'script --return --quiet --command "bash {0}"'
@@ -74,9 +76,36 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
-
name: Run
shell: 'script --return --quiet --command "bash {0}"'
run: |
make -f docker.Makefile ${{ matrix.target }}
validate-gocompat:
runs-on: ubuntu-24.04
env:
GOPATH: ${{ github.workspace }}
GO111MODULE: off
steps:
-
name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: src/github.com/docker/cli
persist-credentials: false
-
name: Set up Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version: "1.26.7"
cache: false
-
name: Run gocompat check
shell: 'script --return --quiet --command "bash {0}"'
working-directory: ${{ github.workspace }}/src/github.com/docker/cli
run: |
make -C ./internal/gocompat verify
+31
View File
@@ -0,0 +1,31 @@
name: zizmor
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
on:
workflow_dispatch:
push:
branches:
- 'main'
- 'master'
- '[0-9]+.[0-9]+'
- '[0-9]+.x'
tags:
- 'v*'
pull_request:
jobs:
run:
uses: crazy-max/.github/.github/workflows/zizmor.yml@46267a6e61cd56aac2fc79943df180152f4c89d6 # v1.10.1
permissions:
contents: read
security-events: write
with:
min-severity: medium
min-confidence: medium
persona: pedantic
+21 -10
View File
@@ -5,7 +5,7 @@ run:
# which causes it to fallback to go1.17 semantics.
#
# TODO(thaJeztah): update "usetesting" settings to enable go1.24 features once our minimum version is go1.24
go: "1.24.3"
go: "1.26.7"
timeout: 5m
@@ -86,12 +86,16 @@ linters:
desc: Use github.com/moby/sys/userns instead.
- pkg: "github.com/containerd/containerd/platforms"
desc: The containerd platforms package was migrated to a separate module. Use github.com/containerd/platforms instead.
- pkg: "github.com/docker/docker/errdefs"
desc: Use github.com/containerd/errdefs instead.
- pkg: "github.com/docker/docker/pkg/system"
desc: This package should not be used unless strictly necessary.
- pkg: "github.com/docker/distribution/uuid"
desc: Use github.com/google/uuid instead.
- pkg: "io/ioutil"
desc: The io/ioutil package has been deprecated, see https://go.dev/doc/go1.16#ioutil
- pkg: "gopkg.in/yaml.v3"
desc: Use go.yaml.in/yaml/v3 instead.
forbidigo:
forbid:
@@ -106,8 +110,15 @@ linters:
excludes:
- G104 # G104: Errors unhandled; (TODO: reduce unhandled errors, or explicitly ignore)
- G115 # G115: integer overflow conversion; (TODO: verify these: https://github.com/docker/cli/issues/5584)
- G117 # G117: Exported struct field matches secret pattern (false positives for legitimate field names)
- G118 # G118: Goroutine uses context.Background/TODO while request-scoped context is available (TODO: evaluate these)
- G122 # G122: Filesystem operation in filepath.Walk/WalkDir callback uses race-prone path (TODO: evaluate these)
- 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")
- G702 # G702: Command injection via taint analysis (TODO: evaluate these)
- G703 # G703: Path traversal via taint analysis (TODO: evaluate these)
- G704 # G704: SSRF via taint analysis (TODO: evaluate these)
- G705 # G705: XSS via taint analysis (TODO: evaluate these)
govet:
enable:
@@ -124,10 +135,9 @@ linters:
no-unaliased: true
alias:
# Enforce alias to prevent it accidentally being used instead of our
# own errdefs package (or vice-versa).
- pkg: github.com/containerd/errdefs
alias: cerrdefs
# Should no longer be aliased, because we no longer allow moby/docker errdefs.
- pkg: "github.com/docker/docker/errdefs"
alias: ""
- pkg: github.com/opencontainers/image-spec/specs-go/v1
alias: ocispec
# Enforce that gotest.tools/v3/assert/cmp is always aliased as "is"
@@ -153,11 +163,7 @@ linters:
arguments: [200]
- name: unused-receiver # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-receiver
- name: use-any # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#use-any
usetesting:
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
- name: use-errors-new # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-errors-new
exclusions:
# We prefer to use an "linters.exclusions.rules" so that new "default" exclusions are not
@@ -221,6 +227,11 @@ linters:
linters:
- staticcheck
# TODO(thaJeztah): remove once https://github.com/leighmcculloch/gocheckcompilerdirectives/issues/7 is fixed.
- text: "compiler directive unrecognized: //go:fix"
linters:
- gocheckcompilerdirectives
# Log a warning if an exclusion rule is unused.
# Default: false
warn-unused: true
+14 -3
View File
@@ -39,6 +39,7 @@ Alexander Larsson <alexl@redhat.com> <alexander.larsson@gmail.com>
Alexander Morozov <lk4d4math@gmail.com>
Alexander Morozov <lk4d4math@gmail.com> <lk4d4@docker.com>
Alexandre Beslic <alexandre.beslic@gmail.com> <abronan@docker.com>
Alexandre Levavasseur <alexandre+oss@13x.fr>
Alexis Couvreur <alexiscouvreur.pro@gmail.com>
Alicia Lauerman <alicia@eta.im> <allydevour@me.com>
Allen Sun <allensun.shl@alibaba-inc.com> <allen.sun@daocloud.io>
@@ -64,11 +65,14 @@ Arko Dasgupta <arko@tetrate.io> <arko.dasgupta@docker.com>
Arko Dasgupta <arko@tetrate.io> <arkodg@users.noreply.github.com>
Arnaud Porterie <icecrime@gmail.com>
Arnaud Porterie <icecrime@gmail.com> <arnaud.porterie@docker.com>
Arthur Flageul <arthur.flageul@gmail.com>
Arthur Flageul <arthur.flageul@gmail.com> <arthur.flageul@docker.com>
Arthur Gautier <baloo@gandi.net> <superbaloo+registrations.github@superbaloo.net>
Arthur Peka <arthur.peka@outlook.com> <arthrp@users.noreply.github.com>
Austin Vazquez <austin.vazquez.dev@gmail.com>
Austin Vazquez <austin.vazquez.dev@gmail.com> <55906459+austinvazquez@users.noreply.github.com>
Austin Vazquez <austin.vazquez.dev@gmail.com> <macedonv@amazon.com>
Austin Vazquez <austin.vazquez@docker.com>
Austin Vazquez <austin.vazquez@docker.com> <55906459+austinvazquez@users.noreply.github.com>
Austin Vazquez <austin.vazquez@docker.com> <austin.vazquez.dev@gmail.com>
Austin Vazquez <austin.vazquez@docker.com> <macedonv@amazon.com>
Avi Miller <avi.miller@oracle.com> <avi.miller@gmail.com>
Ben Bonnefoy <frenchben@docker.com>
Ben Golub <ben.golub@dotcloud.com>
@@ -150,6 +154,8 @@ Dave Henderson <dhenderson@gmail.com> <Dave.Henderson@ca.ibm.com>
Dave Tucker <dt@docker.com> <dave@dtucker.co.uk>
David Alvarez <david.alvarez@flyeralarm.com>
David Alvarez <david.alvarez@flyeralarm.com> <busilezas@gmail.com>
David Dooling <david.dooling@docker.com>
David Dooling <david.dooling@docker.com> <dooling@gmail.com>
David Karlsson <david.karlsson@docker.com>
David Karlsson <david.karlsson@docker.com> <35727626+dvdksn@users.noreply.github.com>
David M. Karr <davidmichaelkarr@gmail.com>
@@ -350,7 +356,9 @@ Louis Opter <kalessin@kalessin.fr>
Louis Opter <kalessin@kalessin.fr> <louis@dotcloud.com>
Lovekesh Kumar <lovekesh.kumar@rtcamp.com>
Luca Favatella <luca.favatella@erlang-solutions.com> <lucafavatella@users.noreply.github.com>
Lukas Michael <lukas.23022005@gmail.com>
Luke Marsden <me@lukemarsden.net> <luke@digital-crocus.com>
Luo Jiyin <luojiyin@hotmail.com>
Lyn <energylyn@zju.edu.cn>
Lynda O'Leary <lyndaoleary29@gmail.com>
Lynda O'Leary <lyndaoleary29@gmail.com> <lyndaoleary@hotmail.com>
@@ -397,6 +405,7 @@ Michael Huettermann <michael@huettermann.net>
Michael Käufl <docker@c.michael-kaeufl.de> <michael-k@users.noreply.github.com>
Michael Spetsiotis <michael_spets@hotmail.com>
Michal Minář <miminar@redhat.com>
Mickael Emirkanian <mickael.emirkanian@docker.com>
Miguel Angel Alvarez Cabrerizo <doncicuto@gmail.com> <30386061+doncicuto@users.noreply.github.com>
Miguel Angel Fernández <elmendalerenda@gmail.com>
Mihai Borobocea <MihaiBorob@gmail.com> <MihaiBorobocea@gmail.com>
@@ -566,6 +575,8 @@ Ulysses Souza <ulysses.souza@docker.com>
Ulysses Souza <ulysses.souza@docker.com> <ulyssessouza@gmail.com>
Umesh Yadav <umesh4257@gmail.com>
Umesh Yadav <umesh4257@gmail.com> <dungeonmaster18@users.noreply.github.com>
Varun Hotani <varunhotani@gmail.com>
Vibhu Anan <vibhuanand@outlook.com>
Victor Lyuboslavsky <victor@victoreda.com>
Victor Vieux <victor.vieux@docker.com> <dev@vvieux.com>
Victor Vieux <victor.vieux@docker.com> <victor.vieux@dotcloud.com>
+39 -2
View File
@@ -2,6 +2,7 @@
# This file lists all contributors to the repository.
# See scripts/docs/generate-authors.sh to make modifications.
4RH1T3CT0R7 <iprintercanon@gmail.com>
A. Lester Buck III <github-reg@nbolt.com>
Aanand Prasad <aanand.prasad@gmail.com>
Aaron L. Xu <liker.xu@foxmail.com>
@@ -42,6 +43,8 @@ Alexander Larsson <alexl@redhat.com>
Alexander Morozov <lk4d4math@gmail.com>
Alexander Ryabov <i@sepa.spb.ru>
Alexandre González <agonzalezro@gmail.com>
Alexandre Levavasseur <alexandre+oss@13x.fr>
Alexandre Vallières-Lagacé <alexandre.valliereslagace@docker.com>
Alexey Igrychev <alexey.igrychev@flant.com>
Alexis Couvreur <alexiscouvreur.pro@gmail.com>
Alfred Landrum <alfred.landrum@docker.com>
@@ -63,6 +66,8 @@ Andreas Köhler <andi5.py@gmx.net>
Andres G. Aragoneses <knocte@gmail.com>
Andres Leon Rangel <aleon1220@gmail.com>
Andrew France <andrew@avito.co.uk>
Andrew He <he.andrew.mail@gmail.com>
Andrew Hopp <andrew.hopp@me.com>
Andrew Hsu <andrewhsu@docker.com>
Andrew Macpherson <hopscotch23@gmail.com>
Andrew McDonnell <bugs@andrewmcdonnell.net>
@@ -86,11 +91,12 @@ Archimedes Trajano <developer@trajano.net>
Arko Dasgupta <arko@tetrate.io>
Arnaud Porterie <icecrime@gmail.com>
Arnaud Rebillout <elboulangero@gmail.com>
Arthur Flageul <arthur.flageul@gmail.com>
Arthur Peka <arthur.peka@outlook.com>
Ashly Mathew <ashly.mathew@sap.com>
Ashwini Oruganti <ashwini.oruganti@gmail.com>
Aslam Ahemad <aslamahemad@gmail.com>
Austin Vazquez <austin.vazquez.dev@gmail.com>
Austin Vazquez <austin.vazquez@docker.com>
Azat Khuyiyakhmetov <shadow_uz@mail.ru>
Bardia Keyoumarsi <bkeyouma@ucsc.edu>
Barnaby Gray <barnaby@pickle.me.uk>
@@ -125,6 +131,7 @@ Brian Goff <cpuguy83@gmail.com>
Brian Tracy <brian.tracy33@gmail.com>
Brian Wieder <brian@4wieders.com>
Bruno Sousa <bruno.sousa@docker.com>
Bruno Verachten <gounthar@gmail.com>
Bryan Bess <squarejaw@bsbess.com>
Bryan Boreham <bjboreham@gmail.com>
Bryan Murphy <bmurphy1976@gmail.com>
@@ -135,10 +142,12 @@ Cao Weiwei <cao.weiwei30@zte.com.cn>
Carlo Mion <mion00@gmail.com>
Carlos Alexandro Becker <caarlos0@gmail.com>
Carlos de Paula <me@carlosedp.com>
carsontham <carsontham@outlook.com>
Carston Schilds <Carston.Schilds@visier.com>
Casey Korver <casey@korver.dev>
Ce Gao <ce.gao@outlook.com>
Cedric Davies <cedricda@microsoft.com>
Cesar Talledo <cesar.talledo@docker.com>
Cezar Sa Espinola <cezarsa@gmail.com>
Chad Faragher <wyckster@hotmail.com>
Chao Wang <wangchao.fnst@cn.fujitsu.com>
@@ -153,6 +162,7 @@ Chen Chuanliang <chen.chuanliang@zte.com.cn>
Chen Hanxiao <chenhanxiao@cn.fujitsu.com>
Chen Mingjie <chenmingjie0828@163.com>
Chen Qiu <cheney-90@hotmail.com>
Ching Wei Kang <164879897+WilliamK112@users.noreply.github.com>
Chris Chinchilla <chris@chrischinchilla.com>
Chris Couzens <ccouzens@gmail.com>
Chris Gavin <chris@chrisgavin.me>
@@ -174,6 +184,7 @@ Christopher Svensson <stoffus@stoffus.com>
Christy Norman <christy@linux.vnet.ibm.com>
Chun Chen <ramichen@tencent.com>
Clinton Kitson <clintonskitson@gmail.com>
Codex <codex@openai.com>
Coenraad Loubser <coenraad@wish.org.za>
Colin Hebert <hebert.colin@gmail.com>
Collin Guarino <collin.guarino@gmail.com>
@@ -220,7 +231,7 @@ David Alvarez <david.alvarez@flyeralarm.com>
David Beitey <david@davidjb.com>
David Calavera <david.calavera@gmail.com>
David Cramer <davcrame@cisco.com>
David Dooling <dooling@gmail.com>
David Dooling <david.dooling@docker.com>
David Gageot <david@gageot.net>
David Karlsson <david.karlsson@docker.com>
David le Blanc <systemmonkey42@users.noreply.github.com>
@@ -230,6 +241,7 @@ David Sheets <dsheets@docker.com>
David Williamson <david.williamson@docker.com>
David Xia <dxia@spotify.com>
David Young <yangboh@cn.ibm.com>
Davlat Davydov <literally_user@hotmail.com>
Deng Guangxing <dengguangxing@huawei.com>
Denis Defreyne <denis@soundcloud.com>
Denis Gladkikh <denis@gladkikh.email>
@@ -237,6 +249,7 @@ Denis Ollier <larchunix@users.noreply.github.com>
Dennis Docter <dennis@d23.nl>
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Derek McGowan <derek@mcg.dev>
Derek Misler <derek.misler@docker.com>
Des Preston <despreston@gmail.com>
Deshi Xiao <dxiao@redhat.com>
Dharmit Shah <shahdharmit@gmail.com>
@@ -256,6 +269,7 @@ Dominik Braun <dominik.braun@nbsp.de>
Don Kjer <don.kjer@gmail.com>
Dong Chen <dongluo.chen@docker.com>
DongGeon Lee <secmatth1996@gmail.com>
Dorin Geman <dorin.geman@docker.com>
Doug Davis <dug@us.ibm.com>
Drew Erny <derny@mirantis.com>
Ed Costello <epc@epcostello.com>
@@ -265,6 +279,7 @@ Eli Uriegas <eli.uriegas@docker.com>
Eli Uriegas <seemethere101@gmail.com>
Elias Faxö <elias.faxo@tre.se>
Elliot Luo <956941328@qq.com>
Eng Zer Jun <engzerjun@gmail.com>
Eric Bode <eric.bode@foundries.io>
Eric Curtin <ericcurtin17@gmail.com>
Eric Engestrom <eric@engestrom.ch>
@@ -345,6 +360,7 @@ Henning Sprang <henning.sprang@gmail.com>
Henry N <henrynmail-github@yahoo.de>
Hernan Garcia <hernandanielg@gmail.com>
Hongbin Lu <hongbin034@gmail.com>
Hossein Abbasi <16090309+hsnabszhdn@users.noreply.github.com>
Hu Keping <hukeping@huawei.com>
Huayi Zhang <irachex@gmail.com>
Hugo Chastel <Hugo-C@users.noreply.github.com>
@@ -465,6 +481,7 @@ Justyn Temme <justyntemme@gmail.com>
Jyrki Puttonen <jyrkiput@gmail.com>
Jérémie Drouet <jeremie.drouet@gmail.com>
Jérôme Petazzoni <jerome.petazzoni@docker.com>
Jörg Sommer <joerg@jo-so.de>
Jörg Thalheim <joerg@higgsboson.tk>
Kai Blin <kai@samba.org>
Kai Qiang Wu (Kennan) <wkq5325@gmail.com>
@@ -533,10 +550,13 @@ Lovekesh Kumar <lovekesh.kumar@rtcamp.com>
Luca Favatella <luca.favatella@erlang-solutions.com>
Luca Marturana <lucamarturana@gmail.com>
Lucas Chan <lucas-github@lucaschan.com>
Ludovic Temgoua Abanda <abandaludovic500@gmail.com>
Luis Henrique Mulinari <luis.mulinari@gmail.com>
Luka Hartwig <mail@lukahartwig.de>
Lukas Heeren <lukas-heeren@hotmail.com>
Lukas Michael <lukas.23022005@gmail.com>
Lukasz Zajaczkowski <Lukasz.Zajaczkowski@ts.fujitsu.com>
Luo Jiyin <luojiyin@hotmail.com>
Lydell Manganti <LydellManganti@users.noreply.github.com>
Lénaïc Huard <lhuard@amadeus.com>
Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
@@ -545,6 +565,7 @@ Maciej Kalisz <maciej.d.kalisz@gmail.com>
Madhav Puri <madhav.puri@gmail.com>
Madhu Venugopal <madhu@socketplane.io>
Madhur Batra <madhurbatra097@gmail.com>
Mahesh Thakur <maheshthakur9152@gmail.com>
Malte Janduda <mail@janduda.net>
Manjunath A Kumatagi <mkumatag@in.ibm.com>
Mansi Nahar <mmn4185@rit.edu>
@@ -572,10 +593,12 @@ Mathieu Rollet <matletix@gmail.com>
Matt Gucci <matt9ucci@gmail.com>
Matt Robenolt <matt@ydekproductions.com>
Matteo Orefice <matteo.orefice@bites4bits.software>
Matteo Panzeri <matteo1782@gmail.com>
Matthew Heon <mheon@redhat.com>
Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
Matthieu MOREL <matthieu.morel35@gmail.com>
Mauro Porras P <mauroporrasp@gmail.com>
Max Morozov <gtmax.yo@gmail.com>
Max Shytikov <mshytikov@gmail.com>
Max-Julian Pogner <max-julian@pogner.at>
Maxime Petazzoni <max@signalfuse.com>
@@ -595,9 +618,12 @@ Michael Prokop <github@michael-prokop.at>
Michael Scharf <github@scharf.gr>
Michael Spetsiotis <michael_spets@hotmail.com>
Michael Steinert <mike.steinert@gmail.com>
Michael Tews <michael@tews.dev>
Michael West <mwest@mdsol.com>
Michael Zampani <michael.zampani@docker.com>
Michal Minář <miminar@redhat.com>
Michał Czeraszkiewicz <czerasz@gmail.com>
Mickael Emirkanian <mickael.emirkanian@docker.com>
Miguel Angel Alvarez Cabrerizo <doncicuto@gmail.com>
Mihai Borobocea <MihaiBorob@gmail.com>
Mihuleacc Sergiu <mihuleac.sergiu@gmail.com>
@@ -610,6 +636,7 @@ Mike Goelzer <mike.goelzer@docker.com>
Mike MacCana <mike.maccana@gmail.com>
mikelinjie <294893458@qq.com>
Mikhail Vasin <vasin@cloud-tv.ru>
Milas Bowman <milas.bowman@docker.com>
Milind Chawre <milindchawre@gmail.com>
Mindaugas Rukas <momomg@gmail.com>
Miroslav Gula <miroslav.gula@naytrolabs.com>
@@ -618,6 +645,7 @@ Mohammad Banikazemi <mb@us.ibm.com>
Mohammad Hossein <mhm98035@gmail.com>
Mohammed Aaqib Ansari <maaquib@gmail.com>
Mohammed Aminu Futa <mohammedfuta2000@gmail.com>
Mohammed Thaha <mohammedthahacse@gmail.com>
Mohini Anne Dsouza <mohini3917@gmail.com>
Moorthy RS <rsmoorthy@gmail.com>
Morgan Bauer <mbauer@us.ibm.com>
@@ -669,6 +697,7 @@ Olli Janatuinen <olli.janatuinen@gmail.com>
Oscar Wieman <oscrx@icloud.com>
Otto Kekäläinen <otto@seravo.fi>
Ovidio Mallo <ovidio.mallo@gmail.com>
Park Jaeon <me@finalchild.dev>
Pascal Borreli <pascal@borreli.com>
Patrick Böänziger <patrick.baenziger@bsi-software.com>
Patrick Daigle <114765035+pdaig@users.noreply.github.com>
@@ -695,6 +724,7 @@ Peter Jaffe <pjaffe@nevo.com>
Peter Kehl <peter.kehl@gmail.com>
Peter Nagy <xificurC@gmail.com>
Peter Salvatore <peter@psftw.com>
Peter Valdemar Mørch <peter@morch.com>
Peter Waller <p@pwaller.net>
Phil Estes <estesp@gmail.com>
Philip Alexander Etling <paetling@gmail.com>
@@ -719,6 +749,7 @@ Ray Tsang <rayt@google.com>
Reficul <xuzhenglun@gmail.com>
Remy Suen <remy.suen@gmail.com>
Renaud Gaubert <rgaubert@nvidia.com>
René Hermenau <rene-hermenau@users.noreply.github.com>
Ricardo N Feliciano <FelicianoTech@gmail.com>
Rich Moyse <rich@moyse.us>
Richard Chen Zheng <58443436+rchenzheng@users.noreply.github.com>
@@ -769,6 +800,7 @@ Scott Collier <emailscottcollier@gmail.com>
Sean Christopherson <sean.j.christopherson@intel.com>
Sean Rodman <srodman7689@gmail.com>
Sebastiaan van Stijn <github@gone.nl>
Seiya Miyata <odradek38@gmail.com>
Sergey Tryuber <Sergeant007@users.noreply.github.com>
Serhat Gülçiçek <serhat25@gmail.com>
Sevki Hasirci <s@sevki.org>
@@ -869,8 +901,10 @@ Umesh Yadav <umesh4257@gmail.com>
Vaclav Struhar <struharv@gmail.com>
Valentin Lorentz <progval+git@progval.net>
Vardan Pogosian <vardan.pogosyan@gmail.com>
Varun Hotani <varunhotani@gmail.com>
Venkateswara Reddy Bukkasamudram <bukkasamudram@outlook.com>
Veres Lajos <vlajos@gmail.com>
Vibhu Anan <vibhuanand@outlook.com>
Victor Vieux <victor.vieux@docker.com>
Victoria Bialas <victoria.bialas@docker.com>
Viktor Stanchev <me@viktorstanchev.com>
@@ -880,6 +914,7 @@ Vincent Batts <vbatts@redhat.com>
Vincent Bernat <Vincent.Bernat@exoscale.ch>
Vincent Demeester <vincent.demeester@docker.com>
Vincent Woo <me@vincentwoo.com>
Vineet Kumar <vineetkumar17112004@gmail.com>
Vishnu Kannan <vishnuk@google.com>
Vivek Goyal <vgoyal@redhat.com>
Wang Jie <wangjie5@chinaskycloud.com>
@@ -896,6 +931,7 @@ Wenlong Zhang <zhangwenlong@loongson.cn>
Wenzhi Liang <wenzhi.liang@gmail.com>
Wes Morgan <cap10morgan@gmail.com>
Wewang Xiaorenfine <wang.xiaoren@zte.com.cn>
Will Wang <willww64@gmail.com>
William Henry <whenry@redhat.com>
Xianglin Gao <xlgao@zju.edu.cn>
Xiaodong Liu <liuxiaodong@loongson.cn>
@@ -908,6 +944,7 @@ Yanqiang Miao <miao.yanqiang@zte.com.cn>
Yassine Tijani <yasstij11@gmail.com>
Yi EungJun <eungjun.yi@navercorp.com>
Ying Li <ying.li@docker.com>
Yoan Wainmann <thebook90yw@gmail.com>
Yong Tang <yong.tang.github@outlook.com>
Yosef Fertel <yfertel@gmail.com>
Yu Peng <yu.peng36@zte.com.cn>
+9 -6
View File
@@ -66,7 +66,7 @@ anybody starts working on it.
We are always thrilled to receive pull requests. We do our best to process them
quickly. If your pull request is not accepted on the first try,
don't get discouraged! Our contributor's guide explains [the review process we
use for simple changes](https://github.com/docker/docker/blob/master/project/REVIEWING.md).
use for simple changes](https://github.com/moby/moby/blob/master/project/REVIEWING.md).
### Talking to other Docker users and contributors
@@ -124,8 +124,7 @@ submitting a pull request.
Update the documentation when creating or modifying features. Test your
documentation changes for clarity, concision, and correctness, as well as a
clean documentation build. See our contributors guide for [our style
guide](https://docs.docker.com/contribute/style/grammar/) and instructions on [building
the documentation](https://docs.docker.com/contribute/).
guide](https://github.com/docker/docs/blob/main/STYLE.md).
Write clean code. Universally formatted code promotes ease of writing, reading,
and maintenance. Always run `gofmt -s -w file.go` on each changed file before
@@ -145,6 +144,7 @@ not enforced. Common prefixes are `docs: <message>`, `vendor: <message>`,
or `telemetry: <message>`.
A standard commit.
```
Fix the exploding flux capacitor
@@ -153,6 +153,7 @@ the sun and the moon align.
```
Using a package as prefix.
```
pkg/foo: prevent panic in flux capacitor
@@ -160,12 +161,14 @@ Calling function A causes the flux capacitor to blow up every time
the sun and the moon align.
```
Updating a specific vendored package.
Updating a specific vendored dependency.
```
vendor: github.com/docker/docker 6ac445c42bad (master, v28.0-dev)
vendor: github.com/moby/moby/client v0.4.0
```
Fixing a broken docs link.
```
docs: fix style/lint issues in deprecated.md
```
@@ -264,7 +267,7 @@ Then you just add a line to every git commit message:
Signed-off-by: Joe Smith <joe.smith@email.com>
Use your real name (sorry, no pseudonyms or anonymous contributions.)
Use a known identity (sorry, no anonymous contributions.)
If you set your `user.name` and `user.email` git configs, you can sign your
commit automatically with `git commit -s`.
+26 -13
View File
@@ -1,26 +1,43 @@
# syntax=docker/dockerfile:1
ARG BASE_VARIANT=alpine
ARG ALPINE_VERSION=3.21
# ALPINE_VERSION sets the version of the alpine base image to use, including for the golang image.
# It must be a supported tag in the docker.io/library/alpine image repository
# that's also available as alpine image variant for the Golang version used.
ARG ALPINE_VERSION=3.23
ARG BASE_DEBIAN_DISTRO=bookworm
ARG GO_VERSION=1.24.3
ARG XX_VERSION=1.6.1
ARG GOVERSIONINFO_VERSION=v1.4.1
ARG GOTESTSUM_VERSION=v1.12.0
ARG GO_VERSION=1.26.7
# XX_VERSION specifies the version of the xx utility to use.
# It must be a valid tag in the docker.io/tonistiigi/xx image repository.
ARG XX_VERSION=1.9.0
# GOVERSIONINFO_VERSION is the version of GoVersionInfo to install.
# It must be a valid tag from https://github.com/josephspurrier/goversioninfo
ARG GOVERSIONINFO_VERSION=v1.5.0
# GOTESTSUM_VERSION sets the version of gotestsum to install in the dev container.
# It must be a valid tag in the https://github.com/gotestyourself/gotestsum repository.
ARG GOTESTSUM_VERSION=v1.13.0
# BUILDX_VERSION sets the version of buildx to use for the e2e tests.
# It must be a tag in the docker.io/docker/buildx-bin image repository
# on Docker Hub.
ARG BUILDX_VERSION=0.24.0
ARG COMPOSE_VERSION=v2.36.2
ARG BUILDX_VERSION=0.34.1
# COMPOSE_VERSION is the version of compose to install in the dev container.
# It must be a tag in the docker.io/docker/compose-bin image repository
# on Docker Hub.
ARG COMPOSE_VERSION=v5.1.3
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS build-base-alpine
ENV GOTOOLCHAIN=local
COPY --link --from=xx / /
RUN apk add --no-cache bash clang lld llvm file git
RUN apk add --no-cache bash clang lld llvm file git git-daemon
WORKDIR /go/src/github.com/docker/cli
FROM build-base-alpine AS build-alpine
@@ -80,7 +97,7 @@ ENV GO111MODULE=auto
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/go/pkg/mod \
gotestsum -- -coverprofile=/tmp/coverage.txt $(go list ./... | grep -vE '/vendor/|/e2e/')
gotestsum -- -coverprofile=/tmp/coverage.txt $(go list ./... | grep -vE '/vendor/|/e2e/|/cmd/docker-trust')
FROM scratch AS test-coverage
COPY --from=test /tmp/coverage.txt /coverage.txt
@@ -105,10 +122,6 @@ FROM docker/buildx-bin:${BUILDX_VERSION} AS buildx
FROM docker/compose-bin:${COMPOSE_VERSION} AS compose
FROM e2e-base-${BASE_VARIANT} AS e2e
ARG NOTARY_VERSION=v0.6.1
ADD --chmod=0755 https://github.com/theupdateframework/notary/releases/download/${NOTARY_VERSION}/notary-Linux-amd64 /usr/local/bin/notary
COPY --link e2e/testdata/notary/root-ca.cert /usr/share/ca-certificates/notary.cert
RUN echo 'notary.cert' >> /etc/ca-certificates.conf && update-ca-certificates
COPY --link --from=gotestsum /out/gotestsum /usr/bin/gotestsum
COPY --link --from=build /out ./build/
COPY --link --from=build-plugins /out ./build/
+12 -3
View File
@@ -34,12 +34,12 @@ test: test-unit ## run tests
.PHONY: test-unit
test-unit: ## run unit tests, to change the output format use: GOTESTSUM_FORMAT=(dots|short|standard-quiet|short-verbose|standard-verbose) make test-unit
gotestsum -- $${TESTDIRS:-$(shell go list ./... | grep -vE '/vendor/|/e2e/')} $(TESTFLAGS)
gotestsum -- $${TESTDIRS:-$(shell go list ./... | grep -vE '/vendor/|/e2e/|/cmd/docker-trust')} $(TESTFLAGS)
.PHONY: test-coverage
test-coverage: ## run test coverage
mkdir -p $(CURDIR)/build/coverage
gotestsum -- $(shell go list ./... | grep -vE '/vendor/|/e2e/') -coverprofile=$(CURDIR)/build/coverage/coverage.txt
gotestsum -- $(shell go list ./... | grep -vE '/vendor/|/e2e/|/cmd/docker-trust') -coverprofile=$(CURDIR)/build/coverage/coverage.txt
.PHONY: lint
lint: ## run all the lint tools
@@ -52,7 +52,7 @@ shellcheck: ## run shellcheck validation
.PHONY: fmt
fmt: ## run gofumpt (if present) or gofmt
@if command -v gofumpt > /dev/null; then \
gofumpt -w -d -lang=1.23 . ; \
gofumpt -w -d -lang=1.24 . ; \
else \
go list -f {{.Dir}} ./... | xargs gofmt -w -s -d ; \
fi
@@ -69,6 +69,15 @@ dynbinary: ## build dynamically linked binary
plugins: ## build example CLI plugins
scripts/build/plugins
.PHONY: trust-plugin
trust-plugin: ## build docker-trust CLI plugins
scripts/build/trust-plugin
.PHONY: install-trust-plugin
install-trust-plugin: trust-plugin
install-trust-plugin: ## install docker-trust CLI plugins
install -D -m 0755 "$$(readlink -f build/docker-trust)" /usr/libexec/docker/cli-plugins/docker-trust
.PHONY: vendor
vendor: ## update vendor with go modules
rm -rf vendor
+13 -2
View File
@@ -3,7 +3,6 @@
[![PkgGoDev](https://pkg.go.dev/badge/github.com/docker/cli)](https://pkg.go.dev/github.com/docker/cli)
[![Build Status](https://img.shields.io/github/actions/workflow/status/docker/cli/build.yml?branch=master&label=build&logo=github)](https://github.com/docker/cli/actions?query=workflow%3Abuild)
[![Test Status](https://img.shields.io/github/actions/workflow/status/docker/cli/test.yml?branch=master&label=test&logo=github)](https://github.com/docker/cli/actions?query=workflow%3Atest)
[![Go Report Card](https://goreportcard.com/badge/github.com/docker/cli)](https://goreportcard.com/report/github.com/docker/cli)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/docker/cli/badge)](https://scorecard.dev/viewer/?uri=github.com/docker/cli)
[![Codecov](https://img.shields.io/codecov/c/github/docker/cli?logo=codecov)](https://codecov.io/gh/docker/cli)
@@ -51,6 +50,18 @@ Run test:
docker buildx bake test
```
Run the unit test:
```
$ make -f docker.Makefile test-unit
```
Run the full test suite:
```
$ make -f docker.Makefile test
```
List all the available targets:
```shell
@@ -62,7 +73,7 @@ make help
Start an interactive development environment:
```shell
make -f docker.Makefile shell
make shell
```
## Legal
+1 -1
View File
@@ -1 +1 @@
28.2.0-dev
29.8.0
+2 -1
View File
@@ -8,6 +8,7 @@ import (
"github.com/docker/cli/cli-plugins/metadata"
"github.com/docker/cli/cli-plugins/plugin"
"github.com/docker/cli/cli/command"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@@ -25,7 +26,7 @@ func main() {
Short: "Print the API version of the server",
RunE: func(_ *cobra.Command, _ []string) error {
apiClient := dockerCLI.Client()
ping, err := apiClient.Ping(context.Background())
ping, err := apiClient.Ping(context.Background(), client.PingOptions{})
if err != nil {
return err
}
+85
View File
@@ -0,0 +1,85 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.25
// Package hooks defines the contract between the Docker CLI and CLI plugin hook
// implementations.
//
// # Audience
//
// This package is intended to be imported by CLI plugin implementations that
// implement a "hooks" subcommand, and by the Docker CLI when invoking those
// hooks.
//
// # Contract and wire format
//
// Hook inputs (see [Request]) are serialized as JSON and passed to the plugin hook
// subcommand (currently as a command-line argument). Hook outputs are emitted by
// the plugin as JSON (see [Response]).
//
// # Stability
//
// The types that represent the hook contract ([Request], [Response] and related
// constants) are considered part of Docker CLI's public Go API.
// Fields and values may be extended in a backwards-compatible way (for example,
// adding new fields), but existing fields and their meaning should remain stable.
// Plugins should ignore unknown fields and unknown hook types to remain
// forwards-compatible.
package hooks
// ResponseType is the type of response from the plugin.
type ResponseType int
const (
NextSteps ResponseType = 0
)
// Request is the type representing the information
// that plugins declaring support for hooks get passed when
// being invoked following a CLI command execution.
type Request struct {
// RootCmd is a string representing the matching hook configuration
// which is currently being invoked. If a hook for "docker context"
// is configured and the user executes "docker context ls", the plugin
// is invoked with "context".
RootCmd string `json:"RootCmd,omitzero"`
// Flags contains flags that were set on the command for which the
// hook was invoked. It uses flag names as key, with leading hyphens
// removed ("--flag" and "-flag" are included as "flag" and "f").
//
// Flag values are not included and are set to an empty string,
// except for boolean flags known to the CLI itself, for which
// the value is either "true", or "false".
//
// Plugins can use this information to adjust their [Response]
// based on whether the command triggering the hook was invoked
// with.
Flags map[string]string `json:"Flags,omitzero"`
// CommandError is a string containing the error output (if any)
// of the command for which the hook was invoked.
CommandError string `json:"CommandError,omitzero"`
}
// Response represents a plugin hook response. Plugins
// declaring support for CLI hooks need to print a JSON
// representation of this type when their hook subcommand
// is invoked.
type Response struct {
Type ResponseType `json:"Type"`
Template string `json:"Template,omitzero"`
}
// HookType is the type of response from the plugin.
//
// Deprecated: use [ResponseType] instead.
//
//go:fix inline
type HookType = ResponseType
// HookMessage represents a plugin hook response.
//
// Deprecated: use [Response] instead.
//
//go:fix inline
type HookMessage = Response
+75
View File
@@ -0,0 +1,75 @@
package hooks
import (
"fmt"
)
const (
hookTemplateCommandName = `{{command}}`
hookTemplateFlagValue = `{{flagValue %q}}`
hookTemplateArg = `{{argValue %d}}`
)
// TemplateReplaceSubcommandName returns a hook template string
// that will be replaced by the CLI subcommand being executed
//
// Example:
//
// Response{
// Type: NextSteps,
// Template: "you ran the subcommand: " + TemplateReplaceSubcommandName(),
// }
//
// When being executed after the command:
//
// docker run --name "my-container" alpine
//
// It results in the message:
//
// you ran the subcommand: run
func TemplateReplaceSubcommandName() string {
return hookTemplateCommandName
}
// TemplateReplaceFlagValue returns a hook template string that will be
// replaced with the flags value when printed by the CLI.
//
// Example:
//
// Response{
// Type: NextSteps,
// Template: "you ran a container named: " + TemplateReplaceFlagValue("name"),
// }
//
// when executed after the command:
//
// docker run --name "my-container" alpine
//
// it results in the message:
//
// you ran a container named: my-container
func TemplateReplaceFlagValue(flag string) string {
return fmt.Sprintf(hookTemplateFlagValue, flag)
}
// TemplateReplaceArg takes an index i and returns a hook
// template string that the CLI will replace the template with
// the ith argument after processing the passed flags.
//
// Example:
//
// Response{
// Type: NextSteps,
// Template: "run this image with `docker run " + TemplateReplaceArg(0) + "`",
// }
//
// when being executed after the command:
//
// docker pull alpine
//
// It results in the message:
//
// Run this image with `docker run alpine`
func TemplateReplaceArg(i int) string {
return fmt.Sprintf(hookTemplateArg, i)
}
+50
View File
@@ -0,0 +1,50 @@
package hooks_test
import (
"testing"
"github.com/docker/cli/cli-plugins/hooks"
)
func TestTemplateHelpers(t *testing.T) {
tests := []struct {
doc string
got func() string
want string
}{
{
doc: "subcommand name",
got: hooks.TemplateReplaceSubcommandName,
want: `{{command}}`,
},
{
doc: "flag value",
got: func() string {
return hooks.TemplateReplaceFlagValue("name")
},
want: `{{flagValue "name"}}`,
},
{
doc: "arg",
got: func() string {
return hooks.TemplateReplaceArg(0)
},
want: `{{argValue 0}}`,
},
{
doc: "arg",
got: func() string {
return hooks.TemplateReplaceArg(3)
},
want: `{{argValue 3}}`,
},
}
for _, tc := range tests {
t.Run(tc.doc, func(t *testing.T) {
if got := tc.got(); got != tc.want {
t.Fatalf("expected %q, got %q", tc.want, got)
}
})
}
}
+12 -7
View File
@@ -1,18 +1,23 @@
package hooks
import (
"fmt"
"io"
import "io"
"github.com/morikuni/aec"
const (
whatsNext = "\n\033[1mWhat's next:\033[0m\n"
indent = " "
)
// PrintNextSteps renders list of [NextSteps] messages and writes them
// to out. It is a no-op if messages is empty.
func PrintNextSteps(out io.Writer, messages []string) {
if len(messages) == 0 {
return
}
_, _ = fmt.Fprintln(out, aec.Bold.Apply("\nWhat's next:"))
for _, n := range messages {
_, _ = fmt.Fprintln(out, " ", n)
_, _ = io.WriteString(out, whatsNext)
for _, msg := range messages {
_, _ = io.WriteString(out, indent)
_, _ = io.WriteString(out, msg)
_, _ = io.WriteString(out, "\n")
}
}
+19 -12
View File
@@ -1,38 +1,45 @@
package hooks
package hooks_test
import (
"bytes"
"strings"
"testing"
"github.com/morikuni/aec"
"github.com/docker/cli/cli-plugins/hooks"
"gotest.tools/v3/assert"
)
func TestPrintHookMessages(t *testing.T) {
testCases := []struct {
const header = "\n\x1b[1mWhat's next:\x1b[0m\n"
tests := []struct {
doc string
messages []string
expectedOutput string
}{
{
messages: []string{},
doc: "no messages",
messages: nil,
expectedOutput: "",
},
{
doc: "single message",
messages: []string{"Bork!"},
expectedOutput: aec.Bold.Apply("\nWhat's next:") + "\n" +
expectedOutput: header +
" Bork!\n",
},
{
doc: "multiple messages",
messages: []string{"Foo", "bar"},
expectedOutput: aec.Bold.Apply("\nWhat's next:") + "\n" +
expectedOutput: header +
" Foo\n" +
" bar\n",
},
}
for _, tc := range testCases {
w := bytes.Buffer{}
PrintNextSteps(&w, tc.messages)
assert.Equal(t, w.String(), tc.expectedOutput)
for _, tc := range tests {
t.Run(tc.doc, func(t *testing.T) {
var w strings.Builder
hooks.PrintNextSteps(&w, tc.messages)
assert.Equal(t, w.String(), tc.expectedOutput)
})
}
}
+68 -89
View File
@@ -1,116 +1,95 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.25
package hooks
import (
"bytes"
"errors"
"fmt"
"strconv"
"strings"
"text/template"
"github.com/spf13/cobra"
)
type HookType int
const (
NextSteps = iota
)
// HookMessage represents a plugin hook response. Plugins
// declaring support for CLI hooks need to print a json
// representation of this type when their hook subcommand
// is invoked.
type HookMessage struct {
Type HookType
Template string
}
// TemplateReplaceSubcommandName returns a hook template string
// that will be replaced by the CLI subcommand being executed
//
// Example:
//
// "you ran the subcommand: " + TemplateReplaceSubcommandName()
//
// when being executed after the command:
// `docker run --name "my-container" alpine`
// will result in the message:
// `you ran the subcommand: run`
func TemplateReplaceSubcommandName() string {
return hookTemplateCommandName
}
// TemplateReplaceFlagValue returns a hook template string
// that will be replaced by the flags value.
//
// Example:
//
// "you ran a container named: " + TemplateReplaceFlagValue("name")
//
// when being executed after the command:
// `docker run --name "my-container" alpine`
// will result in the message:
// `you ran a container named: my-container`
func TemplateReplaceFlagValue(flag string) string {
return fmt.Sprintf(hookTemplateFlagValue, flag)
}
// TemplateReplaceArg takes an index i and returns a hook
// template string that the CLI will replace the template with
// the ith argument, after processing the passed flags.
//
// Example:
//
// "run this image with `docker run " + TemplateReplaceArg(0) + "`"
//
// when being executed after the command:
// `docker pull alpine`
// will result in the message:
// "Run this image with `docker run alpine`"
func TemplateReplaceArg(i int) string {
return fmt.Sprintf(hookTemplateArg, strconv.Itoa(i))
}
const maxMessages = 10
func ParseTemplate(hookTemplate string, cmd *cobra.Command) ([]string, error) {
tmpl := template.New("").Funcs(commandFunctions)
tmpl, err := tmpl.Parse(hookTemplate)
if err != nil {
return nil, err
out := hookTemplate
if strings.Contains(hookTemplate, "{{") {
// Message may be a template.
msgContext := commandInfo{cmd: cmd}
tmpl, err := template.New("").Funcs(template.FuncMap{
"command": msgContext.command,
"flagValue": msgContext.flagValue,
"argValue": msgContext.argValue,
// kept for backward-compatibility with old templates.
"flag": func(_ any, flagName string) (string, error) { return msgContext.flagValue(flagName) },
"arg": func(_ any, i int) (string, error) { return msgContext.argValue(i) },
}).Parse(hookTemplate)
if err != nil {
return nil, err
}
var b bytes.Buffer
err = tmpl.Execute(&b, msgContext)
if err != nil {
return nil, err
}
out = b.String()
}
b := bytes.Buffer{}
err = tmpl.Execute(&b, cmd)
if err != nil {
return nil, err
if n := strings.Count(out, "\n"); n > maxMessages {
return nil, fmt.Errorf("hook template contains too many messages (%d): maximum is %d", n, maxMessages)
}
return strings.Split(b.String(), "\n"), nil
return strings.SplitN(out, "\n", maxMessages), nil
}
var ErrHookTemplateParse = errors.New("failed to parse hook template")
const (
hookTemplateCommandName = "{{.Name}}"
hookTemplateFlagValue = `{{flag . "%s"}}`
hookTemplateArg = "{{arg . %s}}"
)
var commandFunctions = template.FuncMap{
"flag": getFlagValue,
"arg": getArgValue,
// commandInfo provides info about the command for which the hook was invoked.
// It is used for templated hook-messages.
type commandInfo struct {
cmd *cobra.Command
}
func getFlagValue(cmd *cobra.Command, flag string) (string, error) {
cmdFlag := cmd.Flag(flag)
if cmdFlag == nil {
return "", ErrHookTemplateParse
// Name returns the name of the (sub)command for which the hook was invoked.
//
// It's used for backward-compatibility with old templates.
func (c commandInfo) Name() string {
return c.command()
}
// command returns the name of the (sub)command for which the hook was invoked.
func (c commandInfo) command() string {
if c.cmd == nil {
return ""
}
return cmdFlag.Value.String(), nil
return c.cmd.Name()
}
func getArgValue(cmd *cobra.Command, i int) (string, error) {
flags := cmd.Flags()
if flags == nil {
return "", ErrHookTemplateParse
// flagValue returns the value that was set for the given flag when the hook was invoked.
func (c commandInfo) flagValue(flagName string) (string, error) {
if c.cmd == nil {
return "", fmt.Errorf("%w: flagValue: cmd is nil", ErrHookTemplateParse)
}
return flags.Arg(i), nil
f := c.cmd.Flag(flagName)
if f == nil {
return "", fmt.Errorf("%w: flagValue: no flags found", ErrHookTemplateParse)
}
return f.Value.String(), nil
}
// argValue returns the value of the nth argument.
func (c commandInfo) argValue(n int) (string, error) {
if c.cmd == nil {
return "", fmt.Errorf("%w: arg: cmd is nil", ErrHookTemplateParse)
}
flags := c.cmd.Flags()
v := flags.Arg(n)
if v == "" && n >= flags.NArg() {
return "", fmt.Errorf("%w: arg: %dth argument not set", ErrHookTemplateParse, n)
}
return v, nil
}
+64 -25
View File
@@ -1,43 +1,67 @@
package hooks
package hooks_test
import (
"testing"
"github.com/docker/cli/cli-plugins/hooks"
"github.com/spf13/cobra"
"gotest.tools/v3/assert"
)
// TestParseTemplate tests parsing templates as returned by plugins.
//
// It uses fixed string fixtures to lock in compatibility with existing
// plugin templates, so older formats continue to work even if we add new
// template forms.
//
// For helper-backed cases, it also verifies that templates produced by the
// current TemplateReplace* helpers parse to the same output. This lets us
// evolve the emitted template format without breaking older plugins.
func TestParseTemplate(t *testing.T) {
type testFlag struct {
name string
value string
}
testCases := []struct {
template string
tests := []struct {
doc string
template string // compatibility fixture; keep even if helpers emit a newer form
templateFunc func() string
flags []testFlag
args []string
expectedOutput []string
}{
{
doc: "empty template",
template: "",
expectedOutput: []string{""},
},
{
doc: "plain message",
template: "a plain template message",
expectedOutput: []string{"a plain template message"},
},
{
template: TemplateReplaceFlagValue("tag"),
doc: "subcommand name",
template: "hello {{.Name}}", // NOTE: fixture; do not modify without considering plugin compatibility
templateFunc: func() string { return "hello " + hooks.TemplateReplaceSubcommandName() },
expectedOutput: []string{"hello pull"},
},
{
doc: "single flag",
template: `{{flag . "tag"}}`, // NOTE: fixture; do not modify without considering plugin compatibility
templateFunc: func() string { return hooks.TemplateReplaceFlagValue("tag") },
flags: []testFlag{
{
name: "tag",
value: "my-tag",
},
{name: "tag", value: "my-tag"},
},
expectedOutput: []string{"my-tag"},
},
{
template: TemplateReplaceFlagValue("test-one") + " " + TemplateReplaceFlagValue("test2"),
doc: "multiple flags",
template: `{{flag . "test-one"}} {{flag . "test2"}}`, // NOTE: fixture; do not modify without considering plugin compatibility
templateFunc: func() string {
return hooks.TemplateReplaceFlagValue("test-one") + " " + hooks.TemplateReplaceFlagValue("test2")
},
flags: []testFlag{
{
name: "test-one",
@@ -51,36 +75,51 @@ func TestParseTemplate(t *testing.T) {
expectedOutput: []string{"value value2"},
},
{
template: TemplateReplaceArg(0) + " " + TemplateReplaceArg(1),
doc: "multiple args",
template: `{{arg . 0}} {{arg . 1}}`, // NOTE: fixture; do not modify without considering plugin compatibility
templateFunc: func() string { return hooks.TemplateReplaceArg(0) + " " + hooks.TemplateReplaceArg(1) },
args: []string{"zero", "one"},
expectedOutput: []string{"zero one"},
},
{
template: "You just pulled " + TemplateReplaceArg(0),
doc: "arg in sentence",
template: "You just pulled {{arg . 0}}", // NOTE: fixture; do not modify without considering plugin compatibility
templateFunc: func() string { return "You just pulled " + hooks.TemplateReplaceArg(0) },
args: []string{"alpine"},
expectedOutput: []string{"You just pulled alpine"},
},
{
doc: "multiline output",
template: "one line\nanother line!",
expectedOutput: []string{"one line", "another line!"},
},
}
for _, tc := range testCases {
testCmd := &cobra.Command{
Use: "pull",
Args: cobra.ExactArgs(len(tc.args)),
}
for _, f := range tc.flags {
_ = testCmd.Flags().String(f.name, "", "")
err := testCmd.Flag(f.name).Value.Set(f.value)
for _, tc := range tests {
t.Run(tc.doc, func(t *testing.T) {
testCmd := &cobra.Command{
Use: "pull",
Args: cobra.ExactArgs(len(tc.args)),
}
for _, f := range tc.flags {
_ = testCmd.Flags().String(f.name, "", "")
err := testCmd.Flag(f.name).Value.Set(f.value)
assert.NilError(t, err)
}
err := testCmd.Flags().Parse(tc.args)
assert.NilError(t, err)
}
err := testCmd.Flags().Parse(tc.args)
assert.NilError(t, err)
out, err := ParseTemplate(tc.template, testCmd)
assert.NilError(t, err)
assert.DeepEqual(t, out, tc.expectedOutput)
// Validate using fixtures.
out, err := hooks.ParseTemplate(tc.template, testCmd)
assert.NilError(t, err)
assert.DeepEqual(t, out, tc.expectedOutput)
if tc.templateFunc != nil {
// Validate using the current template function equivalent.
out, err = hooks.ParseTemplate(tc.templateFunc(), testCmd)
assert.NilError(t, err)
assert.DeepEqual(t, out, tc.expectedOutput)
}
})
}
}
-30
View File
@@ -1,30 +0,0 @@
package manager
import "github.com/docker/cli/cli-plugins/metadata"
const (
// CommandAnnotationPlugin is added to every stub command added by
// AddPluginCommandStubs with the value "true" and so can be
// used to distinguish plugin stubs from regular commands.
CommandAnnotationPlugin = metadata.CommandAnnotationPlugin
// CommandAnnotationPluginVendor is added to every stub command
// added by AddPluginCommandStubs and contains the vendor of
// that plugin.
CommandAnnotationPluginVendor = metadata.CommandAnnotationPluginVendor
// CommandAnnotationPluginVersion is added to every stub command
// added by AddPluginCommandStubs and contains the version of
// that plugin.
CommandAnnotationPluginVersion = metadata.CommandAnnotationPluginVersion
// CommandAnnotationPluginInvalid is added to any stub command
// added by AddPluginCommandStubs for an invalid command (that
// is, one which failed it's candidate test) and contains the
// reason for the failure.
CommandAnnotationPluginInvalid = metadata.CommandAnnotationPluginInvalid
// CommandAnnotationPluginCommandPath is added to overwrite the
// command path for a plugin invocation.
CommandAnnotationPluginCommandPath = metadata.CommandAnnotationPluginCommandPath
)
-6
View File
@@ -6,12 +6,6 @@ import (
"github.com/docker/cli/cli-plugins/metadata"
)
// Candidate represents a possible plugin candidate, for mocking purposes
type Candidate interface {
Path() string
Metadata() ([]byte, error)
}
type candidate struct {
path string
}
+97 -27
View File
@@ -32,14 +32,12 @@ func (c *fakeCandidate) Metadata() ([]byte, error) {
func TestValidateCandidate(t *testing.T) {
const (
goodPluginName = metadata.NamePrefix + "goodplugin"
builtinName = metadata.NamePrefix + "builtin"
builtinAlias = metadata.NamePrefix + "alias"
builtinName = metadata.NamePrefix + "builtin"
builtinAlias = metadata.NamePrefix + "alias"
badPrefixPath = "/usr/local/libexec/cli-plugins/wobble"
badNamePath = "/usr/local/libexec/cli-plugins/docker-123456"
goodPluginPath = "/usr/local/libexec/cli-plugins/" + goodPluginName
metaExperimental = `{"SchemaVersion": "0.1.0", "Vendor": "e2e-testing", "Experimental": true}`
badPrefixPath = "/usr/local/libexec/cli-plugins/wobble"
badNamePath = "/usr/local/libexec/cli-plugins/docker-123456"
goodPluginPath = "/usr/local/libexec/cli-plugins/" + goodPluginName
)
fakeroot := &cobra.Command{Use: "docker"}
@@ -51,42 +49,114 @@ func TestValidateCandidate(t *testing.T) {
})
for _, tc := range []struct {
name string
c *fakeCandidate
name string
plugin *fakeCandidate
// Either err or invalid may be non-empty, but not both (both can be empty for a good plugin).
err string
invalid string
expVer string
}{
/* Each failing one of the tests */
{name: "empty path", c: &fakeCandidate{path: ""}, err: "plugin candidate path cannot be empty"},
{name: "bad prefix", c: &fakeCandidate{path: badPrefixPath}, err: fmt.Sprintf("does not have %q prefix", metadata.NamePrefix)},
{name: "bad path", c: &fakeCandidate{path: badNamePath}, invalid: "did not match"},
{name: "builtin command", c: &fakeCandidate{path: builtinName}, invalid: `plugin "builtin" duplicates builtin command`},
{name: "builtin alias", c: &fakeCandidate{path: builtinAlias}, invalid: `plugin "alias" duplicates an alias of builtin command "builtin"`},
{name: "fetch failure", c: &fakeCandidate{path: goodPluginPath, exec: false}, invalid: fmt.Sprintf("failed to fetch metadata: faked a failure to exec %q", goodPluginPath)},
{name: "metadata not json", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `xyzzy`}, invalid: "invalid character"},
{name: "empty schemaversion", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{}`}, invalid: `plugin SchemaVersion "" is not valid`},
{name: "invalid schemaversion", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "xyzzy"}`}, invalid: `plugin SchemaVersion "xyzzy" is not valid`},
{name: "no vendor", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0"}`}, invalid: "plugin metadata does not define a vendor"},
{name: "empty vendor", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0", "Vendor": ""}`}, invalid: "plugin metadata does not define a vendor"},
// This one should work
{name: "valid", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0", "Vendor": "e2e-testing"}`}},
{name: "experimental + allowing experimental", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: metaExperimental}},
// Invalid cases.
{
name: "empty path",
plugin: &fakeCandidate{path: ""},
err: "plugin candidate path cannot be empty",
},
{
name: "bad prefix",
plugin: &fakeCandidate{path: badPrefixPath},
err: fmt.Sprintf("does not have %q prefix", metadata.NamePrefix),
},
{
name: "bad path",
plugin: &fakeCandidate{path: badNamePath},
invalid: "did not match",
},
{
name: "builtin command",
plugin: &fakeCandidate{path: builtinName},
invalid: `plugin "builtin" duplicates builtin command`,
},
{
name: "builtin alias",
plugin: &fakeCandidate{path: builtinAlias},
invalid: `plugin "alias" duplicates an alias of builtin command "builtin"`,
},
{
name: "fetch failure",
plugin: &fakeCandidate{path: goodPluginPath, exec: false},
invalid: fmt.Sprintf("failed to fetch metadata: faked a failure to exec %q", goodPluginPath),
},
{
name: "metadata not json",
plugin: &fakeCandidate{path: goodPluginPath, exec: true, meta: `xyzzy`},
invalid: "invalid character",
},
{
name: "empty schemaversion",
plugin: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{}`},
invalid: `plugin SchemaVersion version cannot be empty`,
},
{
name: "invalid schemaversion",
plugin: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "xyzzy"}`},
invalid: `plugin SchemaVersion "xyzzy" has wrong format: must be <major>.<minor>.<patch>`,
},
{
name: "invalid schemaversion major",
plugin: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "2.0.0"}`},
invalid: `plugin SchemaVersion "2.0.0" is not supported: must be lower than 2.0.0`,
},
{
name: "no vendor",
plugin: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0"}`},
invalid: "plugin metadata does not define a vendor",
},
{
name: "empty vendor",
plugin: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0", "Vendor": ""}`},
invalid: "plugin metadata does not define a vendor",
},
// Valid cases.
{
name: "valid",
plugin: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0", "Vendor": "e2e-testing"}`},
expVer: "0.1.0",
},
{
// Including the deprecated "experimental" field should not break processing.
name: "with legacy experimental",
plugin: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0", "Vendor": "e2e-testing", "Experimental": true}`},
expVer: "0.1.0",
},
{
// note that this may not be supported by older CLIs
name: "new minor schema version",
plugin: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.2.0", "Vendor": "e2e-testing"}`},
expVer: "0.2.0",
},
{
// note that this may not be supported by older CLIs
name: "new major schema version",
plugin: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "1.0.0", "Vendor": "e2e-testing"}`},
expVer: "1.0.0",
},
} {
t.Run(tc.name, func(t *testing.T) {
p, err := newPlugin(tc.c, fakeroot.Commands())
p, err := newPlugin(tc.plugin, fakeroot.Commands())
switch {
case tc.err != "":
assert.ErrorContains(t, err, tc.err)
case tc.invalid != "":
assert.NilError(t, err)
assert.Assert(t, is.ErrorType(p.Err, reflect.TypeOf(&pluginError{})))
assert.Assert(t, is.ErrorType(p.Err, reflect.TypeFor[*pluginError]()))
assert.ErrorContains(t, p.Err, tc.invalid)
default:
assert.NilError(t, err)
assert.Equal(t, metadata.NamePrefix+p.Name, goodPluginName)
assert.Equal(t, p.SchemaVersion, "0.1.0")
assert.Equal(t, p.SchemaVersion, tc.expVer)
assert.Equal(t, p.Vendor, "e2e-testing")
}
})
+7 -3
View File
@@ -38,14 +38,14 @@ func AddPluginCommandStubs(dockerCLI config.Provider, rootCmd *cobra.Command) (e
rootCmd.AddCommand(&cobra.Command{
Use: p.Name,
Short: p.ShortDescription,
Hidden: p.Hidden,
Run: func(_ *cobra.Command, _ []string) {},
Annotations: annotations,
DisableFlagParsing: true,
RunE: func(cmd *cobra.Command, args []string) error {
flags := rootCmd.PersistentFlags()
flags.SetOutput(nil)
perr := flags.Parse(args)
if perr != nil {
if err := flags.Parse(args); err != nil {
return err
}
if flags.Changed("help") {
@@ -56,10 +56,14 @@ func AddPluginCommandStubs(dockerCLI config.Provider, rootCmd *cobra.Command) (e
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
// Delegate completion to plugin
cargs := []string{p.Path, cobra.ShellCompRequestCmd, p.Name}
cargs := []string{p.Path, cobra.ShellCompRequestCmd, p.Name} //nolint:prealloc // no need to over-complicate things.
cargs = append(cargs, args...)
cargs = append(cargs, toComplete)
origArgs := os.Args
os.Args = cargs
defer func() {
os.Args = origArgs
}()
runCommand, runErr := PluginRunCommand(dockerCLI, p.Name, cmd)
if runErr != nil {
return nil, cobra.ShellCompDirectiveError
+59
View File
@@ -1,8 +1,12 @@
package manager
import (
"os"
"path/filepath"
"sync"
"testing"
"github.com/docker/cli/internal/test"
"github.com/spf13/cobra"
"gotest.tools/v3/assert"
)
@@ -24,3 +28,58 @@ func TestPluginResourceAttributesEnvvar(t *testing.T) {
env = appendPluginResourceAttributesEnvvar(nil, cmd, Plugin{Name: "compose"})
assert.DeepEqual(t, []string{"OTEL_RESOURCE_ATTRIBUTES=a.b.c=foo,docker.cli.cobra.command_path=docker%20compose"}, env)
}
func TestPluginStubRunEReturnsParseError(t *testing.T) {
cmd, err := preparePluginStubCommand(t)
assert.NilError(t, err)
err = cmd.RunE(cmd, []string{"--definitely-not-a-real-flag"})
assert.ErrorContains(t, err, "unknown flag: --definitely-not-a-real-flag")
}
func TestPluginStubCompletionRestoresOSArgs(t *testing.T) {
cmd, err := preparePluginStubCommand(t)
assert.NilError(t, err)
savedArgs := os.Args
t.Cleanup(func() { os.Args = savedArgs })
originalArgs := []string{"docker", "image", "ls"}
os.Args = append([]string(nil), originalArgs...)
_, directive := cmd.ValidArgsFunction(cmd, []string{"--all"}, "alp")
assert.Equal(t, directive, cobra.ShellCompDirectiveError)
assert.DeepEqual(t, os.Args, originalArgs)
}
func preparePluginStubCommand(t *testing.T) (*cobra.Command, error) {
t.Helper()
pluginCommandStubsOnce = sync.Once{}
tmpDir := t.TempDir()
const cliPlugin = `#!/bin/sh
printf '%s' '{"SchemaVersion":"0.1.0"}'
`
if err := os.WriteFile(filepath.Join(tmpDir, "docker-testplugin"), []byte(cliPlugin), 0o777); err != nil {
return nil, err
}
cli := test.NewFakeCli(nil)
cli.ConfigFile().CLIPluginsExtraDirs = []string{tmpDir}
root := &cobra.Command{Use: "docker"}
root.PersistentFlags().Bool("debug", false, "")
if err := AddPluginCommandStubs(cli, root); err != nil {
return nil, err
}
cmd, _, err := root.Find([]string{"testplugin"})
if err != nil {
return nil, err
}
if cmd == nil {
return nil, os.ErrNotExist
}
return cmd, nil
}
+4 -12
View File
@@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.23
//go:build go1.25
package manager
@@ -23,17 +23,12 @@ func (e *pluginError) Error() string {
return e.cause.Error()
}
// Cause satisfies the errors.causer interface for pluginError.
func (e *pluginError) Cause() error {
return e.cause
}
// Unwrap provides compatibility for Go 1.13 error chains.
func (e *pluginError) Unwrap() error {
return e.cause
}
// MarshalText marshalls the pluginError into a textual form.
// MarshalText marshals the pluginError into a textual form.
func (e *pluginError) MarshalText() (text []byte, err error) {
return []byte(e.cause.Error()), nil
}
@@ -41,14 +36,11 @@ func (e *pluginError) MarshalText() (text []byte, err error) {
// wrapAsPluginError wraps an error in a pluginError with an
// additional message.
func wrapAsPluginError(err error, msg string) error {
if err == nil {
return nil
}
return &pluginError{cause: fmt.Errorf("%s: %w", msg, err)}
}
// NewPluginError creates a new pluginError, analogous to
// newPluginError creates a new pluginError, analogous to
// errors.Errorf.
func NewPluginError(msg string, args ...any) error {
func newPluginError(msg string, args ...any) error {
return &pluginError{cause: fmt.Errorf(msg, args...)}
}
+4 -1
View File
@@ -10,7 +10,7 @@ import (
)
func TestPluginError(t *testing.T) {
err := NewPluginError("new error")
err := newPluginError("new error")
assert.Check(t, is.Error(err, "new error"))
inner := errors.New("testing")
@@ -21,4 +21,7 @@ func TestPluginError(t *testing.T) {
actual, err := json.Marshal(err)
assert.Check(t, err)
assert.Check(t, is.Equal(`"wrapping: testing"`, string(actual)))
err = wrapAsPluginError(nil, "wrapping")
assert.Check(t, is.Error(err, "wrapping: %!w(<nil>)"))
}
+74 -37
View File
@@ -1,8 +1,14 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.25
package manager
import (
"context"
"encoding/json"
"errors"
"fmt"
"strconv"
"strings"
"github.com/docker/cli/cli-plugins/hooks"
@@ -16,15 +22,11 @@ import (
// HookPluginData is the type representing the information
// that plugins declaring support for hooks get passed when
// being invoked following a CLI command execution.
type HookPluginData struct {
// RootCmd is a string representing the matching hook configuration
// which is currently being invoked. If a hook for `docker context` is
// configured and the user executes `docker context ls`, the plugin will
// be invoked with `context`.
RootCmd string
Flags map[string]string
CommandError string
}
//
// Deprecated: use [hooks.Request] instead.
//
//go:fix inline
type HookPluginData = hooks.Request
// RunCLICommandHooks is the entrypoint into the hooks execution flow after
// a main CLI command was executed. It calls the hook subcommand for all
@@ -39,11 +41,11 @@ func RunCLICommandHooks(ctx context.Context, dockerCLI config.Provider, rootCmd,
// RunPluginHooks is the entrypoint for the hooks execution flow
// after a plugin command was just executed by the CLI.
func RunPluginHooks(ctx context.Context, dockerCLI config.Provider, rootCmd, subCommand *cobra.Command, args []string) {
func RunPluginHooks(ctx context.Context, dockerCLI config.Provider, rootCmd, subCommand *cobra.Command, args []string, cmdErrorMessage string) {
commandName := strings.Join(args, " ")
flags := getNaiveFlags(args)
runHooks(ctx, dockerCLI.ConfigFile(), rootCmd, subCommand, commandName, flags, "")
runHooks(ctx, dockerCLI.ConfigFile(), rootCmd, subCommand, commandName, flags, cmdErrorMessage)
}
func runHooks(ctx context.Context, cfg *configfile.ConfigFile, rootCmd, subCommand *cobra.Command, invokedCommand string, flags map[string]string, cmdErrorMessage string) {
@@ -52,11 +54,8 @@ func runHooks(ctx context.Context, cfg *configfile.ConfigFile, rootCmd, subComma
}
func invokeAndCollectHooks(ctx context.Context, cfg *configfile.ConfigFile, rootCmd, subCmd *cobra.Command, subCmdStr string, flags map[string]string, cmdErrorMessage string) []string {
// check if the context was cancelled before invoking hooks
select {
case <-ctx.Done():
if ctx.Err() != nil {
return nil
default:
}
pluginsCfg := cfg.Plugins
@@ -66,47 +65,65 @@ func invokeAndCollectHooks(ctx context.Context, cfg *configfile.ConfigFile, root
pluginDirs := getPluginDirs(cfg)
nextSteps := make([]string, 0, len(pluginsCfg))
for pluginName, pluginCfg := range pluginsCfg {
match, ok := pluginMatch(pluginCfg, subCmdStr)
if !ok {
continue
tryInvokeHook := func(pluginName string, pluginCfg map[string]string) (messages []string, ok bool, err error) {
match, matched := pluginMatch(pluginCfg, subCmdStr, cmdErrorMessage)
if !matched {
return nil, false, nil
}
p, err := getPlugin(pluginName, pluginDirs, rootCmd)
if err != nil {
continue
return nil, false, err
}
hookReturn, err := p.RunHook(ctx, HookPluginData{
resp, err := p.RunHook(ctx, hooks.Request{
RootCmd: match,
Flags: flags,
CommandError: cmdErrorMessage,
})
if err != nil {
// skip misbehaving plugins, but don't halt execution
continue
return nil, false, err
}
var hookMessageData hooks.HookMessage
err = json.Unmarshal(hookReturn, &hookMessageData)
if err != nil {
continue
var message hooks.Response
if err := json.Unmarshal(resp, &message); err != nil {
return nil, false, fmt.Errorf("failed to unmarshal hook response (%q): %w", string(resp), err)
}
// currently the only hook type
if hookMessageData.Type != hooks.NextSteps {
continue
if message.Type != hooks.NextSteps {
return nil, false, errors.New("unexpected hook response type: " + strconv.Itoa(int(message.Type)))
}
processedHook, err := hooks.ParseTemplate(hookMessageData.Template, subCmd)
messages, err = hooks.ParseTemplate(message.Template, subCmd)
if err != nil {
return nil, false, err
}
return messages, true, nil
}
for pluginName, pluginCfg := range pluginsCfg {
messages, ok, err := tryInvokeHook(pluginName, pluginCfg)
if err != nil {
// skip misbehaving plugins, but don't halt execution
logrus.WithFields(logrus.Fields{
"error": err,
"plugin": pluginName,
}).Debug("Plugin hook invocation failed")
continue
}
if !ok {
continue
}
var appended bool
nextSteps, appended = appendNextSteps(nextSteps, processedHook)
nextSteps, appended = appendNextSteps(nextSteps, messages)
if !appended {
logrus.Debugf("Plugin %s responded with an empty hook message %q. Ignoring.", pluginName, string(hookReturn))
logrus.WithFields(logrus.Fields{
"plugin": pluginName,
}).Debug("Plugin responded with an empty hook message; ignoring")
}
}
return nextSteps
@@ -135,14 +152,34 @@ func appendNextSteps(nextSteps []string, processed []string) ([]string, bool) {
// command being executed (such as 'image ls' the root 'docker' is omitted)
// and, if the configuration includes a hook for the invoked command, returns
// the configured hook string.
func pluginMatch(pluginCfg map[string]string, subCmd string) (string, bool) {
configuredPluginHooks, ok := pluginCfg["hooks"]
if !ok || configuredPluginHooks == "" {
//
// Plugins can declare two types of hooks in their configuration:
// - "hooks": fires on every command invocation (success or failure)
// - "error-hooks": fires only when a command fails (cmdErrorMessage is non-empty)
func pluginMatch(pluginCfg map[string]string, subCmd string, cmdErrorMessage string) (string, bool) {
// Check "hooks" first — these always fire regardless of command outcome.
if match, ok := matchHookConfig(pluginCfg["hooks"], subCmd); ok {
return match, true
}
// Check "error-hooks" — these only fire when there was an error.
if cmdErrorMessage != "" {
if match, ok := matchHookConfig(pluginCfg["error-hooks"], subCmd); ok {
return match, true
}
}
return "", false
}
// matchHookConfig checks if a comma-separated hook configuration string
// contains a prefix match for the given subcommand.
func matchHookConfig(configuredHooks string, subCmd string) (string, bool) {
if configuredHooks == "" {
return "", false
}
commands := strings.Split(configuredPluginHooks, ",")
for _, hookCmd := range commands {
for hookCmd := range strings.SplitSeq(configuredHooks, ",") {
if hookMatch(hookCmd, subCmd) {
return hookCmd, true
}
+239 -7
View File
@@ -1,12 +1,23 @@
package manager
import (
"context"
"testing"
"github.com/docker/cli/cli/config/configfile"
"github.com/spf13/cobra"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
type fakeConfigProvider struct {
cfg *configfile.ConfigFile
}
func (f *fakeConfigProvider) ConfigFile() *configfile.ConfigFile {
return f.cfg
}
func TestGetNaiveFlags(t *testing.T) {
testCases := []struct {
args []string
@@ -40,12 +51,15 @@ func TestGetNaiveFlags(t *testing.T) {
func TestPluginMatch(t *testing.T) {
testCases := []struct {
commandString string
pluginConfig map[string]string
expectedMatch string
expectedOk bool
doc string
commandString string
pluginConfig map[string]string
cmdErrorMessage string
expectedMatch string
expectedOk bool
}{
{
doc: "hooks prefix match",
commandString: "image ls",
pluginConfig: map[string]string{
"hooks": "image",
@@ -54,6 +68,7 @@ func TestPluginMatch(t *testing.T) {
expectedOk: true,
},
{
doc: "hooks no match",
commandString: "context ls",
pluginConfig: map[string]string{
"hooks": "build",
@@ -62,6 +77,7 @@ func TestPluginMatch(t *testing.T) {
expectedOk: false,
},
{
doc: "hooks exact match",
commandString: "context ls",
pluginConfig: map[string]string{
"hooks": "context ls",
@@ -70,6 +86,7 @@ func TestPluginMatch(t *testing.T) {
expectedOk: true,
},
{
doc: "hooks first match wins",
commandString: "image ls",
pluginConfig: map[string]string{
"hooks": "image ls,image",
@@ -78,6 +95,7 @@ func TestPluginMatch(t *testing.T) {
expectedOk: true,
},
{
doc: "hooks empty string",
commandString: "image ls",
pluginConfig: map[string]string{
"hooks": "",
@@ -86,6 +104,7 @@ func TestPluginMatch(t *testing.T) {
expectedOk: false,
},
{
doc: "hooks partial token no match",
commandString: "image inspect",
pluginConfig: map[string]string{
"hooks": "image i",
@@ -94,6 +113,7 @@ func TestPluginMatch(t *testing.T) {
expectedOk: false,
},
{
doc: "hooks prefix token match",
commandString: "image inspect",
pluginConfig: map[string]string{
"hooks": "image",
@@ -101,12 +121,140 @@ func TestPluginMatch(t *testing.T) {
expectedMatch: "image",
expectedOk: true,
},
{
doc: "error-hooks match on error",
commandString: "build",
pluginConfig: map[string]string{
"error-hooks": "build",
},
cmdErrorMessage: "exit status 1",
expectedMatch: "build",
expectedOk: true,
},
{
doc: "error-hooks no match on success",
commandString: "build",
pluginConfig: map[string]string{
"error-hooks": "build",
},
cmdErrorMessage: "",
expectedMatch: "",
expectedOk: false,
},
{
doc: "error-hooks prefix match on error",
commandString: "compose up",
pluginConfig: map[string]string{
"error-hooks": "compose",
},
cmdErrorMessage: "exit status 1",
expectedMatch: "compose",
expectedOk: true,
},
{
doc: "error-hooks no match for wrong command",
commandString: "pull",
pluginConfig: map[string]string{
"error-hooks": "build",
},
cmdErrorMessage: "exit status 1",
expectedMatch: "",
expectedOk: false,
},
{
doc: "hooks takes precedence over error-hooks",
commandString: "build",
pluginConfig: map[string]string{
"hooks": "build",
"error-hooks": "build",
},
cmdErrorMessage: "exit status 1",
expectedMatch: "build",
expectedOk: true,
},
{
doc: "hooks fires on success even with error-hooks configured",
commandString: "build",
pluginConfig: map[string]string{
"hooks": "build",
"error-hooks": "build",
},
cmdErrorMessage: "",
expectedMatch: "build",
expectedOk: true,
},
{
doc: "error-hooks with multiple commands",
commandString: "compose up",
pluginConfig: map[string]string{
"error-hooks": "build,compose up,pull",
},
cmdErrorMessage: "exit status 1",
expectedMatch: "compose up",
expectedOk: true,
},
}
for _, tc := range testCases {
match, ok := pluginMatch(tc.pluginConfig, tc.commandString)
assert.Equal(t, ok, tc.expectedOk)
assert.Equal(t, match, tc.expectedMatch)
t.Run(tc.doc, func(t *testing.T) {
match, ok := pluginMatch(tc.pluginConfig, tc.commandString, tc.cmdErrorMessage)
assert.Equal(t, ok, tc.expectedOk)
assert.Equal(t, match, tc.expectedMatch)
})
}
}
func TestMatchHookConfig(t *testing.T) {
testCases := []struct {
doc string
configuredHooks string
subCmd string
expectedMatch string
expectedOk bool
}{
{
doc: "empty config",
configuredHooks: "",
subCmd: "build",
expectedMatch: "",
expectedOk: false,
},
{
doc: "exact match",
configuredHooks: "build",
subCmd: "build",
expectedMatch: "build",
expectedOk: true,
},
{
doc: "prefix match",
configuredHooks: "image",
subCmd: "image ls",
expectedMatch: "image",
expectedOk: true,
},
{
doc: "comma-separated match",
configuredHooks: "pull,build,push",
subCmd: "build",
expectedMatch: "build",
expectedOk: true,
},
{
doc: "no match",
configuredHooks: "pull,push",
subCmd: "build",
expectedMatch: "",
expectedOk: false,
},
}
for _, tc := range testCases {
t.Run(tc.doc, func(t *testing.T) {
match, ok := matchHookConfig(tc.configuredHooks, tc.subCmd)
assert.Equal(t, ok, tc.expectedOk)
assert.Equal(t, match, tc.expectedMatch)
})
}
}
@@ -141,3 +289,87 @@ func TestAppendNextSteps(t *testing.T) {
})
}
}
func TestRunPluginHooksPassesErrorMessage(t *testing.T) {
cfg := configfile.New("")
cfg.Plugins = map[string]map[string]string{
"test-plugin": {"hooks": "build"},
}
provider := &fakeConfigProvider{cfg: cfg}
root := &cobra.Command{Use: "docker"}
sub := &cobra.Command{Use: "build"}
root.AddCommand(sub)
// Should not panic with empty error message (success case)
RunPluginHooks(context.Background(), provider, root, sub, []string{"build"}, "")
// Should not panic with non-empty error message (failure case)
RunPluginHooks(context.Background(), provider, root, sub, []string{"build"}, "exit status 1")
}
func TestRunPluginHooksErrorHooks(t *testing.T) {
cfg := configfile.New("")
cfg.Plugins = map[string]map[string]string{
"test-plugin": {"error-hooks": "build"},
}
provider := &fakeConfigProvider{cfg: cfg}
root := &cobra.Command{Use: "docker"}
sub := &cobra.Command{Use: "build"}
root.AddCommand(sub)
// Should not panic — error-hooks with error message
RunPluginHooks(context.Background(), provider, root, sub, []string{"build"}, "exit status 1")
// Should not panic — error-hooks with no error (should be skipped)
RunPluginHooks(context.Background(), provider, root, sub, []string{"build"}, "")
}
func TestInvokeAndCollectHooksErrorHooksSkippedOnSuccess(t *testing.T) {
cfg := configfile.New("")
cfg.Plugins = map[string]map[string]string{
"nonexistent": {"error-hooks": "build"},
}
root := &cobra.Command{Use: "docker"}
sub := &cobra.Command{Use: "build"}
root.AddCommand(sub)
// On success, error-hooks should not match, so the plugin
// binary is never looked up and no results are returned.
result := invokeAndCollectHooks(
context.Background(), cfg, root, sub,
"build", map[string]string{}, "",
)
assert.Check(t, is.Len(result, 0))
}
func TestInvokeAndCollectHooksNoPlugins(t *testing.T) {
cfg := configfile.New("")
root := &cobra.Command{Use: "docker"}
sub := &cobra.Command{Use: "build"}
root.AddCommand(sub)
result := invokeAndCollectHooks(
context.Background(), cfg, root, sub,
"build", map[string]string{}, "some error",
)
assert.Check(t, is.Len(result, 0))
}
func TestInvokeAndCollectHooksCancelledContext(t *testing.T) {
cfg := configfile.New("")
cfg.Plugins = map[string]map[string]string{
"test-plugin": {"hooks": "build"},
}
root := &cobra.Command{Use: "docker"}
sub := &cobra.Command{Use: "build"}
root.AddCommand(sub)
ctx, cancel := context.WithCancel(context.Background())
cancel() // cancel immediately
result := invokeAndCollectHooks(
ctx, cfg, root, sub,
"build", map[string]string{}, "exit status 1",
)
assert.Check(t, is.Nil(result))
}
+20 -34
View File
@@ -2,6 +2,7 @@ package manager
import (
"context"
"errors"
"os"
"os/exec"
"path/filepath"
@@ -9,28 +10,16 @@ import (
"strings"
"sync"
"github.com/containerd/errdefs"
"github.com/docker/cli/cli-plugins/metadata"
"github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/debug"
"github.com/fvbommel/sortorder"
"github.com/spf13/cobra"
"golang.org/x/sync/errgroup"
)
const (
// ReexecEnvvar is the name of an ennvar which is set to the command
// used to originally invoke the docker CLI when executing a
// plugin. Assuming $PATH and $CWD remain unchanged this should allow
// the plugin to re-execute the original CLI.
ReexecEnvvar = metadata.ReexecEnvvar
// ResourceAttributesEnvvar is the name of the envvar that includes additional
// resource attributes for OTEL.
//
// Deprecated: The "OTEL_RESOURCE_ATTRIBUTES" env-var is part of the OpenTelemetry specification; users should define their own const for this. This const will be removed in the next release.
ResourceAttributesEnvvar = "OTEL_RESOURCE_ATTRIBUTES"
)
// errPluginNotFound is the error returned when a plugin could not be found.
type errPluginNotFound string
@@ -40,17 +29,6 @@ func (e errPluginNotFound) Error() string {
return "Error: No such CLI plugin: " + string(e)
}
type notFound interface{ NotFound() }
// IsNotFound is true if the given error is due to a plugin not being found.
func IsNotFound(err error) bool {
if e, ok := err.(*pluginError); ok {
err = e.Cause()
}
_, ok := err.(notFound)
return ok
}
// getPluginDirs returns the platform-specific locations to search for plugins
// in order of preference.
//
@@ -81,9 +59,17 @@ func addPluginCandidatesFromDir(res map[string][]string, d string) {
return
}
for _, dentry := range dentries {
switch dentry.Type() & os.ModeType { //nolint:exhaustive,nolintlint // no need to include all possible file-modes in this list
case 0, os.ModeSymlink:
// Regular file or symlink, keep going
switch mode := dentry.Type() & os.ModeType; mode { //nolint:exhaustive,nolintlint // no need to include all possible file-modes in this list
case os.ModeSymlink:
if !debug.IsEnabled() {
// Skip broken symlinks unless debug is enabled. With debug
// enabled, this will print a warning in "docker info".
if _, err := os.Stat(filepath.Join(d, dentry.Name())); errors.Is(err, os.ErrNotExist) {
continue
}
}
case 0:
// Regular file, keep going
default:
// Something else, ignore.
continue
@@ -127,7 +113,7 @@ func getPlugin(name string, pluginDirs []string, rootcmd *cobra.Command) (*Plugi
if err != nil {
return nil, err
}
if !IsNotFound(p.Err) {
if !errdefs.IsNotFound(p.Err) {
p.ShadowedPaths = paths[1:]
}
return &p, nil
@@ -164,7 +150,7 @@ func ListPlugins(dockerCli config.Provider, rootcmd *cobra.Command) ([]Plugin, e
if err != nil {
return err
}
if !IsNotFound(p.Err) {
if !errdefs.IsNotFound(p.Err) {
p.ShadowedPaths = paths[1:]
mu.Lock()
defer mu.Unlock()
@@ -185,15 +171,15 @@ func ListPlugins(dockerCli config.Provider, rootcmd *cobra.Command) ([]Plugin, e
return plugins, nil
}
// PluginRunCommand returns an "os/exec".Cmd which when .Run() will execute the named plugin.
// The rootcmd argument is referenced to determine the set of builtin commands in order to detect conficts.
// The error returned satisfies the IsNotFound() predicate if no plugin was found or if the first candidate plugin was invalid somehow.
// PluginRunCommand returns an [os/exec.Cmd] which when [os/exec.Cmd.Run] will execute the named plugin.
// The rootcmd argument is referenced to determine the set of builtin commands in order to detect conflicts.
// The error returned satisfies the [errdefs.IsNotFound] predicate if no plugin was found or if the first candidate plugin was invalid somehow.
func PluginRunCommand(dockerCli config.Provider, name string, rootcmd *cobra.Command) (*exec.Cmd, error) {
// This uses the full original args, not the args which may
// have been provided by cobra to our caller. This is because
// they lack e.g. global options which we must propagate here.
args := os.Args[1:]
if !pluginNameRe.MatchString(name) {
if !isValidPluginName(name) {
// We treat this as "not found" so that callers will
// fallback to their "invalid" command path.
return nil, errPluginNotFound(name)
+8 -11
View File
@@ -5,6 +5,7 @@ import (
"strings"
"testing"
"github.com/containerd/errdefs"
"github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test"
@@ -37,7 +38,7 @@ func TestListPluginCandidates(t *testing.T) {
"plugins3-target", // Will be referenced as a symlink from below
fs.WithFile("docker-plugin1", ""),
fs.WithDir("ignored3"),
fs.WithSymlink("docker-brokensymlink", "broken"), // A broken symlink is still a candidate (but would fail tests later)
fs.WithSymlink("docker-brokensymlink", "broken"), // A broken symlink is ignored
fs.WithFile("non-plugin-symlinked", ""), // This shouldn't appear, but ...
fs.WithSymlink("docker-symlinked", "non-plugin-symlinked"), // ... this link to it should.
),
@@ -71,9 +72,6 @@ func TestListPluginCandidates(t *testing.T) {
"hardlink2": {
dir.Join("plugins2", "docker-hardlink2"),
},
"brokensymlink": {
dir.Join("plugins3", "docker-brokensymlink"),
},
"symlinked": {
dir.Join("plugins3", "docker-symlinked"),
},
@@ -91,7 +89,7 @@ func TestListPluginCandidatesEmpty(t *testing.T) {
// Regression test for https://github.com/docker/cli/issues/5643.
// Check that inaccessible directories that come before accessible ones are ignored
// and do not prevent the latter from being processed.
func TestListPluginCandidatesInaccesibleDir(t *testing.T) {
func TestListPluginCandidatesInaccessibleDir(t *testing.T) {
dir := fs.NewDir(t, t.Name(),
fs.WithDir("no-perm", fs.WithMode(0)),
fs.WithDir("plugins",
@@ -131,7 +129,7 @@ echo '{"SchemaVersion":"0.1.0"}'`, fs.WithMode(0o777)),
_, err = GetPlugin("ccc", cli, &cobra.Command{})
assert.Error(t, err, "Error: No such CLI plugin: ccc")
assert.Assert(t, IsNotFound(err))
assert.Assert(t, errdefs.IsNotFound(err))
}
func TestListPluginsIsSorted(t *testing.T) {
@@ -166,8 +164,8 @@ func TestErrPluginNotFound(t *testing.T) {
var err error = errPluginNotFound("test")
err.(errPluginNotFound).NotFound()
assert.Error(t, err, "Error: No such CLI plugin: test")
assert.Assert(t, IsNotFound(err))
assert.Assert(t, !IsNotFound(nil))
assert.Assert(t, errdefs.IsNotFound(err))
assert.Assert(t, !errdefs.IsNotFound(nil))
}
func TestGetPluginDirs(t *testing.T) {
@@ -179,9 +177,8 @@ func TestGetPluginDirs(t *testing.T) {
pluginDirs := getPluginDirs(cli.ConfigFile())
assert.Equal(t, strings.Join(expected, ":"), strings.Join(pluginDirs, ":"))
extras := []string{
"foo", "bar", "baz",
}
extras := make([]string, 0, 3+len(expected))
extras = append(extras, "foo", "bar", "baz")
expected = append(extras, expected...)
cli.SetConfigFile(&configfile.ConfigFile{
CLIPluginsExtraDirs: extras,
-1
View File
@@ -16,6 +16,5 @@ import (
//
// [ConfigFile.CLIPluginsExtraDirs]: https://pkg.go.dev/github.com/docker/cli@v26.1.4+incompatible/cli/config/configfile#ConfigFile.CLIPluginsExtraDirs
var defaultSystemPluginDirs = []string{
filepath.Join(os.Getenv("ProgramData"), "Docker", "cli-plugins"),
filepath.Join(os.Getenv("ProgramFiles"), "Docker", "cli-plugins"),
}
-23
View File
@@ -1,23 +0,0 @@
package manager
import (
"github.com/docker/cli/cli-plugins/metadata"
)
const (
// NamePrefix is the prefix required on all plugin binary names
NamePrefix = metadata.NamePrefix
// MetadataSubcommandName is the name of the plugin subcommand
// which must be supported by every plugin and returns the
// plugin metadata.
MetadataSubcommandName = metadata.MetadataSubcommandName
// HookSubcommandName is the name of the plugin subcommand
// which must be implemented by plugins declaring support
// for hooks in their metadata.
HookSubcommandName = metadata.HookSubcommandName
)
// Metadata provided by the plugin.
type Metadata = metadata.Metadata
+91 -17
View File
@@ -2,21 +2,21 @@ package manager
import (
"context"
"encoding"
"encoding/json"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"github.com/docker/cli/cli-plugins/hooks"
"github.com/docker/cli/cli-plugins/metadata"
"github.com/docker/cli/internal/lazyregexp"
"github.com/spf13/cobra"
)
var pluginNameRe = lazyregexp.New("^[a-z][a-z0-9]*$")
// Plugin represents a potential plugin with all it's metadata.
type Plugin struct {
metadata.Metadata
@@ -31,12 +31,34 @@ type Plugin struct {
ShadowedPaths []string `json:",omitempty"`
}
// MarshalJSON implements [json.Marshaler] to handle marshaling the
// [Plugin.Err] field (Go doesn't marshal errors by default).
func (p *Plugin) MarshalJSON() ([]byte, error) {
type Alias Plugin // avoid recursion
cp := *p // shallow copy to avoid mutating original
if cp.Err != nil {
if _, ok := cp.Err.(encoding.TextMarshaler); !ok {
cp.Err = &pluginError{cp.Err}
}
}
return json.Marshal((*Alias)(&cp))
}
// pluginCandidate represents a possible plugin candidate, for mocking purposes.
type pluginCandidate interface {
Path() string
Metadata() ([]byte, error)
}
// newPlugin determines if the given candidate is valid and returns a
// Plugin. If the candidate fails one of the tests then `Plugin.Err`
// is set, and is always a `pluginError`, but the `Plugin` is still
// returned with no error. An error is only returned due to a
// non-recoverable error.
func newPlugin(c Candidate, cmds []*cobra.Command) (Plugin, error) {
func newPlugin(c pluginCandidate, cmds []*cobra.Command) (Plugin, error) {
path := c.Path()
if path == "" {
return Plugin{}, errors.New("plugin candidate path cannot be empty")
@@ -62,8 +84,8 @@ func newPlugin(c Candidate, cmds []*cobra.Command) (Plugin, error) {
}
// Now apply the candidate tests, so these update p.Err.
if !pluginNameRe.MatchString(p.Name) {
p.Err = NewPluginError("plugin candidate %q did not match %q", p.Name, pluginNameRe.String())
if !isValidPluginName(p.Name) {
p.Err = newPluginError("plugin candidate %q did not match %q", p.Name, pluginNameFormat)
return p, nil
}
@@ -75,11 +97,11 @@ func newPlugin(c Candidate, cmds []*cobra.Command) (Plugin, error) {
continue
}
if cmd.Name() == p.Name {
p.Err = NewPluginError("plugin %q duplicates builtin command", p.Name)
p.Err = newPluginError("plugin %q duplicates builtin command", p.Name)
return p, nil
}
if cmd.HasAlias(p.Name) {
p.Err = NewPluginError("plugin %q duplicates an alias of builtin command %q", p.Name, cmd.Name())
p.Err = newPluginError("plugin %q duplicates an alias of builtin command %q", p.Name, cmd.Name())
return p, nil
}
}
@@ -95,20 +117,45 @@ func newPlugin(c Candidate, cmds []*cobra.Command) (Plugin, error) {
p.Err = wrapAsPluginError(err, "invalid metadata")
return p, nil
}
if p.Metadata.SchemaVersion != "0.1.0" {
p.Err = NewPluginError("plugin SchemaVersion %q is not valid, must be 0.1.0", p.Metadata.SchemaVersion)
if err := validateSchemaVersion(p.Metadata.SchemaVersion); err != nil {
p.Err = &pluginError{cause: err}
return p, nil
}
if p.Metadata.Vendor == "" {
p.Err = NewPluginError("plugin metadata does not define a vendor")
p.Err = newPluginError("plugin metadata does not define a vendor")
return p, nil
}
return p, nil
}
// validateSchemaVersion validates if the plugin's schemaVersion is supported.
//
// The current schema-version is "0.1.0", but we don't want to break compatibility
// until v2.0.0 of the schema version. Check for the major version to be < 2.0.0.
//
// Note that CLI versions before 28.4.1 may not support these versions as they were
// hard-coded to only accept "0.1.0".
func validateSchemaVersion(version string) error {
if version == "0.1.0" {
return nil
}
if version == "" {
return errors.New("plugin SchemaVersion version cannot be empty")
}
major, _, ok := strings.Cut(version, ".")
majorVersion, err := strconv.Atoi(major)
if !ok || err != nil {
return fmt.Errorf("plugin SchemaVersion %q has wrong format: must be <major>.<minor>.<patch>", version)
}
if majorVersion > 1 {
return fmt.Errorf("plugin SchemaVersion %q is not supported: must be lower than 2.0.0", version)
}
return nil
}
// RunHook executes the plugin's hooks command
// and returns its unprocessed output.
func (p *Plugin) RunHook(ctx context.Context, hookData HookPluginData) ([]byte, error) {
func (p *Plugin) RunHook(ctx context.Context, hookData hooks.Request) ([]byte, error) {
hDataBytes, err := json.Marshal(hookData)
if err != nil {
return nil, wrapAsPluginError(err, "failed to marshall hook data")
@@ -117,10 +164,37 @@ func (p *Plugin) RunHook(ctx context.Context, hookData HookPluginData) ([]byte,
pCmd := exec.CommandContext(ctx, p.Path, p.Name, metadata.HookSubcommandName, string(hDataBytes)) // #nosec G204 -- ignore "Subprocess launched with a potential tainted input or cmd arguments"
pCmd.Env = os.Environ()
pCmd.Env = append(pCmd.Env, metadata.ReexecEnvvar+"="+os.Args[0])
hookCmdOutput, err := pCmd.Output()
if err != nil {
return nil, wrapAsPluginError(err, "failed to execute plugin hook subcommand")
}
return hookCmdOutput, nil
out, err := pCmd.Output()
if err != nil {
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
return nil, wrapAsPluginError(err, "plugin hook subcommand exited unsuccessfully")
}
return nil, wrapAsPluginError(err, "failed to execute plugin hook subcommand: "+pCmd.String())
}
return out, nil
}
// pluginNameFormat is used as part of errors for invalid plugin-names.
// We should consider making this less technical ("must start with "a-z",
// and only consist of lowercase alphanumeric characters").
const pluginNameFormat = `^[a-z][a-z0-9]*$`
func isValidPluginName(s string) bool {
if len(s) == 0 {
return false
}
// first character must be a-z
if c := s[0]; c < 'a' || c > 'z' {
return false
}
// followed by a-z or 0-9
for i := 1; i < len(s); i++ {
c := s[i]
if (c < 'a' || c > 'z') && (c < '0' || c > '9') {
return false
}
}
return true
}
+43
View File
@@ -0,0 +1,43 @@
package manager
import (
"encoding/json"
"errors"
"testing"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
func TestPluginMarshal(t *testing.T) {
const jsonWithError = `{"Name":"some-plugin","Err":"something went wrong"}`
const jsonNoError = `{"Name":"some-plugin"}`
tests := []struct {
doc string
error error
expected string
}{
{
doc: "no error",
expected: jsonNoError,
},
{
doc: "regular error",
error: errors.New("something went wrong"),
expected: jsonWithError,
},
{
doc: "custom error",
error: newPluginError("something went wrong"),
expected: jsonWithError,
},
}
for _, tc := range tests {
t.Run(tc.doc, func(t *testing.T) {
actual, err := json.Marshal(&Plugin{Name: "some-plugin", Err: tc.error})
assert.NilError(t, err)
assert.Check(t, is.Equal(string(actual), tc.expected))
})
}
}
+2
View File
@@ -33,4 +33,6 @@ type Metadata struct {
ShortDescription string `json:",omitempty"`
// URL is a pointer to the plugin's homepage.
URL string `json:",omitempty"`
// Hidden hides the plugin in completion and help message output.
Hidden bool `json:",omitempty"`
}
+33 -11
View File
@@ -14,7 +14,7 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/connhelper"
"github.com/docker/cli/cli/debug"
"github.com/docker/docker/client"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
"go.opentelemetry.io/otel"
)
@@ -80,19 +80,23 @@ func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta metadat
return cmd.Execute()
}
// Run is the top-level entry point to the CLI plugin framework. It should be called from your plugin's `main()` function.
func Run(makeCmd func(command.Cli) *cobra.Command, meta metadata.Metadata) {
// Run is the top-level entry point to the CLI plugin framework. It should
// be called from the plugin's "main()" function. It initializes a new
// [command.DockerCli] instance with the given options before calling
// makeCmd to construct the plugin command, then invokes the plugin command
// using [RunPlugin].
func Run(makeCmd func(command.Cli) *cobra.Command, meta metadata.Metadata, ops ...command.CLIOption) {
otel.SetErrorHandler(debug.OTELErrorHandler)
dockerCli, err := command.NewDockerCli()
dockerCLI, err := command.NewDockerCli(ops...)
if err != nil {
fmt.Fprintln(os.Stderr, err)
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
plugin := makeCmd(dockerCli)
plugin := makeCmd(dockerCLI)
if err := RunPlugin(dockerCli, plugin, meta); err != nil {
if err := RunPlugin(dockerCLI, plugin, meta); err != nil {
var stErr cli.StatusError
if errors.As(err, &stErr) {
// StatusError should only be used for errors, and all errors should
@@ -100,10 +104,10 @@ func Run(makeCmd func(command.Cli) *cobra.Command, meta metadata.Metadata) {
if stErr.StatusCode == 0 { // FIXME(thaJeztah): this should never be used with a zero status-code. Check if we do this anywhere.
stErr.StatusCode = 1
}
_, _ = fmt.Fprintln(dockerCli.Err(), stErr)
_, _ = fmt.Fprintln(dockerCLI.Err(), stErr)
os.Exit(stErr.StatusCode)
}
_, _ = fmt.Fprintln(dockerCli.Err(), err)
_, _ = fmt.Fprintln(dockerCLI.Err(), err)
os.Exit(1)
}
}
@@ -135,7 +139,7 @@ func withPluginClientConn(name string) command.CLIOption {
if err != nil {
return err
}
apiClient, err := client.NewClientWithOpts(client.WithDialContext(helper.Dialer))
apiClient, err := client.New(client.WithDialContext(helper.Dialer))
if err != nil {
return err
}
@@ -164,6 +168,11 @@ func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta
DisableDescriptions: os.Getenv("DOCKER_CLI_DISABLE_COMPLETION_DESCRIPTION") != "",
},
}
// Disable file-completion by default. Most commands and flags should not
// complete with filenames.
cmd.CompletionOptions.SetDefaultShellCompDirective(cobra.ShellCompDirectiveNoFileComp)
opts, _ := cli.SetupPluginRootCommand(cmd)
cmd.SetIn(dockerCli.In())
@@ -175,11 +184,24 @@ func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta
newMetadataSubcommand(plugin, meta),
)
cli.DisableFlagsInUseLine(cmd)
visitAll(cmd,
// prevent adding "[flags]" to the end of the usage line.
func(c *cobra.Command) { c.DisableFlagsInUseLine = true },
)
return cli.NewTopLevelCommand(cmd, dockerCli, opts, cmd.Flags())
}
// visitAll traverses all commands from the root.
func visitAll(root *cobra.Command, fns ...func(*cobra.Command)) {
for _, cmd := range root.Commands() {
visitAll(cmd, fns...)
}
for _, fn := range fns {
fn(root)
}
}
func newMetadataSubcommand(plugin *cobra.Command, meta metadata.Metadata) *cobra.Command {
if meta.ShortDescription == "" {
meta.ShortDescription = plugin.Short
+28
View File
@@ -0,0 +1,28 @@
package plugin
import (
"slices"
"testing"
"github.com/spf13/cobra"
)
func TestVisitAll(t *testing.T) {
root := &cobra.Command{Use: "root"}
sub1 := &cobra.Command{Use: "sub1"}
sub1sub1 := &cobra.Command{Use: "sub1sub1"}
sub1sub2 := &cobra.Command{Use: "sub1sub2"}
sub2 := &cobra.Command{Use: "sub2"}
root.AddCommand(sub1, sub2)
sub1.AddCommand(sub1sub1, sub1sub2)
var visited []string
visitAll(root, func(ccmd *cobra.Command) {
visited = append(visited, ccmd.Name())
})
expected := []string{"sub1sub1", "sub1sub2", "sub1", "sub2", "root"}
if !slices.Equal(expected, visited) {
t.Errorf("expected %#v, got %#v", expected, visited)
}
}
+1 -1
View File
@@ -93,7 +93,7 @@ func (pl *PluginServer) Addr() net.Addr {
// Close ensures that the server is no longer accepting new connections and
// closes all existing connections. Existing connections will receive [io.EOF].
//
// The error value is that of the underlying [net.Listner.Close] call.
// The error value is that of the underlying [net.Listener.Close] call.
func (pl *PluginServer) Close() error {
if pl == nil {
return nil
+4 -4
View File
@@ -47,16 +47,16 @@ func TestPluginServer(t *testing.T) {
select {
case err := <-done:
if !errors.Is(err, io.EOF) {
t.Fatalf("exepcted EOF error, got: %v", err)
t.Fatalf("expected EOF error, got: %v", err)
}
case <-time.After(10 * time.Millisecond):
}
})
t.Run("allows reconnects", func(t *testing.T) {
var calls int32
var calls atomic.Int32
h := func(_ net.Conn) {
atomic.AddInt32(&calls, 1)
calls.Add(1)
}
srv, err := NewPluginServer(h)
@@ -70,7 +70,7 @@ func TestPluginServer(t *testing.T) {
waitForCalls := func(n int) {
poll.WaitOn(t, func(t poll.LogT) poll.Result {
if atomic.LoadInt32(&calls) == int32(n) {
if calls.Load() == int32(n) {
return poll.Success()
}
return poll.Continue("waiting for handler to be called")
+7 -39
View File
@@ -12,7 +12,6 @@ import (
"github.com/fvbommel/sortorder"
"github.com/moby/term"
"github.com/morikuni/aec"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
@@ -167,35 +166,6 @@ func (tcmd *TopLevelCommand) Initialize(ops ...command.CLIOption) error {
return tcmd.dockerCli.Initialize(tcmd.opts, ops...)
}
// VisitAll will traverse all commands from the root.
// This is different from the VisitAll of cobra.Command where only parents
// are checked.
func VisitAll(root *cobra.Command, fn func(*cobra.Command)) {
for _, cmd := range root.Commands() {
VisitAll(cmd, fn)
}
fn(root)
}
// DisableFlagsInUseLine sets the DisableFlagsInUseLine flag on all
// commands within the tree rooted at cmd.
func DisableFlagsInUseLine(cmd *cobra.Command) {
VisitAll(cmd, func(ccmd *cobra.Command) {
// do not add a `[flags]` to the end of the usage line.
ccmd.DisableFlagsInUseLine = true
})
}
// HasCompletionArg returns true if a cobra completion arg request is found.
func HasCompletionArg(args []string) bool {
for _, arg := range args {
if arg == cobra.ShellCompRequestCmd || arg == cobra.ShellCompNoDescRequestCmd {
return true
}
}
return false
}
var helpCommand = &cobra.Command{
Use: "help [command]",
Short: "Help about the command",
@@ -204,7 +174,7 @@ var helpCommand = &cobra.Command{
RunE: func(c *cobra.Command, args []string) error {
cmd, args, e := c.Root().Find(args)
if cmd == nil || e != nil || len(args) > 0 {
return errors.Errorf("unknown help topic: %v", strings.Join(args, " "))
return fmt.Errorf("unknown help topic: %v", strings.Join(args, " "))
}
helpFunc := cmd.HelpFunc()
helpFunc(cmd, args)
@@ -280,11 +250,12 @@ func commandAliases(cmd *cobra.Command) string {
if cmd.HasParent() {
parentPath = cmd.Parent().CommandPath() + " "
}
aliases := cmd.CommandPath()
var aliases strings.Builder
aliases.WriteString(cmd.CommandPath())
for _, alias := range cmd.Aliases {
aliases += ", " + parentPath + alias
aliases.WriteString(", " + parentPath + alias)
}
return aliases
return aliases.String()
}
func topCommands(cmd *cobra.Command) []*cobra.Command {
@@ -380,13 +351,10 @@ func orchestratorSubCommands(cmd *cobra.Command) []*cobra.Command {
func allManagementSubCommands(cmd *cobra.Command) []*cobra.Command {
cmds := []*cobra.Command{}
for _, sub := range cmd.Commands() {
if isPlugin(sub) {
if invalidPluginReason(sub) == "" {
cmds = append(cmds, sub)
}
if invalidPluginReason(sub) != "" {
continue
}
if sub.IsAvailableCommand() && sub.HasSubCommands() {
if sub.IsAvailableCommand() && (isPlugin(sub) || sub.HasSubCommands()) {
cmds = append(cmds, sub)
}
}
+27 -22
View File
@@ -10,28 +10,6 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func TestVisitAll(t *testing.T) {
root := &cobra.Command{Use: "root"}
sub1 := &cobra.Command{Use: "sub1"}
sub1sub1 := &cobra.Command{Use: "sub1sub1"}
sub1sub2 := &cobra.Command{Use: "sub1sub2"}
sub2 := &cobra.Command{Use: "sub2"}
root.AddCommand(sub1, sub2)
sub1.AddCommand(sub1sub1, sub1sub2)
// Take the opportunity to test DisableFlagsInUseLine too
DisableFlagsInUseLine(root)
var visited []string
VisitAll(root, func(ccmd *cobra.Command) {
visited = append(visited, ccmd.Name())
assert.Assert(t, ccmd.DisableFlagsInUseLine, "DisableFlagsInUseLine not set on %q", ccmd.Name())
})
expected := []string{"sub1sub1", "sub1sub2", "sub1", "sub2", "root"}
assert.DeepEqual(t, expected, visited)
}
func TestVendorAndVersion(t *testing.T) {
// Non plugin.
assert.Equal(t, vendorAndVersion(&cobra.Command{Use: "test"}), "")
@@ -78,6 +56,33 @@ func TestInvalidPlugin(t *testing.T) {
assert.DeepEqual(t, invalidPlugins(root), []*cobra.Command{sub1}, cmpopts.IgnoreUnexported(cobra.Command{}))
}
func TestHiddenPlugin(t *testing.T) {
root := &cobra.Command{Use: "root"}
sub1 := &cobra.Command{
Use: "sub1",
Hidden: true,
Annotations: map[string]string{
metadata.CommandAnnotationPlugin: "true",
},
Run: func(cmd *cobra.Command, args []string) {},
}
sub1sub1 := &cobra.Command{Use: "sub1sub1"}
sub1sub2 := &cobra.Command{Use: "sub1sub2"}
sub2 := &cobra.Command{
Use: "sub2",
Annotations: map[string]string{
metadata.CommandAnnotationPlugin: "true",
},
Run: func(cmd *cobra.Command, args []string) {},
}
root.AddCommand(sub1, sub2)
sub1.AddCommand(sub1sub1, sub1sub2)
assert.DeepEqual(t, allManagementSubCommands(root), []*cobra.Command{sub2}, cmpopts.IgnoreFields(cobra.Command{}, "Run"), cmpopts.IgnoreUnexported(cobra.Command{}))
}
func TestCommandAliases(t *testing.T) {
root := &cobra.Command{Use: "root"}
sub := &cobra.Command{Use: "subcommand", Aliases: []string{"alias1", "alias2"}}
+4 -5
View File
@@ -3,18 +3,17 @@ package builder
import (
"context"
"github.com/docker/docker/api/types/build"
"github.com/docker/docker/client"
"github.com/moby/moby/client"
)
type fakeClient struct {
client.Client
builderPruneFunc func(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error)
builderPruneFunc func(ctx context.Context, opts client.BuildCachePruneOptions) (client.BuildCachePruneResult, error)
}
func (c *fakeClient) BuildCachePrune(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error) {
func (c *fakeClient) BuildCachePrune(ctx context.Context, opts client.BuildCachePruneOptions) (client.BuildCachePruneResult, error) {
if c.builderPruneFunc != nil {
return c.builderPruneFunc(ctx, opts)
}
return nil, nil
return client.BuildCachePruneResult{}, nil
}
+20 -7
View File
@@ -6,29 +6,41 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/image"
"github.com/docker/cli/internal/commands"
)
// NewBuilderCommand returns a cobra command for `builder` subcommands
func NewBuilderCommand(dockerCli command.Cli) *cobra.Command {
func init() {
commands.Register(newBuilderCommand)
commands.Register(func(c command.Cli) *cobra.Command {
return newBakeStubCommand(c)
})
}
// newBuilderCommand returns a cobra command for `builder` subcommands
func newBuilderCommand(dockerCLI command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "builder",
Short: "Manage builds",
Args: cli.NoArgs,
RunE: command.ShowHelp(dockerCli.Err()),
RunE: command.ShowHelp(dockerCLI.Err()),
Annotations: map[string]string{"version": "1.31"},
DisableFlagsInUseLine: true,
}
cmd.AddCommand(
NewPruneCommand(dockerCli),
image.NewBuildCommand(dockerCli),
newPruneCommand(dockerCLI),
// we should have a mechanism for registering sub-commands in the cli/internal/commands.Register function.
//nolint:staticcheck // TODO: Remove when migration to cli/internal/commands.Register is complete. (see #6283)
image.NewBuildCommand(dockerCLI),
)
return cmd
}
// NewBakeStubCommand returns a cobra command "stub" for the "bake" subcommand.
// newBakeStubCommand returns a cobra command "stub" for the "bake" subcommand.
// This command is a placeholder / stub that is dynamically replaced by an
// alias for "docker buildx bake" if BuildKit is enabled (and the buildx plugin
// installed).
func NewBakeStubCommand(dockerCLI command.Streams) *cobra.Command {
func newBakeStubCommand(dockerCLI command.Streams) *cobra.Command {
return &cobra.Command{
Use: "bake [OPTIONS] [TARGET...]",
Short: "Build from a file",
@@ -40,5 +52,6 @@ func NewBakeStubCommand(dockerCLI command.Streams) *cobra.Command {
"aliases": "docker buildx bake",
"version": "1.31",
},
DisableFlagsInUseLine: true,
}
}
+47 -25
View File
@@ -8,23 +8,30 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/cli/command/system/pruner"
"github.com/docker/cli/internal/prompt"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/build"
"github.com/docker/go-units"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
type pruneOptions struct {
force bool
all bool
filter opts.FilterOpt
keepStorage opts.MemBytes
func init() {
// Register the prune command to run as part of "docker system prune"
if err := pruner.Register(pruner.TypeBuildCache, pruneFn); err != nil {
panic(err)
}
}
// NewPruneCommand returns a new cobra prune command for images
func NewPruneCommand(dockerCli command.Cli) *cobra.Command {
type pruneOptions struct {
force bool
all bool
filter opts.FilterOpt
reservedSpace opts.MemBytes
}
// newPruneCommand returns a new cobra prune command for images
func newPruneCommand(dockerCLI command.Cli) *cobra.Command {
options := pruneOptions{filter: opts.NewFilterOpt()}
cmd := &cobra.Command{
@@ -32,25 +39,26 @@ func NewPruneCommand(dockerCli command.Cli) *cobra.Command {
Short: "Remove build cache",
Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
spaceReclaimed, output, err := runPrune(cmd.Context(), dockerCli, options)
spaceReclaimed, output, err := runPrune(cmd.Context(), dockerCLI, options)
if err != nil {
return err
}
if output != "" {
fmt.Fprintln(dockerCli.Out(), output)
_, _ = fmt.Fprintln(dockerCLI.Out(), output)
}
fmt.Fprintln(dockerCli.Out(), "Total reclaimed space:", units.HumanSize(float64(spaceReclaimed)))
_, _ = fmt.Fprintln(dockerCLI.Out(), "Total reclaimed space:", units.HumanSize(float64(spaceReclaimed)))
return nil
},
Annotations: map[string]string{"version": "1.39"},
ValidArgsFunction: completion.NoComplete,
Annotations: map[string]string{"version": "1.39"},
ValidArgsFunction: cobra.NoFileCompletions,
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
flags.BoolVarP(&options.force, "force", "f", false, "Do not prompt for confirmation")
flags.BoolVarP(&options.all, "all", "a", false, "Remove all unused build cache, not just dangling ones")
flags.Var(&options.filter, "filter", `Provide filter values (e.g. "until=24h")`)
flags.Var(&options.keepStorage, "keep-storage", "Amount of disk space to keep for cache")
flags.Var(&options.reservedSpace, "keep-storage", "Amount of disk space to keep for cache")
return cmd
}
@@ -61,8 +69,7 @@ const (
)
func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions) (spaceReclaimed uint64, output string, err error) {
pruneFilters := options.filter.Value()
pruneFilters = command.PruneFilters(dockerCli, pruneFilters)
pruneFilters := command.PruneFilters(dockerCli, options.filter.Value())
warning := normalWarning
if options.all {
@@ -78,15 +85,15 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
}
}
report, err := dockerCli.Client().BuildCachePrune(ctx, build.CachePruneOptions{
All: options.all,
KeepStorage: options.keepStorage.Value(), // FIXME(thaJeztah): rewrite to use new options; see https://github.com/moby/moby/pull/48720
Filters: pruneFilters,
resp, err := dockerCli.Client().BuildCachePrune(ctx, client.BuildCachePruneOptions{
All: options.all,
ReservedSpace: options.reservedSpace.Value(),
Filters: pruneFilters,
})
if err != nil {
return 0, "", err
}
report := resp.Report
if len(report.CachesDeleted) > 0 {
var sb strings.Builder
sb.WriteString("Deleted build cache objects:\n")
@@ -104,7 +111,22 @@ type cancelledErr struct{ error }
func (cancelledErr) Cancelled() {}
// CachePrune executes a prune command for build cache
func CachePrune(ctx context.Context, dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error) {
return runPrune(ctx, dockerCli, pruneOptions{force: true, all: all, filter: filter})
// pruneFn prunes the build cache for use in "docker system prune" and
// returns the amount of space reclaimed and a detailed output string.
func pruneFn(ctx context.Context, dockerCLI command.Cli, options pruner.PruneOptions) (uint64, string, error) {
if !options.Confirmed {
// Dry-run: perform validation and produce confirmation before pruning.
var confirmMsg string
if options.All {
confirmMsg = "all build cache"
} else {
confirmMsg = "unused build cache"
}
return 0, confirmMsg, cancelledErr{errors.New("builder prune has been cancelled")}
}
return runPrune(ctx, dockerCLI, pruneOptions{
force: true,
all: options.All,
filter: options.Filter,
})
}
+4 -4
View File
@@ -7,7 +7,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/build"
"github.com/moby/moby/client"
)
func TestBuilderPromptTermination(t *testing.T) {
@@ -15,11 +15,11 @@ func TestBuilderPromptTermination(t *testing.T) {
t.Cleanup(cancel)
cli := test.NewFakeCli(&fakeClient{
builderPruneFunc: func(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error) {
return nil, errors.New("fakeClient builderPruneFunc should not be called")
builderPruneFunc: func(ctx context.Context, opts client.BuildCachePruneOptions) (client.BuildCachePruneResult, error) {
return client.BuildCachePruneResult{}, errors.New("fakeClient builderPruneFunc should not be called")
},
})
cmd := NewPruneCommand(cli)
cmd := newPruneCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
test.TerminatePrompt(ctx, t, cmd, cli)
+10 -11
View File
@@ -3,34 +3,33 @@ package checkpoint
import (
"context"
"github.com/docker/docker/api/types/checkpoint"
"github.com/docker/docker/client"
"github.com/moby/moby/client"
)
type fakeClient struct {
client.Client
checkpointCreateFunc func(container string, options checkpoint.CreateOptions) error
checkpointDeleteFunc func(container string, options checkpoint.DeleteOptions) error
checkpointListFunc func(container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error)
checkpointCreateFunc func(container string, options client.CheckpointCreateOptions) (client.CheckpointCreateResult, error)
checkpointDeleteFunc func(container string, options client.CheckpointRemoveOptions) (client.CheckpointRemoveResult, error)
checkpointListFunc func(container string, options client.CheckpointListOptions) (client.CheckpointListResult, error)
}
func (cli *fakeClient) CheckpointCreate(_ context.Context, container string, options checkpoint.CreateOptions) error {
func (cli *fakeClient) CheckpointCreate(_ context.Context, container string, options client.CheckpointCreateOptions) (client.CheckpointCreateResult, error) {
if cli.checkpointCreateFunc != nil {
return cli.checkpointCreateFunc(container, options)
}
return nil
return client.CheckpointCreateResult{}, nil
}
func (cli *fakeClient) CheckpointDelete(_ context.Context, container string, options checkpoint.DeleteOptions) error {
func (cli *fakeClient) CheckpointRemove(_ context.Context, container string, options client.CheckpointRemoveOptions) (client.CheckpointRemoveResult, error) {
if cli.checkpointDeleteFunc != nil {
return cli.checkpointDeleteFunc(container, options)
}
return nil
return client.CheckpointRemoveResult{}, nil
}
func (cli *fakeClient) CheckpointList(_ context.Context, container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {
func (cli *fakeClient) CheckpointList(_ context.Context, container string, options client.CheckpointListOptions) (client.CheckpointListResult, error) {
if cli.checkpointListFunc != nil {
return cli.checkpointListFunc(container, options)
}
return []checkpoint.Summary{}, nil
return client.CheckpointListResult{}, nil
}
+12 -6
View File
@@ -3,26 +3,32 @@ package checkpoint
import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/internal/commands"
"github.com/spf13/cobra"
)
// NewCheckpointCommand returns the `checkpoint` subcommand (only in experimental)
func NewCheckpointCommand(dockerCli command.Cli) *cobra.Command {
func init() {
commands.Register(newCheckpointCommand)
}
// newCheckpointCommand returns the `checkpoint` subcommand (only in experimental)
func newCheckpointCommand(dockerCLI command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "checkpoint",
Short: "Manage checkpoints",
Args: cli.NoArgs,
RunE: command.ShowHelp(dockerCli.Err()),
RunE: command.ShowHelp(dockerCLI.Err()),
Annotations: map[string]string{
"experimental": "",
"ostype": "linux",
"version": "1.25",
},
DisableFlagsInUseLine: true,
}
cmd.AddCommand(
newCreateCommand(dockerCli),
newListCommand(dockerCli),
newRemoveCommand(dockerCli),
newCreateCommand(dockerCLI),
newListCommand(dockerCLI),
newRemoveCommand(dockerCLI),
)
return cmd
}
+6 -6
View File
@@ -6,8 +6,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/docker/api/types/checkpoint"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@@ -18,7 +17,7 @@ type createOptions struct {
leaveRunning bool
}
func newCreateCommand(dockerCli command.Cli) *cobra.Command {
func newCreateCommand(dockerCLI command.Cli) *cobra.Command {
var opts createOptions
cmd := &cobra.Command{
@@ -28,9 +27,10 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
opts.container = args[0]
opts.checkpoint = args[1]
return runCreate(cmd.Context(), dockerCli, opts)
return runCreate(cmd.Context(), dockerCLI, opts)
},
ValidArgsFunction: completion.NoComplete,
ValidArgsFunction: cobra.NoFileCompletions,
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
@@ -41,7 +41,7 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command {
}
func runCreate(ctx context.Context, dockerCLI command.Cli, opts createOptions) error {
err := dockerCLI.Client().CheckpointCreate(ctx, opts.container, checkpoint.CreateOptions{
_, err := dockerCLI.Client().CheckpointCreate(ctx, opts.container, client.CheckpointCreateOptions{
CheckpointID: opts.checkpoint,
CheckpointDir: opts.checkpointDir,
Exit: !opts.leaveRunning,
+8 -8
View File
@@ -8,7 +8,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/checkpoint"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@@ -16,7 +16,7 @@ import (
func TestCheckpointCreateErrors(t *testing.T) {
testCases := []struct {
args []string
checkpointCreateFunc func(container string, options checkpoint.CreateOptions) error
checkpointCreateFunc func(container string, options client.CheckpointCreateOptions) (client.CheckpointCreateResult, error)
expectedError string
}{
{
@@ -29,8 +29,8 @@ func TestCheckpointCreateErrors(t *testing.T) {
},
{
args: []string{"foo", "bar"},
checkpointCreateFunc: func(container string, options checkpoint.CreateOptions) error {
return errors.New("error creating checkpoint for container foo")
checkpointCreateFunc: func(container string, options client.CheckpointCreateOptions) (client.CheckpointCreateResult, error) {
return client.CheckpointCreateResult{}, errors.New("error creating checkpoint for container foo")
},
expectedError: "error creating checkpoint for container foo",
},
@@ -59,12 +59,12 @@ func TestCheckpointCreateWithOptions(t *testing.T) {
leaveRunning := strconv.FormatBool(tc)
t.Run("leave-running="+leaveRunning, func(t *testing.T) {
var actualContainerName string
var actualOptions checkpoint.CreateOptions
var actualOptions client.CheckpointCreateOptions
cli := test.NewFakeCli(&fakeClient{
checkpointCreateFunc: func(container string, options checkpoint.CreateOptions) error {
checkpointCreateFunc: func(container string, options client.CheckpointCreateOptions) (client.CheckpointCreateResult, error) {
actualContainerName = container
actualOptions = options
return nil
return client.CheckpointCreateResult{}, nil
},
})
cmd := newCreateCommand(cli)
@@ -75,7 +75,7 @@ func TestCheckpointCreateWithOptions(t *testing.T) {
assert.Check(t, cmd.Flags().Set("checkpoint-dir", checkpointDir))
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal(actualContainerName, containerName))
expected := checkpoint.CreateOptions{
expected := client.CheckpointCreateOptions{
CheckpointID: checkpointName,
CheckpointDir: checkpointDir,
Exit: !tc,
+14 -16
View File
@@ -2,7 +2,7 @@ package checkpoint
import (
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/docker/api/types/checkpoint"
"github.com/moby/moby/api/types/checkpoint"
)
const (
@@ -10,25 +10,31 @@ const (
checkpointNameHeader = "CHECKPOINT NAME"
)
// NewFormat returns a format for use with a checkpoint Context
func NewFormat(source string) formatter.Format {
// newFormat returns a format for use with a checkpointContext.
func newFormat(source string) formatter.Format {
if source == formatter.TableFormatKey {
return defaultCheckpointFormat
}
return formatter.Format(source)
}
// FormatWrite writes formatted checkpoints using the Context
func FormatWrite(ctx formatter.Context, checkpoints []checkpoint.Summary) error {
render := func(format func(subContext formatter.SubContext) error) error {
// formatWrite writes formatted checkpoints using the Context
func formatWrite(fmtCtx formatter.Context, checkpoints []checkpoint.Summary) error {
cpContext := &checkpointContext{
HeaderContext: formatter.HeaderContext{
Header: formatter.SubHeaderContext{
"Name": checkpointNameHeader,
},
},
}
return fmtCtx.Write(cpContext, func(format func(subContext formatter.SubContext) error) error {
for _, cp := range checkpoints {
if err := format(&checkpointContext{c: cp}); err != nil {
return err
}
}
return nil
}
return ctx.Write(newCheckpointContext(), render)
})
}
type checkpointContext struct {
@@ -36,14 +42,6 @@ type checkpointContext struct {
c checkpoint.Summary
}
func newCheckpointContext() *checkpointContext {
cpCtx := checkpointContext{}
cpCtx.Header = formatter.SubHeaderContext{
"Name": checkpointNameHeader,
}
return &cpCtx
}
func (c *checkpointContext) MarshalJSON() ([]byte, error) {
return formatter.MarshalJSON(c)
}
+5 -5
View File
@@ -5,7 +5,7 @@ import (
"testing"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/docker/api/types/checkpoint"
"github.com/moby/moby/api/types/checkpoint"
"gotest.tools/v3/assert"
)
@@ -15,7 +15,7 @@ func TestCheckpointContextFormatWrite(t *testing.T) {
expected string
}{
{
formatter.Context{Format: NewFormat(defaultCheckpointFormat)},
formatter.Context{Format: newFormat(defaultCheckpointFormat)},
`CHECKPOINT NAME
checkpoint-1
checkpoint-2
@@ -23,14 +23,14 @@ checkpoint-3
`,
},
{
formatter.Context{Format: NewFormat("{{.Name}}")},
formatter.Context{Format: newFormat("{{.Name}}")},
`checkpoint-1
checkpoint-2
checkpoint-3
`,
},
{
formatter.Context{Format: NewFormat("{{.Name}}:")},
formatter.Context{Format: newFormat("{{.Name}}:")},
`checkpoint-1:
checkpoint-2:
checkpoint-3:
@@ -41,7 +41,7 @@ checkpoint-3:
for _, testcase := range cases {
out := bytes.NewBufferString("")
testcase.context.Output = out
err := FormatWrite(testcase.context, []checkpoint.Summary{
err := formatWrite(testcase.context, []checkpoint.Summary{
{Name: "checkpoint-1"},
{Name: "checkpoint-2"},
{Name: "checkpoint-3"},
+10 -9
View File
@@ -7,7 +7,7 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/docker/api/types/checkpoint"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@@ -15,7 +15,7 @@ type listOptions struct {
checkpointDir string
}
func newListCommand(dockerCli command.Cli) *cobra.Command {
func newListCommand(dockerCLI command.Cli) *cobra.Command {
var opts listOptions
cmd := &cobra.Command{
@@ -24,9 +24,10 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
Short: "List checkpoints for a container",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runList(cmd.Context(), dockerCli, args[0], opts)
return runList(cmd.Context(), dockerCLI, args[0], opts)
},
ValidArgsFunction: completion.ContainerNames(dockerCli, false),
ValidArgsFunction: completion.ContainerNames(dockerCLI, false),
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
@@ -35,8 +36,8 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
return cmd
}
func runList(ctx context.Context, dockerCli command.Cli, container string, opts listOptions) error {
checkpoints, err := dockerCli.Client().CheckpointList(ctx, container, checkpoint.ListOptions{
func runList(ctx context.Context, dockerCLI command.Cli, container string, opts listOptions) error {
checkpoints, err := dockerCLI.Client().CheckpointList(ctx, container, client.CheckpointListOptions{
CheckpointDir: opts.checkpointDir,
})
if err != nil {
@@ -44,8 +45,8 @@ func runList(ctx context.Context, dockerCli command.Cli, container string, opts
}
cpCtx := formatter.Context{
Output: dockerCli.Out(),
Format: NewFormat(formatter.TableFormatKey),
Output: dockerCLI.Out(),
Format: newFormat(formatter.TableFormatKey),
}
return FormatWrite(cpCtx, checkpoints)
return formatWrite(cpCtx, checkpoints.Items)
}
+11 -8
View File
@@ -6,7 +6,8 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/checkpoint"
"github.com/moby/moby/api/types/checkpoint"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/golden"
@@ -15,7 +16,7 @@ import (
func TestCheckpointListErrors(t *testing.T) {
testCases := []struct {
args []string
checkpointListFunc func(container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error)
checkpointListFunc func(container string, options client.CheckpointListOptions) (client.CheckpointListResult, error)
expectedError string
}{
{
@@ -28,8 +29,8 @@ func TestCheckpointListErrors(t *testing.T) {
},
{
args: []string{"foo"},
checkpointListFunc: func(container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {
return []checkpoint.Summary{}, errors.New("error getting checkpoints for container foo")
checkpointListFunc: func(container string, options client.CheckpointListOptions) (client.CheckpointListResult, error) {
return client.CheckpointListResult{}, errors.New("error getting checkpoints for container foo")
},
expectedError: "error getting checkpoints for container foo",
},
@@ -50,17 +51,19 @@ func TestCheckpointListErrors(t *testing.T) {
func TestCheckpointListWithOptions(t *testing.T) {
var containerID, checkpointDir string
cli := test.NewFakeCli(&fakeClient{
checkpointListFunc: func(container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {
checkpointListFunc: func(container string, options client.CheckpointListOptions) (client.CheckpointListResult, error) {
containerID = container
checkpointDir = options.CheckpointDir
return []checkpoint.Summary{
{Name: "checkpoint-foo"},
return client.CheckpointListResult{
Items: []checkpoint.Summary{
{Name: "checkpoint-foo"},
},
}, nil
},
})
cmd := newListCommand(cli)
cmd.SetArgs([]string{"container-foo"})
cmd.Flags().Set("checkpoint-dir", "/dir/foo")
assert.Check(t, cmd.Flags().Set("checkpoint-dir", "/dir/foo"))
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("container-foo", containerID))
assert.Check(t, is.Equal("/dir/foo", checkpointDir))
+9 -12
View File
@@ -1,11 +1,9 @@
package checkpoint
import (
"context"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types/checkpoint"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@@ -13,7 +11,7 @@ type removeOptions struct {
checkpointDir string
}
func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
func newRemoveCommand(dockerCLI command.Cli) *cobra.Command {
var opts removeOptions
cmd := &cobra.Command{
@@ -22,8 +20,14 @@ func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
Short: "Remove a checkpoint",
Args: cli.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
return runRemove(cmd.Context(), dockerCli, args[0], args[1], opts)
containerID, checkpointID := args[0], args[1]
_, err := dockerCLI.Client().CheckpointRemove(cmd.Context(), containerID, client.CheckpointRemoveOptions{
CheckpointID: checkpointID,
CheckpointDir: opts.checkpointDir,
})
return err
},
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
@@ -31,10 +35,3 @@ func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
return cmd
}
func runRemove(ctx context.Context, dockerCli command.Cli, container string, checkpointID string, opts removeOptions) error {
return dockerCli.Client().CheckpointDelete(ctx, container, checkpoint.DeleteOptions{
CheckpointID: checkpointID,
CheckpointDir: opts.checkpointDir,
})
}
+7 -7
View File
@@ -6,7 +6,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/checkpoint"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@@ -14,7 +14,7 @@ import (
func TestCheckpointRemoveErrors(t *testing.T) {
testCases := []struct {
args []string
checkpointDeleteFunc func(container string, options checkpoint.DeleteOptions) error
checkpointDeleteFunc func(container string, options client.CheckpointRemoveOptions) (client.CheckpointRemoveResult, error)
expectedError string
}{
{
@@ -27,8 +27,8 @@ func TestCheckpointRemoveErrors(t *testing.T) {
},
{
args: []string{"foo", "bar"},
checkpointDeleteFunc: func(container string, options checkpoint.DeleteOptions) error {
return errors.New("error deleting checkpoint")
checkpointDeleteFunc: func(container string, options client.CheckpointRemoveOptions) (client.CheckpointRemoveResult, error) {
return client.CheckpointRemoveResult{}, errors.New("error deleting checkpoint")
},
expectedError: "error deleting checkpoint",
},
@@ -49,16 +49,16 @@ func TestCheckpointRemoveErrors(t *testing.T) {
func TestCheckpointRemoveWithOptions(t *testing.T) {
var containerID, checkpointID, checkpointDir string
cli := test.NewFakeCli(&fakeClient{
checkpointDeleteFunc: func(container string, options checkpoint.DeleteOptions) error {
checkpointDeleteFunc: func(container string, options client.CheckpointRemoveOptions) (client.CheckpointRemoveResult, error) {
containerID = container
checkpointID = options.CheckpointID
checkpointDir = options.CheckpointDir
return nil
return client.CheckpointRemoveResult{}, nil
},
})
cmd := newRemoveCommand(cli)
cmd.SetArgs([]string{"container-foo", "checkpoint-bar"})
cmd.Flags().Set("checkpoint-dir", "/dir/foo")
assert.Check(t, cmd.Flags().Set("checkpoint-dir", "/dir/foo"))
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("container-foo", containerID))
assert.Check(t, is.Equal("checkpoint-bar", checkpointID))
+100 -57
View File
@@ -1,10 +1,11 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.23
//go:build go1.25
package command
import (
"context"
"errors"
"fmt"
"io"
"os"
@@ -23,11 +24,8 @@ import (
"github.com/docker/cli/cli/streams"
"github.com/docker/cli/cli/version"
dopts "github.com/docker/cli/opts"
"github.com/docker/docker/api"
"github.com/docker/docker/api/types/build"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/moby/moby/api/types/build"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@@ -45,12 +43,9 @@ type Cli interface {
Client() client.APIClient
Streams
SetIn(in *streams.In)
Apply(ops ...CLIOption) error
config.Provider
ServerInfo() ServerInfo
DefaultVersion() string
CurrentVersion() string
ContentTrustEnabled() bool
BuildKitEnabled() (bool, error)
ContextStore() store.Store
CurrentContext() string
@@ -65,12 +60,12 @@ type Cli interface {
type DockerCli struct {
configFile *configfile.ConfigFile
options *cliflags.ClientOptions
clientOpts []client.Opt
in *streams.In
out *streams.Out
err *streams.Out
client client.APIClient
serverInfo ServerInfo
contentTrust bool
contextStore store.Store
currentContext string
init sync.Once
@@ -88,17 +83,12 @@ type DockerCli struct {
enableGlobalMeter, enableGlobalTracer bool
}
// DefaultVersion returns [api.DefaultVersion].
func (*DockerCli) DefaultVersion() string {
return api.DefaultVersion
}
// CurrentVersion returns the API version currently negotiated, or the default
// version otherwise.
func (cli *DockerCli) CurrentVersion() string {
_ = cli.initialize()
if cli.client == nil {
return api.DefaultVersion
return client.MaxAPIVersion
}
return cli.client.ClientVersion()
}
@@ -157,19 +147,13 @@ func (cli *DockerCli) ServerInfo() ServerInfo {
return cli.serverInfo
}
// ContentTrustEnabled returns whether content trust has been enabled by an
// environment variable.
func (cli *DockerCli) ContentTrustEnabled() bool {
return cli.contentTrust
}
// BuildKitEnabled returns buildkit is enabled or not.
func (cli *DockerCli) BuildKitEnabled() (bool, error) {
// use DOCKER_BUILDKIT env var value if set and not empty
if v := os.Getenv("DOCKER_BUILDKIT"); v != "" {
enabled, err := strconv.ParseBool(v)
if err != nil {
return false, errors.Wrap(err, "DOCKER_BUILDKIT environment variable expects boolean value")
return false, fmt.Errorf("DOCKER_BUILDKIT environment variable expects boolean value: %w", err)
}
return enabled, nil
}
@@ -269,7 +253,7 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...CLIOption)
cli.contextStore = &ContextStoreWithDefault{
Store: store.New(config.ContextStoreDir(), *cli.contextStoreConfig),
Resolver: func() (*DefaultContext, error) {
return ResolveDefaultContext(cli.options, *cli.contextStoreConfig)
return resolveDefaultContext(cli.options, *cli.contextStoreConfig)
},
}
@@ -282,6 +266,17 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...CLIOption)
}
filterResourceAttributesEnvvar()
// early return if GODEBUG is already set or the docker context is
// the default context, i.e. is a virtual context where we won't override
// any GODEBUG values.
if v := os.Getenv("GODEBUG"); cli.currentContext == DefaultContextName || v != "" {
return nil
}
meta, err := cli.contextStore.GetMetadata(cli.currentContext)
if err == nil {
setGoDebug(meta)
}
return nil
}
@@ -295,17 +290,17 @@ func NewAPIClientFromFlags(opts *cliflags.ClientOptions, configFile *configfile.
contextStore := &ContextStoreWithDefault{
Store: store.New(config.ContextStoreDir(), storeConfig),
Resolver: func() (*DefaultContext, error) {
return ResolveDefaultContext(opts, storeConfig)
return resolveDefaultContext(opts, storeConfig)
},
}
endpoint, err := resolveDockerEndpoint(contextStore, resolveContextName(opts, configFile))
if err != nil {
return nil, errors.Wrap(err, "unable to resolve docker endpoint")
return nil, fmt.Errorf("unable to resolve docker endpoint: %w", err)
}
return newAPIClientFromEndpoint(endpoint, configFile)
return newAPIClientFromEndpoint(endpoint, configFile, client.WithUserAgent(UserAgent()))
}
func newAPIClientFromEndpoint(ep docker.Endpoint, configFile *configfile.ConfigFile) (client.APIClient, error) {
func newAPIClientFromEndpoint(ep docker.Endpoint, configFile *configfile.ConfigFile, extraOpts ...client.Opt) (client.APIClient, error) {
opts, err := ep.ClientOpts()
if err != nil {
return nil, err
@@ -313,8 +308,15 @@ func newAPIClientFromEndpoint(ep docker.Endpoint, configFile *configfile.ConfigF
if len(configFile.HTTPHeaders) > 0 {
opts = append(opts, client.WithHTTPHeaders(configFile.HTTPHeaders))
}
opts = append(opts, withCustomHeadersFromEnv(), client.WithUserAgent(UserAgent()))
return client.NewClientWithOpts(opts...)
withCustomHeaders, err := withCustomHeadersFromEnv()
if err != nil {
return nil, err
}
if withCustomHeaders != nil {
opts = append(opts, withCustomHeaders)
}
opts = append(opts, extraOpts...)
return client.New(opts...)
}
func resolveDockerEndpoint(s store.Reader, contextName string) (docker.Endpoint, error) {
@@ -375,24 +377,21 @@ func (cli *DockerCli) initializeFromClient() {
ctx, cancel := context.WithTimeout(cli.baseCtx, cli.getInitTimeout())
defer cancel()
ping, err := cli.client.Ping(ctx)
ping, err := cli.client.Ping(ctx, client.PingOptions{
NegotiateAPIVersion: true,
ForceNegotiate: true,
})
if err != nil {
// Default to true if we fail to connect to daemon
cli.serverInfo = ServerInfo{HasExperimental: true}
if ping.APIVersion != "" {
cli.client.NegotiateAPIVersionPing(ping)
}
return
}
cli.serverInfo = ServerInfo{
HasExperimental: ping.Experimental,
OSType: ping.OSType,
BuildkitVersion: ping.BuilderVersion,
SwarmStatus: ping.SwarmStatus,
}
cli.client.NegotiateAPIVersionPing(ping)
}
// ContextStore returns the ContextStore
@@ -475,15 +474,66 @@ func (cli *DockerCli) getDockerEndPoint() (ep docker.Endpoint, err error) {
return resolveDockerEndpoint(cli.contextStore, cn)
}
// setGoDebug is an escape hatch that sets the GODEBUG environment
// variable value using docker context metadata.
//
// {
// "Name": "my-context",
// "Metadata": { "GODEBUG": "x509negativeserial=1" }
// }
//
// WARNING: Setting x509negativeserial=1 allows Go's x509 library to accept
// X.509 certificates with negative serial numbers.
// This behavior is deprecated and non-compliant with current security
// standards (RFC 5280). Accepting negative serial numbers can introduce
// serious security vulnerabilities, including the risk of certificate
// collision or bypass attacks.
// This option should only be used for legacy compatibility and never in
// production environments.
// Use at your own risk.
func setGoDebug(meta store.Metadata) {
fieldName := "GODEBUG"
godebugEnv := os.Getenv(fieldName)
// early return if GODEBUG is already set. We don't want to override what
// the user already sets.
if godebugEnv != "" {
return
}
var cfg any
var ok bool
switch m := meta.Metadata.(type) {
case DockerContext:
cfg, ok = m.AdditionalFields[fieldName]
if !ok {
return
}
case map[string]any:
cfg, ok = m[fieldName]
if !ok {
return
}
default:
return
}
v, ok := cfg.(string)
if !ok {
return
}
// set the GODEBUG environment variable with whatever was in the context
_ = os.Setenv(fieldName, v)
}
func (cli *DockerCli) initialize() error {
cli.init.Do(func() {
cli.dockerEndpoint, cli.initErr = cli.getDockerEndPoint()
if cli.initErr != nil {
cli.initErr = errors.Wrap(cli.initErr, "unable to resolve docker endpoint")
cli.initErr = fmt.Errorf("unable to resolve docker endpoint: %w", cli.initErr)
return
}
if cli.client == nil {
if cli.client, cli.initErr = newAPIClientFromEndpoint(cli.dockerEndpoint, cli.configFile); cli.initErr != nil {
if cli.client, cli.initErr = newAPIClientFromEndpoint(cli.dockerEndpoint, cli.configFile, cli.clientOpts...); cli.initErr != nil {
return
}
}
@@ -495,16 +545,6 @@ func (cli *DockerCli) initialize() error {
return cli.initErr
}
// Apply all the operation on the cli
func (cli *DockerCli) Apply(ops ...CLIOption) error {
for _, op := range ops {
if err := op(cli); err != nil {
return err
}
}
return nil
}
// ServerInfo stores details about the supported features and platform of the
// server
type ServerInfo struct {
@@ -519,23 +559,26 @@ type ServerInfo struct {
// in the ping response, or if an error occurred, in which case the client
// should use other ways to get the current swarm status, such as the /swarm
// endpoint.
SwarmStatus *swarm.Status
SwarmStatus *client.SwarmStatus
}
// NewDockerCli returns a DockerCli instance with all operators applied on it.
// It applies by default the standard streams, and the content trust from
// environment.
func NewDockerCli(ops ...CLIOption) (*DockerCli, error) {
defaultOps := []CLIOption{
WithContentTrustFromEnv(),
defaultOps := make([]CLIOption, 0, 3+len(ops))
defaultOps = append(defaultOps,
WithDefaultContextStoreConfig(),
WithStandardStreams(),
}
WithUserAgent(UserAgent()),
)
ops = append(defaultOps, ops...)
cli := &DockerCli{baseCtx: context.Background()}
if err := cli.Apply(ops...); err != nil {
return nil, err
for _, op := range ops {
if err := op(cli); err != nil {
return nil, err
}
}
return cli, nil
}
@@ -547,11 +590,11 @@ func getServerHost(hosts []string, defaultToTLS bool) (string, error) {
case 1:
return dopts.ParseHost(defaultToTLS, hosts[0])
default:
return "", errors.New("Specify only one -H")
return "", errors.New("specify only one -H")
}
}
// UserAgent returns the user agent string used for making API requests
// UserAgent returns the default user agent string used for making API requests.
func UserAgent() string {
return "Docker-Client/" + version.Version + " (" + runtime.GOOS + ")"
}
+70 -73
View File
@@ -3,16 +3,16 @@ package command
import (
"context"
"encoding/csv"
"errors"
"fmt"
"io"
"net/http"
"os"
"strconv"
"strings"
"github.com/docker/cli/cli/streams"
"github.com/docker/docker/client"
"github.com/moby/moby/client"
"github.com/moby/term"
"github.com/pkg/errors"
)
// CLIOption is a functional argument to apply options to a [DockerCli]. These
@@ -75,28 +75,6 @@ func WithErrorStream(err io.Writer) CLIOption {
}
}
// WithContentTrustFromEnv enables content trust on a cli from environment variable DOCKER_CONTENT_TRUST value.
func WithContentTrustFromEnv() CLIOption {
return func(cli *DockerCli) error {
cli.contentTrust = false
if e := os.Getenv("DOCKER_CONTENT_TRUST"); e != "" {
if t, err := strconv.ParseBool(e); t || err != nil {
// treat any other value as true
cli.contentTrust = true
}
}
return nil
}
}
// WithContentTrust enables content trust on a cli.
func WithContentTrust(enabled bool) CLIOption {
return func(cli *DockerCli) error {
cli.contentTrust = enabled
return nil
}
}
// WithDefaultContextStoreConfig configures the cli to use the default context store configuration.
func WithDefaultContextStoreConfig() CLIOption {
return func(cli *DockerCli) error {
@@ -126,6 +104,16 @@ func WithInitializeClient(makeClient func(*DockerCli) (client.APIClient, error))
}
}
// WithAPIClientOptions configures additional [client.Opt] to use when
// initializing the API client. These options have no effect if a custom
// client is set (through [WithAPIClient] or [WithInitializeClient]).
func WithAPIClientOptions(c ...client.Opt) CLIOption {
return func(cli *DockerCli) error {
cli.clientOpts = append(cli.clientOpts, c...)
return nil
}
}
// envOverrideHTTPHeaders is the name of the environment-variable that can be
// used to set custom HTTP headers to be sent by the client. This environment
// variable is the equivalent to the HttpHeaders field in the configuration
@@ -180,61 +168,70 @@ const envOverrideHTTPHeaders = "DOCKER_CUSTOM_HEADERS"
// override headers with the same name).
//
// TODO(thaJeztah): this is a client Option, and should be moved to the client. It is non-exported for that reason.
func withCustomHeadersFromEnv() client.Opt {
return func(apiClient *client.Client) error {
value := os.Getenv(envOverrideHTTPHeaders)
if value == "" {
return nil
}
csvReader := csv.NewReader(strings.NewReader(value))
fields, err := csvReader.Read()
if err != nil {
return invalidParameter(errors.Errorf(
"failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs",
envOverrideHTTPHeaders,
func withCustomHeadersFromEnv() (client.Opt, error) {
value := os.Getenv(envOverrideHTTPHeaders)
if value == "" {
return nil, nil
}
csvReader := csv.NewReader(strings.NewReader(value))
fields, err := csvReader.Read()
if err != nil {
return nil, invalidParameter(fmt.Errorf(
"failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs",
envOverrideHTTPHeaders,
))
}
if len(fields) == 0 {
return nil, nil
}
env := map[string]string{}
for _, kv := range fields {
k, v, hasValue := strings.Cut(kv, "=")
// Only strip whitespace in keys; preserve whitespace in values.
k = strings.TrimSpace(k)
if k == "" {
return nil, invalidParameter(fmt.Errorf(
`failed to set custom headers from %s environment variable: value contains a key=value pair with an empty key: '%s'`,
envOverrideHTTPHeaders, kv,
))
}
if len(fields) == 0 {
return nil
// We don't currently allow empty key=value pairs, and produce an error.
// This is something we could allow in future (e.g. to read value
// from an environment variable with the same name). In the meantime,
// produce an error to prevent users from depending on this.
if !hasValue {
return nil, invalidParameter(fmt.Errorf(
`failed to set custom headers from %s environment variable: missing "=" in key=value pair: '%s'`,
envOverrideHTTPHeaders, kv,
))
}
env := map[string]string{}
for _, kv := range fields {
k, v, hasValue := strings.Cut(kv, "=")
env[http.CanonicalHeaderKey(k)] = v
}
// Only strip whitespace in keys; preserve whitespace in values.
k = strings.TrimSpace(k)
if len(env) == 0 {
// We should probably not hit this case, as we don't skip values
// (only return errors), but we don't want to discard existing
// headers with an empty set.
return nil, nil
}
if k == "" {
return invalidParameter(errors.Errorf(
`failed to set custom headers from %s environment variable: value contains a key=value pair with an empty key: '%s'`,
envOverrideHTTPHeaders, kv,
))
}
// TODO(thaJeztah): add a client.WithExtraHTTPHeaders() function to allow these headers to be _added_ to existing ones, instead of _replacing_
// see https://github.com/docker/cli/pull/5098#issuecomment-2147403871 (when updating, also update the WARNING in the function and env-var GoDoc)
return client.WithHTTPHeaders(env), nil
}
// We don't currently allow empty key=value pairs, and produce an error.
// This is something we could allow in future (e.g. to read value
// from an environment variable with the same name). In the meantime,
// produce an error to prevent users from depending on this.
if !hasValue {
return invalidParameter(errors.Errorf(
`failed to set custom headers from %s environment variable: missing "=" in key=value pair: '%s'`,
envOverrideHTTPHeaders, kv,
))
}
env[http.CanonicalHeaderKey(k)] = v
// WithUserAgent configures the User-Agent string for cli HTTP requests.
func WithUserAgent(userAgent string) CLIOption {
return func(cli *DockerCli) error {
if userAgent == "" {
return errors.New("user agent cannot be blank")
}
if len(env) == 0 {
// We should probably not hit this case, as we don't skip values
// (only return errors), but we don't want to discard existing
// headers with an empty set.
return nil
}
// TODO(thaJeztah): add a client.WithExtraHTTPHeaders() function to allow these headers to be _added_ to existing ones, instead of _replacing_
// see https://github.com/docker/cli/pull/5098#issuecomment-2147403871 (when updating, also update the WARNING in the function and env-var GoDoc)
return client.WithHTTPHeaders(env)(apiClient)
cli.clientOpts = append(cli.clientOpts, client.WithUserAgent(userAgent))
return nil
}
}
-28
View File
@@ -1,28 +0,0 @@
package command
import (
"os"
"testing"
"gotest.tools/v3/assert"
)
func contentTrustEnabled(t *testing.T) bool {
t.Helper()
var cli DockerCli
assert.NilError(t, WithContentTrustFromEnv()(&cli))
return cli.contentTrust
}
// NB: Do not t.Parallel() this test -- it messes with the process environment.
func TestWithContentTrustFromEnv(t *testing.T) {
const envvar = "DOCKER_CONTENT_TRUST"
t.Setenv(envvar, "true")
assert.Check(t, contentTrustEnabled(t))
t.Setenv(envvar, "false")
assert.Check(t, !contentTrustEnabled(t))
t.Setenv(envvar, "invalid")
assert.Check(t, contentTrustEnabled(t))
os.Unsetenv(envvar)
assert.Check(t, !contentTrustEnabled(t))
}
+142 -61
View File
@@ -18,10 +18,9 @@ import (
"github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/context/store"
"github.com/docker/cli/cli/flags"
"github.com/docker/docker/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
)
@@ -34,7 +33,7 @@ func TestNewAPIClientFromFlags(t *testing.T) {
apiClient, err := NewAPIClientFromFlags(opts, &configfile.ConfigFile{})
assert.NilError(t, err)
assert.Equal(t, apiClient.DaemonHost(), host)
assert.Equal(t, apiClient.ClientVersion(), api.DefaultVersion)
assert.Equal(t, apiClient.ClientVersion(), client.MaxAPIVersion)
}
func TestNewAPIClientFromFlagsForDefaultSchema(t *testing.T) {
@@ -47,7 +46,7 @@ func TestNewAPIClientFromFlagsForDefaultSchema(t *testing.T) {
apiClient, err := NewAPIClientFromFlags(opts, &configfile.ConfigFile{})
assert.NilError(t, err)
assert.Equal(t, apiClient.DaemonHost(), slug+host)
assert.Equal(t, apiClient.ClientVersion(), api.DefaultVersion)
assert.Equal(t, apiClient.ClientVersion(), client.MaxAPIVersion)
}
func TestNewAPIClientFromFlagsWithCustomHeaders(t *testing.T) {
@@ -71,7 +70,7 @@ func TestNewAPIClientFromFlagsWithCustomHeaders(t *testing.T) {
apiClient, err := NewAPIClientFromFlags(opts, configFile)
assert.NilError(t, err)
assert.Equal(t, apiClient.DaemonHost(), host)
assert.Equal(t, apiClient.ClientVersion(), api.DefaultVersion)
assert.Equal(t, apiClient.ClientVersion(), client.MaxAPIVersion)
// verify User-Agent is not appended to the configfile. see https://github.com/docker/cli/pull/2756
assert.DeepEqual(t, configFile.HTTPHeaders, map[string]string{"My-Header": "Custom-Value"})
@@ -80,7 +79,7 @@ func TestNewAPIClientFromFlagsWithCustomHeaders(t *testing.T) {
"My-Header": "Custom-Value",
"User-Agent": UserAgent(),
}
_, err = apiClient.Ping(context.Background())
_, err = apiClient.Ping(context.TODO(), client.PingOptions{})
assert.NilError(t, err)
assert.DeepEqual(t, received, expectedHeaders)
}
@@ -106,7 +105,7 @@ func TestNewAPIClientFromFlagsWithCustomHeadersFromEnv(t *testing.T) {
apiClient, err := NewAPIClientFromFlags(opts, configFile)
assert.NilError(t, err)
assert.Equal(t, apiClient.DaemonHost(), host)
assert.Equal(t, apiClient.ClientVersion(), api.DefaultVersion)
assert.Equal(t, apiClient.ClientVersion(), client.MaxAPIVersion)
expectedHeaders := http.Header{
"One": []string{"one-value"},
@@ -115,14 +114,14 @@ func TestNewAPIClientFromFlagsWithCustomHeadersFromEnv(t *testing.T) {
"Four": []string{"four-value-override"},
"User-Agent": []string{UserAgent()},
}
_, err = apiClient.Ping(context.Background())
_, err = apiClient.Ping(context.TODO(), client.PingOptions{})
assert.NilError(t, err)
assert.DeepEqual(t, received, expectedHeaders)
}
func TestNewAPIClientFromFlagsWithAPIVersionFromEnv(t *testing.T) {
const customVersion = "v3.3.3"
const expectedVersion = "3.3.3"
const customVersion = "v3.3"
const expectedVersion = "3.3"
t.Setenv("DOCKER_API_VERSION", customVersion)
t.Setenv("DOCKER_HOST", ":2375")
@@ -135,51 +134,55 @@ func TestNewAPIClientFromFlagsWithAPIVersionFromEnv(t *testing.T) {
type fakeClient struct {
client.Client
pingFunc func() (types.Ping, error)
pingFunc func() (client.PingResult, error)
version string
negotiated bool
}
func (c *fakeClient) Ping(_ context.Context) (types.Ping, error) {
return c.pingFunc()
func (c *fakeClient) Ping(_ context.Context, options client.PingOptions) (client.PingResult, error) {
res, err := c.pingFunc()
if options.NegotiateAPIVersion {
if res.APIVersion != "" {
if c.negotiated || options.ForceNegotiate {
c.negotiated = true
}
}
}
return res, err
}
func (c *fakeClient) ClientVersion() string {
return c.version
}
func (c *fakeClient) NegotiateAPIVersionPing(types.Ping) {
c.negotiated = true
}
func TestInitializeFromClient(t *testing.T) {
const defaultVersion = "v1.55"
testcases := []struct {
doc string
pingFunc func() (types.Ping, error)
pingFunc func() (client.PingResult, error)
expectedServer ServerInfo
negotiated bool
}{
{
doc: "successful ping",
pingFunc: func() (types.Ping, error) {
return types.Ping{Experimental: true, OSType: "linux", APIVersion: "v1.30"}, nil
pingFunc: func() (client.PingResult, error) {
return client.PingResult{Experimental: true, OSType: "linux", APIVersion: "v1.44"}, nil
},
expectedServer: ServerInfo{HasExperimental: true, OSType: "linux"},
negotiated: true,
},
{
doc: "failed ping, no API version",
pingFunc: func() (types.Ping, error) {
return types.Ping{}, errors.New("failed")
pingFunc: func() (client.PingResult, error) {
return client.PingResult{}, errors.New("failed")
},
expectedServer: ServerInfo{HasExperimental: true},
},
{
doc: "failed ping, with API version",
pingFunc: func() (types.Ping, error) {
return types.Ping{APIVersion: "v1.33"}, errors.New("failed")
pingFunc: func() (client.PingResult, error) {
return client.PingResult{APIVersion: "v1.44"}, errors.New("failed")
},
expectedServer: ServerInfo{HasExperimental: true},
negotiated: true,
@@ -188,16 +191,16 @@ func TestInitializeFromClient(t *testing.T) {
for _, tc := range testcases {
t.Run(tc.doc, func(t *testing.T) {
apiclient := &fakeClient{
apiClient := &fakeClient{
pingFunc: tc.pingFunc,
version: defaultVersion,
}
cli := &DockerCli{client: apiclient}
cli := &DockerCli{client: apiClient}
err := cli.Initialize(flags.NewClientOptions())
assert.NilError(t, err)
assert.DeepEqual(t, cli.ServerInfo(), tc.expectedServer)
assert.Equal(t, apiclient.negotiated, tc.negotiated)
assert.Equal(t, apiClient.negotiated, tc.negotiated)
})
}
}
@@ -205,58 +208,82 @@ func TestInitializeFromClient(t *testing.T) {
// Makes sure we don't hang forever on the initial connection.
// https://github.com/docker/cli/issues/3652
func TestInitializeFromClientHangs(t *testing.T) {
const (
// Sized against measured scheduler stalls:
// under CPU pressure this test sees 40-90ms stalls;
// this should give about 5x headroom.
// See https://github.com/docker/cli/issues/6003.
clientInitTimeout = 500 * time.Millisecond
// This is only a backstop against a genuine hang.
// It should never be reached on a healthy run.
// So, it should be fine to have a lenient timeout here.
waitTimeout = 10 * time.Second
)
tmpDir := t.TempDir()
socket := filepath.Join(tmpDir, "my.sock")
l, err := net.Listen("unix", socket)
assert.NilError(t, err)
receiveReqCh := make(chan bool)
timeoutCtx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// Buffered, so the handler can record
// that it was reached without a reader
// having to be ready at that instant.
receivedReqCh := make(chan struct{}, 1)
releaseHandlerCh := make(chan struct{})
// Simulate a server that hangs on connections.
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
select {
case <-timeoutCtx.Done():
case receiveReqCh <- true: // Blocks until someone receives on the channel.
case receivedReqCh <- struct{}{}:
default:
}
_, _ = w.Write([]byte("OK"))
<-releaseHandlerCh
}))
ts.Listener = l
ts.Start()
defer ts.Close()
t.Cleanup(func() {
close(releaseHandlerCh)
ts.Close()
})
opts := &flags.ClientOptions{Hosts: []string{"unix://" + socket}}
configFile := &configfile.ConfigFile{}
apiClient, err := NewAPIClientFromFlags(opts, configFile)
assert.NilError(t, err)
initializedCh := make(chan bool)
initErrCh := make(chan error, 1)
go func() {
cli := &DockerCli{client: apiClient, initTimeout: time.Millisecond}
cli := &DockerCli{client: apiClient, initTimeout: clientInitTimeout}
err := cli.Initialize(flags.NewClientOptions())
assert.Check(t, err)
cli.CurrentVersion()
close(initializedCh)
initErrCh <- err
}()
select {
case <-timeoutCtx.Done():
case err := <-initErrCh:
assert.Check(t, err)
case <-time.After(waitTimeout):
t.Fatal("timeout waiting for initialization to complete")
case <-initializedCh:
}
select {
case <-timeoutCtx.Done():
case <-receivedReqCh:
case <-time.After(waitTimeout):
t.Fatal("server never received an init request")
case <-receiveReqCh:
}
}
func TestNewDockerCliAndOperators(t *testing.T) {
// Test default operations and also overriding default ones
cli, err := NewDockerCli(WithInputStream(io.NopCloser(strings.NewReader("some input"))))
outbuf := bytes.NewBuffer(nil)
errbuf := bytes.NewBuffer(nil)
cli, err := NewDockerCli(
WithInputStream(io.NopCloser(strings.NewReader("some input"))),
WithOutputStream(outbuf),
WithErrorStream(errbuf),
)
assert.NilError(t, err)
// Check streams are initialized
assert.Check(t, cli.In() != nil)
@@ -266,19 +293,6 @@ func TestNewDockerCliAndOperators(t *testing.T) {
assert.NilError(t, err)
assert.Equal(t, string(inputStream), "some input")
// Apply can modify a dockerCli after construction
outbuf := bytes.NewBuffer(nil)
errbuf := bytes.NewBuffer(nil)
err = cli.Apply(
WithInputStream(io.NopCloser(strings.NewReader("input"))),
WithOutputStream(outbuf),
WithErrorStream(errbuf),
)
assert.NilError(t, err)
// Check input stream
inputStream, err = io.ReadAll(cli.In())
assert.NilError(t, err)
assert.Equal(t, string(inputStream), "input")
// Check output stream
_, err = fmt.Fprint(cli.Out(), "output")
assert.NilError(t, err)
@@ -296,9 +310,9 @@ func TestNewDockerCliAndOperators(t *testing.T) {
func TestInitializeShouldAlwaysCreateTheContextStore(t *testing.T) {
cli, err := NewDockerCli()
assert.NilError(t, err)
assert.NilError(t, cli.Initialize(flags.NewClientOptions(), WithInitializeClient(func(cli *DockerCli) (client.APIClient, error) {
return client.NewClientWithOpts()
})))
apiClient, err := client.New()
assert.NilError(t, err)
assert.NilError(t, cli.Initialize(flags.NewClientOptions(), WithAPIClient(apiClient)))
assert.Check(t, cli.ContextStore() != nil)
}
@@ -353,3 +367,70 @@ func TestHooksEnabled(t *testing.T) {
assert.Check(t, !cli.HooksEnabled())
})
}
func TestSetGoDebug(t *testing.T) {
t.Run("GODEBUG already set", func(t *testing.T) {
t.Setenv("GODEBUG", "val1,val2")
meta := store.Metadata{}
setGoDebug(meta)
assert.Equal(t, "val1,val2", os.Getenv("GODEBUG"))
})
t.Run("GODEBUG in context metadata can set env", func(t *testing.T) {
t.Setenv("GODEBUG", "")
meta := store.Metadata{
Metadata: DockerContext{
AdditionalFields: map[string]any{
"GODEBUG": "val1,val2=1",
},
},
}
setGoDebug(meta)
assert.Equal(t, "val1,val2=1", os.Getenv("GODEBUG"))
})
}
func TestNewDockerCliWithCustomUserAgent(t *testing.T) {
var received string
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
received = r.UserAgent()
w.WriteHeader(http.StatusOK)
}))
defer ts.Close()
host := strings.Replace(ts.URL, "http://", "tcp://", 1)
opts := &flags.ClientOptions{Hosts: []string{host}}
cli, err := NewDockerCli(
WithUserAgent("fake-agent/0.0.1"),
)
assert.NilError(t, err)
cli.currentContext = DefaultContextName
cli.options = opts
cli.configFile = &configfile.ConfigFile{}
_, err = cli.Client().Ping(context.TODO(), client.PingOptions{})
assert.NilError(t, err)
assert.DeepEqual(t, received, "fake-agent/0.0.1")
}
func TestNewDockerCliWithAPIClientOptions(t *testing.T) {
var received string
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
received = r.UserAgent()
w.WriteHeader(http.StatusOK)
}))
defer ts.Close()
host := strings.Replace(ts.URL, "http://", "tcp://", 1)
opts := &flags.ClientOptions{Hosts: []string{host}}
cli, err := NewDockerCli(
WithAPIClientOptions(client.WithUserAgent("fake-agent/0.0.1")),
)
assert.NilError(t, err)
cli.currentContext = DefaultContextName
cli.options = opts
cli.configFile = &configfile.ConfigFile{}
_, err = cli.Client().Ping(t.Context(), client.PingOptions{})
assert.NilError(t, err)
assert.DeepEqual(t, received, "fake-agent/0.0.1")
}
+21 -101
View File
@@ -1,110 +1,30 @@
package commands
import (
"os"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/builder"
"github.com/docker/cli/cli/command/checkpoint"
"github.com/docker/cli/cli/command/config"
"github.com/docker/cli/cli/command/container"
"github.com/docker/cli/cli/command/context"
"github.com/docker/cli/cli/command/image"
"github.com/docker/cli/cli/command/manifest"
"github.com/docker/cli/cli/command/network"
"github.com/docker/cli/cli/command/node"
"github.com/docker/cli/cli/command/plugin"
"github.com/docker/cli/cli/command/registry"
"github.com/docker/cli/cli/command/secret"
"github.com/docker/cli/cli/command/service"
"github.com/docker/cli/cli/command/stack"
"github.com/docker/cli/cli/command/swarm"
"github.com/docker/cli/cli/command/system"
"github.com/docker/cli/cli/command/trust"
"github.com/docker/cli/cli/command/volume"
_ "github.com/docker/cli/cli/command/builder"
_ "github.com/docker/cli/cli/command/checkpoint"
_ "github.com/docker/cli/cli/command/config"
_ "github.com/docker/cli/cli/command/container"
_ "github.com/docker/cli/cli/command/context"
_ "github.com/docker/cli/cli/command/image"
_ "github.com/docker/cli/cli/command/manifest"
_ "github.com/docker/cli/cli/command/network"
_ "github.com/docker/cli/cli/command/node"
_ "github.com/docker/cli/cli/command/plugin"
_ "github.com/docker/cli/cli/command/registry"
_ "github.com/docker/cli/cli/command/secret"
_ "github.com/docker/cli/cli/command/service"
_ "github.com/docker/cli/cli/command/stack"
_ "github.com/docker/cli/cli/command/swarm"
_ "github.com/docker/cli/cli/command/system"
_ "github.com/docker/cli/cli/command/volume"
"github.com/docker/cli/internal/commands"
"github.com/spf13/cobra"
)
// AddCommands adds all the commands from cli/command to the root command
func AddCommands(cmd *cobra.Command, dockerCli command.Cli) {
cmd.AddCommand(
// commonly used shorthands
container.NewRunCommand(dockerCli),
container.NewExecCommand(dockerCli),
container.NewPsCommand(dockerCli),
image.NewBuildCommand(dockerCli),
image.NewPullCommand(dockerCli),
image.NewPushCommand(dockerCli),
image.NewImagesCommand(dockerCli),
registry.NewLoginCommand(dockerCli),
registry.NewLogoutCommand(dockerCli),
registry.NewSearchCommand(dockerCli),
system.NewVersionCommand(dockerCli),
system.NewInfoCommand(dockerCli),
// management commands
builder.NewBakeStubCommand(dockerCli),
builder.NewBuilderCommand(dockerCli),
checkpoint.NewCheckpointCommand(dockerCli),
container.NewContainerCommand(dockerCli),
context.NewContextCommand(dockerCli),
image.NewImageCommand(dockerCli),
manifest.NewManifestCommand(dockerCli),
network.NewNetworkCommand(dockerCli),
plugin.NewPluginCommand(dockerCli),
system.NewSystemCommand(dockerCli),
trust.NewTrustCommand(dockerCli),
volume.NewVolumeCommand(dockerCli),
// orchestration (swarm) commands
config.NewConfigCommand(dockerCli),
node.NewNodeCommand(dockerCli),
secret.NewSecretCommand(dockerCli),
service.NewServiceCommand(dockerCli),
stack.NewStackCommand(dockerCli),
swarm.NewSwarmCommand(dockerCli),
// legacy commands may be hidden
hide(container.NewAttachCommand(dockerCli)),
hide(container.NewCommitCommand(dockerCli)),
hide(container.NewCopyCommand(dockerCli)),
hide(container.NewCreateCommand(dockerCli)),
hide(container.NewDiffCommand(dockerCli)),
hide(container.NewExportCommand(dockerCli)),
hide(container.NewKillCommand(dockerCli)),
hide(container.NewLogsCommand(dockerCli)),
hide(container.NewPauseCommand(dockerCli)),
hide(container.NewPortCommand(dockerCli)),
hide(container.NewRenameCommand(dockerCli)),
hide(container.NewRestartCommand(dockerCli)),
hide(container.NewRmCommand(dockerCli)),
hide(container.NewStartCommand(dockerCli)),
hide(container.NewStatsCommand(dockerCli)),
hide(container.NewStopCommand(dockerCli)),
hide(container.NewTopCommand(dockerCli)),
hide(container.NewUnpauseCommand(dockerCli)),
hide(container.NewUpdateCommand(dockerCli)),
hide(container.NewWaitCommand(dockerCli)),
hide(image.NewHistoryCommand(dockerCli)),
hide(image.NewImportCommand(dockerCli)),
hide(image.NewLoadCommand(dockerCli)),
hide(image.NewRemoveCommand(dockerCli)),
hide(image.NewSaveCommand(dockerCli)),
hide(image.NewTagCommand(dockerCli)),
hide(system.NewEventsCommand(dockerCli)),
hide(system.NewInspectCommand(dockerCli)),
)
}
func hide(cmd *cobra.Command) *cobra.Command {
// If the environment variable with name "DOCKER_HIDE_LEGACY_COMMANDS" is not empty,
// these legacy commands (such as `docker ps`, `docker exec`, etc)
// will not be shown in output console.
if os.Getenv("DOCKER_HIDE_LEGACY_COMMANDS") == "" {
return cmd
func AddCommands(cmd *cobra.Command, dockerCLI command.Cli) {
for _, c := range commands.Commands() {
cmd.AddCommand(c(dockerCLI))
}
cmdCopy := *cmd
cmdCopy.Hidden = true
cmdCopy.Aliases = []string{}
return &cmdCopy
}
+136 -47
View File
@@ -4,21 +4,13 @@ import (
"os"
"strings"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/volume"
"github.com/docker/docker/client"
"github.com/distribution/reference"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
// ValidArgsFn a function to be used by cobra command as `ValidArgsFunction` to offer command line completion.
//
// Deprecated: use [cobra.CompletionFunc].
type ValidArgsFn = cobra.CompletionFunc
// APIClientProvider provides a method to get an [client.APIClient], initializing
// APIClientProvider provides a method to get a [client.APIClient], initializing
// it if needed.
//
// It's a smaller interface than [command.Cli], and used in situations where an
@@ -30,28 +22,61 @@ type APIClientProvider interface {
// ImageNames offers completion for images present within the local store
func ImageNames(dockerCLI APIClientProvider, limit int) cobra.CompletionFunc {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return Unique(func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if limit > 0 && len(args) >= limit {
return nil, cobra.ShellCompDirectiveNoFileComp
}
list, err := dockerCLI.Client().ImageList(cmd.Context(), image.ListOptions{})
res, err := dockerCLI.Client().ImageList(cmd.Context(), client.ImageListOptions{})
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
var names []string
for _, img := range list {
for _, img := range res.Items {
names = append(names, img.RepoTags...)
}
return names, cobra.ShellCompDirectiveNoFileComp
}
})
}
// ImageNamesWithBase offers completion for images present within the local store,
// including both full image names with tags and base image names (repository names only)
// when multiple tags exist for the same base name
func ImageNamesWithBase(dockerCLI APIClientProvider, limit int) cobra.CompletionFunc {
return Unique(func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if limit > 0 && len(args) >= limit {
return nil, cobra.ShellCompDirectiveNoFileComp
}
res, err := dockerCLI.Client().ImageList(cmd.Context(), client.ImageListOptions{})
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
var names []string
baseNameCounts := make(map[string]int)
for _, img := range res.Items {
names = append(names, img.RepoTags...)
for _, tag := range img.RepoTags {
ref, err := reference.ParseNormalizedNamed(tag)
if err != nil {
continue
}
baseNameCounts[reference.FamiliarName(ref)]++
}
}
for baseName, count := range baseNameCounts {
if count > 1 {
names = append(names, baseName)
}
}
return names, cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp
})
}
// ContainerNames offers completion for container names and IDs
// By default, only names are returned.
// Set DOCKER_COMPLETION_SHOW_CONTAINER_IDS=yes to also complete IDs.
func ContainerNames(dockerCLI APIClientProvider, all bool, filters ...func(container.Summary) bool) cobra.CompletionFunc {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, err := dockerCLI.Client().ContainerList(cmd.Context(), container.ListOptions{
return Unique(func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
res, err := dockerCLI.Client().ContainerList(cmd.Context(), client.ContainerListOptions{
All: all,
})
if err != nil {
@@ -61,7 +86,7 @@ func ContainerNames(dockerCLI APIClientProvider, all bool, filters ...func(conta
showContainerIDs := os.Getenv("DOCKER_COMPLETION_SHOW_CONTAINER_IDS") == "yes"
var names []string
for _, ctr := range list {
for _, ctr := range res.Items {
skip := false
for _, fn := range filters {
if fn != nil && !fn(ctr) {
@@ -75,40 +100,46 @@ func ContainerNames(dockerCLI APIClientProvider, all bool, filters ...func(conta
if showContainerIDs {
names = append(names, ctr.ID)
}
names = append(names, formatter.StripNamePrefix(ctr.Names)...)
for _, n := range ctr.Names {
// Skip legacy link names: "/linked-container/link-name"
if len(n) <= 1 || strings.IndexByte(n[1:], '/') != -1 {
continue
}
names = append(names, strings.TrimPrefix(n, "/"))
}
}
return names, cobra.ShellCompDirectiveNoFileComp
}
})
}
// VolumeNames offers completion for volumes
func VolumeNames(dockerCLI APIClientProvider) cobra.CompletionFunc {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, err := dockerCLI.Client().VolumeList(cmd.Context(), volume.ListOptions{})
return Unique(func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
res, err := dockerCLI.Client().VolumeList(cmd.Context(), client.VolumeListOptions{})
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
var names []string
for _, vol := range list.Volumes {
for _, vol := range res.Items {
names = append(names, vol.Name)
}
return names, cobra.ShellCompDirectiveNoFileComp
}
})
}
// NetworkNames offers completion for networks
func NetworkNames(dockerCLI APIClientProvider) cobra.CompletionFunc {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, err := dockerCLI.Client().NetworkList(cmd.Context(), network.ListOptions{})
return Unique(func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
res, err := dockerCLI.Client().NetworkList(cmd.Context(), client.NetworkListOptions{})
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
var names []string
for _, nw := range list {
for _, nw := range res.Items {
names = append(names, nw.Name)
}
return names, cobra.ShellCompDirectiveNoFileComp
}
})
}
// EnvVarNames offers completion for environment-variable names. This
@@ -124,31 +155,52 @@ func NetworkNames(dockerCLI APIClientProvider) cobra.CompletionFunc {
// export MY_VAR=hello
// docker run --rm --env MY_VAR alpine printenv MY_VAR
// hello
func EnvVarNames(_ *cobra.Command, _ []string, _ string) (names []string, _ cobra.ShellCompDirective) {
envs := os.Environ()
names = make([]string, 0, len(envs))
for _, env := range envs {
name, _, _ := strings.Cut(env, "=")
names = append(names, name)
}
return names, cobra.ShellCompDirectiveNoFileComp
func EnvVarNames() cobra.CompletionFunc {
return Unique(func(_ *cobra.Command, _ []string, _ string) (names []string, _ cobra.ShellCompDirective) {
envs := os.Environ()
names = make([]string, 0, len(envs))
for _, env := range envs {
name, _, _ := strings.Cut(env, "=")
names = append(names, name)
}
return names, cobra.ShellCompDirectiveNoFileComp
})
}
// FromList offers completion for the given list of options.
func FromList(options ...string) cobra.CompletionFunc {
return cobra.FixedCompletions(options, cobra.ShellCompDirectiveNoFileComp)
return Unique(cobra.FixedCompletions(options, cobra.ShellCompDirectiveNoFileComp))
}
// WithPrefix prefixes every element in the slice with the given prefix.
// It is a helper for building "--filter" completions, where each candidate
// value is offered as "key=value".
func WithPrefix(prefix string, values []string) []string {
result := make([]string, len(values))
for i, v := range values {
result[i] = prefix + v
}
return result
}
// WithSuffix appends the given suffix to every element in the slice. It is a
// helper for building "--filter" completions, where filter keys are offered
// with a trailing "=" (combined with [cobra.ShellCompDirectiveNoSpace]).
func WithSuffix(suffix string, values []string) []string {
result := make([]string, len(values))
for i, v := range values {
result[i] = v + suffix
}
return result
}
// FileNames is a convenience function to use [cobra.ShellCompDirectiveDefault],
// which indicates to let the shell perform its default behavior after
// completions have been provided.
func FileNames(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveDefault
}
// NoComplete is used for commands where there's no relevant completion
func NoComplete(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveNoFileComp
func FileNames() cobra.CompletionFunc {
return func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveDefault
}
}
var commonPlatforms = []string{
@@ -188,6 +240,43 @@ var commonPlatforms = []string{
// - we currently exclude architectures that may have unofficial builds,
// but don't have wide adoption (and no support), such as loong64, mipsXXX,
// ppc64 (non-le) to prevent confusion.
func Platforms(_ *cobra.Command, _ []string, _ string) (platforms []string, _ cobra.ShellCompDirective) {
return commonPlatforms, cobra.ShellCompDirectiveNoFileComp
func Platforms() cobra.CompletionFunc {
return func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return commonPlatforms, cobra.ShellCompDirectiveNoFileComp
}
}
// Unique wraps a completion func and removes completion results that are
// already consumed (i.e., appear in "args").
//
// For example:
//
// # initial completion: args is empty, so all results are shown
// command <tab>
// one two three
//
// # "one" is already used so omitted
// command one <tab>
// two three
func Unique(fn cobra.CompletionFunc) cobra.CompletionFunc {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
all, dir := fn(cmd, args, toComplete)
if len(all) == 0 || len(args) == 0 {
return all, dir
}
alreadyCompleted := make(map[string]struct{}, len(args))
for _, a := range args {
alreadyCompleted[a] = struct{}{}
}
out := make([]string, 0, len(all))
for _, c := range all {
if _, ok := alreadyCompleted[c]; !ok {
out = append(out, c)
}
}
return out, dir
}
}
+98 -59
View File
@@ -6,13 +6,11 @@ import (
"sort"
"testing"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/volume"
"github.com/docker/docker/client"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/network"
"github.com/moby/moby/api/types/volume"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -30,38 +28,38 @@ func (c fakeCLI) Client() client.APIClient {
type fakeClient struct {
client.Client
containerListFunc func(options container.ListOptions) ([]container.Summary, error)
imageListFunc func(options image.ListOptions) ([]image.Summary, error)
networkListFunc func(ctx context.Context, options network.ListOptions) ([]network.Summary, error)
volumeListFunc func(filter filters.Args) (volume.ListResponse, error)
containerListFunc func(context.Context, client.ContainerListOptions) (client.ContainerListResult, error)
imageListFunc func(context.Context, client.ImageListOptions) (client.ImageListResult, error)
networkListFunc func(context.Context, client.NetworkListOptions) (client.NetworkListResult, error)
volumeListFunc func(context.Context, client.VolumeListOptions) (client.VolumeListResult, error)
}
func (c *fakeClient) ContainerList(_ context.Context, options container.ListOptions) ([]container.Summary, error) {
func (c *fakeClient) ContainerList(ctx context.Context, options client.ContainerListOptions) (client.ContainerListResult, error) {
if c.containerListFunc != nil {
return c.containerListFunc(options)
return c.containerListFunc(ctx, options)
}
return []container.Summary{}, nil
return client.ContainerListResult{}, nil
}
func (c *fakeClient) ImageList(_ context.Context, options image.ListOptions) ([]image.Summary, error) {
func (c *fakeClient) ImageList(ctx context.Context, options client.ImageListOptions) (client.ImageListResult, error) {
if c.imageListFunc != nil {
return c.imageListFunc(options)
return c.imageListFunc(ctx, options)
}
return []image.Summary{}, nil
return client.ImageListResult{}, nil
}
func (c *fakeClient) NetworkList(ctx context.Context, options network.ListOptions) ([]network.Summary, error) {
func (c *fakeClient) NetworkList(ctx context.Context, options client.NetworkListOptions) (client.NetworkListResult, error) {
if c.networkListFunc != nil {
return c.networkListFunc(ctx, options)
}
return []network.Inspect{}, nil
return client.NetworkListResult{}, nil
}
func (c *fakeClient) VolumeList(_ context.Context, options volume.ListOptions) (volume.ListResponse, error) {
func (c *fakeClient) VolumeList(ctx context.Context, options client.VolumeListOptions) (client.VolumeListResult, error) {
if c.volumeListFunc != nil {
return c.volumeListFunc(options.Filters)
return c.volumeListFunc(ctx, options)
}
return volume.ListResponse{}, nil
return client.VolumeListResult{}, nil
}
func TestCompleteContainerNames(t *testing.T) {
@@ -71,7 +69,7 @@ func TestCompleteContainerNames(t *testing.T) {
filters []func(container.Summary) bool
containers []container.Summary
expOut []string
expOpts container.ListOptions
expOpts client.ContainerListOptions
expDirective cobra.ShellCompDirective
}{
{
@@ -86,8 +84,8 @@ func TestCompleteContainerNames(t *testing.T) {
{ID: "id-b", State: container.StateCreated, Names: []string{"/container-b"}},
{ID: "id-a", State: container.StateExited, Names: []string{"/container-a"}},
},
expOut: []string{"container-c", "container-c/link-b", "container-b", "container-a"},
expOpts: container.ListOptions{All: true},
expOut: []string{"container-c", "container-b", "container-a"},
expOpts: client.ContainerListOptions{All: true},
expDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
@@ -99,8 +97,8 @@ func TestCompleteContainerNames(t *testing.T) {
{ID: "id-b", State: container.StateCreated, Names: []string{"/container-b"}},
{ID: "id-a", State: container.StateExited, Names: []string{"/container-a"}},
},
expOut: []string{"id-c", "container-c", "container-c/link-b", "id-b", "container-b", "id-a", "container-a"},
expOpts: container.ListOptions{All: true},
expOut: []string{"id-c", "container-c", "id-b", "container-b", "id-a", "container-a"},
expOpts: client.ContainerListOptions{All: true},
expDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
@@ -109,7 +107,7 @@ func TestCompleteContainerNames(t *testing.T) {
containers: []container.Summary{
{ID: "id-c", State: container.StateRunning, Names: []string{"/container-c", "/container-c/link-b"}},
},
expOut: []string{"container-c", "container-c/link-b"},
expOut: []string{"container-c"},
expDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
@@ -119,12 +117,12 @@ func TestCompleteContainerNames(t *testing.T) {
func(ctr container.Summary) bool { return ctr.State == container.StateCreated },
},
containers: []container.Summary{
{ID: "id-c", State: container.StateRunning, Names: []string{"/container-c", "/container-c/link-b"}},
{ID: "id-c", State: container.StateRunning, Names: []string{"/container-c"}},
{ID: "id-b", State: container.StateCreated, Names: []string{"/container-b"}},
{ID: "id-a", State: container.StateExited, Names: []string{"/container-a"}},
},
expOut: []string{"container-b"},
expOpts: container.ListOptions{All: true},
expOpts: client.ContainerListOptions{All: true},
expDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
@@ -135,12 +133,12 @@ func TestCompleteContainerNames(t *testing.T) {
func(ctr container.Summary) bool { return ctr.State == container.StateCreated },
},
containers: []container.Summary{
{ID: "id-c", State: container.StateRunning, Names: []string{"/container-c", "/container-c/link-b"}},
{ID: "id-c", State: container.StateRunning, Names: []string{"/container-c"}},
{ID: "id-b", State: container.StateCreated, Names: []string{"/container-b"}},
{ID: "id-a", State: container.StateCreated, Names: []string{"/container-a"}},
},
expOut: []string{"container-a"},
expOpts: container.ListOptions{All: true},
expOpts: client.ContainerListOptions{All: true},
expDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
@@ -155,12 +153,12 @@ func TestCompleteContainerNames(t *testing.T) {
t.Setenv("DOCKER_COMPLETION_SHOW_CONTAINER_IDS", "yes")
}
comp := ContainerNames(fakeCLI{&fakeClient{
containerListFunc: func(opts container.ListOptions) ([]container.Summary, error) {
assert.Check(t, is.DeepEqual(opts, tc.expOpts, cmpopts.IgnoreUnexported(container.ListOptions{}, filters.Args{})))
containerListFunc: func(_ context.Context, opts client.ContainerListOptions) (client.ContainerListResult, error) {
assert.Check(t, is.DeepEqual(opts, tc.expOpts))
if tc.expDirective == cobra.ShellCompDirectiveError {
return nil, errors.New("some error occurred")
return client.ContainerListResult{}, errors.New("some error occurred")
}
return tc.containers, nil
return client.ContainerListResult{Items: tc.containers}, nil
},
}}, tc.showAll, tc.filters...)
@@ -176,7 +174,7 @@ func TestCompleteEnvVarNames(t *testing.T) {
"ENV_A": "hello-a",
"ENV_B": "hello-b",
})
values, directives := EnvVarNames(nil, nil, "")
values, directives := EnvVarNames()(nil, nil, "")
assert.Check(t, is.Equal(directives&cobra.ShellCompDirectiveNoFileComp, cobra.ShellCompDirectiveNoFileComp), "Should not perform file completion")
sort.Strings(values)
@@ -185,7 +183,7 @@ func TestCompleteEnvVarNames(t *testing.T) {
}
func TestCompleteFileNames(t *testing.T) {
values, directives := FileNames(nil, nil, "")
values, directives := FileNames()(nil, nil, "")
assert.Check(t, is.Equal(directives, cobra.ShellCompDirectiveDefault))
assert.Check(t, is.Len(values, 0))
}
@@ -198,6 +196,18 @@ func TestCompleteFromList(t *testing.T) {
assert.Check(t, is.DeepEqual(values, expected))
}
func TestWithPrefix(t *testing.T) {
assert.Check(t, is.DeepEqual(WithPrefix("node=", []string{"n1", "n2"}), []string{"node=n1", "node=n2"}))
assert.Check(t, is.DeepEqual(WithPrefix("node=", []string{}), []string{}))
assert.Check(t, is.DeepEqual(WithPrefix("", []string{"n1"}), []string{"n1"}))
}
func TestWithSuffix(t *testing.T) {
assert.Check(t, is.DeepEqual(WithSuffix("=", []string{"id", "name"}), []string{"id=", "name="}))
assert.Check(t, is.DeepEqual(WithSuffix("=", []string{}), []string{}))
assert.Check(t, is.DeepEqual(WithSuffix("", []string{"id"}), []string{"id"}))
}
func TestCompleteImageNames(t *testing.T) {
tests := []struct {
doc string
@@ -228,11 +238,11 @@ func TestCompleteImageNames(t *testing.T) {
for _, tc := range tests {
t.Run(tc.doc, func(t *testing.T) {
comp := ImageNames(fakeCLI{&fakeClient{
imageListFunc: func(options image.ListOptions) ([]image.Summary, error) {
imageListFunc: func(context.Context, client.ImageListOptions) (client.ImageListResult, error) {
if tc.expDirective == cobra.ShellCompDirectiveError {
return nil, errors.New("some error occurred")
return client.ImageListResult{}, errors.New("some error occurred")
}
return tc.images, nil
return client.ImageListResult{Items: tc.images}, nil
},
}}, -1)
@@ -257,9 +267,24 @@ func TestCompleteNetworkNames(t *testing.T) {
{
doc: "with results",
networks: []network.Summary{
{ID: "nw-c", Name: "network-c"},
{ID: "nw-b", Name: "network-b"},
{ID: "nw-a", Name: "network-a"},
{
Network: network.Network{
ID: "nw-c",
Name: "network-c",
},
},
{
Network: network.Network{
ID: "nw-b",
Name: "network-b",
},
},
{
Network: network.Network{
ID: "nw-a",
Name: "network-a",
},
},
},
expOut: []string{"network-c", "network-b", "network-a"},
expDirective: cobra.ShellCompDirectiveNoFileComp,
@@ -273,11 +298,11 @@ func TestCompleteNetworkNames(t *testing.T) {
for _, tc := range tests {
t.Run(tc.doc, func(t *testing.T) {
comp := NetworkNames(fakeCLI{&fakeClient{
networkListFunc: func(ctx context.Context, options network.ListOptions) ([]network.Summary, error) {
networkListFunc: func(context.Context, client.NetworkListOptions) (client.NetworkListResult, error) {
if tc.expDirective == cobra.ShellCompDirectiveError {
return nil, errors.New("some error occurred")
return client.NetworkListResult{}, errors.New("some error occurred")
}
return tc.networks, nil
return client.NetworkListResult{Items: tc.networks}, nil
},
}})
@@ -288,14 +313,8 @@ func TestCompleteNetworkNames(t *testing.T) {
}
}
func TestCompleteNoComplete(t *testing.T) {
values, directives := NoComplete(nil, nil, "")
assert.Check(t, is.Equal(directives, cobra.ShellCompDirectiveNoFileComp))
assert.Check(t, is.Len(values, 0))
}
func TestCompletePlatforms(t *testing.T) {
values, directives := Platforms(nil, nil, "")
values, directives := Platforms()(nil, nil, "")
assert.Check(t, is.Equal(directives&cobra.ShellCompDirectiveNoFileComp, cobra.ShellCompDirectiveNoFileComp), "Should not perform file completion")
assert.Check(t, is.DeepEqual(values, commonPlatforms))
}
@@ -303,7 +322,7 @@ func TestCompletePlatforms(t *testing.T) {
func TestCompleteVolumeNames(t *testing.T) {
tests := []struct {
doc string
volumes []*volume.Volume
volumes []volume.Volume
expOut []string
expDirective cobra.ShellCompDirective
}{
@@ -313,7 +332,7 @@ func TestCompleteVolumeNames(t *testing.T) {
},
{
doc: "with results",
volumes: []*volume.Volume{
volumes: []volume.Volume{
{Name: "volume-c"},
{Name: "volume-b"},
{Name: "volume-a"},
@@ -330,11 +349,11 @@ func TestCompleteVolumeNames(t *testing.T) {
for _, tc := range tests {
t.Run(tc.doc, func(t *testing.T) {
comp := VolumeNames(fakeCLI{&fakeClient{
volumeListFunc: func(filter filters.Args) (volume.ListResponse, error) {
volumeListFunc: func(context.Context, client.VolumeListOptions) (client.VolumeListResult, error) {
if tc.expDirective == cobra.ShellCompDirectiveError {
return volume.ListResponse{}, errors.New("some error occurred")
return client.VolumeListResult{}, errors.New("some error occurred")
}
return volume.ListResponse{Volumes: tc.volumes}, nil
return client.VolumeListResult{Items: tc.volumes}, nil
},
}})
@@ -344,3 +363,23 @@ func TestCompleteVolumeNames(t *testing.T) {
})
}
}
func TestUnique(t *testing.T) {
base := []string{"alpha", "beta", "gamma"}
comp := Unique(func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
return base, cobra.ShellCompDirectiveNoFileComp
})
values, directives := comp(&cobra.Command{}, []string{"beta"}, "")
assert.Check(t, is.Equal(directives&cobra.ShellCompDirectiveNoFileComp, cobra.ShellCompDirectiveNoFileComp))
assert.Check(t, is.DeepEqual(values, []string{"alpha", "gamma"}))
assert.Check(t, is.DeepEqual(base, []string{"alpha", "beta", "gamma"}))
values, directives = comp(&cobra.Command{}, []string{"gamma"}, "")
assert.Check(t, is.Equal(directives&cobra.ShellCompDirectiveNoFileComp, cobra.ShellCompDirectiveNoFileComp))
assert.Check(t, is.DeepEqual(values, []string{"alpha", "beta"}))
assert.Check(t, is.DeepEqual(base, []string{"alpha", "beta", "gamma"}))
}
+16 -17
View File
@@ -3,42 +3,41 @@ package config
import (
"context"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/client"
"github.com/moby/moby/client"
)
type fakeClient struct {
client.Client
configCreateFunc func(context.Context, swarm.ConfigSpec) (swarm.ConfigCreateResponse, error)
configInspectFunc func(context.Context, string) (swarm.Config, []byte, error)
configListFunc func(context.Context, swarm.ConfigListOptions) ([]swarm.Config, error)
configRemoveFunc func(string) error
configCreateFunc func(context.Context, client.ConfigCreateOptions) (client.ConfigCreateResult, error)
configInspectFunc func(context.Context, string, client.ConfigInspectOptions) (client.ConfigInspectResult, error)
configListFunc func(context.Context, client.ConfigListOptions) (client.ConfigListResult, error)
configRemoveFunc func(context.Context, string, client.ConfigRemoveOptions) (client.ConfigRemoveResult, error)
}
func (c *fakeClient) ConfigCreate(ctx context.Context, spec swarm.ConfigSpec) (swarm.ConfigCreateResponse, error) {
func (c *fakeClient) ConfigCreate(ctx context.Context, options client.ConfigCreateOptions) (client.ConfigCreateResult, error) {
if c.configCreateFunc != nil {
return c.configCreateFunc(ctx, spec)
return c.configCreateFunc(ctx, options)
}
return swarm.ConfigCreateResponse{}, nil
return client.ConfigCreateResult{}, nil
}
func (c *fakeClient) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.Config, []byte, error) {
func (c *fakeClient) ConfigInspect(ctx context.Context, id string, options client.ConfigInspectOptions) (client.ConfigInspectResult, error) {
if c.configInspectFunc != nil {
return c.configInspectFunc(ctx, id)
return c.configInspectFunc(ctx, id, options)
}
return swarm.Config{}, nil, nil
return client.ConfigInspectResult{}, nil
}
func (c *fakeClient) ConfigList(ctx context.Context, options swarm.ConfigListOptions) ([]swarm.Config, error) {
func (c *fakeClient) ConfigList(ctx context.Context, options client.ConfigListOptions) (client.ConfigListResult, error) {
if c.configListFunc != nil {
return c.configListFunc(ctx, options)
}
return []swarm.Config{}, nil
return client.ConfigListResult{}, nil
}
func (c *fakeClient) ConfigRemove(_ context.Context, name string) error {
func (c *fakeClient) ConfigRemove(ctx context.Context, name string, options client.ConfigRemoveOptions) (client.ConfigRemoveResult, error) {
if c.configRemoveFunc != nil {
return c.configRemoveFunc(name)
return c.configRemoveFunc(ctx, name, options)
}
return nil
return client.ConfigRemoveResult{}, nil
}
+16 -10
View File
@@ -4,27 +4,33 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/cli/internal/commands"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
// NewConfigCommand returns a cobra command for `config` subcommands
func NewConfigCommand(dockerCli command.Cli) *cobra.Command {
func init() {
commands.Register(newConfigCommand)
}
// newConfigCommand returns a cobra command for `config` subcommands
func newConfigCommand(dockerCLI command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "config",
Short: "Manage Swarm configs",
Args: cli.NoArgs,
RunE: command.ShowHelp(dockerCli.Err()),
RunE: command.ShowHelp(dockerCLI.Err()),
Annotations: map[string]string{
"version": "1.30",
"swarm": "manager",
},
DisableFlagsInUseLine: true,
}
cmd.AddCommand(
newConfigListCommand(dockerCli),
newConfigCreateCommand(dockerCli),
newConfigInspectCommand(dockerCli),
newConfigRemoveCommand(dockerCli),
newConfigListCommand(dockerCLI),
newConfigCreateCommand(dockerCLI),
newConfigInspectCommand(dockerCLI),
newConfigRemoveCommand(dockerCLI),
)
return cmd
}
@@ -32,12 +38,12 @@ func NewConfigCommand(dockerCli command.Cli) *cobra.Command {
// completeNames offers completion for swarm configs
func completeNames(dockerCLI completion.APIClientProvider) cobra.CompletionFunc {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, err := dockerCLI.Client().ConfigList(cmd.Context(), swarm.ConfigListOptions{})
res, err := dockerCLI.Client().ConfigList(cmd.Context(), client.ConfigListOptions{})
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
var names []string
for _, config := range list {
for _, config := range res.Items {
names = append(names, config.ID)
}
return names, cobra.ShellCompDirectiveNoFileComp
+47 -28
View File
@@ -2,30 +2,30 @@ package config
import (
"context"
"errors"
"fmt"
"io"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/swarm"
"github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client"
"github.com/moby/sys/sequential"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
// CreateOptions specifies some options that are used when creating a config.
type CreateOptions struct {
Name string
TemplateDriver string
File string
Labels opts.ListOpts
// createOptions specifies some options that are used when creating a config.
type createOptions struct {
name string
templateDriver string
file string
labels opts.ListOpts
}
func newConfigCreateCommand(dockerCli command.Cli) *cobra.Command {
createOpts := CreateOptions{
Labels: opts.NewListOpts(opts.ValidateLabel),
func newConfigCreateCommand(dockerCLI command.Cli) *cobra.Command {
createOpts := createOptions{
labels: opts.NewListOpts(opts.ValidateLabel),
}
cmd := &cobra.Command{
@@ -33,42 +33,61 @@ func newConfigCreateCommand(dockerCli command.Cli) *cobra.Command {
Short: "Create a config from a file or STDIN",
Args: cli.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
createOpts.Name = args[0]
createOpts.File = args[1]
return RunConfigCreate(cmd.Context(), dockerCli, createOpts)
createOpts.name = args[0]
createOpts.file = args[1]
return runCreate(cmd.Context(), dockerCLI, createOpts)
},
ValidArgsFunction: completion.NoComplete,
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
switch len(args) {
case 0:
// No completion for the first argument, which is the name for
// the new config, but if a non-empty name is given, we return
// it as completion to allow "tab"-ing to the next completion.
return []string{toComplete}, cobra.ShellCompDirectiveNoFileComp
case 1:
// Second argument is either "-" or a file to load.
//
// TODO(thaJeztah): provide completion for "-".
return nil, cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveDefault
default:
// Command only accepts two arguments.
return nil, cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp
}
},
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
flags.VarP(&createOpts.Labels, "label", "l", "Config labels")
flags.StringVar(&createOpts.TemplateDriver, "template-driver", "", "Template driver")
flags.SetAnnotation("template-driver", "version", []string{"1.37"})
flags.VarP(&createOpts.labels, "label", "l", "Config labels")
flags.StringVar(&createOpts.templateDriver, "template-driver", "", "Template driver")
_ = flags.SetAnnotation("template-driver", "version", []string{"1.37"})
return cmd
}
// RunConfigCreate creates a config with the given options.
func RunConfigCreate(ctx context.Context, dockerCLI command.Cli, options CreateOptions) error {
// runCreate creates a config with the given options.
func runCreate(ctx context.Context, dockerCLI command.Cli, options createOptions) error {
apiClient := dockerCLI.Client()
configData, err := readConfigData(dockerCLI.In(), options.File)
configData, err := readConfigData(dockerCLI.In(), options.file)
if err != nil {
return errors.Errorf("Error reading content from %q: %v", options.File, err)
return fmt.Errorf("error reading content from %q: %v", options.file, err)
}
spec := swarm.ConfigSpec{
Annotations: swarm.Annotations{
Name: options.Name,
Labels: opts.ConvertKVStringsToMap(options.Labels.GetSlice()),
Name: options.name,
Labels: opts.ConvertKVStringsToMap(options.labels.GetSlice()),
},
Data: configData,
}
if options.TemplateDriver != "" {
if options.templateDriver != "" {
spec.Templating = &swarm.Driver{
Name: options.TemplateDriver,
Name: options.templateDriver,
}
}
r, err := apiClient.ConfigCreate(ctx, spec)
r, err := apiClient.ConfigCreate(ctx, client.ConfigCreateOptions{
Spec: spec,
})
if err != nil {
return err
}
+23 -22
View File
@@ -12,7 +12,8 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/swarm"
"github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/golden"
@@ -23,7 +24,7 @@ const configDataFile = "config-create-with-name.golden"
func TestConfigCreateErrors(t *testing.T) {
testCases := []struct {
args []string
configCreateFunc func(context.Context, swarm.ConfigSpec) (swarm.ConfigCreateResponse, error)
configCreateFunc func(context.Context, client.ConfigCreateOptions) (client.ConfigCreateResult, error)
expectedError string
}{
{
@@ -36,8 +37,8 @@ func TestConfigCreateErrors(t *testing.T) {
},
{
args: []string{"name", filepath.Join("testdata", configDataFile)},
configCreateFunc: func(_ context.Context, configSpec swarm.ConfigSpec) (swarm.ConfigCreateResponse, error) {
return swarm.ConfigCreateResponse{}, errors.New("error creating config")
configCreateFunc: func(_ context.Context, options client.ConfigCreateOptions) (client.ConfigCreateResult, error) {
return client.ConfigCreateResult{}, errors.New("error creating config")
},
expectedError: "error creating config",
},
@@ -61,15 +62,15 @@ func TestConfigCreateWithName(t *testing.T) {
const name = "config-with-name"
var actual []byte
cli := test.NewFakeCli(&fakeClient{
configCreateFunc: func(_ context.Context, spec swarm.ConfigSpec) (swarm.ConfigCreateResponse, error) {
if spec.Name != name {
return swarm.ConfigCreateResponse{}, fmt.Errorf("expected name %q, got %q", name, spec.Name)
configCreateFunc: func(_ context.Context, options client.ConfigCreateOptions) (client.ConfigCreateResult, error) {
if options.Spec.Name != name {
return client.ConfigCreateResult{}, fmt.Errorf("expected name %q, got %q", name, options.Spec.Name)
}
actual = spec.Data
actual = options.Spec.Data
return swarm.ConfigCreateResponse{
ID: "ID-" + spec.Name,
return client.ConfigCreateResult{
ID: "ID-" + options.Spec.Name,
}, nil
},
})
@@ -100,13 +101,13 @@ func TestConfigCreateWithLabels(t *testing.T) {
}
cli := test.NewFakeCli(&fakeClient{
configCreateFunc: func(_ context.Context, spec swarm.ConfigSpec) (swarm.ConfigCreateResponse, error) {
if !reflect.DeepEqual(spec, expected) {
return swarm.ConfigCreateResponse{}, fmt.Errorf("expected %+v, got %+v", expected, spec)
configCreateFunc: func(_ context.Context, options client.ConfigCreateOptions) (client.ConfigCreateResult, error) {
if !reflect.DeepEqual(options.Spec, expected) {
return client.ConfigCreateResult{}, fmt.Errorf("expected %+v, got %+v", expected, options.Spec)
}
return swarm.ConfigCreateResponse{
ID: "ID-" + spec.Name,
return client.ConfigCreateResult{
ID: "ID-" + options.Spec.Name,
}, nil
},
})
@@ -126,17 +127,17 @@ func TestConfigCreateWithTemplatingDriver(t *testing.T) {
const name = "config-with-template-driver"
cli := test.NewFakeCli(&fakeClient{
configCreateFunc: func(_ context.Context, spec swarm.ConfigSpec) (swarm.ConfigCreateResponse, error) {
if spec.Name != name {
return swarm.ConfigCreateResponse{}, fmt.Errorf("expected name %q, got %q", name, spec.Name)
configCreateFunc: func(_ context.Context, options client.ConfigCreateOptions) (client.ConfigCreateResult, error) {
if options.Spec.Name != name {
return client.ConfigCreateResult{}, fmt.Errorf("expected name %q, got %q", name, options.Spec.Name)
}
if spec.Templating.Name != expectedDriver.Name {
return swarm.ConfigCreateResponse{}, fmt.Errorf("expected driver %v, got %v", expectedDriver, spec.Labels)
if options.Spec.Templating.Name != expectedDriver.Name {
return client.ConfigCreateResult{}, fmt.Errorf("expected driver %v, got %v", expectedDriver, options.Spec.Labels)
}
return swarm.ConfigCreateResponse{
ID: "ID-" + spec.Name,
return client.ConfigCreateResult{
ID: "ID-" + options.Spec.Name,
}, nil
},
})
+32 -30
View File
@@ -1,14 +1,19 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.25
package config
import (
"fmt"
"slices"
"strings"
"time"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/cli/cli/command/inspect"
"github.com/docker/docker/api/types/swarm"
units "github.com/docker/go-units"
"github.com/docker/go-units"
"github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client"
)
const (
@@ -29,8 +34,8 @@ Data:
{{.Data}}`
)
// NewFormat returns a Format for rendering using a config Context
func NewFormat(source string, quiet bool) formatter.Format {
// newFormat returns a Format for rendering using a configContext.
func newFormat(source string, quiet bool) formatter.Format {
switch source {
case formatter.PrettyFormatKey:
return configInspectPrettyTemplate
@@ -43,31 +48,28 @@ func NewFormat(source string, quiet bool) formatter.Format {
return formatter.Format(source)
}
// FormatWrite writes the context
func FormatWrite(ctx formatter.Context, configs []swarm.Config) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, config := range configs {
// formatWrite writes the context
func formatWrite(fmtCtx formatter.Context, configs client.ConfigListResult) error {
cCtx := &configContext{
HeaderContext: formatter.HeaderContext{
Header: formatter.SubHeaderContext{
"ID": configIDHeader,
"Name": formatter.NameHeader,
"CreatedAt": configCreatedHeader,
"UpdatedAt": configUpdatedHeader,
"Labels": formatter.LabelsHeader,
},
},
}
return fmtCtx.Write(cCtx, func(format func(subContext formatter.SubContext) error) error {
for _, config := range configs.Items {
configCtx := &configContext{c: config}
if err := format(configCtx); err != nil {
return err
}
}
return nil
}
return ctx.Write(newConfigContext(), render)
}
func newConfigContext() *configContext {
cCtx := &configContext{}
cCtx.Header = formatter.SubHeaderContext{
"ID": configIDHeader,
"Name": formatter.NameHeader,
"CreatedAt": configCreatedHeader,
"UpdatedAt": configUpdatedHeader,
"Labels": formatter.LabelsHeader,
}
return cCtx
})
}
type configContext struct {
@@ -104,6 +106,7 @@ func (c *configContext) Labels() string {
for k, v := range mapLabels {
joinLabels = append(joinLabels, k+"="+v)
}
slices.Sort(joinLabels)
return strings.Join(joinLabels, ",")
}
@@ -114,12 +117,12 @@ func (c *configContext) Label(name string) string {
return c.c.Spec.Annotations.Labels[name]
}
// InspectFormatWrite renders the context for a list of configs
func InspectFormatWrite(ctx formatter.Context, refs []string, getRef inspect.GetRefFunc) error {
if ctx.Format != configInspectPrettyTemplate {
return inspect.Inspect(ctx.Output, refs, string(ctx.Format), getRef)
// inspectFormatWrite renders the context for a list of configs
func inspectFormatWrite(fmtCtx formatter.Context, refs []string, getRef inspect.GetRefFunc) error {
if fmtCtx.Format != configInspectPrettyTemplate {
return inspect.Inspect(fmtCtx.Output, refs, string(fmtCtx.Format), getRef)
}
render := func(format func(subContext formatter.SubContext) error) error {
return fmtCtx.Write(&configInspectContext{}, func(format func(subContext formatter.SubContext) error) error {
for _, ref := range refs {
configI, _, err := getRef(ref)
if err != nil {
@@ -134,8 +137,7 @@ func InspectFormatWrite(ctx formatter.Context, refs []string, getRef inspect.Get
}
}
return nil
}
return ctx.Write(&configInspectContext{}, render)
})
}
type configInspectContext struct {
+18 -15
View File
@@ -6,7 +6,8 @@ import (
"time"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/docker/api/types/swarm"
"github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
)
@@ -27,44 +28,46 @@ func TestConfigContextFormatWrite(t *testing.T) {
},
// Table format
{
formatter.Context{Format: NewFormat("table", false)},
formatter.Context{Format: newFormat("table", false)},
`ID NAME CREATED UPDATED
1 passwords Less than a second ago Less than a second ago
2 id_rsa Less than a second ago Less than a second ago
`,
},
{
formatter.Context{Format: NewFormat("table {{.Name}}", true)},
formatter.Context{Format: newFormat("table {{.Name}}", true)},
`NAME
passwords
id_rsa
`,
},
{
formatter.Context{Format: NewFormat("{{.ID}}-{{.Name}}", false)},
formatter.Context{Format: newFormat("{{.ID}}-{{.Name}}", false)},
`1-passwords
2-id_rsa
`,
},
}
configs := []swarm.Config{
{
ID: "1",
Meta: swarm.Meta{CreatedAt: time.Now(), UpdatedAt: time.Now()},
Spec: swarm.ConfigSpec{Annotations: swarm.Annotations{Name: "passwords"}},
},
{
ID: "2",
Meta: swarm.Meta{CreatedAt: time.Now(), UpdatedAt: time.Now()},
Spec: swarm.ConfigSpec{Annotations: swarm.Annotations{Name: "id_rsa"}},
res := client.ConfigListResult{
Items: []swarm.Config{
{
ID: "1",
Meta: swarm.Meta{CreatedAt: time.Now(), UpdatedAt: time.Now()},
Spec: swarm.ConfigSpec{Annotations: swarm.Annotations{Name: "passwords"}},
},
{
ID: "2",
Meta: swarm.Meta{CreatedAt: time.Now(), UpdatedAt: time.Now()},
Spec: swarm.ConfigSpec{Annotations: swarm.Annotations{Name: "id_rsa"}},
},
},
}
for _, tc := range cases {
t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer
tc.context.Output = &out
if err := FormatWrite(tc.context, configs); err != nil {
if err := formatWrite(tc.context, res); err != nil {
assert.ErrorContains(t, err, tc.expected)
} else {
assert.Equal(t, out.String(), tc.expected)
+24 -24
View File
@@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.23
//go:build go1.25
package config
@@ -12,61 +12,61 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/formatter"
flagsHelper "github.com/docker/cli/cli/flags"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
// InspectOptions contains options for the docker config inspect command.
type InspectOptions struct {
Names []string
Format string
Pretty bool
// inspectOptions contains options for the docker config inspect command.
type inspectOptions struct {
names []string
format string
pretty bool
}
func newConfigInspectCommand(dockerCli command.Cli) *cobra.Command {
opts := InspectOptions{}
func newConfigInspectCommand(dockerCLI command.Cli) *cobra.Command {
opts := inspectOptions{}
cmd := &cobra.Command{
Use: "inspect [OPTIONS] CONFIG [CONFIG...]",
Short: "Display detailed information on one or more configs",
Args: cli.RequiresMinArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.Names = args
return RunConfigInspect(cmd.Context(), dockerCli, opts)
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return completeNames(dockerCli)(cmd, args, toComplete)
opts.names = args
return runInspect(cmd.Context(), dockerCLI, opts)
},
ValidArgsFunction: completeNames(dockerCLI),
DisableFlagsInUseLine: true,
}
cmd.Flags().StringVarP(&opts.Format, "format", "f", "", flagsHelper.InspectFormatHelp)
cmd.Flags().BoolVar(&opts.Pretty, "pretty", false, "Print the information in a human friendly format")
cmd.Flags().StringVarP(&opts.format, "format", "f", "", flagsHelper.InspectFormatHelp)
cmd.Flags().BoolVar(&opts.pretty, "pretty", false, "Print the information in a human friendly format")
return cmd
}
// RunConfigInspect inspects the given Swarm config.
func RunConfigInspect(ctx context.Context, dockerCLI command.Cli, opts InspectOptions) error {
// runInspect inspects the given Swarm config.
func runInspect(ctx context.Context, dockerCLI command.Cli, opts inspectOptions) error {
apiClient := dockerCLI.Client()
if opts.Pretty {
opts.Format = "pretty"
if opts.pretty {
opts.format = "pretty"
}
getRef := func(id string) (any, []byte, error) {
return apiClient.ConfigInspectWithRaw(ctx, id)
res, err := apiClient.ConfigInspect(ctx, id, client.ConfigInspectOptions{})
return res.Config, res.Raw, err
}
f := opts.Format
// check if the user is trying to apply a template to the pretty format, which
// is not supported
if strings.HasPrefix(f, "pretty") && f != "pretty" {
if strings.HasPrefix(opts.format, "pretty") && opts.format != "pretty" {
return errors.New("cannot supply extra formatting options to the pretty template")
}
configCtx := formatter.Context{
Output: dockerCLI.Out(),
Format: NewFormat(f, false),
Format: newFormat(opts.format, false),
}
if err := InspectFormatWrite(configCtx, opts.Names, getRef); err != nil {
if err := inspectFormatWrite(configCtx, opts.names, getRef); err != nil {
return cli.StatusError{StatusCode: 1, Status: err.Error()}
}
return nil
+48 -32
View File
@@ -10,7 +10,7 @@ import (
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/builders"
"github.com/docker/docker/api/types/swarm"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
"gotest.tools/v3/golden"
)
@@ -19,7 +19,7 @@ func TestConfigInspectErrors(t *testing.T) {
testCases := []struct {
args []string
flags map[string]string
configInspectFunc func(_ context.Context, configID string) (swarm.Config, []byte, error)
configInspectFunc func(_ context.Context, configID string, _ client.ConfigInspectOptions) (client.ConfigInspectResult, error)
expectedError string
}{
{
@@ -27,8 +27,8 @@ func TestConfigInspectErrors(t *testing.T) {
},
{
args: []string{"foo"},
configInspectFunc: func(_ context.Context, configID string) (swarm.Config, []byte, error) {
return swarm.Config{}, nil, errors.New("error while inspecting the config")
configInspectFunc: func(context.Context, string, client.ConfigInspectOptions) (client.ConfigInspectResult, error) {
return client.ConfigInspectResult{}, errors.New("error while inspecting the config")
},
expectedError: "error while inspecting the config",
},
@@ -41,11 +41,13 @@ func TestConfigInspectErrors(t *testing.T) {
},
{
args: []string{"foo", "bar"},
configInspectFunc: func(_ context.Context, configID string) (swarm.Config, []byte, error) {
configInspectFunc: func(_ context.Context, configID string, _ client.ConfigInspectOptions) (client.ConfigInspectResult, error) {
if configID == "foo" {
return *builders.Config(builders.ConfigName("foo")), nil, nil
return client.ConfigInspectResult{
Config: *builders.Config(builders.ConfigName("foo")),
}, nil
}
return swarm.Config{}, nil, errors.New("error while inspecting the config")
return client.ConfigInspectResult{}, errors.New("error while inspecting the config")
},
expectedError: "error while inspecting the config",
},
@@ -70,25 +72,34 @@ func TestConfigInspectWithoutFormat(t *testing.T) {
testCases := []struct {
name string
args []string
configInspectFunc func(_ context.Context, configID string) (swarm.Config, []byte, error)
configInspectFunc func(_ context.Context, configID string, _ client.ConfigInspectOptions) (client.ConfigInspectResult, error)
}{
{
name: "single-config",
args: []string{"foo"},
configInspectFunc: func(_ context.Context, name string) (swarm.Config, []byte, error) {
configInspectFunc: func(_ context.Context, name string, _ client.ConfigInspectOptions) (client.ConfigInspectResult, error) {
if name != "foo" {
return swarm.Config{}, nil, fmt.Errorf("invalid name, expected %s, got %s", "foo", name)
return client.ConfigInspectResult{}, fmt.Errorf("invalid name, expected %s, got %s", "foo", name)
}
return *builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")), nil, nil
return client.ConfigInspectResult{
Config: *builders.Config(
builders.ConfigID("ID-foo"),
builders.ConfigName("foo"),
),
}, nil
},
},
{
name: "multiple-configs-with-labels",
args: []string{"foo", "bar"},
configInspectFunc: func(_ context.Context, name string) (swarm.Config, []byte, error) {
return *builders.Config(builders.ConfigID("ID-"+name), builders.ConfigName(name), builders.ConfigLabels(map[string]string{
"label1": "label-foo",
})), nil, nil
configInspectFunc: func(_ context.Context, name string, _ client.ConfigInspectOptions) (client.ConfigInspectResult, error) {
return client.ConfigInspectResult{
Config: *builders.Config(
builders.ConfigID("ID-"+name),
builders.ConfigName(name),
builders.ConfigLabels(map[string]string{"label1": "label-foo"}),
),
}, nil
},
},
}
@@ -102,16 +113,19 @@ func TestConfigInspectWithoutFormat(t *testing.T) {
}
func TestConfigInspectWithFormat(t *testing.T) {
configInspectFunc := func(_ context.Context, name string) (swarm.Config, []byte, error) {
return *builders.Config(builders.ConfigName("foo"), builders.ConfigLabels(map[string]string{
"label1": "label-foo",
})), nil, nil
configInspectFunc := func(_ context.Context, name string, _ client.ConfigInspectOptions) (client.ConfigInspectResult, error) {
return client.ConfigInspectResult{
Config: *builders.Config(
builders.ConfigName("foo"),
builders.ConfigLabels(map[string]string{"label1": "label-foo"}),
),
}, nil
}
testCases := []struct {
name string
format string
args []string
configInspectFunc func(_ context.Context, name string) (swarm.Config, []byte, error)
configInspectFunc func(_ context.Context, name string, _ client.ConfigInspectOptions) (client.ConfigInspectResult, error)
}{
{
name: "simple-template",
@@ -141,21 +155,23 @@ func TestConfigInspectWithFormat(t *testing.T) {
func TestConfigInspectPretty(t *testing.T) {
testCases := []struct {
name string
configInspectFunc func(context.Context, string) (swarm.Config, []byte, error)
configInspectFunc func(context.Context, string, client.ConfigInspectOptions) (client.ConfigInspectResult, error)
}{
{
name: "simple",
configInspectFunc: func(_ context.Context, id string) (swarm.Config, []byte, error) {
return *builders.Config(
builders.ConfigLabels(map[string]string{
"lbl1": "value1",
}),
builders.ConfigID("configID"),
builders.ConfigName("configName"),
builders.ConfigCreatedAt(time.Time{}),
builders.ConfigUpdatedAt(time.Time{}),
builders.ConfigData([]byte("payload here")),
), []byte{}, nil
configInspectFunc: func(_ context.Context, id string, _ client.ConfigInspectOptions) (client.ConfigInspectResult, error) {
return client.ConfigInspectResult{
Config: *builders.Config(
builders.ConfigLabels(map[string]string{
"lbl1": "value1",
}),
builders.ConfigID("configID"),
builders.ConfigName("configName"),
builders.ConfigCreatedAt(time.Time{}),
builders.ConfigUpdatedAt(time.Time{}),
builders.ConfigData([]byte("payload here")),
),
}, nil
},
},
}
+23 -23
View File
@@ -6,24 +6,23 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/cli/command/formatter"
flagsHelper "github.com/docker/cli/cli/flags"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/swarm"
"github.com/fvbommel/sortorder"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
// ListOptions contains options for the docker config ls command.
type ListOptions struct {
Quiet bool
Format string
Filter opts.FilterOpt
// listOptions contains options for the docker config ls command.
type listOptions struct {
quiet bool
format string
filter opts.FilterOpt
}
func newConfigListCommand(dockerCli command.Cli) *cobra.Command {
listOpts := ListOptions{Filter: opts.NewFilterOpt()}
func newConfigListCommand(dockerCLI command.Cli) *cobra.Command {
listOpts := listOptions{filter: opts.NewFilterOpt()}
cmd := &cobra.Command{
Use: "ls [OPTIONS]",
@@ -31,44 +30,45 @@ func newConfigListCommand(dockerCli command.Cli) *cobra.Command {
Short: "List configs",
Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return RunConfigList(cmd.Context(), dockerCli, listOpts)
return runList(cmd.Context(), dockerCLI, listOpts)
},
ValidArgsFunction: completion.NoComplete,
ValidArgsFunction: cobra.NoFileCompletions,
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
flags.BoolVarP(&listOpts.Quiet, "quiet", "q", false, "Only display IDs")
flags.StringVar(&listOpts.Format, "format", "", flagsHelper.FormatHelp)
flags.VarP(&listOpts.Filter, "filter", "f", "Filter output based on conditions provided")
flags.BoolVarP(&listOpts.quiet, "quiet", "q", false, "Only display IDs")
flags.StringVar(&listOpts.format, "format", "", flagsHelper.FormatHelp)
flags.VarP(&listOpts.filter, "filter", "f", "Filter output based on conditions provided")
return cmd
}
// RunConfigList lists Swarm configs.
func RunConfigList(ctx context.Context, dockerCLI command.Cli, options ListOptions) error {
// runList lists Swarm configs.
func runList(ctx context.Context, dockerCLI command.Cli, options listOptions) error {
apiClient := dockerCLI.Client()
configs, err := apiClient.ConfigList(ctx, swarm.ConfigListOptions{Filters: options.Filter.Value()})
res, err := apiClient.ConfigList(ctx, client.ConfigListOptions{Filters: options.filter.Value()})
if err != nil {
return err
}
format := options.Format
format := options.format
if len(format) == 0 {
if len(dockerCLI.ConfigFile().ConfigFormat) > 0 && !options.Quiet {
if len(dockerCLI.ConfigFile().ConfigFormat) > 0 && !options.quiet {
format = dockerCLI.ConfigFile().ConfigFormat
} else {
format = formatter.TableFormatKey
}
}
sort.Slice(configs, func(i, j int) bool {
return sortorder.NaturalLess(configs[i].Spec.Name, configs[j].Spec.Name)
sort.Slice(res.Items, func(i, j int) bool {
return sortorder.NaturalLess(res.Items[i].Spec.Name, res.Items[j].Spec.Name)
})
configCtx := formatter.Context{
Output: dockerCLI.Out(),
Format: NewFormat(format, options.Quiet),
Format: newFormat(format, options.quiet),
}
return FormatWrite(configCtx, configs)
return formatWrite(configCtx, res)
}
+69 -59
View File
@@ -10,16 +10,16 @@ import (
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/builders"
"github.com/docker/docker/api/types/swarm"
"github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/golden"
)
func TestConfigListErrors(t *testing.T) {
testCases := []struct {
args []string
configListFunc func(context.Context, swarm.ConfigListOptions) ([]swarm.Config, error)
configListFunc func(context.Context, client.ConfigListOptions) (client.ConfigListResult, error)
expectedError string
}{
{
@@ -27,8 +27,8 @@ func TestConfigListErrors(t *testing.T) {
expectedError: "accepts no argument",
},
{
configListFunc: func(_ context.Context, options swarm.ConfigListOptions) ([]swarm.Config, error) {
return []swarm.Config{}, errors.New("error listing configs")
configListFunc: func(_ context.Context, options client.ConfigListOptions) (client.ConfigListResult, error) {
return client.ConfigListResult{}, errors.New("error listing configs")
},
expectedError: "error listing configs",
},
@@ -48,26 +48,28 @@ func TestConfigListErrors(t *testing.T) {
func TestConfigList(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(_ context.Context, options swarm.ConfigListOptions) ([]swarm.Config, error) {
return []swarm.Config{
*builders.Config(builders.ConfigID("ID-1-foo"),
builders.ConfigName("1-foo"),
builders.ConfigVersion(swarm.Version{Index: 10}),
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
),
*builders.Config(builders.ConfigID("ID-10-foo"),
builders.ConfigName("10-foo"),
builders.ConfigVersion(swarm.Version{Index: 11}),
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
),
*builders.Config(builders.ConfigID("ID-2-foo"),
builders.ConfigName("2-foo"),
builders.ConfigVersion(swarm.Version{Index: 11}),
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
),
configListFunc: func(_ context.Context, options client.ConfigListOptions) (client.ConfigListResult, error) {
return client.ConfigListResult{
Items: []swarm.Config{
*builders.Config(builders.ConfigID("ID-1-foo"),
builders.ConfigName("1-foo"),
builders.ConfigVersion(swarm.Version{Index: 10}),
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
),
*builders.Config(builders.ConfigID("ID-10-foo"),
builders.ConfigName("10-foo"),
builders.ConfigVersion(swarm.Version{Index: 11}),
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
),
*builders.Config(builders.ConfigID("ID-2-foo"),
builders.ConfigName("2-foo"),
builders.ConfigVersion(swarm.Version{Index: 11}),
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
),
},
}, nil
},
})
@@ -78,12 +80,14 @@ func TestConfigList(t *testing.T) {
func TestConfigListWithQuietOption(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(_ context.Context, options swarm.ConfigListOptions) ([]swarm.Config, error) {
return []swarm.Config{
*builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")),
*builders.Config(builders.ConfigID("ID-bar"), builders.ConfigName("bar"), builders.ConfigLabels(map[string]string{
"label": "label-bar",
})),
configListFunc: func(_ context.Context, options client.ConfigListOptions) (client.ConfigListResult, error) {
return client.ConfigListResult{
Items: []swarm.Config{
*builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")),
*builders.Config(builders.ConfigID("ID-bar"), builders.ConfigName("bar"), builders.ConfigLabels(map[string]string{
"label": "label-bar",
})),
},
}, nil
},
})
@@ -95,12 +99,14 @@ func TestConfigListWithQuietOption(t *testing.T) {
func TestConfigListWithConfigFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(_ context.Context, options swarm.ConfigListOptions) ([]swarm.Config, error) {
return []swarm.Config{
*builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")),
*builders.Config(builders.ConfigID("ID-bar"), builders.ConfigName("bar"), builders.ConfigLabels(map[string]string{
"label": "label-bar",
})),
configListFunc: func(_ context.Context, options client.ConfigListOptions) (client.ConfigListResult, error) {
return client.ConfigListResult{
Items: []swarm.Config{
*builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")),
*builders.Config(builders.ConfigID("ID-bar"), builders.ConfigName("bar"), builders.ConfigLabels(map[string]string{
"label": "label-bar",
})),
},
}, nil
},
})
@@ -114,12 +120,14 @@ func TestConfigListWithConfigFormat(t *testing.T) {
func TestConfigListWithFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(_ context.Context, options swarm.ConfigListOptions) ([]swarm.Config, error) {
return []swarm.Config{
*builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")),
*builders.Config(builders.ConfigID("ID-bar"), builders.ConfigName("bar"), builders.ConfigLabels(map[string]string{
"label": "label-bar",
})),
configListFunc: func(_ context.Context, options client.ConfigListOptions) (client.ConfigListResult, error) {
return client.ConfigListResult{
Items: []swarm.Config{
*builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")),
*builders.Config(builders.ConfigID("ID-bar"), builders.ConfigName("bar"), builders.ConfigLabels(map[string]string{
"label": "label-bar",
})),
},
}, nil
},
})
@@ -131,22 +139,24 @@ func TestConfigListWithFormat(t *testing.T) {
func TestConfigListWithFilter(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(_ context.Context, options swarm.ConfigListOptions) ([]swarm.Config, error) {
assert.Check(t, is.Equal("foo", options.Filters.Get("name")[0]))
assert.Check(t, is.Equal("lbl1=Label-bar", options.Filters.Get("label")[0]))
return []swarm.Config{
*builders.Config(builders.ConfigID("ID-foo"),
builders.ConfigName("foo"),
builders.ConfigVersion(swarm.Version{Index: 10}),
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
),
*builders.Config(builders.ConfigID("ID-bar"),
builders.ConfigName("bar"),
builders.ConfigVersion(swarm.Version{Index: 11}),
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
),
configListFunc: func(_ context.Context, options client.ConfigListOptions) (client.ConfigListResult, error) {
assert.Check(t, options.Filters["name"]["foo"])
assert.Check(t, options.Filters["label"]["lbl1=Label-bar"])
return client.ConfigListResult{
Items: []swarm.Config{
*builders.Config(builders.ConfigID("ID-foo"),
builders.ConfigName("foo"),
builders.ConfigVersion(swarm.Version{Index: 10}),
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
),
*builders.Config(builders.ConfigID("ID-bar"),
builders.ConfigName("bar"),
builders.ConfigVersion(swarm.Version{Index: 11}),
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
),
},
}, nil
},
})
+9 -17
View File
@@ -7,39 +7,31 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
// RemoveOptions contains options for the docker config rm command.
type RemoveOptions struct {
Names []string
}
func newConfigRemoveCommand(dockerCli command.Cli) *cobra.Command {
func newConfigRemoveCommand(dockerCLI command.Cli) *cobra.Command {
return &cobra.Command{
Use: "rm CONFIG [CONFIG...]",
Aliases: []string{"remove"},
Short: "Remove one or more configs",
Args: cli.RequiresMinArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts := RemoveOptions{
Names: args,
}
return RunConfigRemove(cmd.Context(), dockerCli, opts)
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return completeNames(dockerCli)(cmd, args, toComplete)
return runRemove(cmd.Context(), dockerCLI, args)
},
ValidArgsFunction: completeNames(dockerCLI),
DisableFlagsInUseLine: true,
}
}
// RunConfigRemove removes the given Swarm configs.
func RunConfigRemove(ctx context.Context, dockerCLI command.Cli, opts RemoveOptions) error {
// runRemove removes the given Swarm configs.
func runRemove(ctx context.Context, dockerCLI command.Cli, names []string) error {
apiClient := dockerCLI.Client()
var errs []error
for _, name := range opts.Names {
if err := apiClient.ConfigRemove(ctx, name); err != nil {
for _, name := range names {
if _, err := apiClient.ConfigRemove(ctx, name, client.ConfigRemoveOptions{}); err != nil {
errs = append(errs, err)
continue
}
+10 -8
View File
@@ -1,12 +1,14 @@
package config
import (
"context"
"errors"
"io"
"strings"
"testing"
"github.com/docker/cli/internal/test"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@@ -14,7 +16,7 @@ import (
func TestConfigRemoveErrors(t *testing.T) {
testCases := []struct {
args []string
configRemoveFunc func(string) error
configRemoveFunc func(context.Context, string, client.ConfigRemoveOptions) (client.ConfigRemoveResult, error)
expectedError string
}{
{
@@ -23,8 +25,8 @@ func TestConfigRemoveErrors(t *testing.T) {
},
{
args: []string{"foo"},
configRemoveFunc: func(name string) error {
return errors.New("error removing config")
configRemoveFunc: func(ctx context.Context, name string, options client.ConfigRemoveOptions) (client.ConfigRemoveResult, error) {
return client.ConfigRemoveResult{}, errors.New("error removing config")
},
expectedError: "error removing config",
},
@@ -46,9 +48,9 @@ func TestConfigRemoveWithName(t *testing.T) {
names := []string{"foo", "bar"}
var removedConfigs []string
cli := test.NewFakeCli(&fakeClient{
configRemoveFunc: func(name string) error {
configRemoveFunc: func(_ context.Context, name string, _ client.ConfigRemoveOptions) (client.ConfigRemoveResult, error) {
removedConfigs = append(removedConfigs, name)
return nil
return client.ConfigRemoveResult{}, nil
},
})
cmd := newConfigRemoveCommand(cli)
@@ -63,12 +65,12 @@ func TestConfigRemoveContinueAfterError(t *testing.T) {
var removedConfigs []string
cli := test.NewFakeCli(&fakeClient{
configRemoveFunc: func(name string) error {
configRemoveFunc: func(_ context.Context, name string, _ client.ConfigRemoveOptions) (client.ConfigRemoveResult, error) {
removedConfigs = append(removedConfigs, name)
if name == "foo" {
return errors.New("error removing config: " + name)
return client.ConfigRemoveResult{}, errors.New("error removing config: " + name)
}
return nil
return client.ConfigRemoveResult{}, nil
},
})
+34 -30
View File
@@ -2,15 +2,15 @@ package container
import (
"context"
"errors"
"io"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/moby/sys/signal"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@@ -23,25 +23,25 @@ type AttachOptions struct {
}
func inspectContainerAndCheckState(ctx context.Context, apiClient client.APIClient, args string) (*container.InspectResponse, error) {
c, err := apiClient.ContainerInspect(ctx, args)
c, err := apiClient.ContainerInspect(ctx, args, client.ContainerInspectOptions{})
if err != nil {
return nil, err
}
if !c.State.Running {
return nil, errors.New("You cannot attach to a stopped container, start it first")
if !c.Container.State.Running {
return nil, errors.New("cannot attach to a stopped container, start it first")
}
if c.State.Paused {
return nil, errors.New("You cannot attach to a paused container, unpause it first")
if c.Container.State.Paused {
return nil, errors.New("cannot attach to a paused container, unpause it first")
}
if c.State.Restarting {
return nil, errors.New("You cannot attach to a restarting container, wait until it is running")
if c.Container.State.Restarting {
return nil, errors.New("cannot attach to a restarting container, wait until it is running")
}
return &c, nil
return &c.Container, nil
}
// NewAttachCommand creates a new cobra.Command for `docker attach`
func NewAttachCommand(dockerCLI command.Cli) *cobra.Command {
// newAttachCommand creates a new cobra.Command for `docker attach`
func newAttachCommand(dockerCLI command.Cli) *cobra.Command {
var opts AttachOptions
cmd := &cobra.Command{
@@ -58,6 +58,7 @@ func NewAttachCommand(dockerCLI command.Cli) *cobra.Command {
ValidArgsFunction: completion.ContainerNames(dockerCLI, false, func(ctr container.Summary) bool {
return ctr.State != container.StatePaused
}),
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
@@ -69,11 +70,19 @@ func NewAttachCommand(dockerCLI command.Cli) *cobra.Command {
// RunAttach executes an `attach` command
func RunAttach(ctx context.Context, dockerCLI command.Cli, containerID string, opts *AttachOptions) error {
detachKeys := opts.DetachKeys
if detachKeys == "" {
detachKeys = dockerCLI.ConfigFile().DetachKeys
}
if err := validateDetachKeys(detachKeys); err != nil {
return err
}
apiClient := dockerCLI.Client()
// request channel to wait for client
waitCtx := context.WithoutCancel(ctx)
resultC, errC := apiClient.ContainerWait(waitCtx, containerID, "")
waitRes := apiClient.ContainerWait(waitCtx, containerID, client.ContainerWaitOptions{})
c, err := inspectContainerAndCheckState(ctx, apiClient, containerID)
if err != nil {
@@ -84,12 +93,7 @@ func RunAttach(ctx context.Context, dockerCLI command.Cli, containerID string, o
return err
}
detachKeys := dockerCLI.ConfigFile().DetachKeys
if opts.DetachKeys != "" {
detachKeys = opts.DetachKeys
}
options := container.AttachOptions{
options := client.ContainerAttachOptions{
Stream: true,
Stdin: !opts.NoStdin && c.Config.OpenStdin,
Stdout: true,
@@ -113,11 +117,11 @@ func RunAttach(ctx context.Context, dockerCLI command.Cli, containerID string, o
defer signal.StopCatch(sigc)
}
resp, errAttach := apiClient.ContainerAttach(ctx, containerID, options)
if errAttach != nil {
return errAttach
res, err := apiClient.ContainerAttach(ctx, containerID, options)
if err != nil {
return err
}
defer resp.Close()
defer res.HijackedResponse.Close()
// If use docker attach command to attach to a stop container, it will return
// "You cannot attach to a stopped container" error, it's ok, but when
@@ -141,7 +145,7 @@ func RunAttach(ctx context.Context, dockerCLI command.Cli, containerID string, o
inputStream: in,
outputStream: dockerCLI.Out(),
errorStream: dockerCLI.Err(),
resp: resp,
resp: res.HijackedResponse,
tty: c.Config.Tty,
detachKeys: options.DetachKeys,
}
@@ -151,19 +155,19 @@ func RunAttach(ctx context.Context, dockerCLI command.Cli, containerID string, o
return err
}
return getExitStatus(errC, resultC)
return getExitStatus(waitRes)
}
func getExitStatus(errC <-chan error, resultC <-chan container.WaitResponse) error {
func getExitStatus(waitRes client.ContainerWaitResult) error {
select {
case result := <-resultC:
case result := <-waitRes.Result:
if result.Error != nil {
return errors.New(result.Error.Message)
}
if result.StatusCode != 0 {
return cli.StatusError{StatusCode: int(result.StatusCode)}
}
case err := <-errC:
case err := <-waitRes.Error:
return err
}
@@ -176,7 +180,7 @@ func resizeTTY(ctx context.Context, dockerCli command.Cli, containerID string) {
// terminal, the only way to get the shell prompt to display for attaches 2+ is to artificially
// resize it, then go back to normal. Without this, every attach after the first will
// require the user to manually resize or hit enter.
resizeTtyTo(ctx, dockerCli.Client(), containerID, height+1, width+1, false)
resizeTTYTo(ctx, dockerCli.Client(), containerID, height+1, width+1, false)
// After the above resizing occurs, the call to MonitorTtySize below will handle resetting back
// to the actual size.
+30 -18
View File
@@ -7,7 +7,8 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/container"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
)
@@ -16,23 +17,31 @@ func TestNewAttachCommandErrors(t *testing.T) {
name string
args []string
expectedError string
containerInspectFunc func(img string) (container.InspectResponse, error)
containerInspectFunc func(img string) (client.ContainerInspectResult, error)
}{
{
name: "client-error",
args: []string{"5cb5bb5e4a3b"},
expectedError: "something went wrong",
containerInspectFunc: func(containerID string) (container.InspectResponse, error) {
return container.InspectResponse{}, errors.New("something went wrong")
containerInspectFunc: func(containerID string) (client.ContainerInspectResult, error) {
return client.ContainerInspectResult{}, errors.New("something went wrong")
},
},
{
name: "invalid-detach-keys",
args: []string{"--detach-keys", "shift-b", "5cb5bb5e4a3b"},
expectedError: "invalid detach keys (shift-b):",
containerInspectFunc: func(containerID string) (client.ContainerInspectResult, error) {
return client.ContainerInspectResult{}, errors.New("something went wrong")
},
},
{
name: "client-stopped",
args: []string{"5cb5bb5e4a3b"},
expectedError: "You cannot attach to a stopped container",
containerInspectFunc: func(containerID string) (container.InspectResponse, error) {
return container.InspectResponse{
ContainerJSONBase: &container.ContainerJSONBase{
expectedError: "cannot attach to a stopped container",
containerInspectFunc: func(containerID string) (client.ContainerInspectResult, error) {
return client.ContainerInspectResult{
Container: container.InspectResponse{
State: &container.State{
Running: false,
},
@@ -43,10 +52,10 @@ func TestNewAttachCommandErrors(t *testing.T) {
{
name: "client-paused",
args: []string{"5cb5bb5e4a3b"},
expectedError: "You cannot attach to a paused container",
containerInspectFunc: func(containerID string) (container.InspectResponse, error) {
return container.InspectResponse{
ContainerJSONBase: &container.ContainerJSONBase{
expectedError: "cannot attach to a paused container",
containerInspectFunc: func(containerID string) (client.ContainerInspectResult, error) {
return client.ContainerInspectResult{
Container: container.InspectResponse{
State: &container.State{
Running: true,
Paused: true,
@@ -58,10 +67,10 @@ func TestNewAttachCommandErrors(t *testing.T) {
{
name: "client-restarting",
args: []string{"5cb5bb5e4a3b"},
expectedError: "You cannot attach to a restarting container",
containerInspectFunc: func(containerID string) (container.InspectResponse, error) {
return container.InspectResponse{
ContainerJSONBase: &container.ContainerJSONBase{
expectedError: "cannot attach to a restarting container",
containerInspectFunc: func(containerID string) (client.ContainerInspectResult, error) {
return client.ContainerInspectResult{
Container: container.InspectResponse{
State: &container.State{
Running: true,
Paused: false,
@@ -74,7 +83,7 @@ func TestNewAttachCommandErrors(t *testing.T) {
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
cmd := NewAttachCommand(test.NewFakeCli(&fakeClient{inspectFunc: tc.containerInspectFunc}))
cmd := newAttachCommand(test.NewFakeCli(&fakeClient{inspectFunc: tc.containerInspectFunc}))
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
@@ -124,7 +133,10 @@ func TestGetExitStatus(t *testing.T) {
resultC <- *testcase.result
}
err := getExitStatus(errC, resultC)
err := getExitStatus(client.ContainerWaitResult{
Result: resultC,
Error: errC,
})
if testcase.expectedError == nil {
assert.NilError(t, err)
+113 -101
View File
@@ -3,232 +3,244 @@ package container
import (
"context"
"io"
"net/http"
"strings"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/moby/moby/client"
)
func mockContainerExportResult(content string) client.ContainerExportResult {
return io.NopCloser(strings.NewReader(content))
}
func mockContainerLogsResult(content string) client.ContainerLogsResult {
return io.NopCloser(strings.NewReader(content))
}
type fakeStreamResult struct {
io.ReadCloser
client.ImagePushResponse // same interface as [client.ImagePushResponse]
}
func (e fakeStreamResult) Read(p []byte) (int, error) { return e.ReadCloser.Read(p) }
func (e fakeStreamResult) Close() error { return e.ReadCloser.Close() }
type fakeClient struct {
client.Client
inspectFunc func(string) (container.InspectResponse, error)
execInspectFunc func(execID string) (container.ExecInspect, error)
execCreateFunc func(containerID string, options container.ExecOptions) (container.ExecCreateResponse, error)
createContainerFunc func(config *container.Config,
hostConfig *container.HostConfig,
networkingConfig *network.NetworkingConfig,
platform *ocispec.Platform,
containerName string) (container.CreateResponse, error)
containerStartFunc func(containerID string, options container.StartOptions) error
imageCreateFunc func(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error)
infoFunc func() (system.Info, error)
containerStatPathFunc func(containerID, path string) (container.PathStat, error)
containerCopyFromFunc func(containerID, srcPath string) (io.ReadCloser, container.PathStat, error)
logFunc func(string, container.LogsOptions) (io.ReadCloser, error)
waitFunc func(string) (<-chan container.WaitResponse, <-chan error)
containerListFunc func(container.ListOptions) ([]container.Summary, error)
containerExportFunc func(string) (io.ReadCloser, error)
containerExecResizeFunc func(id string, options container.ResizeOptions) error
containerRemoveFunc func(ctx context.Context, containerID string, options container.RemoveOptions) error
containerRestartFunc func(ctx context.Context, containerID string, options container.StopOptions) error
containerStopFunc func(ctx context.Context, containerID string, options container.StopOptions) error
containerKillFunc func(ctx context.Context, containerID, signal string) error
containerPruneFunc func(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error)
containerAttachFunc func(ctx context.Context, containerID string, options container.AttachOptions) (types.HijackedResponse, error)
containerDiffFunc func(ctx context.Context, containerID string) ([]container.FilesystemChange, error)
inspectFunc func(string) (client.ContainerInspectResult, error)
execInspectFunc func(execID string) (client.ExecInspectResult, error)
execCreateFunc func(containerID string, options client.ExecCreateOptions) (client.ExecCreateResult, error)
createContainerFunc func(options client.ContainerCreateOptions) (client.ContainerCreateResult, error)
containerStartFunc func(containerID string, options client.ContainerStartOptions) (client.ContainerStartResult, error)
imagePullFunc func(ctx context.Context, parentReference string, options client.ImagePullOptions) (client.ImagePullResponse, error)
infoFunc func() (client.SystemInfoResult, error)
containerStatPathFunc func(containerID, path string) (client.ContainerStatPathResult, error)
containerCopyFromFunc func(containerID, srcPath string) (client.CopyFromContainerResult, error)
containerCopyToFunc func(containerID string, options client.CopyToContainerOptions) (client.CopyToContainerResult, error)
logFunc func(string, client.ContainerLogsOptions) (client.ContainerLogsResult, error)
waitFunc func(string) client.ContainerWaitResult
containerListFunc func(client.ContainerListOptions) (client.ContainerListResult, error)
containerExportFunc func(string) (client.ContainerExportResult, error)
containerExecResizeFunc func(id string, options client.ExecResizeOptions) (client.ExecResizeResult, error)
containerRemoveFunc func(ctx context.Context, containerID string, options client.ContainerRemoveOptions) (client.ContainerRemoveResult, error)
containerRestartFunc func(ctx context.Context, containerID string, options client.ContainerRestartOptions) (client.ContainerRestartResult, error)
containerStopFunc func(ctx context.Context, containerID string, options client.ContainerStopOptions) (client.ContainerStopResult, error)
containerKillFunc func(ctx context.Context, containerID string, options client.ContainerKillOptions) (client.ContainerKillResult, error)
containerPruneFunc func(ctx context.Context, options client.ContainerPruneOptions) (client.ContainerPruneResult, error)
containerAttachFunc func(ctx context.Context, containerID string, options client.ContainerAttachOptions) (client.ContainerAttachResult, error)
containerDiffFunc func(ctx context.Context, containerID string) (client.ContainerDiffResult, error)
containerRenameFunc func(ctx context.Context, oldName, newName string) error
containerCommitFunc func(ctx context.Context, container string, options container.CommitOptions) (container.CommitResponse, error)
containerPauseFunc func(ctx context.Context, container string) error
containerCommitFunc func(ctx context.Context, container string, options client.ContainerCommitOptions) (client.ContainerCommitResult, error)
containerPauseFunc func(ctx context.Context, container string, options client.ContainerPauseOptions) (client.ContainerPauseResult, error)
Version string
}
func (f *fakeClient) ContainerList(_ context.Context, options container.ListOptions) ([]container.Summary, error) {
func (f *fakeClient) ContainerList(_ context.Context, options client.ContainerListOptions) (client.ContainerListResult, error) {
if f.containerListFunc != nil {
return f.containerListFunc(options)
}
return []container.Summary{}, nil
return client.ContainerListResult{}, nil
}
func (f *fakeClient) ContainerInspect(_ context.Context, containerID string) (container.InspectResponse, error) {
func (f *fakeClient) ContainerInspect(_ context.Context, containerID string, _ client.ContainerInspectOptions) (client.ContainerInspectResult, error) {
if f.inspectFunc != nil {
return f.inspectFunc(containerID)
}
return container.InspectResponse{}, nil
return client.ContainerInspectResult{}, nil
}
func (f *fakeClient) ContainerExecCreate(_ context.Context, containerID string, config container.ExecOptions) (container.ExecCreateResponse, error) {
func (f *fakeClient) ExecCreate(_ context.Context, containerID string, config client.ExecCreateOptions) (client.ExecCreateResult, error) {
if f.execCreateFunc != nil {
return f.execCreateFunc(containerID, config)
}
return container.ExecCreateResponse{}, nil
return client.ExecCreateResult{}, nil
}
func (f *fakeClient) ContainerExecInspect(_ context.Context, execID string) (container.ExecInspect, error) {
func (f *fakeClient) ExecInspect(_ context.Context, execID string, _ client.ExecInspectOptions) (client.ExecInspectResult, error) {
if f.execInspectFunc != nil {
return f.execInspectFunc(execID)
}
return container.ExecInspect{}, nil
return client.ExecInspectResult{}, nil
}
func (*fakeClient) ContainerExecStart(context.Context, string, container.ExecStartOptions) error {
return nil
func (*fakeClient) ExecStart(context.Context, string, client.ExecStartOptions) (client.ExecStartResult, error) {
return client.ExecStartResult{}, nil
}
func (f *fakeClient) ContainerCreate(
_ context.Context,
config *container.Config,
hostConfig *container.HostConfig,
networkingConfig *network.NetworkingConfig,
platform *ocispec.Platform,
containerName string,
) (container.CreateResponse, error) {
func (f *fakeClient) ContainerCreate(_ context.Context, options client.ContainerCreateOptions) (client.ContainerCreateResult, error) {
if f.createContainerFunc != nil {
return f.createContainerFunc(config, hostConfig, networkingConfig, platform, containerName)
return f.createContainerFunc(options)
}
return container.CreateResponse{}, nil
return client.ContainerCreateResult{}, nil
}
func (f *fakeClient) ContainerRemove(ctx context.Context, containerID string, options container.RemoveOptions) error {
func (f *fakeClient) ContainerRemove(ctx context.Context, containerID string, options client.ContainerRemoveOptions) (client.ContainerRemoveResult, error) {
if f.containerRemoveFunc != nil {
return f.containerRemoveFunc(ctx, containerID, options)
}
return nil
return client.ContainerRemoveResult{}, nil
}
func (f *fakeClient) ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error) {
if f.imageCreateFunc != nil {
return f.imageCreateFunc(ctx, parentReference, options)
func (f *fakeClient) ImagePull(ctx context.Context, parentReference string, options client.ImagePullOptions) (client.ImagePullResponse, error) {
if f.imagePullFunc != nil {
return f.imagePullFunc(ctx, parentReference, options)
}
return nil, nil
return fakeStreamResult{}, nil
}
func (f *fakeClient) Info(_ context.Context) (system.Info, error) {
func (f *fakeClient) Info(context.Context, client.InfoOptions) (client.SystemInfoResult, error) {
if f.infoFunc != nil {
return f.infoFunc()
}
return system.Info{}, nil
return client.SystemInfoResult{}, nil
}
func (f *fakeClient) ContainerStatPath(_ context.Context, containerID, path string) (container.PathStat, error) {
func (f *fakeClient) ContainerStatPath(_ context.Context, containerID string, options client.ContainerStatPathOptions) (client.ContainerStatPathResult, error) {
if f.containerStatPathFunc != nil {
return f.containerStatPathFunc(containerID, path)
return f.containerStatPathFunc(containerID, options.Path)
}
return container.PathStat{}, nil
return client.ContainerStatPathResult{}, nil
}
func (f *fakeClient) CopyFromContainer(_ context.Context, containerID, srcPath string) (io.ReadCloser, container.PathStat, error) {
func (f *fakeClient) CopyFromContainer(_ context.Context, containerID string, options client.CopyFromContainerOptions) (client.CopyFromContainerResult, error) {
if f.containerCopyFromFunc != nil {
return f.containerCopyFromFunc(containerID, srcPath)
return f.containerCopyFromFunc(containerID, options.SourcePath)
}
return nil, container.PathStat{}, nil
return client.CopyFromContainerResult{}, nil
}
func (f *fakeClient) ContainerLogs(_ context.Context, containerID string, options container.LogsOptions) (io.ReadCloser, error) {
func (f *fakeClient) CopyToContainer(_ context.Context, containerID string, options client.CopyToContainerOptions) (client.CopyToContainerResult, error) {
if f.containerCopyToFunc != nil {
return f.containerCopyToFunc(containerID, options)
}
return client.CopyToContainerResult{}, nil
}
func (f *fakeClient) ContainerLogs(_ context.Context, containerID string, options client.ContainerLogsOptions) (client.ContainerLogsResult, error) {
if f.logFunc != nil {
return f.logFunc(containerID, options)
}
return nil, nil
return http.NoBody, nil
}
func (f *fakeClient) ClientVersion() string {
return f.Version
}
func (f *fakeClient) ContainerWait(_ context.Context, containerID string, _ container.WaitCondition) (<-chan container.WaitResponse, <-chan error) {
func (f *fakeClient) ContainerWait(_ context.Context, containerID string, _ client.ContainerWaitOptions) client.ContainerWaitResult {
if f.waitFunc != nil {
return f.waitFunc(containerID)
}
return nil, nil
return client.ContainerWaitResult{}
}
func (f *fakeClient) ContainerStart(_ context.Context, containerID string, options container.StartOptions) error {
func (f *fakeClient) ContainerStart(_ context.Context, containerID string, options client.ContainerStartOptions) (client.ContainerStartResult, error) {
if f.containerStartFunc != nil {
return f.containerStartFunc(containerID, options)
}
return nil
return client.ContainerStartResult{}, nil
}
func (f *fakeClient) ContainerExport(_ context.Context, containerID string) (io.ReadCloser, error) {
func (f *fakeClient) ContainerExport(_ context.Context, containerID string, _ client.ContainerExportOptions) (client.ContainerExportResult, error) {
if f.containerExportFunc != nil {
return f.containerExportFunc(containerID)
}
return nil, nil
return http.NoBody, nil
}
func (f *fakeClient) ContainerExecResize(_ context.Context, id string, options container.ResizeOptions) error {
func (f *fakeClient) ExecResize(_ context.Context, id string, options client.ExecResizeOptions) (client.ExecResizeResult, error) {
if f.containerExecResizeFunc != nil {
return f.containerExecResizeFunc(id, options)
}
return nil
return client.ExecResizeResult{}, nil
}
func (f *fakeClient) ContainerKill(ctx context.Context, containerID, signal string) error {
func (f *fakeClient) ContainerKill(ctx context.Context, containerID string, options client.ContainerKillOptions) (client.ContainerKillResult, error) {
if f.containerKillFunc != nil {
return f.containerKillFunc(ctx, containerID, signal)
return f.containerKillFunc(ctx, containerID, options)
}
return nil
return client.ContainerKillResult{}, nil
}
func (f *fakeClient) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) {
func (f *fakeClient) ContainerPrune(ctx context.Context, options client.ContainerPruneOptions) (client.ContainerPruneResult, error) {
if f.containerPruneFunc != nil {
return f.containerPruneFunc(ctx, pruneFilters)
return f.containerPruneFunc(ctx, options)
}
return container.PruneReport{}, nil
return client.ContainerPruneResult{}, nil
}
func (f *fakeClient) ContainerRestart(ctx context.Context, containerID string, options container.StopOptions) error {
func (f *fakeClient) ContainerRestart(ctx context.Context, containerID string, options client.ContainerRestartOptions) (client.ContainerRestartResult, error) {
if f.containerRestartFunc != nil {
return f.containerRestartFunc(ctx, containerID, options)
}
return nil
return client.ContainerRestartResult{}, nil
}
func (f *fakeClient) ContainerStop(ctx context.Context, containerID string, options container.StopOptions) error {
func (f *fakeClient) ContainerStop(ctx context.Context, containerID string, options client.ContainerStopOptions) (client.ContainerStopResult, error) {
if f.containerStopFunc != nil {
return f.containerStopFunc(ctx, containerID, options)
}
return nil
return client.ContainerStopResult{}, nil
}
func (f *fakeClient) ContainerAttach(ctx context.Context, containerID string, options container.AttachOptions) (types.HijackedResponse, error) {
func (f *fakeClient) ContainerAttach(ctx context.Context, containerID string, options client.ContainerAttachOptions) (client.ContainerAttachResult, error) {
if f.containerAttachFunc != nil {
return f.containerAttachFunc(ctx, containerID, options)
}
return types.HijackedResponse{}, nil
return client.ContainerAttachResult{}, nil
}
func (f *fakeClient) ContainerDiff(ctx context.Context, containerID string) ([]container.FilesystemChange, error) {
func (f *fakeClient) ContainerDiff(ctx context.Context, containerID string, _ client.ContainerDiffOptions) (client.ContainerDiffResult, error) {
if f.containerDiffFunc != nil {
return f.containerDiffFunc(ctx, containerID)
}
return []container.FilesystemChange{}, nil
return client.ContainerDiffResult{}, nil
}
func (f *fakeClient) ContainerRename(ctx context.Context, oldName, newName string) error {
func (f *fakeClient) ContainerRename(ctx context.Context, oldName string, options client.ContainerRenameOptions) (client.ContainerRenameResult, error) {
if f.containerRenameFunc != nil {
return f.containerRenameFunc(ctx, oldName, newName)
return client.ContainerRenameResult{}, f.containerRenameFunc(ctx, oldName, options.NewName)
}
return nil
return client.ContainerRenameResult{}, nil
}
func (f *fakeClient) ContainerCommit(ctx context.Context, containerID string, options container.CommitOptions) (container.CommitResponse, error) {
func (f *fakeClient) ContainerCommit(ctx context.Context, containerID string, options client.ContainerCommitOptions) (client.ContainerCommitResult, error) {
if f.containerCommitFunc != nil {
return f.containerCommitFunc(ctx, containerID, options)
}
return container.CommitResponse{}, nil
return client.ContainerCommitResult{}, nil
}
func (f *fakeClient) ContainerPause(ctx context.Context, containerID string) error {
func (f *fakeClient) ContainerPause(ctx context.Context, containerID string, options client.ContainerPauseOptions) (client.ContainerPauseResult, error) {
if f.containerPauseFunc != nil {
return f.containerPauseFunc(ctx, containerID)
return f.containerPauseFunc(ctx, containerID, options)
}
return nil
return client.ContainerPauseResult{}, nil
}
func (*fakeClient) Ping(_ context.Context, _ client.PingOptions) (client.PingResult, error) {
return client.PingResult{}, nil
}
+58 -28
View File
@@ -3,43 +3,73 @@ package container
import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/internal/commands"
"github.com/spf13/cobra"
)
// NewContainerCommand returns a cobra command for `container` subcommands
func NewContainerCommand(dockerCli command.Cli) *cobra.Command {
func init() {
commands.Register(newRunCommand)
commands.Register(newExecCommand)
commands.Register(newPsCommand)
commands.Register(newContainerCommand)
commands.RegisterLegacy(newAttachCommand)
commands.RegisterLegacy(newCommitCommand)
commands.RegisterLegacy(newCopyCommand)
commands.RegisterLegacy(newCreateCommand)
commands.RegisterLegacy(newDiffCommand)
commands.RegisterLegacy(newExportCommand)
commands.RegisterLegacy(newKillCommand)
commands.RegisterLegacy(newLogsCommand)
commands.RegisterLegacy(newPauseCommand)
commands.RegisterLegacy(newPortCommand)
commands.RegisterLegacy(newRenameCommand)
commands.RegisterLegacy(newRestartCommand)
commands.RegisterLegacy(newRmCommand)
commands.RegisterLegacy(newStartCommand)
commands.RegisterLegacy(newStatsCommand)
commands.RegisterLegacy(newStopCommand)
commands.RegisterLegacy(newTopCommand)
commands.RegisterLegacy(newUnpauseCommand)
commands.RegisterLegacy(newUpdateCommand)
commands.RegisterLegacy(newWaitCommand)
}
// newContainerCommand returns a cobra command for `container` subcommands
func newContainerCommand(dockerCLI command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "container",
Short: "Manage containers",
Args: cli.NoArgs,
RunE: command.ShowHelp(dockerCli.Err()),
RunE: command.ShowHelp(dockerCLI.Err()),
DisableFlagsInUseLine: true,
}
cmd.AddCommand(
NewAttachCommand(dockerCli),
NewCommitCommand(dockerCli),
NewCopyCommand(dockerCli),
NewCreateCommand(dockerCli),
NewDiffCommand(dockerCli),
NewExecCommand(dockerCli),
NewExportCommand(dockerCli),
NewKillCommand(dockerCli),
NewLogsCommand(dockerCli),
NewPauseCommand(dockerCli),
NewPortCommand(dockerCli),
NewRenameCommand(dockerCli),
NewRestartCommand(dockerCli),
NewRmCommand(dockerCli),
NewRunCommand(dockerCli),
NewStartCommand(dockerCli),
NewStatsCommand(dockerCli),
NewStopCommand(dockerCli),
NewTopCommand(dockerCli),
NewUnpauseCommand(dockerCli),
NewUpdateCommand(dockerCli),
NewWaitCommand(dockerCli),
newListCommand(dockerCli),
newInspectCommand(dockerCli),
NewPruneCommand(dockerCli),
newAttachCommand(dockerCLI),
newCommitCommand(dockerCLI),
newCopyCommand(dockerCLI),
newCreateCommand(dockerCLI),
newDiffCommand(dockerCLI),
newExecCommand(dockerCLI),
newExportCommand(dockerCLI),
newKillCommand(dockerCLI),
newLogsCommand(dockerCLI),
newPauseCommand(dockerCLI),
newPortCommand(dockerCLI),
newRenameCommand(dockerCLI),
newRestartCommand(dockerCLI),
newRemoveCommand(dockerCLI),
newRunCommand(dockerCLI),
newStartCommand(dockerCLI),
newStatsCommand(dockerCLI),
newStopCommand(dockerCLI),
newTopCommand(dockerCLI),
newUnpauseCommand(dockerCLI),
newUpdateCommand(dockerCLI),
newWaitCommand(dockerCLI),
newListCommand(dockerCLI),
newInspectCommand(dockerCLI),
newPruneCommand(dockerCLI),
)
return cmd
}
+22 -9
View File
@@ -2,13 +2,14 @@ package container
import (
"context"
"errors"
"fmt"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/container"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@@ -17,13 +18,14 @@ type commitOptions struct {
reference string
pause bool
noPause bool
comment string
author string
changes opts.ListOpts
}
// NewCommitCommand creates a new cobra.Command for `docker commit`
func NewCommitCommand(dockerCli command.Cli) *cobra.Command {
// newCommitCommand creates a new cobra.Command for `docker commit`
func newCommitCommand(dockerCLI command.Cli) *cobra.Command {
var options commitOptions
cmd := &cobra.Command{
@@ -35,18 +37,29 @@ func NewCommitCommand(dockerCli command.Cli) *cobra.Command {
if len(args) > 1 {
options.reference = args[1]
}
return runCommit(cmd.Context(), dockerCli, &options)
if cmd.Flag("pause").Changed {
if cmd.Flag("no-pause").Changed {
return errors.New("conflicting options: --no-pause and --pause cannot be used together")
}
options.noPause = !options.pause
}
return runCommit(cmd.Context(), dockerCLI, &options)
},
Annotations: map[string]string{
"aliases": "docker container commit, docker commit",
},
ValidArgsFunction: completion.ContainerNames(dockerCli, false),
ValidArgsFunction: completion.ContainerNames(dockerCLI, false),
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
flags.SetInterspersed(false)
flags.BoolVarP(&options.pause, "pause", "p", true, "Pause container during commit")
// TODO(thaJeztah): Deprecated: the --pause flag was deprecated in v29 and can be removed in v30.
flags.BoolVarP(&options.pause, "pause", "p", true, "Pause container during commit (deprecated: use --no-pause instead)")
_ = flags.MarkDeprecated("pause", "and enabled by default. Use --no-pause to disable pausing during commit.")
flags.BoolVar(&options.noPause, "no-pause", false, "Disable pausing container during commit")
flags.StringVarP(&options.comment, "message", "m", "", "Commit message")
flags.StringVarP(&options.author, "author", "a", "", `Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")`)
@@ -57,17 +70,17 @@ func NewCommitCommand(dockerCli command.Cli) *cobra.Command {
}
func runCommit(ctx context.Context, dockerCli command.Cli, options *commitOptions) error {
response, err := dockerCli.Client().ContainerCommit(ctx, options.container, container.CommitOptions{
response, err := dockerCli.Client().ContainerCommit(ctx, options.container, client.ContainerCommitOptions{
Reference: options.reference,
Comment: options.comment,
Author: options.author,
Changes: options.changes.GetSlice(),
Pause: options.pause,
NoPause: options.noPause,
})
if err != nil {
return err
}
fmt.Fprintln(dockerCli.Out(), response.ID)
_, _ = fmt.Fprintln(dockerCli.Out(), response.ID)
return nil
}
+9 -17
View File
@@ -7,36 +7,32 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/container"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
func TestRunCommit(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerCommitFunc: func(
ctx context.Context,
ctr string,
options container.CommitOptions,
) (container.CommitResponse, error) {
containerCommitFunc: func(ctx context.Context, ctr string, options client.ContainerCommitOptions) (client.ContainerCommitResult, error) {
assert.Check(t, is.Equal(options.Author, "Author Name <author@name.com>"))
assert.Check(t, is.DeepEqual(options.Changes, []string{"EXPOSE 80"}))
assert.Check(t, is.Equal(options.Comment, "commit message"))
assert.Check(t, is.Equal(options.Pause, false))
assert.Check(t, is.Equal(options.NoPause, true))
assert.Check(t, is.Equal(ctr, "container-id"))
return container.CommitResponse{ID: "image-id"}, nil
return client.ContainerCommitResult{ID: "image-id"}, nil
},
})
cmd := NewCommitCommand(cli)
cmd := newCommitCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetArgs(
[]string{
"--author", "Author Name <author@name.com>",
"--change", "EXPOSE 80",
"--message", "commit message",
"--pause=false",
"--no-pause",
"container-id",
},
)
@@ -51,16 +47,12 @@ func TestRunCommitClientError(t *testing.T) {
clientError := errors.New("client error")
cli := test.NewFakeCli(&fakeClient{
containerCommitFunc: func(
ctx context.Context,
ctr string,
options container.CommitOptions,
) (container.CommitResponse, error) {
return container.CommitResponse{}, clientError
containerCommitFunc: func(ctx context.Context, ctr string, options client.ContainerCommitOptions) (client.ContainerCommitResult, error) {
return client.ContainerCommitResult{}, clientError
},
})
cmd := NewCommitCommand(cli)
cmd := newCommitCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs([]string{"container-id"})
+39 -9
View File
@@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.23
//go:build go1.25
package container
@@ -8,7 +8,8 @@ import (
"sync"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/docker/api/types/container"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/moby/sys/capability"
"github.com/moby/sys/signal"
"github.com/spf13/cobra"
@@ -122,15 +123,15 @@ func addCompletions(cmd *cobra.Command, dockerCLI completion.APIClientProvider)
_ = cmd.RegisterFlagCompletionFunc("cap-add", completeLinuxCapabilityNames)
_ = cmd.RegisterFlagCompletionFunc("cap-drop", completeLinuxCapabilityNames)
_ = cmd.RegisterFlagCompletionFunc("cgroupns", completeCgroupns())
_ = cmd.RegisterFlagCompletionFunc("env", completion.EnvVarNames)
_ = cmd.RegisterFlagCompletionFunc("env-file", completion.FileNames)
_ = cmd.RegisterFlagCompletionFunc("env", completion.EnvVarNames())
_ = cmd.RegisterFlagCompletionFunc("env-file", completion.FileNames())
_ = cmd.RegisterFlagCompletionFunc("ipc", completeIpc(dockerCLI))
_ = cmd.RegisterFlagCompletionFunc("link", completeLink(dockerCLI))
_ = cmd.RegisterFlagCompletionFunc("log-driver", completeLogDriver(dockerCLI))
_ = cmd.RegisterFlagCompletionFunc("log-opt", completeLogOpt)
_ = cmd.RegisterFlagCompletionFunc("network", completion.NetworkNames(dockerCLI))
_ = cmd.RegisterFlagCompletionFunc("pid", completePid(dockerCLI))
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
_ = cmd.RegisterFlagCompletionFunc("pull", completion.FromList(PullImageAlways, PullImageMissing, PullImageNever))
_ = cmd.RegisterFlagCompletionFunc("restart", completeRestartPolicies)
_ = cmd.RegisterFlagCompletionFunc("security-opt", completeSecurityOpt)
@@ -181,16 +182,45 @@ func completeLink(dockerCLI completion.APIClientProvider) cobra.CompletionFunc {
}
}
// completeLinks implements shell completion for the `--link` option of `rm --link`.
//
// It contacts the API to get names of legacy links on containers.
// In case of an error, an empty list is returned.
func completeLinks(dockerCLI completion.APIClientProvider) cobra.CompletionFunc {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
res, err := dockerCLI.Client().ContainerList(cmd.Context(), client.ContainerListOptions{
All: true,
})
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
var names []string
for _, ctr := range res.Items {
if len(ctr.Names) <= 1 {
// Container has no links names.
continue
}
for _, n := range ctr.Names {
// Skip legacy link names: "/linked-container/link-name"
if len(n) > 1 && strings.IndexByte(n[1:], '/') != -1 {
names = append(names, strings.TrimPrefix(n, "/"))
}
}
}
return names, cobra.ShellCompDirectiveNoFileComp
}
}
// completeLogDriver implements shell completion for the `--log-driver` option of `run` and `create`.
// The log drivers are collected from a call to the Info endpoint with a fallback to a hard-coded list
// of the build-in log drivers.
func completeLogDriver(dockerCLI completion.APIClientProvider) cobra.CompletionFunc {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
info, err := dockerCLI.Client().Info(cmd.Context())
res, err := dockerCLI.Client().Info(cmd.Context(), client.InfoOptions{})
if err != nil {
return builtInLogDrivers(), cobra.ShellCompDirectiveNoFileComp
}
drivers := info.Plugins.Log
drivers := res.Info.Plugins.Log
return drivers, cobra.ShellCompDirectiveNoFileComp
}
}
@@ -279,12 +309,12 @@ func completeUlimit(_ *cobra.Command, _ []string, _ string) ([]string, cobra.She
// completeVolumeDriver contacts the API to get the built-in and installed volume drivers.
func completeVolumeDriver(dockerCLI completion.APIClientProvider) cobra.CompletionFunc {
return func(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
info, err := dockerCLI.Client().Info(cmd.Context())
res, err := dockerCLI.Client().Info(cmd.Context(), client.InfoOptions{})
if err != nil {
// fallback: the built-in drivers
return []string{"local"}, cobra.ShellCompDirectiveNoFileComp
}
drivers := info.Plugins.Volume
drivers := res.Info.Plugins.Volume
return drivers, cobra.ShellCompDirectiveNoFileComp
}
}
+51 -7
View File
@@ -6,7 +6,8 @@ import (
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/builders"
"github.com/docker/docker/api/types/container"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/moby/sys/signal"
"github.com/spf13/cobra"
"gotest.tools/v3/assert"
@@ -26,7 +27,7 @@ func TestCompleteLinuxCapabilityNames(t *testing.T) {
func TestCompletePid(t *testing.T) {
tests := []struct {
containerListFunc func(container.ListOptions) ([]container.Summary, error)
containerListFunc func(client.ContainerListOptions) (client.ContainerListResult, error)
toComplete string
expectedCompletions []string
expectedDirective cobra.ShellCompDirective
@@ -42,10 +43,12 @@ func TestCompletePid(t *testing.T) {
expectedDirective: cobra.ShellCompDirectiveNoSpace,
},
{
containerListFunc: func(container.ListOptions) ([]container.Summary, error) {
return []container.Summary{
*builders.Container("c1"),
*builders.Container("c2"),
containerListFunc: func(client.ContainerListOptions) (client.ContainerListResult, error) {
return client.ContainerListResult{
Items: []container.Summary{
*builders.Container("c1"),
*builders.Container("c2"),
},
}, nil
},
toComplete: "container:",
@@ -59,7 +62,7 @@ func TestCompletePid(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: tc.containerListFunc,
})
completions, directive := completePid(cli)(NewRunCommand(cli), nil, tc.toComplete)
completions, directive := completePid(cli)(newRunCommand(cli), nil, tc.toComplete)
assert.Check(t, is.DeepEqual(completions, tc.expectedCompletions))
assert.Check(t, is.Equal(directive, tc.expectedDirective))
})
@@ -132,3 +135,44 @@ func TestCompleteSignals(t *testing.T) {
assert.Check(t, len(values) > 1)
assert.Check(t, is.Len(values, len(signal.SignalMap)))
}
func TestCompleteLinks(t *testing.T) {
tests := []struct {
doc string
showAll, showIDs bool
filters []func(container.Summary) bool
containers []container.Summary
expOut []string
expDirective cobra.ShellCompDirective
}{
{
doc: "no results",
expDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
doc: "all containers",
showAll: true,
containers: []container.Summary{
{ID: "id-c", State: container.StateRunning, Names: []string{"/container-c", "/container-c/link-b", "/container-c/link-c"}},
{ID: "id-b", State: container.StateCreated, Names: []string{"/container-b", "/container-b/link-a"}},
{ID: "id-a", State: container.StateExited, Names: []string{"/container-a"}},
},
expOut: []string{"container-c/link-b", "container-c/link-c", "container-b/link-a"},
expDirective: cobra.ShellCompDirectiveNoFileComp,
},
}
for _, tc := range tests {
t.Run(tc.doc, func(t *testing.T) {
comp := completeLinks(test.NewFakeCli(&fakeClient{
containerListFunc: func(client.ContainerListOptions) (client.ContainerListResult, error) {
return client.ContainerListResult{Items: tc.containers}, nil
},
}))
containers, directives := comp(&cobra.Command{}, nil, "")
assert.Check(t, is.Equal(directives&tc.expDirective, tc.expDirective))
assert.Check(t, is.DeepEqual(containers, tc.expOut))
})
}
}
+118 -52
View File
@@ -3,6 +3,7 @@ package container
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"os"
@@ -15,11 +16,10 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/streams"
"github.com/docker/docker/api/types/container"
units "github.com/docker/go-units"
"github.com/docker/go-units"
"github.com/moby/go-archive"
"github.com/moby/moby/client"
"github.com/morikuni/aec"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -121,8 +121,8 @@ func copyProgress(ctx context.Context, dst io.Writer, header string, total *int6
return restore, done
}
// NewCopyCommand creates a new `docker cp` command
func NewCopyCommand(dockerCli command.Cli) *cobra.Command {
// newCopyCommand creates a new `docker cp` command
func newCopyCommand(dockerCLI command.Cli) *cobra.Command {
var opts copyOptions
cmd := &cobra.Command{
@@ -147,17 +147,18 @@ container source to stdout.`,
opts.destination = args[1]
if !cmd.Flag("quiet").Changed {
// User did not specify "quiet" flag; suppress output if no terminal is attached
opts.quiet = !dockerCli.Out().IsTerminal()
opts.quiet = !dockerCLI.Out().IsTerminal()
}
return runCopy(cmd.Context(), dockerCli, opts)
return runCopy(cmd.Context(), dockerCLI, opts)
},
Annotations: map[string]string{
"aliases": "docker container cp, docker cp",
},
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
flags.BoolVarP(&opts.followLink, "follow-link", "L", false, "Always follow symbol link in SRC_PATH")
flags.BoolVarP(&opts.followLink, "follow-link", "L", false, "Always follow symlinks in SRC_PATH")
flags.BoolVarP(&opts.copyUIDGID, "archive", "a", false, "Archive mode (copy all uid/gid information)")
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress progress output during copy. Progress output is automatically suppressed if no terminal is attached")
return cmd
@@ -167,6 +168,50 @@ func progressHumanSize(n int64) string {
return units.HumanSizeWithPrecision(float64(n), 3)
}
// localContentSize returns the total size of regular file content at path.
// For a regular file it returns the file size. For a directory it walks
// the tree and sums sizes of all regular files.
func localContentSize(path string) (int64, error) {
fi, err := os.Lstat(path)
if err != nil {
return -1, err
}
if !fi.IsDir() {
if fi.Mode().IsRegular() {
return fi.Size(), nil
}
return 0, nil
}
var total int64
err = filepath.WalkDir(path, func(_ string, d os.DirEntry, err error) error {
if err != nil {
return err
}
if d.Type().IsRegular() {
info, err := d.Info()
if err != nil {
return err
}
total += info.Size()
}
return nil
})
return total, err
}
// copySummary formats the "Successfully copied ..." message.
// When contentSize differs from transferredSize, both values are shown.
func copySummary(contentSize, transferredSize int64, dest string) string {
if contentSize != transferredSize {
return fmt.Sprintf("Successfully copied %s (transferred %s) to %s\n",
progressHumanSize(contentSize), progressHumanSize(transferredSize), dest,
)
}
return fmt.Sprintf("Successfully copied %s to %s\n",
progressHumanSize(contentSize), dest,
)
}
func runCopy(ctx context.Context, dockerCli command.Cli, opts copyOptions) error {
srcContainer, srcPath := splitCpArg(opts.source)
destContainer, destPath := splitCpArg(opts.destination)
@@ -226,14 +271,16 @@ func copyFromContainer(ctx context.Context, dockerCLI command.Cli, copyConfig cp
}
apiClient := dockerCLI.Client()
// if client requests to follow symbol link, then must decide target file to be copied
// if client requests to follow symlinks, then must decide target file to be copied
var rebaseName string
if copyConfig.followLink {
srcStat, err := apiClient.ContainerStatPath(ctx, copyConfig.container, srcPath)
src, err := apiClient.ContainerStatPath(ctx, copyConfig.container, client.ContainerStatPathOptions{
Path: srcPath,
})
// If the destination is a symbolic link, we should follow it.
if err == nil && srcStat.Mode&os.ModeSymlink != 0 {
linkTarget := srcStat.LinkTarget
if err == nil && src.Stat.Mode&os.ModeSymlink != 0 {
linkTarget := src.Stat.LinkTarget
if !isAbs(linkTarget) {
// Join with the parent directory.
srcParent, _ := archive.SplitPathDirEntry(srcPath)
@@ -248,11 +295,14 @@ func copyFromContainer(ctx context.Context, dockerCLI command.Cli, copyConfig cp
ctx, cancel := signal.NotifyContext(ctx, os.Interrupt)
defer cancel()
content, stat, err := apiClient.CopyFromContainer(ctx, copyConfig.container, srcPath)
cpRes, err := apiClient.CopyFromContainer(ctx, copyConfig.container, client.CopyFromContainerOptions{
SourcePath: srcPath,
})
if err != nil {
return err
}
defer content.Close()
content := cpRes.Content
defer func() { _ = content.Close() }()
if dstPath == "-" {
_, err = io.Copy(dockerCLI.Out(), content)
@@ -262,7 +312,7 @@ func copyFromContainer(ctx context.Context, dockerCLI command.Cli, copyConfig cp
srcInfo := archive.CopyInfo{
Path: srcPath,
Exists: true,
IsDir: stat.Mode.IsDir(),
IsDir: cpRes.Stat.Mode.IsDir(),
RebaseName: rebaseName,
}
@@ -289,7 +339,11 @@ func copyFromContainer(ctx context.Context, dockerCLI command.Cli, copyConfig cp
cancel()
<-done
restore()
_, _ = fmt.Fprintln(dockerCLI.Err(), "Successfully copied", progressHumanSize(copiedSize), "to", dstPath)
reportedSize := copiedSize
if !cpRes.Stat.Mode.IsDir() {
reportedSize = cpRes.Stat.Size
}
_, _ = fmt.Fprint(dockerCLI.Err(), copySummary(reportedSize, copiedSize, dstPath))
return res
}
@@ -298,63 +352,66 @@ func copyFromContainer(ctx context.Context, dockerCLI command.Cli, copyConfig cp
// about both the source and destination. The API is a simple tar
// archive/extract API but we can use the stat info header about the
// destination to be more informed about exactly what the destination is.
func copyToContainer(ctx context.Context, dockerCLI command.Cli, copyConfig cpConfig) (err error) {
func copyToContainer(ctx context.Context, dockerCLI command.Cli, copyConfig cpConfig) error {
srcPath := copyConfig.sourcePath
dstPath := copyConfig.destPath
if srcPath != "-" {
// Get an absolute source path.
srcPath, err = resolveLocalPath(srcPath)
p, err := resolveLocalPath(srcPath)
if err != nil {
return err
}
srcPath = p
}
apiClient := dockerCLI.Client()
// Prepare destination copy info by stat-ing the container path.
dstInfo := archive.CopyInfo{Path: dstPath}
dstStat, err := apiClient.ContainerStatPath(ctx, copyConfig.container, dstPath)
if dst, err := apiClient.ContainerStatPath(ctx, copyConfig.container, client.ContainerStatPathOptions{Path: dstPath}); err == nil {
// If the destination is a symbolic link, we should evaluate it.
if dst.Stat.Mode&os.ModeSymlink != 0 {
linkTarget := dst.Stat.LinkTarget
if !isAbs(linkTarget) {
// Join with the parent directory.
dstParent, _ := archive.SplitPathDirEntry(dstPath)
linkTarget = filepath.Join(dstParent, linkTarget)
}
// If the destination is a symbolic link, we should evaluate it.
if err == nil && dstStat.Mode&os.ModeSymlink != 0 {
linkTarget := dstStat.LinkTarget
if !isAbs(linkTarget) {
// Join with the parent directory.
dstParent, _ := archive.SplitPathDirEntry(dstPath)
linkTarget = filepath.Join(dstParent, linkTarget)
dstInfo.Path = linkTarget
dst, err = apiClient.ContainerStatPath(ctx, copyConfig.container, client.ContainerStatPathOptions{Path: linkTarget})
}
// Validate the destination path
if err == nil {
if err := command.ValidateOutputPathFileMode(dst.Stat.Mode); err != nil {
return fmt.Errorf(`destination "%s:%s" must be a directory or a regular file: %w`, copyConfig.container, dstPath, err)
}
dstInfo.Exists, dstInfo.IsDir = true, dst.Stat.Mode.IsDir()
}
dstInfo.Path = linkTarget
dstStat, err = apiClient.ContainerStatPath(ctx, copyConfig.container, linkTarget)
// FIXME(thaJeztah): unhandled error (should this return?)
}
// Validate the destination path
if err := command.ValidateOutputPathFileMode(dstStat.Mode); err != nil {
return errors.Wrapf(err, `destination "%s:%s" must be a directory or a regular file`, copyConfig.container, dstPath)
}
// Ignore any error and assume that the parent directory of the destination
// path exists, in which case the copy may still succeed. If there is any
// type of conflict (e.g., non-directory overwriting an existing directory
// or vice versa) the extraction will fail. If the destination simply did
// not exist, but the parent directory does, the extraction will still
// succeed.
if err == nil {
dstInfo.Exists, dstInfo.IsDir = true, dstStat.Mode.IsDir()
// Ignore any error and assume that the parent directory of the destination
// path exists, in which case the copy may still succeed. If there is any
// type of conflict (e.g., non-directory overwriting an existing directory
// or vice versa) the extraction will fail. If the destination simply did
// not exist, but the parent directory does, the extraction will still
// succeed.
_ = err // Intentionally ignore stat errors (see above)
}
var (
content io.ReadCloser
resolvedDstPath string
copiedSize int64
contentSize int64
sizeErr error
)
if srcPath == "-" {
content = os.Stdin
resolvedDstPath = dstInfo.Path
sizeErr = errors.New("content size not available for stdin")
if !dstInfo.IsDir {
return errors.Errorf("destination \"%s:%s\" must be a directory", copyConfig.container, dstPath)
return fmt.Errorf(`destination "%s:%s" must be a directory`, copyConfig.container, dstPath)
}
} else {
// Prepare source copy info.
@@ -363,6 +420,8 @@ func copyToContainer(ctx context.Context, dockerCLI command.Cli, copyConfig cpCo
return err
}
contentSize, sizeErr = localContentSize(srcInfo.Path)
srcArchive, err := archive.TarResource(srcInfo)
if err != nil {
return err
@@ -397,24 +456,31 @@ func copyToContainer(ctx context.Context, dockerCLI command.Cli, copyConfig cpCo
}
}
options := container.CopyToContainerOptions{
AllowOverwriteDirWithFile: false,
CopyUIDGID: copyConfig.copyUIDGID,
options := client.CopyToContainerOptions{
DestinationPath: resolvedDstPath,
Content: content,
CopyUIDGID: copyConfig.copyUIDGID,
}
if copyConfig.quiet {
return apiClient.CopyToContainer(ctx, copyConfig.container, resolvedDstPath, content, options)
_, err := apiClient.CopyToContainer(ctx, copyConfig.container, options)
return err
}
ctx, cancel := signal.NotifyContext(ctx, os.Interrupt)
restore, done := copyProgress(ctx, dockerCLI.Err(), copyToContainerHeader, &copiedSize)
res := apiClient.CopyToContainer(ctx, copyConfig.container, resolvedDstPath, content, options)
// TODO(thaJeztah): error-handling looks odd here; should it be handled differently?
_, err := apiClient.CopyToContainer(ctx, copyConfig.container, options)
cancel()
<-done
restore()
fmt.Fprintln(dockerCLI.Err(), "Successfully copied", progressHumanSize(copiedSize), "to", copyConfig.container+":"+dstInfo.Path)
reportedSize := copiedSize
if sizeErr == nil {
reportedSize = contentSize
}
_, _ = fmt.Fprint(dockerCLI.Err(), copySummary(reportedSize, copiedSize, copyConfig.container+":"+dstInfo.Path))
return res
return err
}
// We use `:` as a delimiter between CONTAINER and PATH, but `:` could also be
+248 -7
View File
@@ -9,9 +9,10 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/container"
"github.com/moby/go-archive"
"github.com/moby/go-archive/compression"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/fs"
@@ -52,9 +53,11 @@ func TestRunCopyFromContainerToStdout(t *testing.T) {
tarContent := "the tar content"
cli := test.NewFakeCli(&fakeClient{
containerCopyFromFunc: func(ctr, srcPath string) (io.ReadCloser, container.PathStat, error) {
containerCopyFromFunc: func(ctr, srcPath string) (client.CopyFromContainerResult, error) {
assert.Check(t, is.Equal("container", ctr))
return io.NopCloser(strings.NewReader(tarContent)), container.PathStat{}, nil
return client.CopyFromContainerResult{
Content: io.NopCloser(strings.NewReader(tarContent)),
}, nil
},
})
err := runCopy(context.TODO(), cli, copyOptions{
@@ -73,10 +76,12 @@ func TestRunCopyFromContainerToFilesystem(t *testing.T) {
destDir := fs.NewDir(t, "cp-test")
cli := test.NewFakeCli(&fakeClient{
containerCopyFromFunc: func(ctr, srcPath string) (io.ReadCloser, container.PathStat, error) {
containerCopyFromFunc: func(ctr, srcPath string) (client.CopyFromContainerResult, error) {
assert.Check(t, is.Equal("container", ctr))
readCloser, err := archive.Tar(srcDir.Path(), compression.None)
return readCloser, container.PathStat{}, err
return client.CopyFromContainerResult{
Content: readCloser,
}, err
},
})
err := runCopy(context.TODO(), cli, copyOptions{
@@ -99,10 +104,12 @@ func TestRunCopyFromContainerToFilesystemMissingDestinationDirectory(t *testing.
defer destDir.Remove()
cli := test.NewFakeCli(&fakeClient{
containerCopyFromFunc: func(ctr, srcPath string) (io.ReadCloser, container.PathStat, error) {
containerCopyFromFunc: func(ctr, srcPath string) (client.CopyFromContainerResult, error) {
assert.Check(t, is.Equal("container", ctr))
readCloser, err := archive.TarWithOptions(destDir.Path(), &archive.TarOptions{})
return readCloser, container.PathStat{}, err
return client.CopyFromContainerResult{
Content: readCloser,
}, err
},
})
err := runCopy(context.TODO(), cli, copyOptions{
@@ -205,3 +212,237 @@ func TestRunCopyFromContainerToFilesystemIrregularDestination(t *testing.T) {
expected := `"/dev/random" must be a directory or a regular file`
assert.ErrorContains(t, err, expected)
}
func TestCopySummary(t *testing.T) {
tests := []struct {
name string
contentSize int64
transferredSize int64
dest string
wantContains string
wantNoContain string
}{
{
name: "different sizes shows both",
contentSize: 5,
transferredSize: 2048,
dest: "/dst",
wantContains: "(transferred",
},
{
name: "equal sizes shows single value",
contentSize: 100,
transferredSize: 100,
dest: "/dst",
wantNoContain: "(transferred",
},
{
name: "both zero",
contentSize: 0,
transferredSize: 0,
dest: "ctr:/dst",
wantContains: "Successfully copied 0B to ctr:/dst",
wantNoContain: "(transferred",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
got := copySummary(tc.contentSize, tc.transferredSize, tc.dest)
if tc.wantContains != "" {
assert.Check(t, is.Contains(got, tc.wantContains))
}
if tc.wantNoContain != "" {
assert.Check(t, !strings.Contains(got, tc.wantNoContain), "unexpected substring %q in %q", tc.wantNoContain, got)
}
})
}
}
func TestCopyFromContainerReportsFileSize(t *testing.T) {
// The file content is "hello" (5 bytes), but the TAR archive wrapping
// it is much larger due to headers and padding. The success message
// should report the actual file size (5B), not the TAR stream size.
srcDir := fs.NewDir(t, "cp-test-from",
fs.WithFile("file1", "hello"))
destDir := fs.NewDir(t, "cp-test-from-dest")
const fileSize int64 = 5
fakeCli := test.NewFakeCli(&fakeClient{
containerCopyFromFunc: func(ctr, srcPath string) (client.CopyFromContainerResult, error) {
readCloser, err := archive.Tar(srcDir.Path(), compression.None)
return client.CopyFromContainerResult{
Content: readCloser,
Stat: container.PathStat{
Name: "file1",
Size: fileSize,
},
}, err
},
})
err := runCopy(context.TODO(), fakeCli, copyOptions{
source: "container:/file1",
destination: destDir.Path(),
})
assert.NilError(t, err)
errOut := fakeCli.ErrBuffer().String()
assert.Check(t, is.Contains(errOut, "Successfully copied 5B"))
assert.Check(t, is.Contains(errOut, "(transferred"))
}
func TestCopyToContainerReportsFileSize(t *testing.T) {
// Create a temp file with known content ("hello" = 5 bytes).
// The TAR archive sent to the container is larger, but the success
// message should report the actual content size.
srcFile := fs.NewFile(t, "cp-test-to", fs.WithContent("hello"))
fakeCli := test.NewFakeCli(&fakeClient{
containerStatPathFunc: func(containerID, path string) (client.ContainerStatPathResult, error) {
return client.ContainerStatPathResult{
Stat: container.PathStat{
Name: "tmp",
Mode: os.ModeDir | 0o755,
},
}, nil
},
containerCopyToFunc: func(containerID string, options client.CopyToContainerOptions) (client.CopyToContainerResult, error) {
_, _ = io.Copy(io.Discard, options.Content)
return client.CopyToContainerResult{}, nil
},
})
err := runCopy(context.TODO(), fakeCli, copyOptions{
source: srcFile.Path(),
destination: "container:/tmp",
})
assert.NilError(t, err)
errOut := fakeCli.ErrBuffer().String()
assert.Check(t, is.Contains(errOut, "Successfully copied 5B"))
assert.Check(t, is.Contains(errOut, "(transferred"))
}
func TestCopyToContainerReportsEmptyFileSize(t *testing.T) {
srcFile := fs.NewFile(t, "cp-test-empty", fs.WithContent(""))
fakeCli := test.NewFakeCli(&fakeClient{
containerStatPathFunc: func(containerID, path string) (client.ContainerStatPathResult, error) {
return client.ContainerStatPathResult{
Stat: container.PathStat{
Name: "tmp",
Mode: os.ModeDir | 0o755,
},
}, nil
},
containerCopyToFunc: func(containerID string, options client.CopyToContainerOptions) (client.CopyToContainerResult, error) {
_, _ = io.Copy(io.Discard, options.Content)
return client.CopyToContainerResult{}, nil
},
})
err := runCopy(context.TODO(), fakeCli, copyOptions{
source: srcFile.Path(),
destination: "container:/tmp",
})
assert.NilError(t, err)
errOut := fakeCli.ErrBuffer().String()
assert.Check(t, is.Contains(errOut, "Successfully copied 0B"))
assert.Check(t, is.Contains(errOut, "(transferred"))
}
func TestCopyToContainerReportsDirectorySize(t *testing.T) {
// Create a temp directory with files "aaa" (3 bytes) + "bbb" (3 bytes) = 6 bytes.
// The TAR archive is much larger, but the success message should report 6B.
srcDir := fs.NewDir(t, "cp-test-dir",
fs.WithFile("aaa", "aaa"),
fs.WithFile("bbb", "bbb"),
)
fakeCli := test.NewFakeCli(&fakeClient{
containerStatPathFunc: func(containerID, path string) (client.ContainerStatPathResult, error) {
return client.ContainerStatPathResult{
Stat: container.PathStat{
Name: "tmp",
Mode: os.ModeDir | 0o755,
},
}, nil
},
containerCopyToFunc: func(containerID string, options client.CopyToContainerOptions) (client.CopyToContainerResult, error) {
_, _ = io.Copy(io.Discard, options.Content)
return client.CopyToContainerResult{}, nil
},
})
err := runCopy(context.TODO(), fakeCli, copyOptions{
source: srcDir.Path() + string(os.PathSeparator),
destination: "container:/tmp",
})
assert.NilError(t, err)
errOut := fakeCli.ErrBuffer().String()
assert.Check(t, is.Contains(errOut, "Successfully copied 6B"))
assert.Check(t, is.Contains(errOut, "(transferred"))
}
func TestCopyFromContainerReportsDirectorySize(t *testing.T) {
// When copying a directory from a container, cpRes.Stat.Mode.IsDir() is true,
// so reportedSize falls back to copiedSize (the tar stream bytes).
srcDir := fs.NewDir(t, "cp-test-fromdir",
fs.WithFile("file1", "hello"))
destDir := fs.NewDir(t, "cp-test-fromdir-dest")
fakeCli := test.NewFakeCli(&fakeClient{
containerCopyFromFunc: func(ctr, srcPath string) (client.CopyFromContainerResult, error) {
readCloser, err := archive.Tar(srcDir.Path(), compression.None)
return client.CopyFromContainerResult{
Content: readCloser,
Stat: container.PathStat{
Name: "mydir",
Mode: os.ModeDir | 0o755,
},
}, err
},
})
err := runCopy(context.TODO(), fakeCli, copyOptions{
source: "container:/mydir",
destination: destDir.Path(),
})
assert.NilError(t, err)
errOut := fakeCli.ErrBuffer().String()
assert.Check(t, is.Contains(errOut, "Successfully copied"))
// For directories from container, content size is unknown so
// reportedSize == copiedSize and "(transferred ...)" is omitted.
assert.Check(t, !strings.Contains(errOut, "(transferred"))
}
func TestCopyToContainerStdinReportsTransferredSize(t *testing.T) {
// When copying from stdin, content size is unknown.
// The message should report transferred bytes without "(transferred ...)".
r, w, _ := os.Pipe()
_, _ = w.WriteString("some data from stdin")
w.Close()
oldStdin := os.Stdin
os.Stdin = r
t.Cleanup(func() { os.Stdin = oldStdin })
fakeCli := test.NewFakeCli(&fakeClient{
containerStatPathFunc: func(containerID, path string) (client.ContainerStatPathResult, error) {
return client.ContainerStatPathResult{
Stat: container.PathStat{
Name: "tmp",
Mode: os.ModeDir | 0o755,
},
}, nil
},
containerCopyToFunc: func(containerID string, options client.CopyToContainerOptions) (client.CopyToContainerResult, error) {
_, _ = io.Copy(io.Discard, options.Content)
return client.CopyToContainerResult{}, nil
},
})
err := runCopy(context.TODO(), fakeCli, copyOptions{
source: "-",
destination: "container:/tmp",
})
assert.NilError(t, err)
errOut := fakeCli.ErrBuffer().String()
assert.Check(t, is.Contains(errOut, "Successfully copied"))
// stdin has no content size, so reportedSize == copiedSize and
// "(transferred ...)" should not appear.
assert.Check(t, !strings.Contains(errOut, "(transferred"))
}
+115 -131
View File
@@ -4,33 +4,27 @@ import (
"archive/tar"
"bytes"
"context"
"errors"
"fmt"
"io"
"net/netip"
"os"
"path"
"strings"
cerrdefs "github.com/containerd/errdefs"
"github.com/containerd/errdefs"
"github.com/containerd/platforms"
"github.com/distribution/reference"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/cli/command/image"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/config/types"
"github.com/docker/cli/cli/streams"
"github.com/docker/cli/cli/trust"
"github.com/docker/cli/internal/jsonstream"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/container"
imagetypes "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/client"
"github.com/moby/moby/api/types/mount"
"github.com/moby/moby/client"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
@@ -45,14 +39,13 @@ const (
type createOptions struct {
name string
platform string
untrusted bool
pull string // always, missing, never
quiet bool
useAPISocket bool
}
// NewCreateCommand creates a new cobra.Command for `docker create`
func NewCreateCommand(dockerCli command.Cli) *cobra.Command {
// newCreateCommand creates a new cobra.Command for `docker create`
func newCreateCommand(dockerCLI command.Cli) *cobra.Command {
var options createOptions
var copts *containerOptions
@@ -65,52 +58,52 @@ func NewCreateCommand(dockerCli command.Cli) *cobra.Command {
if len(args) > 1 {
copts.Args = args[1:]
}
return runCreate(cmd.Context(), dockerCli, cmd.Flags(), &options, copts)
return runCreate(cmd.Context(), dockerCLI, cmd.Flags(), &options, copts)
},
Annotations: map[string]string{
"aliases": "docker container create, docker create",
},
ValidArgsFunction: completion.ImageNames(dockerCli, -1),
ValidArgsFunction: completion.ImageNames(dockerCLI, -1),
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
flags.SetInterspersed(false)
flags.StringVar(&options.name, "name", "", "Assign a name to the container")
flags.StringVar(&options.pull, "pull", PullImageMissing, `Pull image before creating ("`+PullImageAlways+`", "|`+PullImageMissing+`", "`+PullImageNever+`")`)
flags.StringVar(&options.pull, "pull", PullImageMissing, `Pull image before creating ("`+PullImageAlways+`", "`+PullImageMissing+`", "`+PullImageNever+`")`)
flags.BoolVarP(&options.quiet, "quiet", "q", false, "Suppress the pull output")
flags.BoolVarP(&options.useAPISocket, "use-api-socket", "", false, "Bind mount Docker API socket and required auth")
flags.SetAnnotation("use-api-socket", "experimentalCLI", nil) // Marks flag as experimental for now.
_ = flags.SetAnnotation("use-api-socket", "experimentalCLI", nil) // Mark flag as experimental for now.
// Add an explicit help that doesn't have a `-h` to prevent the conflict
// with hostname
flags.Bool("help", false, "Print usage")
command.AddPlatformFlag(flags, &options.platform)
command.AddTrustVerificationFlags(flags, &options.untrusted, dockerCli.ContentTrustEnabled())
// TODO(thaJeztah): consider adding platform as "image create option" on containerOptions
flags.StringVar(&options.platform, "platform", os.Getenv("DOCKER_DEFAULT_PLATFORM"), "Set platform if server is multi-platform capable")
_ = flags.SetAnnotation("platform", "version", []string{"1.32"})
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
// TODO(thaJeztah): DEPRECATED: remove in v29.1 or v30
flags.Bool("disable-content-trust", true, "Skip image verification (deprecated)")
_ = flags.MarkDeprecated("disable-content-trust", "support for docker content trust was removed")
copts = addFlags(flags)
addCompletions(cmd, dockerCli)
flags.VisitAll(func(flag *pflag.Flag) {
// Set a default completion function if none was set. We don't look
// up if it does already have one set, because Cobra does this for
// us, and returns an error (which we ignore for this reason).
_ = cmd.RegisterFlagCompletionFunc(flag.Name, completion.NoComplete)
})
addCompletions(cmd, dockerCLI)
return cmd
}
func runCreate(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet, options *createOptions, copts *containerOptions) error {
func runCreate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet, options *createOptions, copts *containerOptions) error {
if err := validatePullOpt(options.pull); err != nil {
return cli.StatusError{
Status: withHelp(err, "create").Error(),
StatusCode: 125,
}
}
proxyConfig := dockerCli.ConfigFile().ParseProxyConfig(dockerCli.Client().DaemonHost(), opts.ConvertKVStringsToMapWithNil(copts.env.GetSlice()))
newEnv := []string{}
proxyConfig := dockerCLI.ConfigFile().ParseProxyConfig(dockerCLI.Client().DaemonHost(), opts.ConvertKVStringsToMapWithNil(copts.env.GetSlice()))
newEnv := make([]string, 0, len(proxyConfig))
for k, v := range proxyConfig {
if v == nil {
newEnv = append(newEnv, k)
@@ -119,42 +112,53 @@ func runCreate(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet,
}
}
copts.env = *opts.NewListOptsRef(&newEnv, nil)
containerCfg, err := parse(flags, copts, dockerCli.ServerInfo().OSType)
serverInfo, err := dockerCLI.Client().Ping(ctx, client.PingOptions{})
if err != nil {
return err
}
containerCfg, err := parse(flags, copts, serverInfo.OSType)
if err != nil {
return cli.StatusError{
Status: withHelp(err, "create").Error(),
StatusCode: 125,
}
}
id, err := createContainer(ctx, dockerCli, containerCfg, options)
id, err := createContainer(ctx, dockerCLI, containerCfg, options)
if err != nil {
return err
}
_, _ = fmt.Fprintln(dockerCli.Out(), id)
_, _ = fmt.Fprintln(dockerCLI.Out(), id)
return nil
}
// FIXME(thaJeztah): this is the only code-path that uses APIClient.ImageCreate. Rewrite this to use the regular "pull" code (or vice-versa).
func pullImage(ctx context.Context, dockerCli command.Cli, img string, options *createOptions) error {
encodedAuth, err := command.RetrieveAuthTokenFromImage(dockerCli.ConfigFile(), img)
func pullImage(ctx context.Context, dockerCLI command.Cli, img string, options *createOptions) error {
encodedAuth, err := command.RetrieveAuthTokenFromImage(dockerCLI.ConfigFile(), img)
if err != nil {
return err
}
responseBody, err := dockerCli.Client().ImageCreate(ctx, img, imagetypes.CreateOptions{
var ociPlatforms []ocispec.Platform
if options.platform != "" {
// Already validated.
ociPlatforms = append(ociPlatforms, platforms.MustParse(options.platform))
}
resp, err := dockerCLI.Client().ImagePull(ctx, img, client.ImagePullOptions{
RegistryAuth: encodedAuth,
Platform: options.platform,
Platforms: ociPlatforms,
})
if err != nil {
return err
}
defer responseBody.Close()
defer func() {
_ = resp.Close()
}()
out := dockerCli.Err()
out := dockerCLI.Err()
if options.quiet {
out = streams.NewOut(io.Discard)
}
return jsonstream.Display(ctx, responseBody, out)
return jsonstream.Display(ctx, resp, out)
}
type cidFile struct {
@@ -167,13 +171,13 @@ func (cid *cidFile) Close() error {
if cid.file == nil {
return nil
}
cid.file.Close()
_ = cid.file.Close()
if cid.written {
return nil
}
if err := os.Remove(cid.path); err != nil {
return errors.Wrapf(err, "failed to remove the CID file '%s'", cid.path)
if err := os.Remove(cid.path); err != nil && !errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("failed to remove the CID file: %w", err)
}
return nil
@@ -183,8 +187,8 @@ func (cid *cidFile) Write(id string) error {
if cid.file == nil {
return nil
}
if _, err := cid.file.Write([]byte(id)); err != nil {
return errors.Wrap(err, "failed to write the container ID to the file")
if _, err := cid.file.WriteString(id); err != nil {
return fmt.Errorf("failed to write the container ID (%s) to file: %w", id, err)
}
cid.written = true
return nil
@@ -195,33 +199,39 @@ func newCIDFile(cidPath string) (*cidFile, error) {
return &cidFile{}, nil
}
if _, err := os.Stat(cidPath); err == nil {
return nil, errors.Errorf("container ID file found, make sure the other container isn't running or delete %s", cidPath)
return nil, errors.New("container ID file found, make sure the other container isn't running or delete " + cidPath)
}
f, err := os.Create(cidPath)
if err != nil {
return nil, errors.Wrap(err, "failed to create the container ID file")
return nil, fmt.Errorf("failed to create the container ID file: %w", err)
}
return &cidFile{path: cidPath, file: f}, nil
}
//nolint:gocyclo
func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *containerConfig, options *createOptions) (containerID string, err error) {
func createContainer(ctx context.Context, dockerCLI command.Cli, containerCfg *containerConfig, options *createOptions) (containerID string, _ error) {
config := containerCfg.Config
hostConfig := containerCfg.HostConfig
networkingConfig := containerCfg.NetworkingConfig
var (
trustedRef reference.Canonical
namedRef reference.Named
)
var namedRef reference.Named
// TODO(thaJeztah): add a platform option-type / flag-type.
if options.platform != "" {
if _, err := platforms.Parse(options.platform); err != nil {
return "", err
}
}
containerIDFile, err := newCIDFile(hostConfig.ContainerIDFile)
if err != nil {
return "", err
}
defer containerIDFile.Close()
defer func() {
_ = containerIDFile.Close()
}()
ref, err := reference.ParseAnyReference(config.Image)
if err != nil {
@@ -229,15 +239,6 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
}
if named, ok := ref.(reference.Named); ok {
namedRef = reference.TagNameOnly(named)
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && !options.untrusted {
var err error
trustedRef, err = image.TrustedReference(ctx, dockerCli, taggedRef)
if err != nil {
return "", err
}
config.Image = reference.FamiliarString(trustedRef)
}
}
const dockerConfigPathInContainer = "/run/secrets/docker/config.json"
@@ -245,18 +246,18 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
if options.useAPISocket {
// We'll create two new mounts to handle this flag:
//
// 1. Mount the actual docker socket.
// 2. A synthezised ~/.docker/config.json with resolved tokens.
// 2. A synthesized ~/.docker/config.json with resolved tokens.
socket := dockerCli.DockerEndpoint().Host
if !strings.HasPrefix(socket, "unix://") {
return "", fmt.Errorf("flag --use-api-socket can only be used with unix sockets: docker endpoint %s incompatible", socket)
if dockerCLI.ServerInfo().OSType == "windows" {
return "", errors.New("flag --use-api-socket can't be used with a Windows Docker Engine")
}
socket = strings.TrimPrefix(socket, "unix://") // should we confirm absolute path?
// hard-code engine socket path until https://github.com/moby/moby/pull/43459 gives us a discovery mechanism
containerCfg.HostConfig.Mounts = append(containerCfg.HostConfig.Mounts, mount.Mount{
Type: mount.TypeBind,
Source: socket,
Source: "/var/run/docker.sock",
Target: "/var/run/docker.sock",
BindOptions: &mount.BindOptions{},
})
@@ -284,18 +285,18 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
})
*/
var envvarPresent bool
for _, envvar := range containerCfg.Config.Env {
if strings.HasPrefix(envvar, "DOCKER_CONFIG=") {
envvarPresent = true
var envVarPresent bool
for _, envVar := range containerCfg.Config.Env {
if strings.HasPrefix(envVar, "DOCKER_CONFIG=") {
envVarPresent = true
}
}
// If the DOCKER_CONFIG env var is already present, we assume the client knows
// what they're doing and don't inject the creds.
if !envvarPresent {
if !envVarPresent {
// Resolve this here for later, ensuring we error our before we create the container.
creds, err := readCredentials(dockerCli)
creds, err := readCredentials(dockerCLI)
if err != nil {
return "", fmt.Errorf("resolving credentials failed: %w", err)
}
@@ -309,51 +310,51 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
}
var platform *ocispec.Platform
// Engine API version 1.41 first introduced the option to specify platform on
// create. It will produce an error if you try to set a platform on older API
// versions, so check the API version here to maintain backwards
// compatibility for CLI users.
if options.platform != "" && versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.41") {
if options.platform != "" {
p, err := platforms.Parse(options.platform)
if err != nil {
return "", errors.Wrap(invalidParameter(err), "error parsing specified platform")
return "", invalidParameter(fmt.Errorf("error parsing specified platform: %w", err))
}
platform = &p
}
pullAndTagImage := func() error {
if err := pullImage(ctx, dockerCli, config.Image, options); err != nil {
return err
}
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && trustedRef != nil {
return trust.TagTrusted(ctx, dockerCli.Client(), dockerCli.Err(), trustedRef, taggedRef)
}
return nil
}
if options.pull == PullImageAlways {
if err := pullAndTagImage(); err != nil {
if err := pullImage(ctx, dockerCLI, config.Image, options); err != nil {
return "", err
}
}
hostConfig.ConsoleSize[0], hostConfig.ConsoleSize[1] = dockerCli.Out().GetTtySize()
hostConfig.ConsoleSize[0], hostConfig.ConsoleSize[1] = dockerCLI.Out().GetTtySize()
response, err := dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, platform, options.name)
response, err := dockerCLI.Client().ContainerCreate(ctx, client.ContainerCreateOptions{
Name: options.name,
// Image: config.Image, // TODO(thaJeztah): pass image-ref separate
Platform: platform,
Config: config,
HostConfig: hostConfig,
NetworkingConfig: networkingConfig,
})
if err != nil {
// Pull image if it does not exist locally and we have the PullImageMissing option. Default behavior.
if cerrdefs.IsNotFound(err) && namedRef != nil && options.pull == PullImageMissing {
if errdefs.IsNotFound(err) && namedRef != nil && options.pull == PullImageMissing {
if !options.quiet {
// we don't want to write to stdout anything apart from container.ID
_, _ = fmt.Fprintf(dockerCli.Err(), "Unable to find image '%s' locally\n", reference.FamiliarString(namedRef))
_, _ = fmt.Fprintf(dockerCLI.Err(), "Unable to find image '%s' locally\n", reference.FamiliarString(namedRef))
}
if err := pullAndTagImage(); err != nil {
if err := pullImage(ctx, dockerCLI, config.Image, options); err != nil {
return "", err
}
var retryErr error
response, retryErr = dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, platform, options.name)
response, retryErr = dockerCLI.Client().ContainerCreate(ctx, client.ContainerCreateOptions{
Name: options.name,
// Image: config.Image, // TODO(thaJeztah): pass image-ref separate
Platform: platform,
Config: config,
HostConfig: hostConfig,
NetworkingConfig: networkingConfig,
})
if retryErr != nil {
return "", retryErr
}
@@ -362,41 +363,20 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
}
}
if warn := localhostDNSWarning(*hostConfig); warn != "" {
response.Warnings = append(response.Warnings, warn)
}
containerID = response.ID
for _, w := range response.Warnings {
_, _ = fmt.Fprintln(dockerCli.Err(), "WARNING:", w)
}
err = containerIDFile.Write(containerID)
if options.useAPISocket && len(apiSocketCreds) > 0 {
// Create a new config file with just the auth.
newConfig := &configfile.ConfigFile{
if err := copyDockerConfigIntoContainer(ctx, dockerCLI.Client(), response.ID, dockerConfigPathInContainer, &configfile.ConfigFile{
AuthConfigs: apiSocketCreds,
}
if err := copyDockerConfigIntoContainer(ctx, dockerCli.Client(), containerID, dockerConfigPathInContainer, newConfig); err != nil {
return "", fmt.Errorf("injecting docker config.json into container failed: %w", err)
}); err != nil {
response.Warnings = append(response.Warnings, fmt.Sprintf("injecting docker config.json into container failed: %v", err))
}
}
return containerID, err
}
// check the DNS settings passed via --dns against localhost regexp to warn if
// they are trying to set a DNS to a localhost address.
//
// TODO(thaJeztah): move this to the daemon, which can make a better call if it will work or not (depending on networking mode).
func localhostDNSWarning(hostConfig container.HostConfig) string {
for _, dnsIP := range hostConfig.DNS {
if addr, err := netip.ParseAddr(dnsIP); err == nil && addr.IsLoopback() {
return fmt.Sprintf("Localhost DNS (%s) may fail in containers.", addr)
}
for _, w := range response.Warnings {
_, _ = fmt.Fprintln(dockerCLI.Err(), "WARNING:", w)
}
return ""
err = containerIDFile.Write(response.ID)
return response.ID, err
}
func validatePullOpt(val string) error {
@@ -420,7 +400,7 @@ func validatePullOpt(val string) error {
//
// The path should be an absolute path in the container, commonly
// /root/.docker/config.json.
func copyDockerConfigIntoContainer(ctx context.Context, dockerAPI client.APIClient, containerID string, configPath string, config *configfile.ConfigFile) error {
func copyDockerConfigIntoContainer(ctx context.Context, apiClient client.APIClient, containerID string, configPath string, config *configfile.ConfigFile) error {
var configBuf bytes.Buffer
if err := config.SaveToWriter(&configBuf); err != nil {
return fmt.Errorf("saving creds: %w", err)
@@ -429,13 +409,14 @@ func copyDockerConfigIntoContainer(ctx context.Context, dockerAPI client.APIClie
// We don't need to get super fancy with the tar creation.
var tarBuf bytes.Buffer
tarWriter := tar.NewWriter(&tarBuf)
tarWriter.WriteHeader(&tar.Header{
_ = tarWriter.WriteHeader(&tar.Header{
Name: configPath,
Size: int64(configBuf.Len()),
Mode: 0o600,
})
if _, err := io.Copy(tarWriter, &configBuf); err != nil {
_ = tarWriter.Close()
return fmt.Errorf("writing config to tar file for config copy: %w", err)
}
@@ -443,8 +424,11 @@ func copyDockerConfigIntoContainer(ctx context.Context, dockerAPI client.APIClie
return fmt.Errorf("closing tar for config copy failed: %w", err)
}
if err := dockerAPI.CopyToContainer(ctx, containerID, "/",
&tarBuf, container.CopyToContainerOptions{}); err != nil {
_, err := apiClient.CopyToContainer(ctx, containerID, client.CopyToContainerOptions{
DestinationPath: "/",
Content: &tarBuf,
})
if err != nil {
return fmt.Errorf("copying config.json into container failed: %w", err)
}
+50 -112
View File
@@ -5,6 +5,7 @@ import (
"errors"
"io"
"os"
"path/filepath"
"runtime"
"sort"
"strings"
@@ -13,13 +14,10 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/notary"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/system"
"github.com/google/go-cmp/cmp"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/system"
"github.com/moby/moby/client"
"github.com/spf13/pflag"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -45,17 +43,31 @@ func TestNewCIDFileWhenFileAlreadyExists(t *testing.T) {
}
func TestCIDFileCloseWithNoWrite(t *testing.T) {
tempdir := fs.NewDir(t, "test-cid-file")
defer tempdir.Remove()
// Closing should remove the file if it was not written to.
t.Run("closing should remove file", func(t *testing.T) {
filename := filepath.Join(t.TempDir(), "cidfile-1")
file, err := newCIDFile(filename)
assert.NilError(t, err)
assert.Check(t, is.Equal(file.path, filename))
path := tempdir.Join("cidfile")
file, err := newCIDFile(path)
assert.NilError(t, err)
assert.Check(t, is.Equal(file.path, path))
assert.NilError(t, file.Close())
_, err = os.Stat(filename)
assert.Check(t, os.IsNotExist(err))
})
assert.NilError(t, file.Close())
_, err = os.Stat(path)
assert.Check(t, os.IsNotExist(err))
// Closing (and removing) the file should not produce an error if the file no longer exists.
t.Run("close should remove file", func(t *testing.T) {
filename := filepath.Join(t.TempDir(), "cidfile-2")
file, err := newCIDFile(filename)
assert.NilError(t, err)
assert.Check(t, is.Equal(file.path, filename))
assert.NilError(t, os.Remove(filename))
_, err = os.Stat(filename)
assert.Check(t, os.IsNotExist(err))
assert.NilError(t, file.Close())
})
}
func TestCIDFileCloseWithWrite(t *testing.T) {
@@ -116,36 +128,31 @@ func TestCreateContainerImagePullPolicy(t *testing.T) {
t.Run(tc.PullPolicy, func(t *testing.T) {
pullCounter := 0
client := &fakeClient{
createContainerFunc: func(
config *container.Config,
hostConfig *container.HostConfig,
networkingConfig *network.NetworkingConfig,
platform *ocispec.Platform,
containerName string,
) (container.CreateResponse, error) {
apiClient := &fakeClient{
createContainerFunc: func(options client.ContainerCreateOptions) (client.ContainerCreateResult, error) {
defer func() { tc.ResponseCounter++ }()
switch tc.ResponseCounter {
case 0:
return container.CreateResponse{}, fakeNotFound{}
return client.ContainerCreateResult{}, fakeNotFound{}
default:
return container.CreateResponse{ID: containerID}, nil
return client.ContainerCreateResult{ID: containerID}, nil
}
},
imageCreateFunc: func(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error) {
imagePullFunc: func(ctx context.Context, parentReference string, options client.ImagePullOptions) (client.ImagePullResponse, error) {
defer func() { pullCounter++ }()
return io.NopCloser(strings.NewReader("")), nil
return fakeStreamResult{ReadCloser: io.NopCloser(strings.NewReader(""))}, nil
},
infoFunc: func() (system.Info, error) {
return system.Info{IndexServerAddress: "https://indexserver.example.com"}, nil
infoFunc: func() (client.SystemInfoResult, error) {
return client.SystemInfoResult{
Info: system.Info{IndexServerAddress: "https://indexserver.example.com"},
}, nil
},
}
fakeCLI := test.NewFakeCli(client)
fakeCLI := test.NewFakeCli(apiClient)
id, err := createContainer(context.Background(), fakeCLI, config, &createOptions{
name: "name",
platform: runtime.GOOS,
untrusted: true,
pull: tc.PullPolicy,
name: "name",
platform: runtime.GOOS,
pull: tc.PullPolicy,
})
if tc.ExpectedErrMsg != "" {
@@ -206,7 +213,7 @@ func TestCreateContainerValidateFlags(t *testing.T) {
},
} {
t.Run(tc.name, func(t *testing.T) {
cmd := NewCreateCommand(test.NewFakeCli(&fakeClient{}))
cmd := newCreateCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
@@ -221,55 +228,6 @@ func TestCreateContainerValidateFlags(t *testing.T) {
}
}
func TestNewCreateCommandWithContentTrustErrors(t *testing.T) {
testCases := []struct {
name string
args []string
expectedError string
notaryFunc test.NotaryClientFuncType
}{
{
name: "offline-notary-server",
notaryFunc: notary.GetOfflineNotaryRepository,
expectedError: "client is offline",
args: []string{"image:tag"},
},
{
name: "uninitialized-notary-server",
notaryFunc: notary.GetUninitializedNotaryRepository,
expectedError: "remote trust data does not exist",
args: []string{"image:tag"},
},
{
name: "empty-notary-server",
notaryFunc: notary.GetEmptyTargetsNotaryRepository,
expectedError: "No valid trust data for tag",
args: []string{"image:tag"},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
fakeCLI := test.NewFakeCli(&fakeClient{
createContainerFunc: func(config *container.Config,
hostConfig *container.HostConfig,
networkingConfig *network.NetworkingConfig,
platform *ocispec.Platform,
containerName string,
) (container.CreateResponse, error) {
return container.CreateResponse{}, errors.New("shouldn't try to pull image")
},
}, test.EnableContentTrust)
fakeCLI.SetNotaryClient(tc.notaryFunc)
cmd := NewCreateCommand(fakeCLI)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.ErrorContains(t, err, tc.expectedError)
})
}
}
func TestNewCreateCommandWithWarnings(t *testing.T) {
testCases := []struct {
name string
@@ -291,30 +249,15 @@ func TestNewCreateCommandWithWarnings(t *testing.T) {
args: []string{"image:tag"},
warnings: []string{"warning from daemon", "another warning from daemon"},
},
{
name: "container-create-localhost-dns",
args: []string{"--dns=127.0.0.11", "image:tag"},
warning: true,
},
{
name: "container-create-localhost-dns-ipv6",
args: []string{"--dns=::1", "image:tag"},
warning: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
fakeCLI := test.NewFakeCli(&fakeClient{
createContainerFunc: func(config *container.Config,
hostConfig *container.HostConfig,
networkingConfig *network.NetworkingConfig,
platform *ocispec.Platform,
containerName string,
) (container.CreateResponse, error) {
return container.CreateResponse{Warnings: tc.warnings}, nil
createContainerFunc: func(options client.ContainerCreateOptions) (client.ContainerCreateResult, error) {
return client.ContainerCreateResult{Warnings: tc.warnings}, nil
},
})
cmd := NewCreateCommand(fakeCLI)
cmd := newCreateCommand(fakeCLI)
cmd.SetOut(io.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
@@ -344,15 +287,10 @@ func TestCreateContainerWithProxyConfig(t *testing.T) {
sort.Strings(expected)
fakeCLI := test.NewFakeCli(&fakeClient{
createContainerFunc: func(config *container.Config,
hostConfig *container.HostConfig,
networkingConfig *network.NetworkingConfig,
platform *ocispec.Platform,
containerName string,
) (container.CreateResponse, error) {
sort.Strings(config.Env)
assert.DeepEqual(t, config.Env, expected)
return container.CreateResponse{}, nil
createContainerFunc: func(options client.ContainerCreateOptions) (client.ContainerCreateResult, error) {
sort.Strings(options.Config.Env)
assert.DeepEqual(t, options.Config.Env, expected)
return client.ContainerCreateResult{}, nil
},
})
fakeCLI.SetConfigFile(&configfile.ConfigFile{
@@ -366,7 +304,7 @@ func TestCreateContainerWithProxyConfig(t *testing.T) {
},
},
})
cmd := NewCreateCommand(fakeCLI)
cmd := newCreateCommand(fakeCLI)
cmd.SetOut(io.Discard)
cmd.SetArgs([]string{"image:tag"})
err := cmd.Execute()
+11 -20
View File
@@ -7,44 +7,35 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/cli/command/formatter"
"github.com/pkg/errors"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
type diffOptions struct {
container string
}
// NewDiffCommand creates a new cobra.Command for `docker diff`
func NewDiffCommand(dockerCli command.Cli) *cobra.Command {
var opts diffOptions
// newDiffCommand creates a new cobra.Command for `docker diff`
func newDiffCommand(dockerCLI command.Cli) *cobra.Command {
return &cobra.Command{
Use: "diff CONTAINER",
Short: "Inspect changes to files or directories on a container's filesystem",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.container = args[0]
return runDiff(cmd.Context(), dockerCli, &opts)
return runDiff(cmd.Context(), dockerCLI, args[0])
},
Annotations: map[string]string{
"aliases": "docker container diff, docker diff",
},
ValidArgsFunction: completion.ContainerNames(dockerCli, false),
ValidArgsFunction: completion.ContainerNames(dockerCLI, false),
DisableFlagsInUseLine: true,
}
}
func runDiff(ctx context.Context, dockerCli command.Cli, opts *diffOptions) error {
if opts.container == "" {
return errors.New("Container name cannot be empty")
}
changes, err := dockerCli.Client().ContainerDiff(ctx, opts.container)
func runDiff(ctx context.Context, dockerCLI command.Cli, containerID string) error {
res, err := dockerCLI.Client().ContainerDiff(ctx, containerID, client.ContainerDiffOptions{})
if err != nil {
return err
}
diffCtx := formatter.Context{
Output: dockerCli.Out(),
Format: NewDiffFormat("{{.Type}} {{.Path}}"),
Output: dockerCLI.Out(),
Format: newDiffFormat("{{.Type}} {{.Path}}"),
}
return DiffFormatWrite(diffCtx, changes)
return diffFormatWrite(diffCtx, res)
}
+21 -38
View File
@@ -8,35 +8,35 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/container"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
func TestRunDiff(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerDiffFunc: func(
ctx context.Context,
containerID string,
) ([]container.FilesystemChange, error) {
return []container.FilesystemChange{
{
Kind: container.ChangeModify,
Path: "/path/to/file0",
},
{
Kind: container.ChangeAdd,
Path: "/path/to/file1",
},
{
Kind: container.ChangeDelete,
Path: "/path/to/file2",
containerDiffFunc: func(ctx context.Context, containerID string) (client.ContainerDiffResult, error) {
return client.ContainerDiffResult{
Changes: []container.FilesystemChange{
{
Kind: container.ChangeModify,
Path: "/path/to/file0",
},
{
Kind: container.ChangeAdd,
Path: "/path/to/file1",
},
{
Kind: container.ChangeDelete,
Path: "/path/to/file2",
},
},
}, nil
},
})
cmd := NewDiffCommand(cli)
cmd := newDiffCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetArgs([]string{"container-id"})
@@ -60,15 +60,12 @@ func TestRunDiffClientError(t *testing.T) {
clientError := errors.New("client error")
cli := test.NewFakeCli(&fakeClient{
containerDiffFunc: func(
ctx context.Context,
containerID string,
) ([]container.FilesystemChange, error) {
return nil, clientError
containerDiffFunc: func(ctx context.Context, containerID string) (client.ContainerDiffResult, error) {
return client.ContainerDiffResult{}, clientError
},
})
cmd := NewDiffCommand(cli)
cmd := newDiffCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
@@ -77,17 +74,3 @@ func TestRunDiffClientError(t *testing.T) {
err := cmd.Execute()
assert.ErrorIs(t, err, clientError)
}
func TestRunDiffEmptyContainerError(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cmd := NewDiffCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
containerID := ""
cmd.SetArgs([]string{containerID})
err := cmd.Execute()
assert.Error(t, err, "Container name cannot be empty")
}

Some files were not shown because too many files have changed in this diff Show More