Compare commits

..
201 Commits
Author SHA1 Message Date
Sebastiaan van StijnandGitHub c05bf59c7d Merge pull request #4848 from thaJeztah/24.0_vendor_docker_24.0.9
[24.0] vendor: github.com/docker/docker v24.0.9
2024-02-07 10:47:03 +01:00
Sebastiaan van Stijn 0bf165cbcd vendor: github.com/docker/docker v24.0.9
no changes in vendored code

full diff: https://github.com/docker/docker/compare/v24.0.8....v24.0.9

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-02-03 11:55:41 +01:00
Brian GoffandGitHub 2936816130 Merge pull request #4840 from thaJeztah/24.0_vendor_runc_1.1.12
[24.0] vendor: github.com/opencontainers/runc v1.1.12
2024-01-31 12:53:14 -08:00
Sebastiaan van Stijn 50a008a288 vendor: github.com/opencontainers/runc v1.1.12
no changes in vendored code

- release notes: https://github.com/opencontainers/runc/releases/tag/v1.1.12
- full diff: https://github.com/opencontainers/runc/compare/v1.1.11...v1.1.12

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-01-31 21:30:49 +01:00
Brian GoffandGitHub 07d335afb2 Merge pull request #4838 from thaJeztah/24.0_vendor_runc_v1.1.11
[24.0] vendor: github.com/docker/docker v24.0.8
2024-01-31 12:07:26 -08:00
Sebastiaan van Stijn 3e7d90796c vendor: github.com/docker/docker v24.0.8
- Ensure that non-JSON-parsing errors are returned to the caller
- pkg/idtools: remove sync.Once, and include lookup error
- pkg/ioutils: Make subsequent Close attempts noop

full diff: https://github.com/docker/docker/compare/v24.0.7...v24.0.8

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-01-31 15:47:20 +01:00
Sebastiaan van Stijn 979eeaa248 vendor: github.com/opencontainers/runc v1.1.11
full diff: https://github.com/opencontainers/runc/compare/v1.1.7...v1.1.11

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-01-31 15:39:59 +01:00
Sebastiaan van StijnandGitHub e0dfb46e22 Merge pull request #4829 from thaJeztah/24.0_backport_go_compat
[24.0 backport] add //go:build directives to prevent downgrading to go1.16 language
2024-01-25 15:19:29 +01:00
Sebastiaan van Stijn ca4e8ebdbd add //go:build directives to prevent downgrading to go1.16 language
This is a follow-up to 0e73168b7e

This repository is not yet a module (i.e., does not have a `go.mod`). This
is not problematic when building the code in GOPATH or "vendor" mode, but
when using the code as a module-dependency (in module-mode), different semantics
are applied since Go1.21, which switches Go _language versions_ on a per-module,
per-package, or even per-file base.

A condensed summary of that logic [is as follows][1]:

- For modules that have a go.mod containing a go version directive; that
  version is considered a minimum _required_ version (starting with the
  go1.19.13 and go1.20.8 patch releases: before those, it was only a
  recommendation).
- For dependencies that don't have a go.mod (not a module), go language
  version go1.16 is assumed.
- Likewise, for modules that have a go.mod, but the file does not have a
  go version directive, go language version go1.16 is assumed.
- If a go.work file is present, but does not have a go version directive,
  language version go1.17 is assumed.

When switching language versions, Go _downgrades_ the language version,
which means that language features (such as generics, and `any`) are not
available, and compilation fails. For example:

    # 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)

Note that these fallbacks are per-module, per-package, and can even be
per-file, so _(indirect) dependencies_ can still use modern language
features, as long as their respective go.mod has a version specified.

Unfortunately, these failures do not occur when building locally (using
vendor / GOPATH mode), but will affect consumers of the module.

Obviously, this situation is not ideal, and the ultimate solution is to
move to go modules (add a go.mod), but this comes with a non-insignificant
risk in other areas (due to our complex dependency tree).

We can revert to using go1.16 language features only, but this may be
limiting, and may still be problematic when (e.g.) matching signatures
of dependencies.

There is an escape hatch: adding a `//go:build` directive to files that
make use of go language features. From the [go toolchain docs][2]:

> 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 patch adds `//go:build` directives to those files using recent additions
to the language. It's currently using go1.19 as version to match the version
in our "vendor.mod", but we can consider being more permissive ("any" requires
go1.18 or up), or more "optimistic" (force go1.21, which is the version we
currently use to build).

For completeness sake, note that any file _without_ a `//go:build` directive
will continue to use go1.16 language version when used as a module.

[1]: https://github.com/golang/go/blob/58c28ba286dd0e98fe4cca80f5d64bbcb824a685/src/cmd/go/internal/gover/version.go#L9-L56
[2]; https://go.dev/doc/toolchain#:~:text=The%20go%20line%20for,file%20to%20Go%201.22

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 70216b662d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-01-25 14:34:59 +01:00
Sebastiaan van StijnandGitHub d44992a3de Merge pull request #4827 from thaJeztah/24.0_update_engine
[24.0] vendor: github.com/docker/docker v24.0.7
2024-01-25 11:40:56 +01:00
Sebastiaan van Stijn 41e3a4ce1f vendor: github.com/docker/docker v24.0.7
- api/types/versions: rename max/min as it collides with go1.21 builtin
- full diff: https://github.com/docker/cli/compare/v24.0.6...v24.0.7

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-01-25 10:52:36 +01:00
Sebastiaan van StijnandGitHub 6bce8001c0 Merge pull request #4826 from thaJeztah/24.0_update_golang_1.20.13
[24.0] update to go1.20.13
2024-01-24 16:52:19 +01:00
Sebastiaan van StijnandGitHub 02d2f482da Merge pull request #4824 from thaJeztah/24.0_backport_4653-fix-credential-helper
[24.0 backport] Fix setting ServerAddress property in NativeStore
2024-01-24 16:52:01 +01:00
Sebastiaan van Stijn 27f03ce8e1 update to go1.20.13
go1.20.13 (released 2024-01-09) includes fixes to the runtime and the crypto/tls
package. See the Go 1.20.13 milestone on our issue tracker for details:

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

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-01-24 16:08:00 +01:00
Eric BodeandSebastiaan van Stijn bda52bd5c2 Fix setting ServerAddress property in NativeStore
This will return the ServerAddress property when using the NativeStore.
This happens when you use docker credential helpers, not the credential
store.

The reason this fix is needed is because it needs to be propagated
properly down towards `moby/moby` project in the following logic:

```golang
func authorizationCredsFromAuthConfig(authConfig registrytypes.AuthConfig) docker.AuthorizerOpt {
	cfgHost := registry.ConvertToHostname(authConfig.ServerAddress)
	if cfgHost == "" || cfgHost == registry.IndexHostname {
		cfgHost = registry.DefaultRegistryHost
	}

	return docker.WithAuthCreds(func(host string) (string, string, error) {
		if cfgHost != host {
			logrus.WithFields(logrus.Fields{
				"host":    host,
				"cfgHost": cfgHost,
			}).Warn("Host doesn't match")
			return "", "", nil
		}
		if authConfig.IdentityToken != "" {
			return "", authConfig.IdentityToken, nil
		}
		return authConfig.Username, authConfig.Password, nil
	})
}
```
This logic resides in the following file :
`daemon/containerd/resolver.go` .

In the case when using the containerd storage feature when setting the
`cfgHost` variable from the `authConfig.ServerAddress` it will always be
empty. Since it will never be returned from the NativeStore currently.
Therefore Docker Hub images will work fine, but anything else will fail
since the `cfgHost` will always be the `registry.DefaultRegistryHost`.

Signed-off-by: Eric Bode <eric.bode@foundries.io>
(cherry picked from commit b24e7f85a4)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-01-24 15:44:59 +01:00
Sebastiaan van StijnandGitHub bb3e6c03e4 Merge pull request #4768 from thaJeztah/24.0_backport_update_alpine_3.18
[24.0 backport] Dockerfile: update ALPINE_VERSION to 3.18
2024-01-10 15:10:38 +01:00
Sebastiaan van Stijn 6bb590f0b9 Dockerfile: update ALPINE_VERSION to 3.18
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 6a74a63ee2)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-01-10 14:21:52 +01:00
Sebastiaan van StijnandGitHub b0c5946ba5 Merge pull request #4750 from dvdksn/24.0_backport_docs-cli-format-example-links
[24.0 backport] docs: add links to volume ls, network ls, stack ps formatting examples
2024-01-03 17:22:25 +01:00
David Karlsson bff22cbacf docs: add links to volume ls, network ls, stack ps formatting examples
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit 878b1c55b7)
2024-01-03 17:05:27 +01:00
Sebastiaan van StijnandGitHub 0f82fd8861 Merge pull request #4710 from thaJeztah/24.0_backport_deprecated
[24.0 backport] docs/deprecated: add missing versions for "-g / --graph", and mark logentries log-driver for removal
2023-12-13 10:43:40 +01:00
Sebastiaan van Stijn f8b1e75618 docs/deprecated: mark logentries log-driver for removal
The service has been discontinued on November 15, 2022:

> Dear Logentries user,
>
> We have identified you as the owner of, or collaborator of, a Logentries
> account.
>
> The Logentries service will be discontinued on November 15th, 2022. This
> means that your Logentries account access will be removed and all your
> log data will be permanently deleted on this date.
>
> Next Steps
> If you are interested in an alternative Rapid7 log management solution,
> InsightOps will be available for purchase through December 16th, 2022.
> Please note, there is no support to migrate your existing Logentries
> account to InsightOps.
>
> Thank you for being a valued user of Logentries.
>
> Thank you,
> Rapid7 Customer Success

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c1a1a920fc96a638ba40573908d15f252631264b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-12-13 10:00:16 +01:00
Sebastiaan van Stijn 7ba6984ec6 docs/deprecated.md: add version for "-g" / "--graph" removal
commit 304c100ed2 updated the deprecation
status for these options, but forgot to update the status in the table.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 3f519b8241)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-12-13 09:57:26 +01:00
Sebastiaan van StijnandGitHub fb2f337bc1 Merge pull request #4706 from thaJeztah/24.0_backport_docs
[24.0 backport] assorted documentation updates
2023-12-11 22:03:10 +01:00
Per LundbergandSebastiaan van Stijn a976e5084a exec.md: remove misleading part
"By default" implies that this is something which could be
disabled for an individual `docker exec` call. This doesn't seem
to be the case, so removing the "by default" part would make
these docs clearer to me.

Signed-off-by: Per Lundberg <per.lundberg@hibox.tv>
(cherry picked from commit a431b1dda6)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-12-11 21:52:34 +01:00
TheRealGramdalfandSebastiaan van Stijn 3ab117e7cd Fix typo in dockerd reference documentation
Signed-off-by: Graeme Wiebe <graeme.wiebe@gmail.com>
(cherry picked from commit e93ec2f6a6)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-12-11 21:52:22 +01:00
Sebastiaan van Stijn f9cdb6f96a docs: update debian examples to use bookworm
"bullseye" is no longer the "latest" debian, so these
examples were now incorrect.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 6468c63c81)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-12-11 21:51:18 +01:00
Hugo ChastelandSebastiaan van Stijn 13a7d571a1 Add zstd as supported in load command doc
Signed-off-by: Hugo Chastel <Hugo-C@users.noreply.github.com>
(cherry picked from commit f387558b55)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-12-11 21:51:06 +01:00
saurabhandSebastiaan van Stijn 55cec698b7 --env-file about comments doc updated
Signed-off-by: Saurabh Kumar <saurabhkumar0184@gmail.com>

(cherry picked from commit efc9236794)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-12-11 21:50:52 +01:00
Sebastiaan van Stijn 9df8eb2b9c docs: update redirect metadata for hugo
docs.docker.com switched from Jekyll to Hugo, which uses "aliases"
instead of "redirect_from".

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 07338fe965)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-12-11 21:50:38 +01:00
Sebastiaan van StijnandGitHub f5a9aabe74 Merge pull request #4695 from thaJeztah/24.0_update_golang_1.20.12
[24.0] update to go1.20.12
2023-12-07 17:40:21 +01:00
Sebastiaan van Stijn cda067a175 update to go1.20.12
go1.20.12 (released 2023-12-05) includes security fixes to the go command,
and the net/http and path/filepath packages, as well as bug fixes to the
compiler and the go command. See the Go 1.20.12 milestone on our issue
tracker for details.

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

from the security mailing:

[security] Go 1.21.5 and Go 1.20.12 are released

Hello gophers,

We have just released Go versions 1.21.5 and 1.20.12, minor point releases.

These minor releases include 3 security fixes following the security policy:

- net/http: limit chunked data overhead

  A malicious HTTP sender can use chunk extensions to cause a receiver
  reading from a request or response body to read many more bytes from
  the network than are in the body.

  A malicious HTTP client can further exploit this to cause a server to
  automatically read a large amount of data (up to about 1GiB) when a
  handler fails to read the entire body of a request.

  Chunk extensions are a little-used HTTP feature which permit including
  additional metadata in a request or response body sent using the chunked
  encoding. The net/http chunked encoding reader discards this metadata.
  A sender can exploit this by inserting a large metadata segment with
  each byte transferred. The chunk reader now produces an error if the
  ratio of real body to encoded bytes grows too small.

  Thanks to Bartek Nowotarski for reporting this issue.

  This is CVE-2023-39326 and Go issue https://go.dev/issue/64433.

- cmd/go: go get may unexpectedly fallback to insecure git

  Using go get to fetch a module with the ".git" suffix may unexpectedly
  fallback to the insecure "git://" protocol if the module is unavailable
  via the secure "https://" and "git+ssh://" protocols, even if GOINSECURE
  is not set for said module. This only affects users who are not using
  the module proxy and are fetching modules directly (i.e. GOPROXY=off).

  Thanks to David Leadbeater for reporting this issue.

  This is CVE-2023-45285 and Go issue https://go.dev/issue/63845.

- path/filepath: retain trailing \ when cleaning paths like \\?\c:\

  Go 1.20.11 and Go 1.21.4 inadvertently changed the definition of the
  volume name in Windows paths starting with \\?\, resulting in
  filepath.Clean(\\?\c:\) returning \\?\c: rather than \\?\c:\ (among
  other effects). The previous behavior has been restored.

  This is an update to CVE-2023-45283 and Go issue https://go.dev/issue/64028.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-12-06 01:41:51 +01:00
Sebastiaan van Stijn 998d2e8d78 update to go1.20.11
go1.20.11 (released 2023-11-07) includes security fixes to the path/filepath
package, as well as bug fixes to the linker and the net/http package. See the
Go 1.20.11 milestone on our issue tracker for details:

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

from the security mailing:

[security] Go 1.21.4 and Go 1.20.11 are released

Hello gophers,

We have just released Go versions 1.21.4 and 1.20.11, minor point releases.

These minor releases include 2 security fixes following the security policy:

- path/filepath: recognize `\??\` as a Root Local Device path prefix.

  On Windows, a path beginning with `\??\` is a Root Local Device path equivalent
  to a path beginning with `\\?\`. Paths with a `\??\` prefix may be used to
  access arbitrary locations on the system. For example, the path `\??\c:\x`
  is equivalent to the more common path c:\x.

  The filepath package did not recognize paths with a `\??\` prefix as special.

  Clean could convert a rooted path such as `\a\..\??\b` into
  the root local device path `\??\b`. It will now convert this
  path into `.\??\b`.

  `IsAbs` did not report paths beginning with `\??\` as absolute.
  It now does so.

  VolumeName now reports the `\??\` prefix as a volume name.

  `Join(`\`, `??`, `b`)` could convert a seemingly innocent
  sequence of path elements into the root local device path
  `\??\b`. It will now convert this to `\.\??\b`.

  This is CVE-2023-45283 and https://go.dev/issue/63713.

- path/filepath: recognize device names with trailing spaces and superscripts

  The `IsLocal` function did not correctly detect reserved names in some cases:

  - reserved names followed by spaces, such as "COM1 ".
  - "COM" or "LPT" followed by a superscript 1, 2, or 3.

  `IsLocal` now correctly reports these names as non-local.

  This is CVE-2023-45284 and https://go.dev/issue/63713.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-12-06 01:41:18 +01:00
Sebastiaan van StijnandGitHub 65bc42b4af Merge pull request #4682 from thaJeztah/24.0_backport_noraw
[24.0 backport] docs: remove "{% raw %}" / "{% endraw %}" Jekyl (liquid) leftovers
2023-11-28 10:26:40 +01:00
Sebastiaan van StijnandGitHub 00dbc19cab Merge pull request #4680 from thaJeztah/24.0_backport_fix_flag_typo
[24.0 backport] docs/man: fix -name flag with single hyphen
2023-11-27 22:12:19 +01:00
Sebastiaan van Stijn 207d9edaa7 docs: reference/commandlin/cli: remove redundant italic
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 354f62f0c5)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-11-27 22:06:20 +01:00
Sebastiaan van Stijn e799792d8a docs: remove "{% raw %}" / "{% endraw %}" Jekyl (liquid) leftovers
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit e2626200aa)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-11-27 22:06:20 +01:00
Sebastiaan van Stijn 327b84fcbf docs/man: fix -name flag with single hyphen
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 174cbb588f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-11-27 21:00:38 +01:00
Sebastiaan van StijnandGitHub 48ec4f339e Merge pull request #4639 from dvdksn/backport_dockerd-default-nw-opt
[24.0 Backport] docs: add default-network-opt daemon option
2023-11-06 13:31:52 +01:00
David Karlsson 88a745999d docs: add default-network-opt daemon option
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit 848fe622ce)
2023-11-06 13:23:17 +01:00
Sebastiaan van StijnandGitHub afdd53b4e3 Merge pull request #4629 from thaJeztah/24.0_update_engine
[24.0] vendor: github.com/docker/docker v24.0.6
2023-10-26 09:06:42 +02:00
Brian GoffandGitHub 12c309fe91 Merge pull request #4628 from thaJeztah/24.0_backport_bump_compress
[24.0 backport] vendor: github.com/klauspost/compress v1.17.2
2023-10-25 17:42:02 -07:00
Sebastiaan van Stijn f42719820d vendor: github.com/docker/docker v24.0.6
full diff: https://github.com/moby/moby/compare/v24.0.5...v24.0.6

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-26 00:37:11 +02:00
Sebastiaan van Stijn 17770189de vendor: github.com/klauspost/compress v1.17.2
fixes data corruption with zstd output in "best"

- 1.17.2 diff: https://github.com/klauspost/compress/compare/v1.17.1...v1.17.2
- full diff: https://github.com/klauspost/compress/compare/v1.16.5...v1.17.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 6372c6aae6)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-25 23:17:39 +02:00
Sebastiaan van Stijn cde0441dc8 vendor: github.com/klauspost/compress v1.16.5
full diff: https://github.com/klauspost/compress/compare/v1.16.3...v1.16.5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 497b13c661)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-25 23:17:35 +02:00
Sebastiaan van StijnandGitHub d9f94d5719 Merge pull request #4618 from thaJeztah/24.0_backport_cli-issue-502
[24.0 backport] Add docker ps status descriptions
2023-10-23 16:11:33 +02:00
Sam ThibaultandSebastiaan van Stijn 54d83fbbf4 Add docker ps status descriptions
Signed-off-by: Sam Thibault <sam.thibault@docker.com>
(cherry picked from commit 8bf121c3bc)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-23 12:34:39 +02:00
Sebastiaan van StijnandGitHub 30a185e936 Merge pull request #4609 from thaJeztah/24.0_backport_x_net
[24.0 backport] vendor: golang.org/x/net v0.17.0
2023-10-19 14:06:59 +02:00
Sebastiaan van Stijn d43c48d5ab vendor: golang.org/x/net v0.17.0
full diff: https://github.com/golang/net/compare/v0.10.0...v0.17.0

This fixes the same CVE as go1.21.3 and go1.20.10;

- net/http: rapid stream resets can cause excessive work

  A malicious HTTP/2 client which rapidly creates requests and
  immediately resets them can cause excessive server resource consumption.
  While the total number of requests is bounded to the
  http2.Server.MaxConcurrentStreams setting, resetting an in-progress
  request allows the attacker to create a new request while the existing
  one is still executing.

  HTTP/2 servers now bound the number of simultaneously executing
  handler goroutines to the stream concurrency limit. New requests
  arriving when at the limit (which can only happen after the client
  has reset an existing, in-flight request) will be queued until a
  handler exits. If the request queue grows too large, the server
  will terminate the connection.

  This issue is also fixed in golang.org/x/net/http2 v0.17.0,
  for users manually configuring HTTP/2.

  The default stream concurrency limit is 250 streams (requests)
  per HTTP/2 connection. This value may be adjusted using the
  golang.org/x/net/http2 package; see the Server.MaxConcurrentStreams
  setting and the ConfigureServer function.

  This is CVE-2023-39325 and Go issue https://go.dev/issue/63417.
  This is also tracked by CVE-2023-44487.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a27466fb6f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-19 12:35:49 +02:00
Sebastiaan van Stijn 1919679638 vendor: golang.org/x/crypto v0.14.0
full diff: https://github.com/golang/crypto/compare/v0.9.0...v0.14.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 612a171557)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-19 12:34:31 +02:00
Sebastiaan van Stijn 6c5bc490d4 vendor: golang.org/x/term v0.13.0
- term: consistently return zeroes on GetSize error

full diff: https://github.com/golang/term/compare/v0.8.0...v0.13.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 392db31e2a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-19 12:33:19 +02:00
Sebastiaan van Stijn 66558a4e64 vendor: golang.org/x/text v0.13.0
full diff: https://github.com/golang/text/compare/v0.9.0...v0.13.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ac307788a6)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-19 12:32:30 +02:00
Sebastiaan van Stijn 0d554b549b vendor: golang.org/x/sys v0.13.0
full diff: https://github.com/golang/sys/compare/v0.10.0...v0.13.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 48655f794c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-19 12:31:38 +02:00
Sebastiaan van Stijn 8c4dc6c603 vendor: golang.org/x/crypto v0.9.0
full diff: https://github.com/golang/crypto/compare/v0.3.0...v0.9.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c9d56b8504)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-19 12:29:57 +02:00
Sebastiaan van Stijn aef1157742 vendor: golang.org/x/sys v0.10.0
full diff: https://github.com/golang/sys/compare/v0.8.0...v0.10.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ffea6940e7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-19 12:27:19 +02:00
Sebastiaan van Stijn 54894f0224 vendor: golang.org/x/sync v0.3.0
full diff: https://github.com/golang/sync/compare/v0.1.0...v0.3.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 1554b49329)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-19 12:27:00 +02:00
Bjorn NeergaardandGitHub 0f109aafa8 Merge pull request #4584 from thaJeztah/24.0_backport_update_actions
[24.0 backport] build(deps): bump actions/checkout from 3 to 4
2023-10-13 08:49:32 -07:00
Bjorn NeergaardandGitHub 89ce230bd8 Merge pull request #4587 from thaJeztah/24.0_backport_go1.21_prepare
[24.0 backport] assorted dockerfile and test updates
2023-10-13 08:49:15 -07:00
Sebastiaan van StijnandGitHub db6e494b40 Merge pull request #4594 from thaJeztah/24.0_backport_update_md2man
[24.0 backport] update go-md2man to v2.0.3
2023-10-13 17:27:19 +02:00
Sebastiaan van StijnandGitHub 5b3e376f86 Merge pull request #4597 from thaJeztah/24.0_update_go1.20.10
[24.0] update to go1.20.10
2023-10-12 14:20:26 +02:00
Sebastiaan van Stijn a47889a70f update to go1.20.10
go1.20.10 (released 2023-10-10) includes a security fix to the net/http package.
See the Go 1.20.10 milestone on our issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.20.10+label%3ACherryPickApproved

full diff: https://github.com/golang/go/compare/go1.20.9...go1.20.10

From the security mailing:

[security] Go 1.21.3 and Go 1.20.10 are released

Hello gophers,

We have just released Go versions 1.21.3 and 1.20.10, minor point releases.

These minor releases include 1 security fixes following the security policy:

- net/http: rapid stream resets can cause excessive work

  A malicious HTTP/2 client which rapidly creates requests and
  immediately resets them can cause excessive server resource consumption.
  While the total number of requests is bounded to the
  http2.Server.MaxConcurrentStreams setting, resetting an in-progress
  request allows the attacker to create a new request while the existing
  one is still executing.

  HTTP/2 servers now bound the number of simultaneously executing
  handler goroutines to the stream concurrency limit. New requests
  arriving when at the limit (which can only happen after the client
  has reset an existing, in-flight request) will be queued until a
  handler exits. If the request queue grows too large, the server
  will terminate the connection.

  This issue is also fixed in golang.org/x/net/http2 v0.17.0,
  for users manually configuring HTTP/2.

  The default stream concurrency limit is 250 streams (requests)
  per HTTP/2 connection. This value may be adjusted using the
  golang.org/x/net/http2 package; see the Server.MaxConcurrentStreams
  setting and the ConfigureServer function.

  This is CVE-2023-39325 and Go issue https://go.dev/issue/63417.
  This is also tracked by CVE-2023-44487.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-11 20:04:46 +02:00
Sebastiaan van Stijn 3c10203b39 update to go1.20.9
go1.20.9 (released 2023-10-05) includes one security fixes to the cmd/go package,
as well as bug fixes to the go command and the linker. See the Go 1.20.9
milestone on our issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.20.9+label%3ACherryPickApproved

full diff: https://github.com/golang/go/compare/go1.20.8...go1.20.9

From the security mailing:

[security] Go 1.21.2 and Go 1.20.9 are released

Hello gophers,

We have just released Go versions 1.21.2 and 1.20.9, minor point releases.

These minor releases include 1 security fixes following the security policy:

- cmd/go: line directives allows arbitrary execution during build

  "//line" directives can be used to bypass the restrictions on "//go:cgo_"
  directives, allowing blocked linker and compiler flags to be passed during
  compliation. This can result in unexpected execution of arbitrary code when
  running "go build". The line directive requires the absolute path of the file in
  which the directive lives, which makes exploting this issue significantly more
  complex.

  This is CVE-2023-39323 and Go issue https://go.dev/issue/63211.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-11 20:04:12 +02:00
Sebastiaan van Stijn 9662d73735 update go-md2man to v2.0.3
full diff: https://github.com/cpuguy83/go-md2man/compare/v2.0.1...v2.0.3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 3f1195e4ec)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-11 19:24:29 +02:00
Tianon GraviandSebastiaan van Stijn 35453d6c4f Update minimum Go version to 1.19
On Go 1.18 since a5ebe2282a, we get:

    # github.com/docker/docker-credential-helpers/client
    vendor/github.com/docker/docker-credential-helpers/client/command.go:34:39: programCmd.Environ undefined (type *exec.Cmd has no field or method Environ)
    note: module requires Go 1.19
    # github.com/docker/cli/cli/connhelper/commandconn
    cli/connhelper/commandconn/commandconn.go:71:22: undefined: atomic.Bool
    cli/connhelper/commandconn/commandconn.go:76:22: undefined: atomic.Bool
    cli/connhelper/commandconn/commandconn.go:77:22: undefined: atomic.Bool
    cli/connhelper/commandconn/commandconn.go:78:22: undefined: atomic.Bool

These go away when building against 1.19+.

Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
(cherry picked from commit 0f59f04f57)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-29 10:00:53 +02:00
dependabot[bot]andSebastiaan van Stijn 2a76b0c4e7 build(deps): bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [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/v3...v4)

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

Signed-off-by: dependabot[bot] <support@github.com>
(cherry picked from commit dee40053f6)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:34:32 +02:00
Sebastiaan van Stijn 1ebaef3663 Dockerfile: use GOTOOLCHAIN=local
This may find its way into the official images, but until it does, let's
make sure we don't get unexpected updates of go.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit e9759cee69)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:30:13 +02:00
Sebastiaan van Stijn 8a7833ab62 Dockerfile: build gotestsum and goversioninfo without cgo
It's not needed to build these binaries. The Dockerfile.dev image already
has CGO_ENABLED=0 as default in the golang image, so does not need updates.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit f07e7e1eed)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:29:40 +02:00
Sebastiaan van Stijn 2e86812d7a e2e: update to use compose v2, and don't depend on distro-packages
We were depending on alpine's package repository to install compose,
but for debian we used compose's GitHub releases. Depending on distro
packages means that we don't know when updates will happen, and versions
may diverge because of that; for example, alpine 3.18 updated to compose
v2;

On alpine 3.17:

    make -f docker.Makefile build-e2e-image
    docker run --rm docker-cli-e2e docker-compose --version
    docker-compose version 1.29.2, build unknown

On alpine 3.18:

    make -f docker.Makefile build-e2e-image
    docker run --rm docker-cli-e2e docker-compose --version
    Docker Compose version v2.17.3

This caused our e2e script to fail, as it made assumptions about the name
format created by compose, which changed from underscores to hyphens in v2;

    Container cliendtoendsuite-engine-1  Running
    Error: No such object: cliendtoendsuite_engine_1

This patch:

- updates the Dockerfile to install compose from the compose-bin image
- adjusts the e2e script for the new naming scheme format
- removes the version field from the compose-files used in e2e, as they
  are no longer used by compose.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 9e424af5da)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:29:27 +02:00
Sebastiaan van Stijn e7ca37861b Dockerfile: use COPY --link where possible
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit af05a68828)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:28:47 +02:00
Bjorn NeergaardandGitHub 1f8118b1cc Merge pull request #4565 from thaJeztah/24.0_backport_docker_tag_dupwords
[24.0 backport] docs: fix duplicate words in "docker tag" reference
2023-09-15 08:17:43 -06:00
Sebastiaan van Stijn f2a3d50b30 docs: fix duplicate words in "docker tag" reference
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 3a16c3bb09)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-14 13:45:34 +02:00
Bjorn NeergaardandGitHub edae25f8af Merge pull request #4561 from thaJeztah/24.0_backport_update_golang_1.20.8
[24.0 backport] update to go1.20.8
2023-09-13 10:05:54 -06:00
Bjorn NeergaardandGitHub d848d49be9 Merge pull request #4543 from thaJeztah/24.0_backport_bump_golangci_lint
[24.0 backport] update golangci-lint to v1.54.2
2023-09-13 10:05:27 -06:00
Sebastiaan van Stijn 4feeefbd68 update to go1.20.8
go1.20.8 (released 2023-09-06) includes two security fixes to the html/template
package, as well as bug fixes to the compiler, the go command, the runtime,
and the crypto/tls, go/types, net/http, and path/filepath packages. See the
Go 1.20.8 milestone on our issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.20.8+label%3ACherryPickApproved

full diff: https://github.com/golang/go/compare/go1.20.7...go1.20.8

From the security mailing:

[security] Go 1.21.1 and Go 1.20.8 are released

Hello gophers,

We have just released Go versions 1.21.1 and 1.20.8, minor point releases.

These minor releases include 4 security fixes following the security policy:

- cmd/go: go.mod toolchain directive allows arbitrary execution
  The go.mod toolchain directive, introduced in Go 1.21, could be leveraged to
  execute scripts and binaries relative to the root of the module when the "go"
  command was executed within the module. This applies to modules downloaded using
  the "go" command from the module proxy, as well as modules downloaded directly
  using VCS software.

  Thanks to Juho Nurminen of Mattermost for reporting this issue.

  This is CVE-2023-39320 and Go issue https://go.dev/issue/62198.

- html/template: improper handling of HTML-like comments within script contexts
  The html/template package did not properly handle HMTL-like "<!--" and "-->"
  comment tokens, nor hashbang "#!" comment tokens, in <script> contexts. This may
  cause the template parser to improperly interpret the contents of <script>
  contexts, causing actions to be improperly escaped. This could be leveraged to
  perform an XSS attack.

  Thanks to Takeshi Kaneko (GMO Cybersecurity by Ierae, Inc.) for reporting this
  issue.

  This is CVE-2023-39318 and Go issue https://go.dev/issue/62196.

- html/template: improper handling of special tags within script contexts
  The html/template package did not apply the proper rules for handling occurrences
  of "<script", "<!--", and "</script" within JS literals in <script> contexts.
  This may cause the template parser to improperly consider script contexts to be
  terminated early, causing actions to be improperly escaped. This could be
  leveraged to perform an XSS attack.

  Thanks to Takeshi Kaneko (GMO Cybersecurity by Ierae, Inc.) for reporting this
  issue.

  This is CVE-2023-39319 and Go issue https://go.dev/issue/62197.

- crypto/tls: panic when processing post-handshake message on QUIC connections
  Processing an incomplete post-handshake message for a QUIC connection caused a panic.

  Thanks to Marten Seemann for reporting this issue.

  This is CVE-2023-39321 and CVE-2023-39322 and Go issue https://go.dev/issue/62266.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 4b00be585c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-13 17:49:18 +02:00
Bjorn NeergaardandGitHub ed223bc820 Merge pull request #4544 from thaJeztah/24.0_backport_fix_events_json_format
[24.0 backport] cli/command/system: fix "docker events" not supporting --format=json
2023-08-31 11:24:32 -06:00
Sebastiaan van Stijn fab55e13ce cli/command/system: fix "docker events" not supporting --format=json
Before this patch:

    docker events --format=json
    json
    json
    json
    ^C

With this patch:

    docker events --format=json
    {"status":"create","id":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","from":"hello-world","Type":"container","Action":"create","Actor":{"ID":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","Attributes":{"image":"hello-world","name":"dreamy_goldstine"}},"scope":"local","time":1693168508,"timeNano":1693168508190136885}
    {"status":"attach","id":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","from":"hello-world","Type":"container","Action":"attach","Actor":{"ID":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","Attributes":{"image":"hello-world","name":"dreamy_goldstine"}},"scope":"local","time":1693168508,"timeNano":1693168508192851593}
    {"Type":"network","Action":"connect","Actor":{"ID":"c54920dd5074a73e28bea62007e0334d81cc040a90372be311cf16806403d350","Attributes":{"container":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","name":"bridge","type":"bridge"}},"scope":"local","time":1693168508,"timeNano":1693168508212398802}
    {"status":"start","id":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","from":"hello-world","Type":"container","Action":"start","Actor":{"ID":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","Attributes":{"image":"hello-world","name":"dreamy_goldstine"}},"scope":"local","time":1693168508,"timeNano":1693168508312969843}
    ^C

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 6dfdd1eae9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-29 17:36:44 +02:00
Sebastiaan van Stijn 989b340a6c update golangci-lint to v1.54.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit db6209abdd)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-29 14:22:46 +02:00
Sebastiaan van StijnandGitHub 2fcff17544 Merge pull request #4537 from thaJeztah/24.0_backort_docs_fixes
[24.0 backport] docs/reference: run.md: remove stray whitespace and update cli-docs-tool to v0.6.0
2023-08-29 11:44:13 +02:00
Sebastiaan van StijnandGitHub b74d8e1a53 Merge pull request #4538 from thaJeztah/24.0_backport_history_test
[24.0 backport] un-skip history test and fix golden mismatches
2023-08-29 11:43:55 +02:00
Sebastiaan van StijnandGitHub 3789f8a39e Merge pull request #4542 from thaJeztah/24.0_backport_manifest_deref
[24.0 backport] cli/registry: fix client.pullManifestList not de-referencing manifest, and remove "v1" check
2023-08-29 11:43:38 +02:00
Sebastiaan van Stijn d3485b9e9f cli/registry: client.iterateEndpoints: remove check for APIVersion1
registryService.LookupPullEndpoints uses lookupV2Endpoints
https://github.com/moby/moby/blob/v24.0.5/registry/service.go#L137-L142

which, as the name indicates, only returns V2 endpoints;
https://github.com/moby/moby/blob/v24.0.5/registry/service_v2.go#L10-L80

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 22b4bab90f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-29 09:45:37 +02:00
Sebastiaan van Stijn 613380299f cli/registry: fix client.pullManifestList not de-referencing manifest
Kudos to gosec;

    cli/registry/client/fetcher.go:205:57: G601: Implicit memory aliasing in for loop. (gosec)
            imageManifest.Descriptor.Platform = types.OCIPlatform(&manifestDescriptor.Platform)
                                                                  ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 5250f1bab5)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-29 09:45:37 +02:00
Sebastiaan van Stijn b83959e001 force TestNewHistoryCommandSuccess to use UTC timezone
This test was skipped if the host was not using UTC timezone, because the output
of timestamps would be different, causing the test to fail.

This patch overrides the TZ env-var to make the test use UTC, so that we don't
have to skip the test.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 42ac5d4bf9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-28 23:00:49 +02:00
Jason HallandSebastiaan van Stijn 28a08a22b9 un-skip history test and fix golden mismatches
Signed-off-by: Jason Hall <jason@chainguard.dev>
(cherry picked from commit f5e224e940)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-28 23:00:37 +02:00
Sebastiaan van Stijn 8e0393932b update cli-docs-tool to v0.6.0
release notes: https://github.com/docker/cli-docs-tool/releases/tag/v0.6.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 17f4c8259b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-28 22:58:11 +02:00
Sebastiaan van Stijn efd052eb85 docs/reference: run.md: remove stray whitespace
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 3d2aac6a0d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-28 22:43:15 +02:00
Sebastiaan van StijnandGitHub cdd81d6559 Merge pull request #4528 from thaJeztah/24.0_backport_docs
[24.0 backport] assorted (docs) backports
2023-08-25 17:23:07 +02:00
Vaclav StruharandSebastiaan van Stijn d9770a962e adding -c option for docker run/build in manpages
Signed-off-by: Vaclav Struhar <struharv@gmail.com>
(cherry picked from commit be219b3172)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 17:10:12 +02:00
Sebastiaan van Stijn 6efe73abe0 cli/command/manifest: update link to Go documentation
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 273f2cd95e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 17:04:36 +02:00
Sebastiaan van Stijn d977531018 man: update links to Go documentation
Go documentation moved to the `go.dev` domain;

    curl -sI https://golang.org/doc/install/source#environment | grep 'location'
    location: https://go.dev/doc/install/source

Also updated some links to use https, where available.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 722e3aae4f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 17:04:36 +02:00
Sebastiaan van Stijn e9f843bf04 docs/reference: update links to Go documentation
Go documentation moved to the `go.dev` domain;

    curl -sI https://golang.org/doc/install/source#environment | grep 'location'
    location: https://go.dev/doc/install/source

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit dc4feccb89)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 17:04:36 +02:00
Sebastiaan van Stijn cfbaee4689 CONTRIBUTING.md: update links
- docs moved to https://go.dev/doc/
- blog moved to https://go.dev/blog/
- update DCO link to use https

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 1d3af726eb)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 17:04:36 +02:00
Sebastiaan van Stijn daeee46977 update flag-description for --cgroup-parent
This attempts to make it clearer that the --cgroup-parent option is only used
for the containers used during build. Instead of mentioning "build container",
I opted for using "RUN instructions" (to match the --network description),
although this may not be ideal (as it assumes the "Dockerfile" front-end, which
of course may not be the case).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit e050312e6d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 17:03:46 +02:00
Ed MorleyandSebastiaan van Stijn 08ad72160f Update docs/command output for volume pruning
In previous versions of the Docker API, `system prune --volumes` and `volume prune`
would remove all dangling volumes. With API v1.42, this was changed so that only
anonymous volumes would be removed unless the all filter was specified.

Some of the docs were updated in #4218, however, there were a couple of places
left that didn't make the anonymous vs named volumes distinction clear.

This replaces #4079, which was bitrotted by #4218. See also #4028.

Closes #4079.

Signed-off-by: Ed Morley <501702+edmorley@users.noreply.github.com>
(cherry picked from commit 6e2e92d774)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 17:03:13 +02:00
Sebastiaan van Stijn 3c4fe7b3e6 docs: add missing docs for "DOCKER_TLS" env-var
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit b52fd79f1d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 17:02:22 +02:00
Sebastiaan van StijnandGitHub 98ffe42d84 Merge pull request #4517 from thaJeztah/24.0_backport_docker-cli-slows-bash-init
[24.0 backport] Stop slowing bash init by caching plugins path slowly
2023-08-23 14:04:35 +02:00
Sebastiaan van StijnandGitHub 0d5df48121 Merge pull request #4520 from thaJeztah/24.0_backport_patternmatcher_dockerignore
[24.0 backport] replace dockerfile/dockerignore with patternmatcher/ignorefile
2023-08-23 14:04:04 +02:00
Sebastiaan van StijnandGitHub bf081eec36 Merge pull request #4512 from thaJeztah/24.0_backport_manifest_token_actions
[24.0 backport] cli/registry/client: set actions when authn with token
2023-08-23 14:03:17 +02:00
Oded ArbelandSebastiaan van Stijn dc45bcc993 Stop slowing bash init by caching plugins path slowly
Fixes issue #3889 by only loading docker plugins path when needed: if it is fast enough than it shouldn't be a problem to do this on demand; OTOH if it is slow then we shouldn't do this during *every* bash session initialization, regardless if docker completion will be needed or not.

Signed-off-by: Oded Arbel <oded@geek.co.il>
(cherry picked from commit 1da67be9ca)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 13:31:46 +02:00
Sebastiaan van Stijn 710dd00e95 replace dockerfile/dockerignore with patternmatcher/ignorefile
The BuildKit dockerignore package was migrated to the patternmatcher
repository / module. This patch updates our uses of the BuildKit package
with its new location.

A small local change was made to keep the format of the existing error message,
because the "ignorefile" package is slightly more agnostic in that respect
and doesn't include ".dockerignore" in the error message.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 5bff12354d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 13:22:56 +02:00
Sebastiaan van Stijn bf632329d2 vendor: github.com/moby/patternmatcher v0.6.0
- integrate frontend/dockerfile/dockerignore from buildkit

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

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 55ff9e6093)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 13:22:00 +02:00
Sebastiaan van StijnandGitHub 724548bc7d Merge pull request #4508 from thaJeztah/24.0_backport_lazy_ping
[24.0 backport] cmd/docker: areFlagsSupported: don't Ping if not needed
2023-08-23 11:47:27 +02:00
Sebastiaan van Stijn 3c6c0bce1c cli/registry/client: set actions when authn with token
When using a personal access token, Docker Hub produces an error if actions
are requested beyond the token's allowed actions. This resulted in errors
when using a PAT with limited permissions to do a "docker manifest inspect".

This patch sets actions to "pull" only by default, and requests "push" action
for requests that need it.

To verify:

- create a PAT with limited access (read-only)
- log in with your username and the PAT as password

Before this patch:

    docker manifest inspect ubuntu:latest
    Get "https://registry-1.docker.io/v2/library/ubuntu/manifests/latest": unauthorized: access token has insufficient scopes

With this patch applied:

    docker manifest inspect ubuntu:latest
    {
       "schemaVersion": 2,
       "mediaType": "application/vnd.oci.image.index.v1+json",
       "manifests": [
          {
             "mediaType": "application/vnd.oci.image.manifest.v1+json",
             "size": 424,
             "digest": "sha256:56887c5194fddd8db7e36ced1c16b3569d89f74c801dc8a5adbf48236fb34564",
             "platform": {
                "architecture": "amd64",
                "os": "linux"
             }
          },
          {
             "mediaType": "application/vnd.oci.image.manifest.v1+json",
             "size": 424,
             "digest": "sha256:c835a4f2a632bc91a2b494e871549f0dd83f2966c780e66435774e77e048ddf0",
             "platform": {
                "architecture": "arm",
                "os": "linux",
                "variant": "v7"
             }
          }
       ]
    }

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit d2047b954e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-22 21:55:01 +02:00
Sebastiaan van Stijn 65655cc262 cmd/docker: areFlagsSupported: don't Ping if not needed
This is a similar fix as 006c946389, which
fixed this for detection of commands that were executed. Make sure we don't
call the "/_ping" endpoint if we don't need to.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit bb57783ab8)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-22 10:46:50 +02:00
Sebastiaan van StijnandGitHub 580730fce9 Merge pull request #4500 from neersighted/backport_4478
[24.0 backport] login: Add message about using PATs
2023-08-17 20:37:25 +02:00
Djordje LukicandBjorn Neergaard 11606268f8 login: Add message about using PATs
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
(cherry picked from commit 8d51f36ca3)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-08-17 06:56:09 -06:00
Sebastiaan van StijnandGitHub 27a19966fb Merge pull request #4491 from dvdksn/24.0_backport_docs/host-gateway
[24.0 Backport] docs: document special host-gateway value for add-host
2023-08-09 13:28:05 +02:00
David Karlsson a8987063b3 docs: document special host-gateway value for add-host
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit 299925f4c3)
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2023-08-09 09:19:14 +02:00
Sebastiaan van StijnandGitHub b74562d917 Merge pull request #4476 from thaJeztah/24.0_backport_update_go1.20.7
[24.0 backport] update to go1.20.7
2023-08-02 11:51:04 +02:00
Sebastiaan van Stijn c0e376854b update to go1.20.7
Includes a fix for CVE-2023-29409

go1.20.7 (released 2023-08-01) includes a security fix to the crypto/tls
package, as well as bug fixes to the assembler and the compiler. See the
Go 1.20.7 milestone on our issue tracker for details:

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

From the mailing list announcement:

[security] Go 1.20.7 and Go 1.19.12 are released

Hello gophers,

We have just released Go versions 1.20.7 and 1.19.12, minor point releases.

These minor releases include 1 security fixes following the security policy:

- crypto/tls: restrict RSA keys in certificates to <= 8192 bits

  Extremely large RSA keys in certificate chains can cause a client/server
  to expend significant CPU time verifying signatures. Limit this by
  restricting the size of RSA keys transmitted during handshakes to <=
  8192 bits.

  Based on a survey of publicly trusted RSA keys, there are currently only
  three certificates in circulation with keys larger than this, and all
  three appear to be test certificates that are not actively deployed. It
  is possible there are larger keys in use in private PKIs, but we target
  the web PKI, so causing breakage here in the interests of increasing the
  default safety of users of crypto/tls seems reasonable.

  Thanks to Mateusz Poliwczak for reporting this issue.

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

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 6517db9398)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-01 23:53:48 +02:00
Sebastiaan van StijnandGitHub 3bc4543f83 Merge pull request #4471 from thaJeztah/24.0_backport_bump_gotest_tools
[24.0 backport] vendor: gotest.tools/v3 v3.5.0
2023-08-01 16:27:40 +02:00
Sebastiaan van Stijn 1481c8ce9a vendor: gotest.tools/v3 v3.5.0
- go.mod: update dependencies and go version by
- Use Go1.20
- Fix couple of typos
- Added `WithStdout` and `WithStderr` helpers
- Moved `cmdOperators` handling from `RunCmd` to `StartCmd`
- Deprecate `assert.ErrorType`
- Remove outdated Dockerfile
- add godoc links

full diff: https://github.com/gotestyourself/gotest.tools/compare/v3.4.0...v3.5.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 0b535c791a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-29 21:34:33 +02:00
Sebastiaan van StijnandGitHub b17b6b562d Merge pull request #4460 from thaJeztah/24.0_update_engine
[24.0] vendor: github.com/docker/docker v24.0.5
2023-07-25 15:03:00 +02:00
Sebastiaan van Stijn e97c765575 vendor: github.com/docker/docker v24.0.5
no changes in vendored files

full diff: https://github.com/docker/docker/compare/d4a26c153000...v24.0.5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-25 08:55:10 +02:00
Sebastiaan van StijnandGitHub ced0996600 Merge pull request #4450 from vvoland/fix-issue-4414-Danial-Gharib-24
[24.0 backport] configfile: Initialize nil AuthConfigs
2023-07-19 21:44:22 +02:00
DanialandPaweł Gronowski 1ee40e2c74 configfile: Initialize nil AuthConfigs
Initialize AuthConfigs map if it's nil before returning it.
This fixes fileStore.Store nil dereference panic when adding a new key
to the map.

Signed-off-by: Danial Gharib <danial.mail.gh@gmail.com>
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit ad43df5e86)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-07-19 16:00:16 +02:00
Sebastiaan van StijnandGitHub 40cc1d8eae Merge pull request #4445 from thaJeztah/24.0_backport_buildx_0.11.2
[24.0 backport Dockerfile: update buildx to v0.11.2
2023-07-19 00:59:56 +02:00
Sebastiaan van StijnandGitHub 3c2278afae Merge pull request #4443 from thaJeztah/24.0_update_engine2
[24.0] vendor: github.com/docker/docker v24.0.5-0.20230718221249-d4a26c153000
2023-07-19 00:27:09 +02:00
Sebastiaan van Stijn 3bd6d6902e Dockerfile: update buildx to v0.11.2
release notes: https://github.com/docker/buildx/releases/tag/v0.11.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 00870d68fc)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-19 00:25:33 +02:00
Sebastiaan van Stijn 05bf7fbcc8 vendor: github.com/docker/docker v24.0.5-0.20230718221249-d4a26c153000
full diff: https://github.com/docker/docker/compare/8443a06149b5ba9c0763b92f832698474bcf2a13...d4a26c1530005b690de81af697398756bd2908ce

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-19 00:17:46 +02:00
Sebastiaan van StijnandGitHub c6d7c0bb21 Merge pull request #4438 from thaJeztah/24.0_update_engine
[24.0] vendor: github.com/docker/docker v24.0.5-0.20230717072055-8443a06149b5
2023-07-17 11:58:29 +02:00
Sebastiaan van StijnandGitHub dd08d44044 Merge pull request #4425 from thaJeztah/24.0_backport_credential-store-improvements
[24.0 backport] docs: rephrase section on credential stores for docker login
2023-07-17 11:39:07 +02:00
Sebastiaan van StijnandGitHub 809975d8bd Merge pull request #4423 from thaJeztah/24.0_backport_dont-ignore-volume-parse-err
[24.0 backport] cli/container: Don't ignore error when parsing volume spec
2023-07-17 11:38:35 +02:00
Sebastiaan van Stijn 8b5023dd2e vendor: github.com/docker/docker v24.0.5-0.20230717072055-8443a06149b5
tip of the v24.0 branch

full diff: https://github.com/docker/docker/compare/36e9e796c6fc84202c32a852f6cdcd6ed175f96b...8443a06149b5ba9c0763b92f832698474bcf2a13

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-17 09:30:01 +02:00
Sebastiaan van StijnandGitHub 9edd9a1f2f Merge pull request #4430 from thaJeztah/24.0_backport_update_buildx
[24.0 backport] Dockerfile: update buildx to v0.11.1
2023-07-15 15:16:33 +02:00
Sebastiaan van StijnandGitHub e93cdb6ca5 Merge pull request #4428 from thaJeztah/24.0_backport_update_go_1.20.6
[24.0 backport] update go to go1.20.6
2023-07-15 15:08:38 +02:00
Sebastiaan van Stijn 2a6348d1b2 Dockerfile: update buildx to v0.11.1
update the version we use in the dev-container;

- Fix a regression for bake where services in profiles would not be loaded.
- Fix a regression where --cgroup-parent option had no effect during build.
- Fix a regression where valid docker contexts could fail buildx builder name validation.
- Fix an issue where the host-gateway special address could not be used as an argument to --add-host.
- Fix a possible panic when terminal is resized during the build.

release notes: https://github.com/docker/buildx/releases/tag/v0.11.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ff9f1be19e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 15:03:54 +02:00
Sebastiaan van Stijn f4782b3250 update go to go1.20.6
go1.20.6 (released 2023-07-11) includes a security fix to the net/http package,
as well as bug fixes to the compiler, cgo, the cover tool, the go command,
the runtime, and the crypto/ecdsa, go/build, go/printer, net/mail, and text/template
packages. See the Go 1.20.6 milestone on our issue tracker for details.

https://github.com/golang/go/issues?q=milestone%3AGo1.20.6+label%3ACherryPickApproved

Full diff: https://github.com/golang/go/compare/go1.20.5...go1.20.6

These minor releases include 1 security fixes following the security policy:

net/http: insufficient sanitization of Host header

The HTTP/1 client did not fully validate the contents of the Host header.
A maliciously crafted Host header could inject additional headers or entire
requests. The HTTP/1 client now refuses to send requests containing an
invalid Request.Host or Request.URL.Host value.

Thanks to Bartek Nowotarski for reporting this issue.

Includes security fixes for [CVE-2023-29406 ][1] and Go issue https://go.dev/issue/60374

[1]: https://github.com/advisories/GHSA-f8f7-69v5-w4vx

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 680fafdc9c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 14:49:10 +02:00
Sebastiaan van StijnandGitHub a5024666e7 Merge pull request #4424 from thaJeztah/24.0_backport_update-xx
[24.0 backport] Dockerfile: update to xx 1.2.1
2023-07-15 14:46:32 +02:00
Sebastiaan van StijnandGitHub 39b2a6cc6a Merge pull request #4426 from thaJeztah/24.0_update_engine
[24.0] vendor: github.com/docker/docker v24.0.5-0.20230714235725-36e9e796c6fc
2023-07-15 13:02:13 +02:00
Sebastiaan van Stijn 7d06f6b2f7 vendor: github.com/docker/docker v24.0.5-0.20230714235725-36e9e796c6fc
full diff: https://github.com/docker/docker/compare/v24.0.4...36e9e796c6fc84202c32a852f6cdcd6ed175f96b

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 02:23:53 +02:00
David KarlssonandSebastiaan van Stijn 1447974b83 docs: rephrase section on credential stores for docker login
Signed-off-by: David Karlsson <david.karlsson@docker.com>
(cherry picked from commit 9828575314)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:13:51 +02:00
CrazyMaxandSebastiaan van Stijn 46293e97f7 Dockerfile: update to xx 1.2.1
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit fca67dd817)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:09:59 +02:00
Paweł GronowskiandSebastiaan van Stijn bfe2ff8208 cli/container: Don't ignore error when parsing volume spec
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit fe7afb700f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:06:57 +02:00
Sebastiaan van StijnandGitHub 380eb72940 Merge pull request #4407 from thaJeztah/24.0_update_engine
[24.0] vendor: github.com/docker/docker v24.0.4
2023-07-13 16:56:44 +02:00
Sebastiaan van Stijn b407429628 vendor: github.com/docker/docker v24.0.4
full diff: https://github.com/docker/docker/compare/v24.0.2...v24.0.4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-10 09:48:09 +02:00
Sebastiaan van Stijn 79c42c0b97 vendor: golang.org/x/net v0.10.0
full diff: https://github.com/golang/net/compare/v0.8.0...v0.10.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-07 18:07:19 +02:00
Sebastiaan van Stijn a96d0a526c vendor: golang.org/x/text v0.9.0
no changes in vendored files

full diff: https://github.com/golang/text/compare/v0.8.0...v0.9.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-07 18:06:32 +02:00
Sebastiaan van Stijn 5c5c50d717 vendor: golang.org/x/term v0.8.0
no changes in vendored files

full diff: https://github.com/golang/term/compare/v0.6.0...v0.8.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-07 18:05:12 +02:00
Sebastiaan van Stijn 4bf11b7562 vendor: golang.org/x/sys v0.8.0
full diff: https://github.com/golang/sys/compare/v0.6.0...v0.8.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-07 18:03:50 +02:00
Sebastiaan van Stijn 224c7dbec4 vendor: github.com/sirupsen/logrus v1.9.3
full diff: https://github.com/sirupsen/logrus/compare/v1.9.0...v1.9.3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-07 18:00:12 +02:00
Sebastiaan van Stijn e25d5c64c5 vendor: github.com/opencontainers/image-spec v1.1.0-rc3
full diff: https://github.com/opencontainers/image-spec/compare/3a7f492d3f1b...v1.1.0-rc3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-07 17:58:46 +02:00
Sebastiaan van Stijn 419e94df4a vendor: github.com/moby/swarmkit/v2 v2.0.0-20230531205928-01bb7a41396b
no changes in vendored files

full diff: https://github.com/moby/swarmkit/compare/75e92ce14ff7...01bb7a41396b

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-07 17:56:34 +02:00
Bjorn NeergaardandGitHub 3713ee1eea Merge pull request #4395 from thaJeztah/24.0_backport_fix-connhelper-docker-example
[24.0 backport] ssh: fix error on commandconn close, add ping and default timeout
2023-06-30 11:55:44 -06:00
Laura BrehmandSebastiaan van Stijn 2d5f041bde commandconn: return original error while closing
Changes the `Read` and `Write` error handling
logic to return the original error while closing
the connection. We still skip calling `handleEOF`
if already closing the connection.

Fixes the flaky `TestCloseWhileWriting` and
`TestCloseWhileReading` tests.

Co-authored-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
(cherry picked from commit d5f564adaa)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-30 19:23:36 +02:00
Laura BrehmandSebastiaan van Stijn 520e3600ee commandconn: don't return error if command closed successfully
---
commandconn: fix race on `Close()`

During normal operation, if a `Read()` or `Write()` call results
in an EOF, we call `onEOF()` to handle the terminating command,
and store it's exit value.

However, if a Read/Write call was blocked while `Close()` is called
the in/out pipes are immediately closed which causes an EOF to be
returned. Here, we shouldn't call `onEOF()`, since the reason why
we got an EOF is because we're already terminating the connection.
This also prevents a race between two calls to the commands `Wait()`,
in the `Close()` call and `onEOF()`

---
Add CLI init timeout to SSH connections

---
connhelper: add 30s ssh default dialer timeout

(same as non-ssh dialer)

Signed-off-by: Laura Brehm <laurabrehm@hey.com>
(cherry picked from commit a5ebe2282a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-30 19:23:12 +02:00
Sebastiaan van StijnandGitHub fad718c7ea Merge pull request #4393 from thaJeztah/24.0_backport_debug_relax
[24.0 backport] docker info: fix condition for printing debug information
2023-06-30 15:38:59 +02:00
Sebastiaan van Stijn cd68c8f003 docker info: fix condition for printing debug information
The daemon collects this information regardless if "debug" is
enabled. Print the debugging information if either the daemon,
or the client has debug enabled.

We should probably improve this logic and print any of these if
set (but some special rules are needed for file-descriptors, which
may use "-1".

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 92d7a234dd)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-30 15:15:38 +02:00
Bjorn NeergaardandGitHub 05fabe63ba Merge pull request #4368 from thaJeztah/24.0_backport_update_buildx_0.11
[24.0 backport] Dockerfile: update gotestsum to v1.10.0, buildx v0.11.0
2023-06-28 06:22:26 -06:00
Sebastiaan van StijnandGitHub 0a2dcdb446 Merge pull request #4381 from thaJeztah/24.0_backport_update-link-overlay-driver
[24.0 backport] docs: update link location for the overlay driver
2023-06-27 12:35:42 +02:00
David KarlssonandSebastiaan van Stijn a78fd6ca69 docs: update link location for the overlay driver
File location changes in docker/docs#17176

Signed-off-by: David Karlsson <david.karlsson@docker.com>
(cherry picked from commit 035e26fb0b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-27 09:28:19 +02:00
Sebastiaan van StijnandGitHub ddb9220abf Merge pull request #4375 from dvdksn/24.0_backport_fix-staticip-example
[24.0 Backport] Fix static ip example (docker run)
2023-06-26 17:22:57 +02:00
David Karlsson 9cd335d44b docs: fix static ip example, network needs a subnet
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit 5936fd2a86)
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2023-06-26 17:04:24 +02:00
Sebastiaan van StijnandGitHub bcc889f6cf Merge pull request #4373 from dvdksn/24.0_backport_dockerd-fix-alternative-runtimes-link
[24.0 Backport] Fix broken link in dockerd cli reference
2023-06-26 16:19:10 +02:00
David Karlsson d61e4fe879 docs: fix broken link
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit b85d6a8f9e)
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2023-06-26 15:11:55 +02:00
Sebastiaan van StijnandGitHub ee62dcd8dc Merge pull request #4369 from thaJeztah/24.0_backport_dockerd-runtimes-refresh
[24.0 backport] docs: update the runtime configuration section
2023-06-26 14:27:36 +02:00
Bjorn NeergaardandGitHub b3750a8461 Merge pull request #4371 from thaJeztah/24.0_backport_no_homedir
[24.0 backport] cli/command/context: don't use pkg/homedir in test
2023-06-26 06:12:01 -06:00
Sebastiaan van Stijn 8e3a2942a5 cli/command/context: don't use pkg/homedir in test
I'm considering deprecating the "Key()" utility, as it was only
used in tests.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 79ff64f06d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-26 13:37:34 +02:00
David KarlssonandSebastiaan van Stijn c3ef1ceadf docs: update the runtime configuration section
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit 6c7d17fa01)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-26 12:46:56 +02:00
Sebastiaan van Stijn 44eebb8bc1 Dockerfile: update buildx to v0.11.0
Update the version of buildx we use in the dev-container to v0.11.0;
https://github.com/docker/buildx/releases/tag/v0.11.0

Full diff: https://github.com/docker/buildx/compare/v0.10.4..v0.11.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit bf5d1ce973)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-26 12:17:36 +02:00
Sebastiaan van Stijn 7ecfa2e7fd Dockerfile: update gotestsum to v1.10.0
full diff: https://github.com/gotestyourself/gotestsum/compare/v1.8.2...v1.10.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 9c2694d2b0)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-26 12:17:33 +02:00
Sebastiaan van StijnandGitHub 751bb353fe Merge pull request #4351 from thaJeztah/24.0_backport_update_go_1.20.5
[24.0 backport] update go to go1.20.5, alpine 3.17
2023-06-21 10:55:21 +02:00
Sebastiaan van Stijn f11f309090 update go to go1.20.5
go1.20.5 (released 2023-06-06) includes four security fixes to the cmd/go and
runtime packages, as well as bug fixes to the compiler, the go command, the
runtime, and the crypto/rsa, net, and os packages. See the Go 1.20.5 milestone
on our issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.20.5+label%3ACherryPickApproved

full diff: https://github.com/golang/go/compare/go1.20.4...go1.20.5

These minor releases include 3 security fixes following the security policy:

- cmd/go: cgo code injection
  The go command may generate unexpected code at build time when using cgo. This
  may result in unexpected behavior when running a go program which uses cgo.

  This may occur when running an untrusted module which contains directories with
  newline characters in their names. Modules which are retrieved using the go command,
  i.e. via "go get", are not affected (modules retrieved using GOPATH-mode, i.e.
  GO111MODULE=off, may be affected).

  Thanks to Juho Nurminen of Mattermost for reporting this issue.

  This is CVE-2023-29402 and Go issue https://go.dev/issue/60167.

- runtime: unexpected behavior of setuid/setgid binaries

  The Go runtime didn't act any differently when a binary had the setuid/setgid
  bit set. On Unix platforms, if a setuid/setgid binary was executed with standard
  I/O file descriptors closed, opening any files could result in unexpected
  content being read/written with elevated prilieges. Similarly if a setuid/setgid
  program was terminated, either via panic or signal, it could leak the contents
  of its registers.

  Thanks to Vincent Dehors from Synacktiv for reporting this issue.

  This is CVE-2023-29403 and Go issue https://go.dev/issue/60272.

- cmd/go: improper sanitization of LDFLAGS

  The go command may execute arbitrary code at build time when using cgo. This may
  occur when running "go get" on a malicious module, or when running any other
  command which builds untrusted code. This is can by triggered by linker flags,
  specified via a "#cgo LDFLAGS" directive.

  Thanks to Juho Nurminen of Mattermost for reporting this issue.

  This is CVE-2023-29404 and CVE-2023-29405 and Go issues https://go.dev/issue/60305 and https://go.dev/issue/60306.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 3b8d5da66b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-14 21:37:48 +02:00
Sebastiaan van Stijn 3a6c11773d Dockerfile: update ALPINE_VERSION to 3.17
Official Golang images are now only available for 3.18 and 3.17;
3.18 doesn't look to play well with gotestsum, so sticking to
an older version.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit acb248f8d5)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-14 21:37:46 +02:00
Sebastiaan van StijnandGitHub 0823df7daa Merge pull request #4339 from thaJeztah/24.0_backport_move_attach_keys
[24.0 backport] docs: move "--detach-keys" example to examples section, add to "docker run" as well
2023-06-12 21:37:14 +02:00
Sebastiaan van Stijn 11af1189d7 docs: add "--detach-keys" example to docker run reference
This is a copy of the section we have on the "docker attach" reference page.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 47951ff446)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-09 10:07:19 +02:00
Sebastiaan van Stijn f118c05e87 docs: move "--detach-keys" example to examples section
Also adds a named anchor, so that the section gets linked from the
options table.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c17b0df2a5)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-09 10:07:19 +02:00
Sebastiaan van StijnandGitHub be0e76bf84 Merge pull request #4326 from thaJeztah/24.0_backport_fix_context_godoc
[24.0 backport] cli/command: fix GoDoc referencing wrong const
2023-06-02 14:20:15 +02:00
Sebastiaan van Stijn f66f7ed7ff cli/command: fix GoDoc referencing wrong const
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 0692d762ac)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-02 14:13:14 +02:00
Sebastiaan van StijnandGitHub ec621aae2d Merge pull request #4328 from thaJeztah/24.0_backport_dockerfile_goproxy
[24.0 backport] Dockerfile.vendor: update GOPROXY to use default with fallback
2023-06-02 14:08:51 +02:00
Sebastiaan van Stijn 2814c01b09 Dockerfile.vendor: update GOPROXY to use default with fallback
Use the default proxy, to assist with vanity domains mis-behaving, but keep
a fallback for situations where we need to get modules from GitHub directly.

This should hopefully help with the gopkg.in/yaml.v2 domain often going AWOL;

    #14 245.9 	gopkg.in/yaml.v2@v2.4.0: unrecognized import path "gopkg.in/yaml.v2": reading https://gopkg.in/yaml.v2?go-get=1: 502 Bad Gateway
    #14 245.9 	server response: Cannot obtain refs from GitHub: cannot talk to GitHub: Get https://github.com/go-yaml/yaml.git/info/refs?service=git-upload-pack: write tcp 10.131.9.188:60820->140.82.121.3:443: write: broken pipe

    curl 'https://gopkg.in/yaml.v2?go-get=1'
    Cannot obtain refs from GitHub: cannot talk to GitHub: Get https://github.com/go-yaml/yaml.git/info/refs?service=git-upload-pack: write tcp 10.131.9.188:60820->140.82.121.3:443: write: broken pipe

From the Go documentation; https://go.dev/ref/mod#goproxy-protocol

> List elements may be separated by commas (,) or pipes (|), which determine error
> fallback behavior. When a URL is followed by a comma, the go command falls back
> to later sources only after a 404 (Not Found) or 410 (Gone) response. When a URL
> is followed by a pipe, the go command falls back to later sources after any error,
> including non-HTTP errors such as timeouts. This error handling behavior lets a
> proxy act as a gatekeeper for unknown modules. For example, a proxy could respond
> with error 403 (Forbidden) for modules not on an approved list (see Private proxy
> serving private modules).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 6458dcbe51)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-02 13:15:18 +02:00
Sebastiaan van StijnandGitHub 4dc5ea0e80 Merge pull request #4320 from thaJeztah/24.0_update_engine
[24.0] vendor: github.com/docker/docker v24.0.2
2023-06-01 14:38:31 +02:00
Sebastiaan van Stijn 32f66cbe51 vendor: github.com/docker/docker v24.0.2
no changes in vendored files

full diff: https://github.com/docker/docker/compare/v24.0.1...v24.0.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-31 22:48:27 +02:00
Sebastiaan van StijnandGitHub cb74dfcd85 Merge pull request #4313 from thaJeztah/24.0_update_engine
[24.0] vendor: github.com/docker/docker v24.0.1
2023-05-25 22:26:27 +02:00
Sebastiaan van Stijn dc4707edb0 [24.0] vendor: github.com/docker/docker v24.0.1
no changes in vendored files

full diff: https://github.com/docker/docker/compare/v24.0.0-rc.3...v24.0.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-25 22:11:54 +02:00
Sebastiaan van StijnandGitHub 680212238b Merge pull request #4310 from thaJeztah/24.0_backport_fix_daemon_proxy 2023-05-19 17:51:02 +02:00
Sebastiaan van Stijn 298e67926e docs: fix example for proxies in daemon.json
commit c846428cb6 added proxies to the
example `daemon.json`, based on the implementation that was added in
https://github.com/moby/moby/commit/427c7cc5f86364466c7173e8ca59b97c3876471d.

However, a follow-up pull request changed the proxy-configuration in`daemon.json`
to nest the configuration in a "proxies" struct, and the documentation was
not updated accordingly; see:
https://github.com/moby/moby/commit/101dafd049949a4da65dcefd495828a6644e1ce1

This patch fixes the example.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 2713d0bcde)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-19 17:29:30 +02:00
Sebastiaan van StijnandGitHub aa40216965 Merge pull request #4308 from thaJeztah/24.0_backport_docs_fixes 2023-05-19 15:08:06 +02:00
Sebastiaan van Stijn 9175ffa9b2 man: remove devicemapper from examples
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 4c11f73dcb)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-19 14:45:52 +02:00
A. Lester Buck IIIandSebastiaan van Stijn beb0330a72 Correct "ps --no-trunc" example output
Signed-off-by: A. Lester Buck III <github-reg@nbolt.com>
(cherry picked from commit 988e37956d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-19 14:38:03 +02:00
Sebastiaan van Stijn 405be90634 docs: remove AuFS from glossary
The AuFS storage driver was deprecated and now removed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit b222900520)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-19 14:37:51 +02:00
Sebastiaan van Stijn 7a269817b5 docs: remove Docker Toolbox from glossary
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit e4211c91ed)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-19 14:37:51 +02:00
Sebastiaan van Stijn 41ef7c45cc docs: remove boot2docker and docker-machine from glossary
boot2docker is deprecated, and so is docker-machine

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c246ea8517)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-19 14:37:48 +02:00
Sebastiaan van StijnandGitHub 199b872c98 Merge pull request #4302 from thaJeztah/24.0_backport_completion_remove_aufs_overlay
[24.0 backport] contrib/completion: remove aufs, legacy overlay
2023-05-19 10:07:01 +02:00
Sebastiaan van StijnandGitHub 661f70b52d Merge pull request #4305 from thaJeztah/24.0_backport_daemon_remove_deprecated_drivers
[24.0 backport] docs: remove uses of deprecated AuFS, legacy overlay storage drivers
2023-05-19 09:50:27 +02:00
Sebastiaan van Stijn c184a61dab docs/deprecated: remove "disabled by default" for AuFS, overlay
These drivers have been removed in docker 24.0, so it's no longer
possible to enable them.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c61b565183)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-19 01:23:37 +02:00
Sebastiaan van Stijn e7a60449f7 docs: remove aufs and legacy overlay
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 9f537a756e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-19 01:23:37 +02:00
Sebastiaan van Stijn 77541afeab contrib/completion: remove aufs, legacy overlay
The AuFS and (legacy) overlay storage drivers have been deprecated and
removed, so remove them from the completion scripts.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 73fbcdea05)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-19 01:01:55 +02:00
Bjorn NeergaardandGitHub f4b354f688 Merge pull request #4299 from thaJeztah/24.0_backport_drop_the_dot
[24.0 backport] docs/deprecated: remove .patch release from deprecation status
2023-05-18 22:47:36 +01:00
Sebastiaan van Stijn e67a7acd06 docs/deprecated: remove .patch release from deprecation status
commit de8b696ed6 removed the patch
releases from the deprecation doc, but when we switched to the
SemVer(ish) format for v23.0, we accidentally added them back.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 6460eea54d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-18 22:49:56 +02:00
Sebastiaan van StijnandGitHub 98fdcd769b Merge pull request #4287 from thaJeztah/24.0_update_engine2
[24.0] vendor: github.com/docker/docker v24.0.0-rc.3
2023-05-12 15:10:05 +01:00
Sebastiaan van Stijn fb6ae356c7 vendor: github.com/docker/docker v24.0.0-rc.3
no changes in vendored files

full diff: https://github.com/docker/docker/compare/v24.0.0-rc.2...v24.0.0-rc.3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-12 00:03:10 +02:00
Sebastiaan van StijnandGitHub 1d7dd91593 Merge pull request #4286 from thaJeztah/24.0_backport_vendor_distribution_v2.8.2
[24.0 backport] vendor: github.com/docker/distribution v2.8.2
2023-05-11 19:49:59 +02:00
Sebastiaan van Stijn de93c9b260 vendor: github.com/docker/distribution v2.8.2
CI

- Dockerfile: fix filenames of artifacts

Bugfixes

-  Fix panic in inmemory driver
-  Add code to handle pagination of parts. Fixes max layer size of 10GB bug
-  Parse http forbidden as denied
-  Revert "registry/client: set Accept: identity header when getting layers

Runtime

- Update to go1.19.9
- Dockerfile: update xx to v1.2.1 ([#3907](https://github.com/distribution/distribution/pull/3907))

Security

- Fix [CVE-2022-28391](https://www.cve.org/CVERecord?id=CVE-2022-28391) by bumping alpine from 3.14 to 3.16
- Fix [CVE-2023-2253](https://www.cve.org/CVERecord?id=CVE-2023-2253) runaway allocation on /v2/_catalog [`521ea3d9`](https://github.com/distribution/distribution/commit/521ea3d973cb0c7089ebbcdd4ccadc34be941f54)

full diff: https://github.com/docker/distribution/compare/v2.8.1...v2.8.2-beta.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 353e0a942d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-11 19:16:03 +02:00
Sebastiaan van StijnandGitHub 75f2669d56 Merge pull request #4277 from thaJeztah/24.0_backport_fix_cli_plugins_metadata_experimental_deprecation
[24.0 backport] cli-plugins/manager: fix deprecation comment of Metadata.Experimental
2023-05-11 16:42:02 +02:00
Sebastiaan van StijnandGitHub 46615e8724 Merge pull request #4275 from thaJeztah/24.0_backport_update_tag_documentation
[24.0 backport] Update tag docs to clarify name
2023-05-10 21:14:31 +02:00
Sebastiaan van Stijn cafdcf283e cli-plugins/manager: fix deprecation comment of Metadata.Experimental
This field was marked deprecated in 977d3ae046,
which is part of v20.10 and up, but the comment was missing a newline before
the deprecation message, which may be picked up by IDEs, but is not matching
the correct format, so may not be picked up by linters.

This patch fixes the format, to make sure linters pick up that the field is
deprecated.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 72e3813ab9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-09 22:23:10 +02:00
Craig OsterhoutandSebastiaan van Stijn 3768143c2e Update tag docs to clarify name
Signed-off-by: Craig Osterhout <craig.osterhout@docker.com>
(cherry picked from commit 4119d268e7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-09 22:08:47 +02:00
Sebastiaan van StijnandGitHub 59e9fbd497 Merge pull request #4271 from dvdksn/24.0_backport_docs/host-flag
[24.0 Backport] docs: add description and examples for docker -H
2023-05-08 15:33:22 +02:00
David Karlsson 52ac1a974c docs: update description for docker -H flag
Signed-off-by: David Karlsson <david.karlsson@docker.com>
(cherry picked from commit 759fa585cf)
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2023-05-08 15:16:07 +02:00
Sebastiaan van StijnandGitHub f25ae85b8e Merge pull request #4264 from thaJeztah/24.0_backport_vendor_docker_24.0.0-rc.2
[24.0 backport] vendor: github.com/docker/docker v24.0.0-rc.2
2023-05-08 08:56:26 +02:00
Sebastiaan van Stijn 58f37f630c vendor: github.com/docker/docker v24.0.0-rc.2
no diff, because it's the same as the previous commit, but now tagged;

https://github.com/docker/docker/compare/8d9a40a820349860405e142249c55215aa4da8e3...v24.0.0-rc.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 1d8e2b6525)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-06 13:55:17 +02:00
976 changed files with 14985 additions and 58414 deletions
+4 -4
View File
@@ -55,10 +55,10 @@ jobs:
fetch-depth: 0
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v2
-
name: Build
uses: docker/bake-action@v4
uses: docker/bake-action@v3
with:
targets: ${{ matrix.target }}
set: |
@@ -118,10 +118,10 @@ jobs:
uses: actions/checkout@v4
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v2
-
name: Build
uses: docker/bake-action@v4
uses: docker/bake-action@v3
with:
targets: plugins-cross
set: |
@@ -1,15 +1,6 @@
name: codeql
on:
push:
branches:
- 'master'
- '[0-9]+.[0-9]+'
tags:
- 'v*'
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
@@ -24,13 +15,7 @@ on:
jobs:
codeql:
runs-on: 'ubuntu-latest'
timeout-minutes: 360
permissions:
actions: read
contents: read
security-events: write
runs-on: ubuntu-20.04
steps:
-
name: Checkout
@@ -42,11 +27,6 @@ jobs:
if: ${{ github.event_name == 'pull_request' }}
run: |
git checkout HEAD^2
-
name: Update Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
-
name: Initialize CodeQL
uses: github/codeql-action/init@v2
@@ -58,5 +38,3 @@ jobs:
-
name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:go"
+1 -1
View File
@@ -48,7 +48,7 @@ jobs:
docker info
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v2
-
name: Run ${{ matrix.target }}
run: |
+3 -3
View File
@@ -23,10 +23,10 @@ jobs:
uses: actions/checkout@v4
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v2
-
name: Test
uses: docker/bake-action@v4
uses: docker/bake-action@v3
with:
targets: test-coverage
-
@@ -63,7 +63,7 @@ jobs:
name: Set up Go
uses: actions/setup-go@v4
with:
go-version: 1.21.3
go-version: 1.20.13
-
name: Test
run: |
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
uses: actions/checkout@v4
-
name: Run
uses: docker/bake-action@v4
uses: docker/bake-action@v3
with:
targets: ${{ matrix.target }}
+4
View File
@@ -1,5 +1,9 @@
# Contributing to Docker
Want to hack on Docker? Awesome! We have a contributor's guide that explains
[setting up a Docker development environment and the contribution
process](https://docs.docker.com/opensource/project/who-written-for/).
This page contains information about reporting issues as well as some tips and
guidelines useful to experienced open source contributors. Finally, make sure
you read our [community guidelines](#docker-community-guidelines) before you
+2 -2
View File
@@ -1,8 +1,8 @@
# syntax=docker/dockerfile:1
ARG BASE_VARIANT=alpine
ARG GO_VERSION=1.21.3
ARG ALPINE_VERSION=3.17
ARG GO_VERSION=1.20.13
ARG ALPINE_VERSION=3.18
ARG XX_VERSION=1.2.1
ARG GOVERSIONINFO_VERSION=v1.3.0
ARG GOTESTSUM_VERSION=v1.10.0
+6
View File
@@ -24,6 +24,7 @@
people = [
"albers",
"cpuguy83",
"ndeloof",
"rumpl",
"silvin-lubecki",
"stevvooe",
@@ -97,6 +98,11 @@
Email = "dnephin@gmail.com"
GitHub = "dnephin"
[people.ndeloof]
Name = "Nicolas De Loof"
Email = "nicolas.deloof@gmail.com"
GitHub = "ndeloof"
[people.neersighted]
Name = "Bjorn Neergaard"
Email = "bneergaard@mirantis.com"
+1 -1
View File
@@ -1 +1 @@
25.0.0-dev
24.0.0-dev
+3 -1
View File
@@ -1,6 +1,8 @@
package manager
import "os/exec"
import (
exec "golang.org/x/sys/execabs"
)
// Candidate represents a possible plugin candidate, for mocking purposes
type Candidate interface {
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package manager
import (
+1 -1
View File
@@ -3,7 +3,6 @@ package manager
import (
"context"
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
@@ -14,6 +13,7 @@ import (
"github.com/fvbommel/sortorder"
"github.com/spf13/cobra"
"golang.org/x/sync/errgroup"
exec "golang.org/x/sys/execabs"
)
// ReexecEnvvar is the name of an ennvar which is set to the command
+1
View File
@@ -1,4 +1,5 @@
//go:build !windows
// +build !windows
package manager
+4
View File
@@ -22,4 +22,8 @@ type Metadata struct {
ShortDescription string `json:",omitempty"`
// URL is a pointer to the plugin's homepage.
URL string `json:",omitempty"`
// Experimental specifies whether the plugin is experimental.
//
// Deprecated: experimental features are now always enabled in the CLI
Experimental bool `json:",omitempty"`
}
+1
View File
@@ -1,4 +1,5 @@
//go:build !windows
// +build !windows
package manager
+2 -2
View File
@@ -131,7 +131,7 @@ func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta
DisableDescriptions: true,
},
}
opts, _ := cli.SetupPluginRootCommand(cmd)
opts, flags := cli.SetupPluginRootCommand(cmd)
cmd.SetIn(dockerCli.In())
cmd.SetOut(dockerCli.Out())
@@ -144,7 +144,7 @@ func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta
cli.DisableFlagsInUseLine(cmd)
return cli.NewTopLevelCommand(cmd, dockerCli, opts, cmd.Flags())
return cli.NewTopLevelCommand(cmd, dockerCli, opts, flags)
}
func newMetadataSubcommand(plugin *cobra.Command, meta manager.Metadata) *cobra.Command {
+10 -6
View File
@@ -9,6 +9,7 @@ import (
pluginmanager "github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config"
cliflags "github.com/docker/cli/cli/flags"
"github.com/docker/docker/pkg/homedir"
"github.com/docker/docker/registry"
@@ -22,9 +23,12 @@ import (
// setupCommonRootCommand contains the setup common to
// SetupRootCommand and SetupPluginRootCommand.
func setupCommonRootCommand(rootCmd *cobra.Command) (*cliflags.ClientOptions, *cobra.Command) {
func setupCommonRootCommand(rootCmd *cobra.Command) (*cliflags.ClientOptions, *pflag.FlagSet, *cobra.Command) {
opts := cliflags.NewClientOptions()
opts.InstallFlags(rootCmd.Flags())
flags := rootCmd.Flags()
flags.StringVar(&opts.ConfigDir, "config", config.Dir(), "Location of client config files")
opts.InstallFlags(flags)
cobra.AddTemplateFunc("add", func(a, b int) int { return a + b })
cobra.AddTemplateFunc("hasAliases", hasAliases)
@@ -69,20 +73,20 @@ func setupCommonRootCommand(rootCmd *cobra.Command) (*cliflags.ClientOptions, *c
}
}
return opts, helpCommand
return opts, flags, helpCommand
}
// SetupRootCommand sets default usage, help, and error handling for the
// root command.
func SetupRootCommand(rootCmd *cobra.Command) (opts *cliflags.ClientOptions, helpCmd *cobra.Command) {
func SetupRootCommand(rootCmd *cobra.Command) (*cliflags.ClientOptions, *pflag.FlagSet, *cobra.Command) {
rootCmd.SetVersionTemplate("Docker version {{.Version}}\n")
return setupCommonRootCommand(rootCmd)
}
// SetupPluginRootCommand sets default usage, help and error handling for a plugin root command.
func SetupPluginRootCommand(rootCmd *cobra.Command) (*cliflags.ClientOptions, *pflag.FlagSet) {
opts, _ := setupCommonRootCommand(rootCmd)
return opts, rootCmd.Flags()
opts, flags, _ := setupCommonRootCommand(rootCmd)
return opts, flags
}
// FlagErrorFunc prints an error message which matches the format of the
+8 -8
View File
@@ -3,34 +3,34 @@ package checkpoint
import (
"context"
"github.com/docker/docker/api/types/checkpoint"
"github.com/docker/docker/api/types"
"github.com/docker/docker/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 types.CheckpointCreateOptions) error
checkpointDeleteFunc func(container string, options types.CheckpointDeleteOptions) error
checkpointListFunc func(container string, options types.CheckpointListOptions) ([]types.Checkpoint, error)
}
func (cli *fakeClient) CheckpointCreate(_ context.Context, container string, options checkpoint.CreateOptions) error {
func (cli *fakeClient) CheckpointCreate(_ context.Context, container string, options types.CheckpointCreateOptions) error {
if cli.checkpointCreateFunc != nil {
return cli.checkpointCreateFunc(container, options)
}
return nil
}
func (cli *fakeClient) CheckpointDelete(_ context.Context, container string, options checkpoint.DeleteOptions) error {
func (cli *fakeClient) CheckpointDelete(_ context.Context, container string, options types.CheckpointDeleteOptions) error {
if cli.checkpointDeleteFunc != nil {
return cli.checkpointDeleteFunc(container, options)
}
return nil
}
func (cli *fakeClient) CheckpointList(_ context.Context, container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {
func (cli *fakeClient) CheckpointList(_ context.Context, container string, options types.CheckpointListOptions) ([]types.Checkpoint, error) {
if cli.checkpointListFunc != nil {
return cli.checkpointListFunc(container, options)
}
return []checkpoint.Summary{}, nil
return []types.Checkpoint{}, nil
}
+7 -3
View File
@@ -7,7 +7,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/docker/docker/api/types"
"github.com/spf13/cobra"
)
@@ -41,11 +41,15 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command {
}
func runCreate(dockerCli command.Cli, opts createOptions) error {
err := dockerCli.Client().CheckpointCreate(context.Background(), opts.container, checkpoint.CreateOptions{
client := dockerCli.Client()
checkpointOpts := types.CheckpointCreateOptions{
CheckpointID: opts.checkpoint,
CheckpointDir: opts.checkpointDir,
Exit: !opts.leaveRunning,
})
}
err := client.CheckpointCreate(context.Background(), opts.container, checkpointOpts)
if err != nil {
return err
}
+8 -8
View File
@@ -6,7 +6,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/checkpoint"
"github.com/docker/docker/api/types"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -15,7 +15,7 @@ import (
func TestCheckpointCreateErrors(t *testing.T) {
testCases := []struct {
args []string
checkpointCreateFunc func(container string, options checkpoint.CreateOptions) error
checkpointCreateFunc func(container string, options types.CheckpointCreateOptions) error
expectedError string
}{
{
@@ -28,7 +28,7 @@ func TestCheckpointCreateErrors(t *testing.T) {
},
{
args: []string{"foo", "bar"},
checkpointCreateFunc: func(container string, options checkpoint.CreateOptions) error {
checkpointCreateFunc: func(container string, options types.CheckpointCreateOptions) error {
return errors.Errorf("error creating checkpoint for container foo")
},
expectedError: "error creating checkpoint for container foo",
@@ -50,7 +50,7 @@ func TestCheckpointCreateWithOptions(t *testing.T) {
var containerID, checkpointID, checkpointDir string
var exit bool
cli := test.NewFakeCli(&fakeClient{
checkpointCreateFunc: func(container string, options checkpoint.CreateOptions) error {
checkpointCreateFunc: func(container string, options types.CheckpointCreateOptions) error {
containerID = container
checkpointID = options.CheckpointID
checkpointDir = options.CheckpointDir
@@ -59,14 +59,14 @@ func TestCheckpointCreateWithOptions(t *testing.T) {
},
})
cmd := newCreateCommand(cli)
cp := "checkpoint-bar"
cmd.SetArgs([]string{"container-foo", cp})
checkpoint := "checkpoint-bar"
cmd.SetArgs([]string{"container-foo", checkpoint})
cmd.Flags().Set("leave-running", "true")
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(cp, checkpointID))
assert.Check(t, is.Equal(checkpoint, checkpointID))
assert.Check(t, is.Equal("/dir/foo", checkpointDir))
assert.Check(t, is.Equal(false, exit))
assert.Check(t, is.Equal(cp, strings.TrimSpace(cli.OutBuffer().String())))
assert.Check(t, is.Equal(checkpoint, strings.TrimSpace(cli.OutBuffer().String())))
}
+7 -6
View File
@@ -2,12 +2,13 @@ package checkpoint
import (
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/docker/api/types/checkpoint"
"github.com/docker/docker/api/types"
)
const (
defaultCheckpointFormat = "table {{.Name}}"
checkpointNameHeader = "CHECKPOINT NAME"
checkpointNameHeader = "CHECKPOINT NAME"
)
// NewFormat returns a format for use with a checkpoint Context
@@ -20,10 +21,10 @@ func NewFormat(source string) formatter.Format {
}
// FormatWrite writes formatted checkpoints using the Context
func FormatWrite(ctx formatter.Context, checkpoints []checkpoint.Summary) error {
func FormatWrite(ctx formatter.Context, checkpoints []types.Checkpoint) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, cp := range checkpoints {
if err := format(&checkpointContext{c: cp}); err != nil {
for _, checkpoint := range checkpoints {
if err := format(&checkpointContext{c: checkpoint}); err != nil {
return err
}
}
@@ -34,7 +35,7 @@ func FormatWrite(ctx formatter.Context, checkpoints []checkpoint.Summary) error
type checkpointContext struct {
formatter.HeaderContext
c checkpoint.Summary
c types.Checkpoint
}
func newCheckpointContext() *checkpointContext {
+7 -6
View File
@@ -5,7 +5,7 @@ import (
"testing"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/docker/api/types/checkpoint"
"github.com/docker/docker/api/types"
"gotest.tools/v3/assert"
)
@@ -38,14 +38,15 @@ checkpoint-3:
},
}
checkpoints := []types.Checkpoint{
{Name: "checkpoint-1"},
{Name: "checkpoint-2"},
{Name: "checkpoint-3"},
}
for _, testcase := range cases {
out := bytes.NewBufferString("")
testcase.context.Output = out
err := FormatWrite(testcase.context, []checkpoint.Summary{
{Name: "checkpoint-1"},
{Name: "checkpoint-2"},
{Name: "checkpoint-3"},
})
err := FormatWrite(testcase.context, checkpoints)
assert.NilError(t, err)
assert.Equal(t, out.String(), testcase.expected)
}
+7 -3
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/docker/docker/api/types"
"github.com/spf13/cobra"
)
@@ -36,9 +36,13 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
}
func runList(dockerCli command.Cli, container string, opts listOptions) error {
checkpoints, err := dockerCli.Client().CheckpointList(context.Background(), container, checkpoint.ListOptions{
client := dockerCli.Client()
listOpts := types.CheckpointListOptions{
CheckpointDir: opts.checkpointDir,
})
}
checkpoints, err := client.CheckpointList(context.Background(), container, listOpts)
if err != nil {
return err
}
+6 -6
View File
@@ -5,7 +5,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/checkpoint"
"github.com/docker/docker/api/types"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -15,7 +15,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 types.CheckpointListOptions) ([]types.Checkpoint, error)
expectedError string
}{
{
@@ -28,8 +28,8 @@ func TestCheckpointListErrors(t *testing.T) {
},
{
args: []string{"foo"},
checkpointListFunc: func(container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {
return []checkpoint.Summary{}, errors.Errorf("error getting checkpoints for container foo")
checkpointListFunc: func(container string, options types.CheckpointListOptions) ([]types.Checkpoint, error) {
return []types.Checkpoint{}, errors.Errorf("error getting checkpoints for container foo")
},
expectedError: "error getting checkpoints for container foo",
},
@@ -49,10 +49,10 @@ 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 types.CheckpointListOptions) ([]types.Checkpoint, error) {
containerID = container
checkpointDir = options.CheckpointDir
return []checkpoint.Summary{
return []types.Checkpoint{
{Name: "checkpoint-foo"},
}, nil
},
+9 -5
View File
@@ -5,7 +5,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types/checkpoint"
"github.com/docker/docker/api/types"
"github.com/spf13/cobra"
)
@@ -32,9 +32,13 @@ func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
return cmd
}
func runRemove(dockerCli command.Cli, container string, checkpointID string, opts removeOptions) error {
return dockerCli.Client().CheckpointDelete(context.Background(), container, checkpoint.DeleteOptions{
CheckpointID: checkpointID,
func runRemove(dockerCli command.Cli, container string, checkpoint string, opts removeOptions) error {
client := dockerCli.Client()
removeOpts := types.CheckpointDeleteOptions{
CheckpointID: checkpoint,
CheckpointDir: opts.checkpointDir,
})
}
return client.CheckpointDelete(context.Background(), container, removeOpts)
}
+4 -4
View File
@@ -5,7 +5,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/checkpoint"
"github.com/docker/docker/api/types"
"github.com/pkg/errors"
"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 types.CheckpointDeleteOptions) error
expectedError string
}{
{
@@ -27,7 +27,7 @@ func TestCheckpointRemoveErrors(t *testing.T) {
},
{
args: []string{"foo", "bar"},
checkpointDeleteFunc: func(container string, options checkpoint.DeleteOptions) error {
checkpointDeleteFunc: func(container string, options types.CheckpointDeleteOptions) error {
return errors.Errorf("error deleting checkpoint")
},
expectedError: "error deleting checkpoint",
@@ -48,7 +48,7 @@ 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 types.CheckpointDeleteOptions) error {
containerID = container
checkpointID = options.CheckpointID
checkpointDir = options.CheckpointDir
+13 -8
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package command
import (
@@ -189,7 +192,7 @@ func (cli *DockerCli) ManifestStore() manifeststore.Store {
// registry
func (cli *DockerCli) RegistryClient(allowInsecure bool) registryclient.RegistryClient {
resolver := func(ctx context.Context, index *registry.IndexInfo) registry.AuthConfig {
return ResolveAuthConfig(cli.ConfigFile(), index)
return ResolveAuthConfig(ctx, cli, index)
}
return registryclient.NewRegistryClient(resolver, UserAgent(), allowInsecure)
}
@@ -260,15 +263,17 @@ func NewAPIClientFromFlags(opts *cliflags.ClientOptions, configFile *configfile.
}
func newAPIClientFromEndpoint(ep docker.Endpoint, configFile *configfile.ConfigFile) (client.APIClient, error) {
opts, err := ep.ClientOpts()
clientOpts, err := ep.ClientOpts()
if err != nil {
return nil, err
}
if len(configFile.HTTPHeaders) > 0 {
opts = append(opts, client.WithHTTPHeaders(configFile.HTTPHeaders))
customHeaders := make(map[string]string, len(configFile.HTTPHeaders))
for k, v := range configFile.HTTPHeaders {
customHeaders[k] = v
}
opts = append(opts, client.WithUserAgent(UserAgent()))
return client.NewClientWithOpts(opts...)
customHeaders["User-Agent"] = UserAgent()
clientOpts = append(clientOpts, client.WithHTTPHeaders(customHeaders))
return client.NewClientWithOpts(clientOpts...)
}
func resolveDockerEndpoint(s store.Reader, contextName string) (docker.Endpoint, error) {
@@ -362,7 +367,7 @@ func (cli *DockerCli) ContextStore() store.Store {
// order of preference:
//
// 1. The "--context" command-line option.
// 2. The "DOCKER_CONTEXT" environment variable ([EnvOverrideContext]).
// 2. The "DOCKER_CONTEXT" environment variable.
// 3. The current context as configured through the in "currentContext"
// field in the CLI configuration file ("~/.docker/config.json").
// 4. If no context is configured, use the "default" context.
@@ -404,7 +409,7 @@ func resolveContextName(opts *cliflags.ClientOptions, config *configfile.ConfigF
if os.Getenv(client.EnvOverrideHost) != "" {
return DefaultContextName
}
if ctxName := os.Getenv(EnvOverrideContext); ctxName != "" {
if ctxName := os.Getenv("DOCKER_CONTEXT"); ctxName != "" {
return ctxName
}
if config != nil && config.CurrentContext != "" {
+1 -2
View File
@@ -6,7 +6,6 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/volume"
"github.com/spf13/cobra"
)
@@ -34,7 +33,7 @@ func ImageNames(dockerCli command.Cli) ValidArgsFn {
// Set DOCKER_COMPLETION_SHOW_CONTAINER_IDS=yes to also complete IDs.
func ContainerNames(dockerCli command.Cli, all bool, filters ...func(types.Container) bool) ValidArgsFn {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, err := dockerCli.Client().ContainerList(cmd.Context(), container.ListOptions{
list, err := dockerCli.Client().ContainerList(cmd.Context(), types.ContainerListOptions{
All: all,
})
if err != nil {
+1 -1
View File
@@ -103,7 +103,7 @@ func (c *configContext) Labels() string {
}
var joinLabels []string
for k, v := range mapLabels {
joinLabels = append(joinLabels, k+"="+v)
joinLabels = append(joinLabels, fmt.Sprintf("%s=%s", k, v))
}
return strings.Join(joinLabels, ",")
}
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package config
import (
+15 -15
View File
@@ -8,7 +8,7 @@ import (
"time"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/builders"
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
"github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
@@ -43,7 +43,7 @@ func TestConfigInspectErrors(t *testing.T) {
args: []string{"foo", "bar"},
configInspectFunc: func(_ context.Context, configID string) (swarm.Config, []byte, error) {
if configID == "foo" {
return *builders.Config(builders.ConfigName("foo")), nil, nil
return *Config(ConfigName("foo")), nil, nil
}
return swarm.Config{}, nil, errors.Errorf("error while inspecting the config")
},
@@ -58,7 +58,7 @@ func TestConfigInspectErrors(t *testing.T) {
)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
cmd.Flags().Set(key, value)
}
cmd.SetOut(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
@@ -78,14 +78,14 @@ func TestConfigInspectWithoutFormat(t *testing.T) {
if name != "foo" {
return swarm.Config{}, nil, errors.Errorf("Invalid name, expected %s, got %s", "foo", name)
}
return *builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")), nil, nil
return *Config(ConfigID("ID-foo"), ConfigName("foo")), nil, 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{
return *Config(ConfigID("ID-"+name), ConfigName(name), ConfigLabels(map[string]string{
"label1": "label-foo",
})), nil, nil
},
@@ -102,7 +102,7 @@ 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{
return *Config(ConfigName("foo"), ConfigLabels(map[string]string{
"label1": "label-foo",
})), nil, nil
}
@@ -131,7 +131,7 @@ func TestConfigInspectWithFormat(t *testing.T) {
})
cmd := newConfigInspectCommand(cli)
cmd.SetArgs(tc.args)
assert.Check(t, cmd.Flags().Set("format", tc.format))
cmd.Flags().Set("format", tc.format)
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("config-inspect-with-format.%s.golden", tc.name))
}
@@ -145,15 +145,15 @@ func TestConfigInspectPretty(t *testing.T) {
{
name: "simple",
configInspectFunc: func(_ context.Context, id string) (swarm.Config, []byte, error) {
return *builders.Config(
builders.ConfigLabels(map[string]string{
return *Config(
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")),
ConfigID("configID"),
ConfigName("configName"),
ConfigCreatedAt(time.Time{}),
ConfigUpdatedAt(time.Time{}),
ConfigData([]byte("payload here")),
), []byte{}, nil
},
},
@@ -165,7 +165,7 @@ func TestConfigInspectPretty(t *testing.T) {
cmd := newConfigInspectCommand(cli)
cmd.SetArgs([]string{"configID"})
assert.Check(t, cmd.Flags().Set("pretty", "true"))
cmd.Flags().Set("pretty", "true")
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("config-inspect-pretty.%s.golden", tc.name))
}
+36 -36
View File
@@ -8,7 +8,7 @@ import (
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/builders"
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors"
@@ -50,23 +50,23 @@ func TestConfigList(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(_ context.Context, options types.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)),
*Config(ConfigID("ID-1-foo"),
ConfigName("1-foo"),
ConfigVersion(swarm.Version{Index: 10}),
ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
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)),
*Config(ConfigID("ID-10-foo"),
ConfigName("10-foo"),
ConfigVersion(swarm.Version{Index: 11}),
ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
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)),
*Config(ConfigID("ID-2-foo"),
ConfigName("2-foo"),
ConfigVersion(swarm.Version{Index: 11}),
ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
),
}, nil
},
@@ -80,15 +80,15 @@ func TestConfigListWithQuietOption(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(_ context.Context, options types.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{
*Config(ConfigID("ID-foo"), ConfigName("foo")),
*Config(ConfigID("ID-bar"), ConfigName("bar"), ConfigLabels(map[string]string{
"label": "label-bar",
})),
}, nil
},
})
cmd := newConfigListCommand(cli)
assert.Check(t, cmd.Flags().Set("quiet", "true"))
cmd.Flags().Set("quiet", "true")
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-quiet-option.golden")
}
@@ -97,8 +97,8 @@ func TestConfigListWithConfigFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(_ context.Context, options types.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{
*Config(ConfigID("ID-foo"), ConfigName("foo")),
*Config(ConfigID("ID-bar"), ConfigName("bar"), ConfigLabels(map[string]string{
"label": "label-bar",
})),
}, nil
@@ -116,15 +116,15 @@ func TestConfigListWithFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(_ context.Context, options types.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{
*Config(ConfigID("ID-foo"), ConfigName("foo")),
*Config(ConfigID("ID-bar"), ConfigName("bar"), ConfigLabels(map[string]string{
"label": "label-bar",
})),
}, nil
},
})
cmd := newConfigListCommand(cli)
assert.Check(t, cmd.Flags().Set("format", "{{ .Name }} {{ .Labels }}"))
cmd.Flags().Set("format", "{{ .Name }} {{ .Labels }}")
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-format.golden")
}
@@ -135,24 +135,24 @@ func TestConfigListWithFilter(t *testing.T) {
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)),
*Config(ConfigID("ID-foo"),
ConfigName("foo"),
ConfigVersion(swarm.Version{Index: 10}),
ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
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)),
*Config(ConfigID("ID-bar"),
ConfigName("bar"),
ConfigVersion(swarm.Version{Index: 11}),
ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
),
}, nil
},
})
cmd := newConfigListCommand(cli)
assert.Check(t, cmd.Flags().Set("filter", "name=foo"))
assert.Check(t, cmd.Flags().Set("filter", "label=lbl1=Label-bar"))
cmd.Flags().Set("filter", "name=foo")
cmd.Flags().Set("filter", "label=lbl1=Label-bar")
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-filter.golden")
}
+28 -29
View File
@@ -17,11 +17,12 @@ import (
"github.com/spf13/cobra"
)
// AttachOptions group options for `attach` command
type AttachOptions struct {
NoStdin bool
Proxy bool
DetachKeys string
type attachOptions struct {
noStdin bool
proxy bool
detachKeys string
container string
}
func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, args string) (*types.ContainerJSON, error) {
@@ -44,16 +45,15 @@ func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, ar
// NewAttachCommand creates a new cobra.Command for `docker attach`
func NewAttachCommand(dockerCli command.Cli) *cobra.Command {
var opts AttachOptions
var container string
var opts attachOptions
cmd := &cobra.Command{
Use: "attach [OPTIONS] CONTAINER",
Short: "Attach local standard input, output, and error streams to a running container",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
container = args[0]
return RunAttach(context.Background(), dockerCli, container, &opts)
opts.container = args[0]
return runAttach(dockerCli, &opts)
},
Annotations: map[string]string{
"aliases": "docker container attach, docker attach",
@@ -64,39 +64,38 @@ func NewAttachCommand(dockerCli command.Cli) *cobra.Command {
}
flags := cmd.Flags()
flags.BoolVar(&opts.NoStdin, "no-stdin", false, "Do not attach STDIN")
flags.BoolVar(&opts.Proxy, "sig-proxy", true, "Proxy all received signals to the process")
flags.StringVar(&opts.DetachKeys, "detach-keys", "", "Override the key sequence for detaching a container")
flags.BoolVar(&opts.noStdin, "no-stdin", false, "Do not attach STDIN")
flags.BoolVar(&opts.proxy, "sig-proxy", true, "Proxy all received signals to the process")
flags.StringVar(&opts.detachKeys, "detach-keys", "", "Override the key sequence for detaching a container")
return cmd
}
// RunAttach executes an `attach` command
func RunAttach(ctx context.Context, dockerCli command.Cli, target string, opts *AttachOptions) error {
apiClient := dockerCli.Client()
func runAttach(dockerCli command.Cli, opts *attachOptions) error {
ctx := context.Background()
client := dockerCli.Client()
// request channel to wait for client
resultC, errC := apiClient.ContainerWait(ctx, target, "")
resultC, errC := client.ContainerWait(ctx, opts.container, "")
c, err := inspectContainerAndCheckState(ctx, apiClient, target)
c, err := inspectContainerAndCheckState(ctx, client, opts.container)
if err != nil {
return err
}
if err := dockerCli.In().CheckTty(!opts.NoStdin, c.Config.Tty); err != nil {
if err := dockerCli.In().CheckTty(!opts.noStdin, c.Config.Tty); err != nil {
return err
}
detachKeys := dockerCli.ConfigFile().DetachKeys
if opts.DetachKeys != "" {
detachKeys = opts.DetachKeys
if opts.detachKeys != "" {
dockerCli.ConfigFile().DetachKeys = opts.detachKeys
}
options := container.AttachOptions{
options := types.ContainerAttachOptions{
Stream: true,
Stdin: !opts.NoStdin && c.Config.OpenStdin,
Stdin: !opts.noStdin && c.Config.OpenStdin,
Stdout: true,
Stderr: true,
DetachKeys: detachKeys,
DetachKeys: dockerCli.ConfigFile().DetachKeys,
}
var in io.ReadCloser
@@ -104,13 +103,13 @@ func RunAttach(ctx context.Context, dockerCli command.Cli, target string, opts *
in = dockerCli.In()
}
if opts.Proxy && !c.Config.Tty {
if opts.proxy && !c.Config.Tty {
sigc := notifyAllSignals()
go ForwardAllSignals(ctx, apiClient, target, sigc)
go ForwardAllSignals(ctx, dockerCli, opts.container, sigc)
defer signal.StopCatch(sigc)
}
resp, errAttach := apiClient.ContainerAttach(ctx, target, options)
resp, errAttach := client.ContainerAttach(ctx, opts.container, options)
if errAttach != nil {
return errAttach
}
@@ -124,13 +123,13 @@ func RunAttach(ctx context.Context, dockerCli command.Cli, target string, opts *
// the container and not exit.
//
// Recheck the container's state to avoid attach block.
_, err = inspectContainerAndCheckState(ctx, apiClient, target)
_, err = inspectContainerAndCheckState(ctx, client, opts.container)
if err != nil {
return err
}
if c.Config.Tty && dockerCli.Out().IsTerminal() {
resizeTTY(ctx, dockerCli, target)
resizeTTY(ctx, dockerCli, opts.container)
}
streamer := hijackedIOStreamer{
+13 -14
View File
@@ -7,7 +7,6 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client"
specs "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -22,22 +21,22 @@ type fakeClient struct {
networkingConfig *network.NetworkingConfig,
platform *specs.Platform,
containerName string) (container.CreateResponse, error)
containerStartFunc func(container string, options container.StartOptions) error
containerStartFunc func(container string, options types.ContainerStartOptions) error
imageCreateFunc func(parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error)
infoFunc func() (system.Info, error)
infoFunc func() (types.Info, error)
containerStatPathFunc func(container, path string) (types.ContainerPathStat, error)
containerCopyFromFunc func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error)
logFunc func(string, container.LogsOptions) (io.ReadCloser, error)
logFunc func(string, types.ContainerLogsOptions) (io.ReadCloser, error)
waitFunc func(string) (<-chan container.WaitResponse, <-chan error)
containerListFunc func(container.ListOptions) ([]types.Container, error)
containerListFunc func(types.ContainerListOptions) ([]types.Container, error)
containerExportFunc func(string) (io.ReadCloser, error)
containerExecResizeFunc func(id string, options container.ResizeOptions) error
containerRemoveFunc func(ctx context.Context, container string, options container.RemoveOptions) error
containerExecResizeFunc func(id string, options types.ResizeOptions) error
containerRemoveFunc func(ctx context.Context, container string, options types.ContainerRemoveOptions) error
containerKillFunc func(ctx context.Context, container, signal string) error
Version string
}
func (f *fakeClient) ContainerList(_ context.Context, options container.ListOptions) ([]types.Container, error) {
func (f *fakeClient) ContainerList(_ context.Context, options types.ContainerListOptions) ([]types.Container, error) {
if f.containerListFunc != nil {
return f.containerListFunc(options)
}
@@ -83,7 +82,7 @@ func (f *fakeClient) ContainerCreate(
return container.CreateResponse{}, nil
}
func (f *fakeClient) ContainerRemove(ctx context.Context, container string, options container.RemoveOptions) error {
func (f *fakeClient) ContainerRemove(ctx context.Context, container string, options types.ContainerRemoveOptions) error {
if f.containerRemoveFunc != nil {
return f.containerRemoveFunc(ctx, container, options)
}
@@ -97,11 +96,11 @@ func (f *fakeClient) ImageCreate(_ context.Context, parentReference string, opti
return nil, nil
}
func (f *fakeClient) Info(_ context.Context) (system.Info, error) {
func (f *fakeClient) Info(_ context.Context) (types.Info, error) {
if f.infoFunc != nil {
return f.infoFunc()
}
return system.Info{}, nil
return types.Info{}, nil
}
func (f *fakeClient) ContainerStatPath(_ context.Context, container, path string) (types.ContainerPathStat, error) {
@@ -118,7 +117,7 @@ func (f *fakeClient) CopyFromContainer(_ context.Context, container, srcPath str
return nil, types.ContainerPathStat{}, nil
}
func (f *fakeClient) ContainerLogs(_ context.Context, container string, options container.LogsOptions) (io.ReadCloser, error) {
func (f *fakeClient) ContainerLogs(_ context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error) {
if f.logFunc != nil {
return f.logFunc(container, options)
}
@@ -136,7 +135,7 @@ func (f *fakeClient) ContainerWait(_ context.Context, container string, _ contai
return nil, nil
}
func (f *fakeClient) ContainerStart(_ context.Context, container string, options container.StartOptions) error {
func (f *fakeClient) ContainerStart(_ context.Context, container string, options types.ContainerStartOptions) error {
if f.containerStartFunc != nil {
return f.containerStartFunc(container, options)
}
@@ -150,7 +149,7 @@ func (f *fakeClient) ContainerExport(_ context.Context, container string) (io.Re
return nil, nil
}
func (f *fakeClient) ContainerExecResize(_ context.Context, id string, options container.ResizeOptions) error {
func (f *fakeClient) ContainerExecResize(_ context.Context, id string, options types.ResizeOptions) error {
if f.containerExecResizeFunc != nil {
return f.containerExecResizeFunc(id, options)
}
+9 -4
View File
@@ -8,7 +8,7 @@ import (
"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/docker/docker/api/types"
"github.com/spf13/cobra"
)
@@ -59,13 +59,18 @@ func NewCommitCommand(dockerCli command.Cli) *cobra.Command {
func runCommit(dockerCli command.Cli, options *commitOptions) error {
ctx := context.Background()
response, err := dockerCli.Client().ContainerCommit(ctx, options.container, container.CommitOptions{
Reference: options.reference,
name := options.container
reference := options.reference
commitOptions := types.ContainerCommitOptions{
Reference: reference,
Comment: options.comment,
Author: options.author,
Changes: options.changes.GetAll(),
Pause: options.pause,
})
}
response, err := dockerCli.Client().ContainerCommit(ctx, name, commitOptions)
if err != nil {
return err
}
+18 -18
View File
@@ -8,17 +8,17 @@ import (
"regexp"
"github.com/containerd/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/streams"
"github.com/docker/cli/opts"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
apiclient "github.com/docker/docker/client"
"github.com/docker/docker/pkg/jsonmessage"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
@@ -91,7 +91,7 @@ func runCreate(dockerCli command.Cli, flags *pflag.FlagSet, options *createOptio
if v == nil {
newEnv = append(newEnv, k)
} else {
newEnv = append(newEnv, k+"="+*v)
newEnv = append(newEnv, fmt.Sprintf("%s=%s", k, *v))
}
}
copts.env = *opts.NewListOptsRef(&newEnv, nil)
@@ -104,17 +104,17 @@ func runCreate(dockerCli command.Cli, flags *pflag.FlagSet, options *createOptio
reportError(dockerCli.Err(), "create", err.Error(), true)
return cli.StatusError{StatusCode: 125}
}
id, err := createContainer(context.Background(), dockerCli, containerCfg, options)
response, err := createContainer(context.Background(), dockerCli, containerCfg, options)
if err != nil {
return err
}
_, _ = fmt.Fprintln(dockerCli.Out(), id)
fmt.Fprintln(dockerCli.Out(), response.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, image string, opts *createOptions) error {
encodedAuth, err := command.RetrieveAuthTokenFromImage(dockerCli.ConfigFile(), image)
encodedAuth, err := command.RetrieveAuthTokenFromImage(ctx, dockerCli, image)
if err != nil {
return err
}
@@ -185,7 +185,7 @@ func newCIDFile(path string) (*cidFile, error) {
}
//nolint:gocyclo
func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *containerConfig, opts *createOptions) (containerID string, err error) {
func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *containerConfig, opts *createOptions) (*container.CreateResponse, error) {
config := containerCfg.Config
hostConfig := containerCfg.HostConfig
networkingConfig := containerCfg.NetworkingConfig
@@ -200,13 +200,13 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
containerIDFile, err := newCIDFile(hostConfig.ContainerIDFile)
if err != nil {
return "", err
return nil, err
}
defer containerIDFile.Close()
ref, err := reference.ParseAnyReference(config.Image)
if err != nil {
return "", err
return nil, err
}
if named, ok := ref.(reference.Named); ok {
namedRef = reference.TagNameOnly(named)
@@ -215,7 +215,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
var err error
trustedRef, err = image.TrustedReference(ctx, dockerCli, taggedRef)
if err != nil {
return "", err
return nil, err
}
config.Image = reference.FamiliarString(trustedRef)
}
@@ -239,14 +239,14 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
if opts.platform != "" && versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.41") {
p, err := platforms.Parse(opts.platform)
if err != nil {
return "", errors.Wrap(err, "error parsing specified platform")
return nil, errors.Wrap(err, "error parsing specified platform")
}
platform = &p
}
if opts.pull == PullImageAlways {
if err := pullAndTagImage(); err != nil {
return "", err
return nil, err
}
}
@@ -255,31 +255,31 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
response, err := dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, platform, opts.name)
if err != nil {
// Pull image if it does not exist locally and we have the PullImageMissing option. Default behavior.
if errdefs.IsNotFound(err) && namedRef != nil && opts.pull == PullImageMissing {
if apiclient.IsErrNotFound(err) && namedRef != nil && opts.pull == PullImageMissing {
if !opts.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))
}
if err := pullAndTagImage(); err != nil {
return "", err
return nil, err
}
var retryErr error
response, retryErr = dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, platform, opts.name)
if retryErr != nil {
return "", retryErr
return nil, retryErr
}
} else {
return "", err
return nil, err
}
}
for _, w := range response.Warnings {
_, _ = fmt.Fprintf(dockerCli.Err(), "WARNING: %s\n", w)
fmt.Fprintf(dockerCli.Err(), "WARNING: %s\n", w)
}
err = containerIDFile.Write(response.ID)
return response.ID, err
return &response, err
}
func warnOnOomKillDisable(hostConfig container.HostConfig, stderr io.Writer) {
+49 -54
View File
@@ -18,7 +18,6 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/system"
"github.com/google/go-cmp/cmp"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/pflag"
@@ -80,10 +79,8 @@ func TestCIDFileCloseWithWrite(t *testing.T) {
}
func TestCreateContainerImagePullPolicy(t *testing.T) {
const (
imageName = "does-not-exist-locally"
containerID = "abcdef"
)
imageName := "does-not-exist-locally"
containerID := "abcdef"
config := &containerConfig{
Config: &container.Config{
Image: imageName,
@@ -94,18 +91,18 @@ func TestCreateContainerImagePullPolicy(t *testing.T) {
cases := []struct {
PullPolicy string
ExpectedPulls int
ExpectedID string
ExpectedBody container.CreateResponse
ExpectedErrMsg string
ResponseCounter int
}{
{
PullPolicy: PullImageMissing,
ExpectedPulls: 1,
ExpectedID: containerID,
ExpectedBody: container.CreateResponse{ID: containerID},
}, {
PullPolicy: PullImageAlways,
ExpectedPulls: 1,
ExpectedID: containerID,
ExpectedBody: container.CreateResponse{ID: containerID},
ResponseCounter: 1, // This lets us return a container on the first pull
}, {
PullPolicy: PullImageNever,
@@ -113,52 +110,50 @@ func TestCreateContainerImagePullPolicy(t *testing.T) {
ExpectedErrMsg: "error fake not found",
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.PullPolicy, func(t *testing.T) {
pullCounter := 0
for _, c := range cases {
c := c
pullCounter := 0
client := &fakeClient{
createContainerFunc: func(
config *container.Config,
hostConfig *container.HostConfig,
networkingConfig *network.NetworkingConfig,
platform *specs.Platform,
containerName string,
) (container.CreateResponse, error) {
defer func() { tc.ResponseCounter++ }()
switch tc.ResponseCounter {
case 0:
return container.CreateResponse{}, fakeNotFound{}
default:
return container.CreateResponse{ID: containerID}, nil
}
},
imageCreateFunc: func(parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) {
defer func() { pullCounter++ }()
return io.NopCloser(strings.NewReader("")), nil
},
infoFunc: func() (system.Info, error) {
return system.Info{IndexServerAddress: "https://indexserver.example.com"}, nil
},
}
fakeCLI := test.NewFakeCli(client)
id, err := createContainer(context.Background(), fakeCLI, config, &createOptions{
name: "name",
platform: runtime.GOOS,
untrusted: true,
pull: tc.PullPolicy,
})
if tc.ExpectedErrMsg != "" {
assert.Check(t, is.ErrorContains(err, tc.ExpectedErrMsg))
} else {
assert.Check(t, err)
assert.Check(t, is.Equal(tc.ExpectedID, id))
}
assert.Check(t, is.Equal(tc.ExpectedPulls, pullCounter))
client := &fakeClient{
createContainerFunc: func(
config *container.Config,
hostConfig *container.HostConfig,
networkingConfig *network.NetworkingConfig,
platform *specs.Platform,
containerName string,
) (container.CreateResponse, error) {
defer func() { c.ResponseCounter++ }()
switch c.ResponseCounter {
case 0:
return container.CreateResponse{}, fakeNotFound{}
default:
return container.CreateResponse{ID: containerID}, nil
}
},
imageCreateFunc: func(parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) {
defer func() { pullCounter++ }()
return io.NopCloser(strings.NewReader("")), nil
},
infoFunc: func() (types.Info, error) {
return types.Info{IndexServerAddress: "https://indexserver.example.com"}, nil
},
}
cli := test.NewFakeCli(client)
body, err := createContainer(context.Background(), cli, config, &createOptions{
name: "name",
platform: runtime.GOOS,
untrusted: true,
pull: c.PullPolicy,
})
if c.ExpectedErrMsg != "" {
assert.ErrorContains(t, err, c.ExpectedErrMsg)
} else {
assert.NilError(t, err)
assert.Check(t, is.DeepEqual(c.ExpectedBody, *body))
}
assert.Check(t, is.Equal(c.ExpectedPulls, pullCounter))
}
}
@@ -355,5 +350,5 @@ func TestCreateContainerWithProxyConfig(t *testing.T) {
type fakeNotFound struct{}
func (f fakeNotFound) NotFound() {}
func (f fakeNotFound) Error() string { return "error fake not found" }
func (f fakeNotFound) NotFound() bool { return true }
func (f fakeNotFound) Error() string { return "error fake not found" }
+7 -6
View File
@@ -28,6 +28,7 @@ type ExecOptions struct {
Privileged bool
Env opts.ListOpts
Workdir string
Container string
Command []string
EnvFile opts.ListOpts
}
@@ -43,16 +44,15 @@ func NewExecOptions() ExecOptions {
// NewExecCommand creates a new cobra.Command for `docker exec`
func NewExecCommand(dockerCli command.Cli) *cobra.Command {
options := NewExecOptions()
var container string
cmd := &cobra.Command{
Use: "exec [OPTIONS] CONTAINER COMMAND [ARG...]",
Short: "Execute a command in a running container",
Args: cli.RequiresMinArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
container = args[0]
options.Container = args[0]
options.Command = args[1:]
return RunExec(context.Background(), dockerCli, container, options)
return RunExec(dockerCli, options)
},
ValidArgsFunction: completion.ContainerNames(dockerCli, false, func(container types.Container) bool {
return container.State != "paused"
@@ -96,19 +96,20 @@ func NewExecCommand(dockerCli command.Cli) *cobra.Command {
}
// RunExec executes an `exec` command
func RunExec(ctx context.Context, dockerCli command.Cli, container string, options ExecOptions) error {
func RunExec(dockerCli command.Cli, options ExecOptions) error {
execConfig, err := parseExec(options, dockerCli.ConfigFile())
if err != nil {
return err
}
ctx := context.Background()
client := dockerCli.Client()
// We need to check the tty _before_ we do the ContainerExecCreate, because
// otherwise if we error out we will leak execIDs on the server (and
// there's no easy way to clean those up). But also in order to make "not
// exist" errors take precedence we do a dummy inspect first.
if _, err := client.ContainerInspect(ctx, container); err != nil {
if _, err := client.ContainerInspect(ctx, options.Container); err != nil {
return err
}
if !execConfig.Detach {
@@ -119,7 +120,7 @@ func RunExec(ctx context.Context, dockerCli command.Cli, container string, optio
fillConsoleSize(execConfig, dockerCli)
response, err := client.ContainerExecCreate(ctx, container, *execConfig)
response, err := client.ContainerExecCreate(ctx, options.Container, *execConfig)
if err != nil {
return err
}
+3 -2
View File
@@ -169,7 +169,8 @@ func TestRunExec(t *testing.T) {
{
doc: "successful detach",
options: withDefaultOpts(ExecOptions{
Detach: true,
Container: "thecontainer",
Detach: true,
}),
client: fakeClient{execCreateFunc: execCreateWithID},
},
@@ -194,7 +195,7 @@ func TestRunExec(t *testing.T) {
t.Run(testcase.doc, func(t *testing.T) {
cli := test.NewFakeCli(&testcase.client)
err := RunExec(context.Background(), cli, "thecontainer", testcase.options)
err := RunExec(cli, testcase.options)
if testcase.expectedError != "" {
assert.ErrorContains(t, err, testcase.expectedError)
} else {
+1 -1
View File
@@ -87,7 +87,7 @@ func (h *hijackedIOStreamer) setupInput() (restore func(), err error) {
var restoreOnce sync.Once
restore = func() {
restoreOnce.Do(func() {
_ = restoreTerminal(h.streams, h.inputStream)
restoreTerminal(h.streams, h.inputStream)
})
}
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package container
import (
+3 -3
View File
@@ -11,7 +11,7 @@ import (
flagsHelper "github.com/docker/cli/cli/flags"
"github.com/docker/cli/opts"
"github.com/docker/cli/templates"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -68,8 +68,8 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
return &cmd
}
func buildContainerListOptions(opts *psOptions) (*container.ListOptions, error) {
options := &container.ListOptions{
func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, error) {
options := &types.ContainerListOptions{
All: opts.all,
Limit: opts.last,
Size: opts.size,
+31 -32
View File
@@ -7,10 +7,9 @@ import (
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/builders"
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/golden"
@@ -130,7 +129,7 @@ func TestContainerListErrors(t *testing.T) {
testCases := []struct {
args []string
flags map[string]string
containerListFunc func(container.ListOptions) ([]types.Container, error)
containerListFunc func(types.ContainerListOptions) ([]types.Container, error)
expectedError string
}{
{
@@ -146,7 +145,7 @@ func TestContainerListErrors(t *testing.T) {
expectedError: `wrong number of args for join`,
},
{
containerListFunc: func(_ container.ListOptions) ([]types.Container, error) {
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return nil, fmt.Errorf("error listing containers")
},
expectedError: "error listing containers",
@@ -160,7 +159,7 @@ func TestContainerListErrors(t *testing.T) {
)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
cmd.Flags().Set(key, value)
}
cmd.SetOut(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
@@ -169,13 +168,13 @@ func TestContainerListErrors(t *testing.T) {
func TestContainerListWithoutFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ container.ListOptions) ([]types.Container, error) {
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{
*builders.Container("c1"),
*builders.Container("c2", builders.WithName("foo")),
*builders.Container("c3", builders.WithPort(80, 80, builders.TCP), builders.WithPort(81, 81, builders.TCP), builders.WithPort(82, 82, builders.TCP)),
*builders.Container("c4", builders.WithPort(81, 81, builders.UDP)),
*builders.Container("c5", builders.WithPort(82, 82, builders.IP("8.8.8.8"), builders.TCP)),
*Container("c1"),
*Container("c2", WithName("foo")),
*Container("c3", WithPort(80, 80, TCP), WithPort(81, 81, TCP), WithPort(82, 82, TCP)),
*Container("c4", WithPort(81, 81, UDP)),
*Container("c5", WithPort(82, 82, IP("8.8.8.8"), TCP)),
}, nil
},
})
@@ -186,15 +185,15 @@ func TestContainerListWithoutFormat(t *testing.T) {
func TestContainerListNoTrunc(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ container.ListOptions) ([]types.Container, error) {
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{
*builders.Container("c1"),
*builders.Container("c2", builders.WithName("foo/bar")),
*Container("c1"),
*Container("c2", WithName("foo/bar")),
}, nil
},
})
cmd := newListCommand(cli)
assert.Check(t, cmd.Flags().Set("no-trunc", "true"))
cmd.Flags().Set("no-trunc", "true")
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-without-format-no-trunc.golden")
}
@@ -202,15 +201,15 @@ func TestContainerListNoTrunc(t *testing.T) {
// Test for GitHub issue docker/docker#21772
func TestContainerListNamesMultipleTime(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ container.ListOptions) ([]types.Container, error) {
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{
*builders.Container("c1"),
*builders.Container("c2", builders.WithName("foo/bar")),
*Container("c1"),
*Container("c2", WithName("foo/bar")),
}, nil
},
})
cmd := newListCommand(cli)
assert.Check(t, cmd.Flags().Set("format", "{{.Names}} {{.Names}}"))
cmd.Flags().Set("format", "{{.Names}} {{.Names}}")
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-format-name-name.golden")
}
@@ -218,15 +217,15 @@ func TestContainerListNamesMultipleTime(t *testing.T) {
// Test for GitHub issue docker/docker#30291
func TestContainerListFormatTemplateWithArg(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ container.ListOptions) ([]types.Container, error) {
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{
*builders.Container("c1", builders.WithLabel("some.label", "value")),
*builders.Container("c2", builders.WithName("foo/bar"), builders.WithLabel("foo", "bar")),
*Container("c1", WithLabel("some.label", "value")),
*Container("c2", WithName("foo/bar"), WithLabel("foo", "bar")),
}, nil
},
})
cmd := newListCommand(cli)
assert.Check(t, cmd.Flags().Set("format", `{{.Names}} {{.Label "some.label"}}`))
cmd.Flags().Set("format", `{{.Names}} {{.Label "some.label"}}`)
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-format-with-arg.golden")
}
@@ -269,15 +268,15 @@ func TestContainerListFormatSizeSetsOption(t *testing.T) {
tc := tc
t.Run(tc.doc, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(options container.ListOptions) ([]types.Container, error) {
containerListFunc: func(options types.ContainerListOptions) ([]types.Container, error) {
assert.Check(t, is.Equal(options.Size, tc.sizeExpected))
return []types.Container{}, nil
},
})
cmd := newListCommand(cli)
assert.Check(t, cmd.Flags().Set("format", tc.format))
cmd.Flags().Set("format", tc.format)
if tc.sizeFlag != "" {
assert.Check(t, cmd.Flags().Set("size", tc.sizeFlag))
cmd.Flags().Set("size", tc.sizeFlag)
}
assert.NilError(t, cmd.Execute())
})
@@ -286,10 +285,10 @@ func TestContainerListFormatSizeSetsOption(t *testing.T) {
func TestContainerListWithConfigFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ container.ListOptions) ([]types.Container, error) {
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{
*builders.Container("c1", builders.WithLabel("some.label", "value"), builders.WithSize(10700000)),
*builders.Container("c2", builders.WithName("foo/bar"), builders.WithLabel("foo", "bar"), builders.WithSize(3200000)),
*Container("c1", WithLabel("some.label", "value"), WithSize(10700000)),
*Container("c2", WithName("foo/bar"), WithLabel("foo", "bar"), WithSize(3200000)),
}, nil
},
})
@@ -303,10 +302,10 @@ func TestContainerListWithConfigFormat(t *testing.T) {
func TestContainerListWithFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ container.ListOptions) ([]types.Container, error) {
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{
*builders.Container("c1", builders.WithLabel("some.label", "value")),
*builders.Container("c2", builders.WithName("foo/bar"), builders.WithLabel("foo", "bar")),
*Container("c1", WithLabel("some.label", "value")),
*Container("c2", WithName("foo/bar"), WithLabel("foo", "bar")),
}, nil
},
})
+4 -3
View File
@@ -7,7 +7,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/container"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stdcopy"
"github.com/spf13/cobra"
)
@@ -60,7 +60,7 @@ func runLogs(dockerCli command.Cli, opts *logsOptions) error {
return err
}
responseBody, err := dockerCli.Client().ContainerLogs(ctx, c.ID, container.LogsOptions{
options := types.ContainerLogsOptions{
ShowStdout: true,
ShowStderr: true,
Since: opts.since,
@@ -69,7 +69,8 @@ func runLogs(dockerCli command.Cli, opts *logsOptions) error {
Follow: opts.follow,
Tail: opts.tail,
Details: opts.details,
})
}
responseBody, err := dockerCli.Client().ContainerLogs(ctx, c.ID, options)
if err != nil {
return err
}
+2 -2
View File
@@ -12,8 +12,8 @@ import (
is "gotest.tools/v3/assert/cmp"
)
var logFn = func(expectedOut string) func(string, container.LogsOptions) (io.ReadCloser, error) {
return func(container string, opts container.LogsOptions) (io.ReadCloser, error) {
var logFn = func(expectedOut string) func(string, types.ContainerLogsOptions) (io.ReadCloser, error) {
return func(container string, opts types.ContainerLogsOptions) (io.ReadCloser, error) {
return io.NopCloser(strings.NewReader(expectedOut)), nil
}
}
+109 -164
View File
@@ -13,119 +13,117 @@ import (
"strings"
"time"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/compose/loader"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/container"
mounttypes "github.com/docker/docker/api/types/mount"
networktypes "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
"github.com/docker/go-connections/nat"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
cdi "tags.cncf.io/container-device-interface/pkg/parser"
)
var deviceCgroupRuleRegexp = regexp.MustCompile(`^[acb] ([0-9]+|\*):([0-9]+|\*) [rwm]{1,3}$`)
// containerOptions is a data object with all the options for creating a container
type containerOptions struct {
attach opts.ListOpts
volumes opts.ListOpts
tmpfs opts.ListOpts
mounts opts.MountOpt
blkioWeightDevice opts.WeightdeviceOpt
deviceReadBps opts.ThrottledeviceOpt
deviceWriteBps opts.ThrottledeviceOpt
links opts.ListOpts
aliases opts.ListOpts
linkLocalIPs opts.ListOpts
deviceReadIOps opts.ThrottledeviceOpt
deviceWriteIOps opts.ThrottledeviceOpt
env opts.ListOpts
labels opts.ListOpts
deviceCgroupRules opts.ListOpts
devices opts.ListOpts
gpus opts.GpuOpts
ulimits *opts.UlimitOpt
sysctls *opts.MapOpts
publish opts.ListOpts
expose opts.ListOpts
dns opts.ListOpts
dnsSearch opts.ListOpts
dnsOptions opts.ListOpts
extraHosts opts.ListOpts
volumesFrom opts.ListOpts
envFile opts.ListOpts
capAdd opts.ListOpts
capDrop opts.ListOpts
groupAdd opts.ListOpts
securityOpt opts.ListOpts
storageOpt opts.ListOpts
labelsFile opts.ListOpts
loggingOpts opts.ListOpts
privileged bool
pidMode string
utsMode string
usernsMode string
cgroupnsMode string
publishAll bool
stdin bool
tty bool
oomKillDisable bool
oomScoreAdj int
containerIDFile string
entrypoint string
hostname string
domainname string
memory opts.MemBytes
memoryReservation opts.MemBytes
memorySwap opts.MemSwapBytes
kernelMemory opts.MemBytes
user string
workingDir string
cpuCount int64
cpuShares int64
cpuPercent int64
cpuPeriod int64
cpuRealtimePeriod int64
cpuRealtimeRuntime int64
cpuQuota int64
cpus opts.NanoCPUs
cpusetCpus string
cpusetMems string
blkioWeight uint16
ioMaxBandwidth opts.MemBytes
ioMaxIOps uint64
swappiness int64
netMode opts.NetworkOpt
macAddress string
ipv4Address string
ipv6Address string
ipcMode string
pidsLimit int64
restartPolicy string
readonlyRootfs bool
loggingDriver string
cgroupParent string
volumeDriver string
stopSignal string
stopTimeout int
isolation string
shmSize opts.MemBytes
noHealthcheck bool
healthCmd string
healthInterval time.Duration
healthTimeout time.Duration
healthStartPeriod time.Duration
healthStartInterval time.Duration
healthRetries int
runtime string
autoRemove bool
init bool
annotations *opts.MapOpts
attach opts.ListOpts
volumes opts.ListOpts
tmpfs opts.ListOpts
mounts opts.MountOpt
blkioWeightDevice opts.WeightdeviceOpt
deviceReadBps opts.ThrottledeviceOpt
deviceWriteBps opts.ThrottledeviceOpt
links opts.ListOpts
aliases opts.ListOpts
linkLocalIPs opts.ListOpts
deviceReadIOps opts.ThrottledeviceOpt
deviceWriteIOps opts.ThrottledeviceOpt
env opts.ListOpts
labels opts.ListOpts
deviceCgroupRules opts.ListOpts
devices opts.ListOpts
gpus opts.GpuOpts
ulimits *opts.UlimitOpt
sysctls *opts.MapOpts
publish opts.ListOpts
expose opts.ListOpts
dns opts.ListOpts
dnsSearch opts.ListOpts
dnsOptions opts.ListOpts
extraHosts opts.ListOpts
volumesFrom opts.ListOpts
envFile opts.ListOpts
capAdd opts.ListOpts
capDrop opts.ListOpts
groupAdd opts.ListOpts
securityOpt opts.ListOpts
storageOpt opts.ListOpts
labelsFile opts.ListOpts
loggingOpts opts.ListOpts
privileged bool
pidMode string
utsMode string
usernsMode string
cgroupnsMode string
publishAll bool
stdin bool
tty bool
oomKillDisable bool
oomScoreAdj int
containerIDFile string
entrypoint string
hostname string
domainname string
memory opts.MemBytes
memoryReservation opts.MemBytes
memorySwap opts.MemSwapBytes
kernelMemory opts.MemBytes
user string
workingDir string
cpuCount int64
cpuShares int64
cpuPercent int64
cpuPeriod int64
cpuRealtimePeriod int64
cpuRealtimeRuntime int64
cpuQuota int64
cpus opts.NanoCPUs
cpusetCpus string
cpusetMems string
blkioWeight uint16
ioMaxBandwidth opts.MemBytes
ioMaxIOps uint64
swappiness int64
netMode opts.NetworkOpt
macAddress string
ipv4Address string
ipv6Address string
ipcMode string
pidsLimit int64
restartPolicy string
readonlyRootfs bool
loggingDriver string
cgroupParent string
volumeDriver string
stopSignal string
stopTimeout int
isolation string
shmSize opts.MemBytes
noHealthcheck bool
healthCmd string
healthInterval time.Duration
healthTimeout time.Duration
healthStartPeriod time.Duration
healthRetries int
runtime string
autoRemove bool
init bool
annotations *opts.MapOpts
Image string
Args []string
@@ -185,7 +183,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions {
flags.VarP(&copts.labels, "label", "l", "Set meta data on a container")
flags.Var(&copts.labelsFile, "label-file", "Read in a line delimited file of labels")
flags.BoolVar(&copts.readonlyRootfs, "read-only", false, "Mount the container's root filesystem as read only")
flags.StringVar(&copts.restartPolicy, "restart", string(container.RestartPolicyDisabled), "Restart policy to apply when a container exits")
flags.StringVar(&copts.restartPolicy, "restart", "no", "Restart policy to apply when a container exits")
flags.StringVar(&copts.stopSignal, "stop-signal", "", "Signal to stop the container")
flags.IntVar(&copts.stopTimeout, "stop-timeout", 0, "Timeout (in seconds) to stop a container")
flags.SetAnnotation("stop-timeout", "version", []string{"1.25"})
@@ -252,8 +250,6 @@ func addFlags(flags *pflag.FlagSet) *containerOptions {
flags.DurationVar(&copts.healthTimeout, "health-timeout", 0, "Maximum time to allow one check to run (ms|s|m|h) (default 0s)")
flags.DurationVar(&copts.healthStartPeriod, "health-start-period", 0, "Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s)")
flags.SetAnnotation("health-start-period", "version", []string{"1.29"})
flags.DurationVar(&copts.healthStartInterval, "health-start-interval", 0, "Time between running the check during the start period (ms|s|m|h) (default 0s)")
flags.SetAnnotation("health-start-interval", "version", []string{"1.44"})
flags.BoolVar(&copts.noHealthcheck, "no-healthcheck", false, "Disable any container-specified HEALTHCHECK")
// Resource management
@@ -456,17 +452,12 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
// parsing flags, we haven't yet sent a _ping to the daemon to determine
// what operating system it is.
deviceMappings := []container.DeviceMapping{}
var cdiDeviceNames []string
for _, device := range copts.devices.GetAll() {
var (
validated string
deviceMapping container.DeviceMapping
err error
)
if cdi.IsQualifiedName(device) {
cdiDeviceNames = append(cdiDeviceNames, device)
continue
}
validated, err = validateDevice(device, serverOS)
if err != nil {
return nil, err
@@ -538,8 +529,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
copts.healthInterval != 0 ||
copts.healthTimeout != 0 ||
copts.healthStartPeriod != 0 ||
copts.healthRetries != 0 ||
copts.healthStartInterval != 0
copts.healthRetries != 0
if copts.noHealthcheck {
if haveHealthSettings {
return nil, errors.Errorf("--no-healthcheck conflicts with --health-* options")
@@ -562,29 +552,16 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
if copts.healthStartPeriod < 0 {
return nil, fmt.Errorf("--health-start-period cannot be negative")
}
if copts.healthStartInterval < 0 {
return nil, fmt.Errorf("--health-start-interval cannot be negative")
}
healthConfig = &container.HealthConfig{
Test: probe,
Interval: copts.healthInterval,
Timeout: copts.healthTimeout,
StartPeriod: copts.healthStartPeriod,
StartInterval: copts.healthStartInterval,
Retries: copts.healthRetries,
Test: probe,
Interval: copts.healthInterval,
Timeout: copts.healthTimeout,
StartPeriod: copts.healthStartPeriod,
Retries: copts.healthRetries,
}
}
deviceRequests := copts.gpus.Value()
if len(cdiDeviceNames) > 0 {
cdiDeviceRequest := container.DeviceRequest{
Driver: "cdi",
DeviceIDs: cdiDeviceNames,
}
deviceRequests = append(deviceRequests, cdiDeviceRequest)
}
resources := container.Resources{
CgroupParent: copts.cgroupParent,
Memory: copts.memory.Value(),
@@ -615,7 +592,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
Ulimits: copts.ulimits.GetList(),
DeviceCgroupRules: copts.deviceCgroupRules.GetAll(),
Devices: deviceMappings,
DeviceRequests: deviceRequests,
DeviceRequests: copts.gpus.Value(),
}
config := &container.Config{
@@ -712,12 +689,6 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
return nil, err
}
// Put the endpoint-specific MacAddress of the "main" network attachment into the container Config for backward
// compatibility with older daemons.
if nw, ok := networkingConfig.EndpointsConfig[hostConfig.NetworkMode.NetworkName()]; ok {
config.MacAddress = nw.MacAddress //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
}
return &containerConfig{
Config: config,
HostConfig: hostConfig,
@@ -738,20 +709,6 @@ func parseNetworkOpts(copts *containerOptions) (map[string]*networktypes.Endpoin
hasUserDefined, hasNonUserDefined bool
)
if len(copts.netMode.Value()) == 0 {
n := opts.NetworkAttachmentOpts{
Target: "default",
}
if err := applyContainerOptions(&n, copts); err != nil {
return nil, err
}
ep, err := parseNetworkAttachmentOpt(n)
if err != nil {
return nil, err
}
endpoints["default"] = ep
}
for i, n := range copts.netMode.Value() {
n := n
if container.NetworkMode(n.Target).IsUserDefined() {
@@ -793,7 +750,8 @@ func parseNetworkOpts(copts *containerOptions) (map[string]*networktypes.Endpoin
return endpoints, nil
}
func applyContainerOptions(n *opts.NetworkAttachmentOpts, copts *containerOptions) error { //nolint:gocyclo
func applyContainerOptions(n *opts.NetworkAttachmentOpts, copts *containerOptions) error {
// TODO should copts.MacAddress actually be set on the first network? (currently it's not)
// TODO should we error if _any_ advanced option is used? (i.e. forbid to combine advanced notation with the "old" flags (`--network-alias`, `--link`, `--ip`, `--ip6`)?
if len(n.Aliases) > 0 && copts.aliases.Len() > 0 {
return errdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --network-alias and per-network alias"))
@@ -807,17 +765,11 @@ func applyContainerOptions(n *opts.NetworkAttachmentOpts, copts *containerOption
if n.IPv6Address != "" && copts.ipv6Address != "" {
return errdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --ip6 and per-network IPv6 address"))
}
if n.MacAddress != "" && copts.macAddress != "" {
return errdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --mac-address and per-network MAC address"))
}
if len(n.LinkLocalIPs) > 0 && copts.linkLocalIPs.Len() > 0 {
return errdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --link-local-ip and per-network link-local IP addresses"))
}
if copts.aliases.Len() > 0 {
n.Aliases = make([]string, copts.aliases.Len())
copy(n.Aliases, copts.aliases.GetAll())
}
if n.Target != "default" && copts.links.Len() > 0 {
if copts.links.Len() > 0 {
n.Links = make([]string, copts.links.Len())
copy(n.Links, copts.links.GetAll())
}
@@ -827,9 +779,8 @@ func applyContainerOptions(n *opts.NetworkAttachmentOpts, copts *containerOption
if copts.ipv6Address != "" {
n.IPv6Address = copts.ipv6Address
}
if copts.macAddress != "" {
n.MacAddress = copts.macAddress
}
// TODO should linkLocalIPs be added to the _first_ network only, or to _all_ networks? (should this be a per-network option as well?)
if copts.linkLocalIPs.Len() > 0 {
n.LinkLocalIPs = make([]string, copts.linkLocalIPs.Len())
copy(n.LinkLocalIPs, copts.linkLocalIPs.GetAll())
@@ -866,12 +817,6 @@ func parseNetworkAttachmentOpt(ep opts.NetworkAttachmentOpts) (*networktypes.End
LinkLocalIPs: ep.LinkLocalIPs,
}
}
if ep.MacAddress != "" {
if _, err := opts.ValidateMACAddress(ep.MacAddress); err != nil {
return nil, errors.Errorf("%s is not a valid mac address", ep.MacAddress)
}
epConfig.MacAddress = ep.MacAddress
}
return epConfig, nil
}
@@ -1119,8 +1064,8 @@ func validateAttach(val string) (string, error) {
func validateAPIVersion(c *containerConfig, serverAPIVersion string) error {
for _, m := range c.HostConfig.Mounts {
if err := command.ValidateMountWithAPIVersion(m, serverAPIVersion); err != nil {
return err
if m.BindOptions != nil && m.BindOptions.NonRecursive && versions.LessThan(serverAPIVersion, "1.40") {
return errors.Errorf("bind-nonrecursive requires API v1.40 or later")
}
}
return nil
+108 -245
View File
@@ -64,21 +64,21 @@ func setupRunFlags() (*pflag.FlagSet, *containerOptions) {
return flags, copts
}
func mustParse(t *testing.T, args string) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig) {
func mustParse(t *testing.T, args string) (*container.Config, *container.HostConfig) {
t.Helper()
config, hostConfig, nwConfig, err := parseRun(append(strings.Split(args, " "), "ubuntu", "bash"))
config, hostConfig, _, err := parseRun(append(strings.Split(args, " "), "ubuntu", "bash"))
assert.NilError(t, err)
return config, hostConfig, nwConfig
return config, hostConfig
}
func TestParseRunLinks(t *testing.T) {
if _, hostConfig, _ := mustParse(t, "--link a:b"); len(hostConfig.Links) == 0 || hostConfig.Links[0] != "a:b" {
if _, hostConfig := mustParse(t, "--link a:b"); len(hostConfig.Links) == 0 || hostConfig.Links[0] != "a:b" {
t.Fatalf("Error parsing links. Expected []string{\"a:b\"}, received: %v", hostConfig.Links)
}
if _, hostConfig, _ := mustParse(t, "--link a:b --link c:d"); len(hostConfig.Links) < 2 || hostConfig.Links[0] != "a:b" || hostConfig.Links[1] != "c:d" {
if _, hostConfig := mustParse(t, "--link a:b --link c:d"); len(hostConfig.Links) < 2 || hostConfig.Links[0] != "a:b" || hostConfig.Links[1] != "c:d" {
t.Fatalf("Error parsing links. Expected []string{\"a:b\", \"c:d\"}, received: %v", hostConfig.Links)
}
if _, hostConfig, _ := mustParse(t, ""); len(hostConfig.Links) != 0 {
if _, hostConfig := mustParse(t, ""); len(hostConfig.Links) != 0 {
t.Fatalf("Error parsing links. No link expected, received: %v", hostConfig.Links)
}
}
@@ -128,7 +128,7 @@ func TestParseRunAttach(t *testing.T) {
for _, tc := range tests {
tc := tc
t.Run(tc.input, func(t *testing.T) {
config, _, _ := mustParse(t, tc.input)
config, _ := mustParse(t, tc.input)
assert.Equal(t, config.AttachStdin, tc.expected.AttachStdin)
assert.Equal(t, config.AttachStdout, tc.expected.AttachStdout)
assert.Equal(t, config.AttachStderr, tc.expected.AttachStderr)
@@ -186,7 +186,7 @@ func TestParseRunWithInvalidArgs(t *testing.T) {
func TestParseWithVolumes(t *testing.T) {
// A single volume
arr, tryit := setupPlatformVolume([]string{`/tmp`}, []string{`c:\tmp`})
if config, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds != nil {
if config, hostConfig := mustParse(t, tryit); hostConfig.Binds != nil {
t.Fatalf("Error parsing volume flags, %q should not mount-bind anything. Received %v", tryit, hostConfig.Binds)
} else if _, exists := config.Volumes[arr[0]]; !exists {
t.Fatalf("Error parsing volume flags, %q is missing from volumes. Received %v", tryit, config.Volumes)
@@ -194,7 +194,7 @@ func TestParseWithVolumes(t *testing.T) {
// Two volumes
arr, tryit = setupPlatformVolume([]string{`/tmp`, `/var`}, []string{`c:\tmp`, `c:\var`})
if config, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds != nil {
if config, hostConfig := mustParse(t, tryit); hostConfig.Binds != nil {
t.Fatalf("Error parsing volume flags, %q should not mount-bind anything. Received %v", tryit, hostConfig.Binds)
} else if _, exists := config.Volumes[arr[0]]; !exists {
t.Fatalf("Error parsing volume flags, %s is missing from volumes. Received %v", arr[0], config.Volumes)
@@ -204,13 +204,13 @@ func TestParseWithVolumes(t *testing.T) {
// A single bind mount
arr, tryit = setupPlatformVolume([]string{`/hostTmp:/containerTmp`}, []string{os.Getenv("TEMP") + `:c:\containerTmp`})
if config, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || hostConfig.Binds[0] != arr[0] {
if config, hostConfig := mustParse(t, tryit); hostConfig.Binds == nil || hostConfig.Binds[0] != arr[0] {
t.Fatalf("Error parsing volume flags, %q should mount-bind the path before the colon into the path after the colon. Received %v %v", arr[0], hostConfig.Binds, config.Volumes)
}
// Two bind mounts.
arr, tryit = setupPlatformVolume([]string{`/hostTmp:/containerTmp`, `/hostVar:/containerVar`}, []string{os.Getenv("ProgramData") + `:c:\ContainerPD`, os.Getenv("TEMP") + `:c:\containerTmp`})
if _, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || compareRandomizedStrings(hostConfig.Binds[0], hostConfig.Binds[1], arr[0], arr[1]) != nil {
if _, hostConfig := mustParse(t, tryit); hostConfig.Binds == nil || compareRandomizedStrings(hostConfig.Binds[0], hostConfig.Binds[1], arr[0], arr[1]) != nil {
t.Fatalf("Error parsing volume flags, `%s and %s` did not mount-bind correctly. Received %v", arr[0], arr[1], hostConfig.Binds)
}
@@ -219,26 +219,26 @@ func TestParseWithVolumes(t *testing.T) {
arr, tryit = setupPlatformVolume(
[]string{`/hostTmp:/containerTmp:ro`, `/hostVar:/containerVar:rw`},
[]string{os.Getenv("TEMP") + `:c:\containerTmp:rw`, os.Getenv("ProgramData") + `:c:\ContainerPD:rw`})
if _, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || compareRandomizedStrings(hostConfig.Binds[0], hostConfig.Binds[1], arr[0], arr[1]) != nil {
if _, hostConfig := mustParse(t, tryit); hostConfig.Binds == nil || compareRandomizedStrings(hostConfig.Binds[0], hostConfig.Binds[1], arr[0], arr[1]) != nil {
t.Fatalf("Error parsing volume flags, `%s and %s` did not mount-bind correctly. Received %v", arr[0], arr[1], hostConfig.Binds)
}
// Similar to previous test but with alternate modes which are only supported by Linux
if runtime.GOOS != "windows" {
arr, tryit = setupPlatformVolume([]string{`/hostTmp:/containerTmp:ro,Z`, `/hostVar:/containerVar:rw,Z`}, []string{})
if _, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || compareRandomizedStrings(hostConfig.Binds[0], hostConfig.Binds[1], arr[0], arr[1]) != nil {
if _, hostConfig := mustParse(t, tryit); hostConfig.Binds == nil || compareRandomizedStrings(hostConfig.Binds[0], hostConfig.Binds[1], arr[0], arr[1]) != nil {
t.Fatalf("Error parsing volume flags, `%s and %s` did not mount-bind correctly. Received %v", arr[0], arr[1], hostConfig.Binds)
}
arr, tryit = setupPlatformVolume([]string{`/hostTmp:/containerTmp:Z`, `/hostVar:/containerVar:z`}, []string{})
if _, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || compareRandomizedStrings(hostConfig.Binds[0], hostConfig.Binds[1], arr[0], arr[1]) != nil {
if _, hostConfig := mustParse(t, tryit); hostConfig.Binds == nil || compareRandomizedStrings(hostConfig.Binds[0], hostConfig.Binds[1], arr[0], arr[1]) != nil {
t.Fatalf("Error parsing volume flags, `%s and %s` did not mount-bind correctly. Received %v", arr[0], arr[1], hostConfig.Binds)
}
}
// One bind mount and one volume
arr, tryit = setupPlatformVolume([]string{`/hostTmp:/containerTmp`, `/containerVar`}, []string{os.Getenv("TEMP") + `:c:\containerTmp`, `c:\containerTmp`})
if config, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || len(hostConfig.Binds) > 1 || hostConfig.Binds[0] != arr[0] {
if config, hostConfig := mustParse(t, tryit); hostConfig.Binds == nil || len(hostConfig.Binds) > 1 || hostConfig.Binds[0] != arr[0] {
t.Fatalf("Error parsing volume flags, %s and %s should only one and only one bind mount %s. Received %s", arr[0], arr[1], arr[0], hostConfig.Binds)
} else if _, exists := config.Volumes[arr[1]]; !exists {
t.Fatalf("Error parsing volume flags %s and %s. %s is missing from volumes. Received %v", arr[0], arr[1], arr[1], config.Volumes)
@@ -247,7 +247,7 @@ func TestParseWithVolumes(t *testing.T) {
// Root to non-c: drive letter (Windows specific)
if runtime.GOOS == "windows" {
arr, tryit = setupPlatformVolume([]string{}, []string{os.Getenv("SystemDrive") + `\:d:`})
if config, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || len(hostConfig.Binds) > 1 || hostConfig.Binds[0] != arr[0] || len(config.Volumes) != 0 {
if config, hostConfig := mustParse(t, tryit); hostConfig.Binds == nil || len(hostConfig.Binds) > 1 || hostConfig.Binds[0] != arr[0] || len(config.Volumes) != 0 {
t.Fatalf("Error parsing %s. Should have a single bind mount and no volumes", arr[0])
}
}
@@ -290,14 +290,8 @@ func TestParseWithMacAddress(t *testing.T) {
if _, _, _, err := parseRun([]string{invalidMacAddress, "img", "cmd"}); err != nil && err.Error() != "invalidMacAddress is not a valid mac address" {
t.Fatalf("Expected an error with %v mac-address, got %v", invalidMacAddress, err)
}
config, hostConfig, nwConfig := mustParse(t, validMacAddress)
if config.MacAddress != "92:d0:c6:0a:29:33" { //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
t.Fatalf("Expected the config to have '92:d0:c6:0a:29:33' as container-wide MacAddress, got '%v'",
config.MacAddress) //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
}
defaultNw := hostConfig.NetworkMode.NetworkName()
if nwConfig.EndpointsConfig[defaultNw].MacAddress != "92:d0:c6:0a:29:33" {
t.Fatalf("Expected the default endpoint to have the MacAddress '92:d0:c6:0a:29:33' set, got '%v'", nwConfig.EndpointsConfig[defaultNw].MacAddress)
if config, _ := mustParse(t, validMacAddress); config.MacAddress != "92:d0:c6:0a:29:33" {
t.Fatalf("Expected the config to have '92:d0:c6:0a:29:33' as MacAddress, got '%v'", config.MacAddress)
}
}
@@ -307,7 +301,7 @@ func TestRunFlagsParseWithMemory(t *testing.T) {
err := flags.Parse(args)
assert.ErrorContains(t, err, `invalid argument "invalid" for "-m, --memory" flag`)
_, hostconfig, _ := mustParse(t, "--memory=1G")
_, hostconfig := mustParse(t, "--memory=1G")
assert.Check(t, is.Equal(int64(1073741824), hostconfig.Memory))
}
@@ -317,10 +311,10 @@ func TestParseWithMemorySwap(t *testing.T) {
err := flags.Parse(args)
assert.ErrorContains(t, err, `invalid argument "invalid" for "--memory-swap" flag`)
_, hostconfig, _ := mustParse(t, "--memory-swap=1G")
_, hostconfig := mustParse(t, "--memory-swap=1G")
assert.Check(t, is.Equal(int64(1073741824), hostconfig.MemorySwap))
_, hostconfig, _ = mustParse(t, "--memory-swap=-1")
_, hostconfig = mustParse(t, "--memory-swap=-1")
assert.Check(t, is.Equal(int64(-1), hostconfig.MemorySwap))
}
@@ -335,14 +329,14 @@ func TestParseHostname(t *testing.T) {
hostnameWithDomain := "--hostname=hostname.domainname"
hostnameWithDomainTld := "--hostname=hostname.domainname.tld"
for hostname, expectedHostname := range validHostnames {
if config, _, _ := mustParse(t, fmt.Sprintf("--hostname=%s", hostname)); config.Hostname != expectedHostname {
if config, _ := mustParse(t, fmt.Sprintf("--hostname=%s", hostname)); config.Hostname != expectedHostname {
t.Fatalf("Expected the config to have 'hostname' as %q, got %q", expectedHostname, config.Hostname)
}
}
if config, _, _ := mustParse(t, hostnameWithDomain); config.Hostname != "hostname.domainname" || config.Domainname != "" {
if config, _ := mustParse(t, hostnameWithDomain); config.Hostname != "hostname.domainname" || config.Domainname != "" {
t.Fatalf("Expected the config to have 'hostname' as hostname.domainname, got %q", config.Hostname)
}
if config, _, _ := mustParse(t, hostnameWithDomainTld); config.Hostname != "hostname.domainname.tld" || config.Domainname != "" {
if config, _ := mustParse(t, hostnameWithDomainTld); config.Hostname != "hostname.domainname.tld" || config.Domainname != "" {
t.Fatalf("Expected the config to have 'hostname' as hostname.domainname.tld, got %q", config.Hostname)
}
}
@@ -356,14 +350,14 @@ func TestParseHostnameDomainname(t *testing.T) {
"domainname-63-bytes-long-should-be-valid-and-without-any-errors": "domainname-63-bytes-long-should-be-valid-and-without-any-errors",
}
for domainname, expectedDomainname := range validDomainnames {
if config, _, _ := mustParse(t, "--domainname="+domainname); config.Domainname != expectedDomainname {
if config, _ := mustParse(t, "--domainname="+domainname); config.Domainname != expectedDomainname {
t.Fatalf("Expected the config to have 'domainname' as %q, got %q", expectedDomainname, config.Domainname)
}
}
if config, _, _ := mustParse(t, "--hostname=some.prefix --domainname=domainname"); config.Hostname != "some.prefix" || config.Domainname != "domainname" {
if config, _ := mustParse(t, "--hostname=some.prefix --domainname=domainname"); config.Hostname != "some.prefix" || config.Domainname != "domainname" {
t.Fatalf("Expected the config to have 'hostname' as 'some.prefix' and 'domainname' as 'domainname', got %q and %q", config.Hostname, config.Domainname)
}
if config, _, _ := mustParse(t, "--hostname=another-prefix --domainname=domainname.tld"); config.Hostname != "another-prefix" || config.Domainname != "domainname.tld" {
if config, _ := mustParse(t, "--hostname=another-prefix --domainname=domainname.tld"); config.Hostname != "another-prefix" || config.Domainname != "domainname.tld" {
t.Fatalf("Expected the config to have 'hostname' as 'another-prefix' and 'domainname' as 'domainname.tld', got %q and %q", config.Hostname, config.Domainname)
}
}
@@ -372,8 +366,8 @@ func TestParseWithExpose(t *testing.T) {
invalids := map[string]string{
":": "invalid port format for --expose: :",
"8080:9090": "invalid port format for --expose: 8080:9090",
"/tcp": "invalid range format for --expose: /tcp, error: empty string specified for ports",
"/udp": "invalid range format for --expose: /udp, error: empty string specified for ports",
"/tcp": "invalid range format for --expose: /tcp, error: Empty string specified for ports.",
"/udp": "invalid range format for --expose: /udp, error: Empty string specified for ports.",
"NaN/tcp": `invalid range format for --expose: NaN/tcp, error: strconv.ParseUint: parsing "NaN": invalid syntax`,
"NaN-NaN/tcp": `invalid range format for --expose: NaN-NaN/tcp, error: strconv.ParseUint: parsing "NaN": invalid syntax`,
"8080-NaN/tcp": `invalid range format for --expose: 8080-NaN/tcp, error: strconv.ParseUint: parsing "NaN": invalid syntax`,
@@ -423,114 +417,61 @@ func TestParseWithExpose(t *testing.T) {
func TestParseDevice(t *testing.T) {
skip.If(t, runtime.GOOS != "linux") // Windows and macOS validate server-side
testCases := []struct {
devices []string
deviceMapping *container.DeviceMapping
deviceRequests []container.DeviceRequest
}{
{
devices: []string{"/dev/snd"},
deviceMapping: &container.DeviceMapping{
PathOnHost: "/dev/snd",
PathInContainer: "/dev/snd",
CgroupPermissions: "rwm",
},
valids := map[string]container.DeviceMapping{
"/dev/snd": {
PathOnHost: "/dev/snd",
PathInContainer: "/dev/snd",
CgroupPermissions: "rwm",
},
{
devices: []string{"/dev/snd:rw"},
deviceMapping: &container.DeviceMapping{
PathOnHost: "/dev/snd",
PathInContainer: "/dev/snd",
CgroupPermissions: "rw",
},
"/dev/snd:rw": {
PathOnHost: "/dev/snd",
PathInContainer: "/dev/snd",
CgroupPermissions: "rw",
},
{
devices: []string{"/dev/snd:/something"},
deviceMapping: &container.DeviceMapping{
PathOnHost: "/dev/snd",
PathInContainer: "/something",
CgroupPermissions: "rwm",
},
"/dev/snd:/something": {
PathOnHost: "/dev/snd",
PathInContainer: "/something",
CgroupPermissions: "rwm",
},
{
devices: []string{"/dev/snd:/something:rw"},
deviceMapping: &container.DeviceMapping{
PathOnHost: "/dev/snd",
PathInContainer: "/something",
CgroupPermissions: "rw",
},
},
{
devices: []string{"vendor.com/class=name"},
deviceMapping: nil,
deviceRequests: []container.DeviceRequest{
{
Driver: "cdi",
DeviceIDs: []string{"vendor.com/class=name"},
},
},
},
{
devices: []string{"vendor.com/class=name", "/dev/snd:/something:rw"},
deviceMapping: &container.DeviceMapping{
PathOnHost: "/dev/snd",
PathInContainer: "/something",
CgroupPermissions: "rw",
},
deviceRequests: []container.DeviceRequest{
{
Driver: "cdi",
DeviceIDs: []string{"vendor.com/class=name"},
},
},
"/dev/snd:/something:rw": {
PathOnHost: "/dev/snd",
PathInContainer: "/something",
CgroupPermissions: "rw",
},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("%s", tc.devices), func(t *testing.T) {
var args []string
for _, d := range tc.devices {
args = append(args, fmt.Sprintf("--device=%v", d))
}
args = append(args, "img", "cmd")
_, hostconfig, _, err := parseRun(args)
assert.NilError(t, err)
if tc.deviceMapping != nil {
if assert.Check(t, is.Len(hostconfig.Devices, 1)) {
assert.Check(t, is.DeepEqual(*tc.deviceMapping, hostconfig.Devices[0]))
}
} else {
assert.Check(t, is.Len(hostconfig.Devices, 0))
}
assert.Check(t, is.DeepEqual(tc.deviceRequests, hostconfig.DeviceRequests))
})
for device, deviceMapping := range valids {
_, hostconfig, _, err := parseRun([]string{fmt.Sprintf("--device=%v", device), "img", "cmd"})
if err != nil {
t.Fatal(err)
}
if len(hostconfig.Devices) != 1 {
t.Fatalf("Expected 1 devices, got %v", hostconfig.Devices)
}
if hostconfig.Devices[0] != deviceMapping {
t.Fatalf("Expected %v, got %v", deviceMapping, hostconfig.Devices)
}
}
}
func TestParseNetworkConfig(t *testing.T) {
tests := []struct {
name string
flags []string
expected map[string]*networktypes.EndpointSettings
expectedCfg container.Config
expectedHostCfg container.HostConfig
expectedErr string
name string
flags []string
expected map[string]*networktypes.EndpointSettings
expectedCfg container.HostConfig
expectedErr string
}{
{
name: "single-network-legacy",
flags: []string{"--network", "net1"},
expected: map[string]*networktypes.EndpointSettings{},
expectedHostCfg: container.HostConfig{NetworkMode: "net1"},
name: "single-network-legacy",
flags: []string{"--network", "net1"},
expected: map[string]*networktypes.EndpointSettings{},
expectedCfg: container.HostConfig{NetworkMode: "net1"},
},
{
name: "single-network-advanced",
flags: []string{"--network", "name=net1"},
expected: map[string]*networktypes.EndpointSettings{},
expectedHostCfg: container.HostConfig{NetworkMode: "net1"},
name: "single-network-advanced",
flags: []string{"--network", "name=net1"},
expected: map[string]*networktypes.EndpointSettings{},
expectedCfg: container.HostConfig{NetworkMode: "net1"},
},
{
name: "single-network-legacy-with-options",
@@ -556,7 +497,7 @@ func TestParseNetworkConfig(t *testing.T) {
Aliases: []string{"web1", "web2"},
},
},
expectedHostCfg: container.HostConfig{NetworkMode: "net1"},
expectedCfg: container.HostConfig{NetworkMode: "net1"},
},
{
name: "multiple-network-advanced-mixed",
@@ -572,7 +513,6 @@ func TestParseNetworkConfig(t *testing.T) {
"--network-alias", "web2",
"--network", "net2",
"--network", "name=net3,alias=web3,driver-opt=field3=value3,ip=172.20.88.22,ip6=2001:db8::8822",
"--network", "name=net4,mac-address=02:32:1c:23:00:04,link-local-ip=169.254.169.254",
},
expected: map[string]*networktypes.EndpointSettings{
"net1": {
@@ -594,18 +534,12 @@ func TestParseNetworkConfig(t *testing.T) {
},
Aliases: []string{"web3"},
},
"net4": {
MacAddress: "02:32:1c:23:00:04",
IPAMConfig: &networktypes.EndpointIPAMConfig{
LinkLocalIPs: []string{"169.254.169.254"},
},
},
},
expectedHostCfg: container.HostConfig{NetworkMode: "net1"},
expectedCfg: container.HostConfig{NetworkMode: "net1"},
},
{
name: "single-network-advanced-with-options",
flags: []string{"--network", "name=net1,alias=web1,alias=web2,driver-opt=field1=value1,driver-opt=field2=value2,ip=172.20.88.22,ip6=2001:db8::8822,mac-address=02:32:1c:23:00:04"},
flags: []string{"--network", "name=net1,alias=web1,alias=web2,driver-opt=field1=value1,driver-opt=field2=value2,ip=172.20.88.22,ip6=2001:db8::8822"},
expected: map[string]*networktypes.EndpointSettings{
"net1": {
DriverOpts: map[string]string{
@@ -616,30 +550,16 @@ func TestParseNetworkConfig(t *testing.T) {
IPv4Address: "172.20.88.22",
IPv6Address: "2001:db8::8822",
},
Aliases: []string{"web1", "web2"},
MacAddress: "02:32:1c:23:00:04",
Aliases: []string{"web1", "web2"},
},
},
expectedCfg: container.Config{MacAddress: "02:32:1c:23:00:04"},
expectedHostCfg: container.HostConfig{NetworkMode: "net1"},
expectedCfg: container.HostConfig{NetworkMode: "net1"},
},
{
name: "multiple-networks",
flags: []string{"--network", "net1", "--network", "name=net2"},
expected: map[string]*networktypes.EndpointSettings{"net1": {}, "net2": {}},
expectedHostCfg: container.HostConfig{NetworkMode: "net1"},
},
{
name: "advanced-options-with-standalone-mac-address-flag",
flags: []string{"--network=name=net1,alias=foobar", "--mac-address", "52:0f:f3:dc:50:10"},
expected: map[string]*networktypes.EndpointSettings{
"net1": {
Aliases: []string{"foobar"},
MacAddress: "52:0f:f3:dc:50:10",
},
},
expectedCfg: container.Config{MacAddress: "52:0f:f3:dc:50:10"},
expectedHostCfg: container.HostConfig{NetworkMode: "net1"},
name: "multiple-networks",
flags: []string{"--network", "net1", "--network", "name=net2"},
expected: map[string]*networktypes.EndpointSettings{"net1": {}, "net2": {}},
expectedCfg: container.HostConfig{NetworkMode: "net1"},
},
{
name: "conflict-network",
@@ -666,26 +586,11 @@ func TestParseNetworkConfig(t *testing.T) {
flags: []string{"--network", "name=host", "--network", "net1"},
expectedErr: `conflicting options: cannot attach both user-defined and non-user-defined network-modes`,
},
{
name: "conflict-options-link-local-ip",
flags: []string{"--network", "name=net1,link-local-ip=169.254.169.254", "--link-local-ip", "169.254.10.8"},
expectedErr: `conflicting options: cannot specify both --link-local-ip and per-network link-local IP addresses`,
},
{
name: "conflict-options-mac-address",
flags: []string{"--network", "name=net1,mac-address=02:32:1c:23:00:04", "--mac-address", "02:32:1c:23:00:04"},
expectedErr: `conflicting options: cannot specify both --mac-address and per-network MAC address`,
},
{
name: "invalid-mac-address",
flags: []string{"--network", "name=net1,mac-address=foobar"},
expectedErr: "foobar is not a valid mac address",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
config, hConfig, nwConfig, err := parseRun(tc.flags)
_, hConfig, nwConfig, err := parseRun(tc.flags)
if tc.expectedErr != "" {
assert.Error(t, err, tc.expectedErr)
@@ -693,8 +598,7 @@ func TestParseNetworkConfig(t *testing.T) {
}
assert.NilError(t, err)
assert.DeepEqual(t, config.MacAddress, tc.expectedCfg.MacAddress) //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
assert.DeepEqual(t, hConfig.NetworkMode, tc.expectedHostCfg.NetworkMode)
assert.DeepEqual(t, hConfig.NetworkMode, tc.expectedCfg.NetworkMode)
assert.DeepEqual(t, nwConfig.EndpointsConfig, tc.expected)
})
}
@@ -744,75 +648,34 @@ func TestRunFlagsParseShmSize(t *testing.T) {
}
func TestParseRestartPolicy(t *testing.T) {
tests := []struct {
input string
expected container.RestartPolicy
expectedErr string
}{
{
input: "",
invalids := map[string]string{
"always:2:3": "invalid restart policy format: maximum retry count must be an integer",
"on-failure:invalid": "invalid restart policy format: maximum retry count must be an integer",
}
valids := map[string]container.RestartPolicy{
"": {},
"always": {
Name: "always",
MaximumRetryCount: 0,
},
{
input: "no",
expected: container.RestartPolicy{
Name: container.RestartPolicyDisabled,
},
},
{
input: ":1",
expectedErr: "invalid restart policy format: no policy provided before colon",
},
{
input: "always",
expected: container.RestartPolicy{
Name: container.RestartPolicyAlways,
},
},
{
input: "always:1",
expected: container.RestartPolicy{
Name: container.RestartPolicyAlways,
MaximumRetryCount: 1,
},
},
{
input: "always:2:3",
expectedErr: "invalid restart policy format: maximum retry count must be an integer",
},
{
input: "on-failure:1",
expected: container.RestartPolicy{
Name: container.RestartPolicyOnFailure,
MaximumRetryCount: 1,
},
},
{
input: "on-failure:invalid",
expectedErr: "invalid restart policy format: maximum retry count must be an integer",
},
{
input: "unless-stopped",
expected: container.RestartPolicy{
Name: container.RestartPolicyUnlessStopped,
},
},
{
input: "unless-stopped:invalid",
expectedErr: "invalid restart policy format: maximum retry count must be an integer",
"on-failure:1": {
Name: "on-failure",
MaximumRetryCount: 1,
},
}
for _, tc := range tests {
tc := tc
t.Run(tc.input, func(t *testing.T) {
_, hostConfig, _, err := parseRun([]string{"--restart=" + tc.input, "img", "cmd"})
if tc.expectedErr != "" {
assert.Check(t, is.Error(err, tc.expectedErr))
assert.Check(t, is.Nil(hostConfig))
} else {
assert.NilError(t, err)
assert.Check(t, is.DeepEqual(hostConfig.RestartPolicy, tc.expected))
}
})
for restart, expectedError := range invalids {
if _, _, _, err := parseRun([]string{fmt.Sprintf("--restart=%s", restart), "img", "cmd"}); err == nil || err.Error() != expectedError {
t.Fatalf("Expected an error with message '%v' for %v, got %v", expectedError, restart, err)
}
}
for restart, expected := range valids {
_, hostconfig, _, err := parseRun([]string{fmt.Sprintf("--restart=%v", restart), "img", "cmd"})
if err != nil {
t.Fatal(err)
}
if hostconfig.RestartPolicy != expected {
t.Fatalf("Expected %v, got %v", expected, hostconfig.RestartPolicy)
}
}
}
@@ -857,8 +720,8 @@ func TestParseHealth(t *testing.T) {
checkError("--no-healthcheck conflicts with --health-* options",
"--no-healthcheck", "--health-cmd=/check.sh -q", "img", "cmd")
health = checkOk("--health-timeout=2s", "--health-retries=3", "--health-interval=4.5s", "--health-start-period=5s", "--health-start-interval=1s", "img", "cmd")
if health.Timeout != 2*time.Second || health.Retries != 3 || health.Interval != 4500*time.Millisecond || health.StartPeriod != 5*time.Second || health.StartInterval != 1*time.Second {
health = checkOk("--health-timeout=2s", "--health-retries=3", "--health-interval=4.5s", "--health-start-period=5s", "img", "cmd")
if health.Timeout != 2*time.Second || health.Retries != 3 || health.Interval != 4500*time.Millisecond || health.StartPeriod != 5*time.Second {
t.Fatalf("--health-*: got %#v", health)
}
}
+11 -9
View File
@@ -8,7 +8,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/container"
"github.com/docker/docker/api/types"
"github.com/docker/docker/errdefs"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@@ -52,16 +52,18 @@ func runRm(dockerCli command.Cli, opts *rmOptions) error {
ctx := context.Background()
var errs []string
errChan := parallelOperation(ctx, opts.containers, func(ctx context.Context, ctrID string) error {
ctrID = strings.Trim(ctrID, "/")
if ctrID == "" {
options := types.ContainerRemoveOptions{
RemoveVolumes: opts.rmVolumes,
RemoveLinks: opts.rmLink,
Force: opts.force,
}
errChan := parallelOperation(ctx, opts.containers, func(ctx context.Context, container string) error {
container = strings.Trim(container, "/")
if container == "" {
return errors.New("Container name cannot be empty")
}
return dockerCli.Client().ContainerRemove(ctx, ctrID, container.RemoveOptions{
RemoveVolumes: opts.rmVolumes,
RemoveLinks: opts.rmLink,
Force: opts.force,
})
return dockerCli.Client().ContainerRemove(ctx, container, options)
})
for _, name := range opts.containers {
+2 -2
View File
@@ -9,7 +9,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types"
"github.com/docker/docker/errdefs"
"gotest.tools/v3/assert"
)
@@ -29,7 +29,7 @@ func TestRemoveForce(t *testing.T) {
mutex := new(sync.Mutex)
cli := test.NewFakeCli(&fakeClient{
containerRemoveFunc: func(ctx context.Context, container string, options container.RemoveOptions) error {
containerRemoveFunc: func(ctx context.Context, container string, options types.ContainerRemoveOptions) error {
// containerRemoveFunc is called in parallel for each container
// by the remove command so append must be synchronized.
mutex.Lock()
+24 -22
View File
@@ -12,6 +12,7 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/moby/sys/signal"
"github.com/moby/term"
@@ -100,7 +101,7 @@ func runRun(dockerCli command.Cli, flags *pflag.FlagSet, ropts *runOptions, copt
if v == nil {
newEnv = append(newEnv, k)
} else {
newEnv = append(newEnv, k+"="+*v)
newEnv = append(newEnv, fmt.Sprintf("%s=%s", k, *v))
}
}
copts.env = *opts.NewListOptsRef(&newEnv, nil)
@@ -121,7 +122,7 @@ func runRun(dockerCli command.Cli, flags *pflag.FlagSet, ropts *runOptions, copt
func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptions, containerCfg *containerConfig) error {
config := containerCfg.Config
stdout, stderr := dockerCli.Out(), dockerCli.Err()
apiClient := dockerCli.Client()
client := dockerCli.Client()
config.ArgsEscaped = false
@@ -143,14 +144,14 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio
ctx, cancelFun := context.WithCancel(context.Background())
defer cancelFun()
containerID, err := createContainer(ctx, dockerCli, containerCfg, &opts.createOptions)
createResponse, err := createContainer(ctx, dockerCli, containerCfg, &opts.createOptions)
if err != nil {
reportError(stderr, "run", err.Error(), true)
return runStartContainerErr(err)
}
if opts.sigProxy {
sigc := notifyAllSignals()
go ForwardAllSignals(ctx, apiClient, containerID, sigc)
go ForwardAllSignals(ctx, dockerCli, createResponse.ID, sigc)
defer signal.StopCatch(sigc)
}
@@ -163,33 +164,26 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio
waitDisplayID = make(chan struct{})
go func() {
defer close(waitDisplayID)
_, _ = fmt.Fprintln(stdout, containerID)
fmt.Fprintln(stdout, createResponse.ID)
}()
}
attach := config.AttachStdin || config.AttachStdout || config.AttachStderr
if attach {
detachKeys := dockerCli.ConfigFile().DetachKeys
if opts.detachKeys != "" {
detachKeys = opts.detachKeys
dockerCli.ConfigFile().DetachKeys = opts.detachKeys
}
closeFn, err := attachContainer(ctx, dockerCli, containerID, &errCh, config, container.AttachOptions{
Stream: true,
Stdin: config.AttachStdin,
Stdout: config.AttachStdout,
Stderr: config.AttachStderr,
DetachKeys: detachKeys,
})
closeFn, err := attachContainer(ctx, dockerCli, &errCh, config, createResponse.ID)
if err != nil {
return err
}
defer closeFn()
}
statusChan := waitExitOrRemoved(ctx, apiClient, containerID, copts.autoRemove)
statusChan := waitExitOrRemoved(ctx, dockerCli, createResponse.ID, copts.autoRemove)
// start the container
if err := apiClient.ContainerStart(ctx, containerID, container.StartOptions{}); err != nil {
if err := client.ContainerStart(ctx, createResponse.ID, types.ContainerStartOptions{}); err != nil {
// If we have hijackedIOStreamer, we should notify
// hijackedIOStreamer we are going to exit and wait
// to avoid the terminal are not restored.
@@ -207,8 +201,8 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio
}
if (config.AttachStdin || config.AttachStdout || config.AttachStderr) && config.Tty && dockerCli.Out().IsTerminal() {
if err := MonitorTtySize(ctx, dockerCli, containerID, false); err != nil {
_, _ = fmt.Fprintln(stderr, "Error monitoring TTY size:", err)
if err := MonitorTtySize(ctx, dockerCli, createResponse.ID, false); err != nil {
fmt.Fprintln(stderr, "Error monitoring TTY size:", err)
}
}
@@ -238,7 +232,15 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio
return nil
}
func attachContainer(ctx context.Context, dockerCli command.Cli, containerID string, errCh *chan error, config *container.Config, options container.AttachOptions) (func(), error) {
func attachContainer(ctx context.Context, dockerCli command.Cli, errCh *chan error, config *container.Config, containerID string) (func(), error) {
options := types.ContainerAttachOptions{
Stream: true,
Stdin: config.AttachStdin,
Stdout: config.AttachStdout,
Stderr: config.AttachStderr,
DetachKeys: dockerCli.ConfigFile().DetachKeys,
}
resp, errAttach := dockerCli.Client().ContainerAttach(ctx, containerID, options)
if errAttach != nil {
return nil, errAttach
@@ -248,13 +250,13 @@ func attachContainer(ctx context.Context, dockerCli command.Cli, containerID str
out, cerr io.Writer
in io.ReadCloser
)
if options.Stdin {
if config.AttachStdin {
in = dockerCli.In()
}
if options.Stdout {
if config.AttachStdout {
out = dockerCli.Out()
}
if options.Stderr {
if config.AttachStderr {
if config.Tty {
cerr = dockerCli.Out()
} else {
+3 -3
View File
@@ -5,7 +5,7 @@ import (
"os"
gosignal "os/signal"
"github.com/docker/docker/client"
"github.com/docker/cli/cli/command"
"github.com/moby/sys/signal"
"github.com/sirupsen/logrus"
)
@@ -13,7 +13,7 @@ import (
// ForwardAllSignals forwards signals to the container
//
// The channel you pass in must already be setup to receive any signals you want to forward.
func ForwardAllSignals(ctx context.Context, apiClient client.ContainerAPIClient, cid string, sigc <-chan os.Signal) {
func ForwardAllSignals(ctx context.Context, cli command.Cli, cid string, sigc <-chan os.Signal) {
var (
s os.Signal
ok bool
@@ -48,7 +48,7 @@ func ForwardAllSignals(ctx context.Context, apiClient client.ContainerAPIClient,
continue
}
if err := apiClient.ContainerKill(ctx, cid, sig); err != nil {
if err := cli.Client().ContainerKill(ctx, cid, sig); err != nil {
logrus.Debugf("Error sending signal: %s", err)
}
}
+4 -2
View File
@@ -6,6 +6,7 @@ import (
"testing"
"time"
"github.com/docker/cli/internal/test"
"github.com/moby/sys/signal"
)
@@ -14,15 +15,16 @@ func TestForwardSignals(t *testing.T) {
defer cancel()
called := make(chan struct{})
apiClient := &fakeClient{containerKillFunc: func(ctx context.Context, container, signal string) error {
client := &fakeClient{containerKillFunc: func(ctx context.Context, container, signal string) error {
close(called)
return nil
}}
cli := test.NewFakeCli(client)
sigc := make(chan os.Signal)
defer close(sigc)
go ForwardAllSignals(ctx, apiClient, t.Name(), sigc)
go ForwardAllSignals(ctx, cli, t.Name(), sigc)
timer := time.NewTimer(30 * time.Second)
defer timer.Stop()
+1
View File
@@ -1,4 +1,5 @@
//go:build !windows
// +build !windows
package container
+5 -2
View File
@@ -1,4 +1,5 @@
//go:build !windows
// +build !windows
package container
@@ -9,6 +10,7 @@ import (
"testing"
"time"
"github.com/docker/cli/internal/test"
"golang.org/x/sys/unix"
"gotest.tools/v3/assert"
)
@@ -22,17 +24,18 @@ func TestIgnoredSignals(t *testing.T) {
defer cancel()
var called bool
apiClient := &fakeClient{containerKillFunc: func(ctx context.Context, container, signal string) error {
client := &fakeClient{containerKillFunc: func(ctx context.Context, container, signal string) error {
called = true
return nil
}}
cli := test.NewFakeCli(client)
sigc := make(chan os.Signal)
defer close(sigc)
done := make(chan struct{})
go func() {
ForwardAllSignals(ctx, apiClient, t.Name(), sigc)
ForwardAllSignals(ctx, cli, t.Name(), sigc)
close(done)
}()
+21 -24
View File
@@ -10,7 +10,6 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/moby/sys/signal"
"github.com/moby/term"
"github.com/pkg/errors"
@@ -28,9 +27,7 @@ type StartOptions struct {
Containers []string
}
// NewStartOptions creates a new StartOptions.
//
// Deprecated: create a new [StartOptions] directly.
// NewStartOptions creates a new StartOptions
func NewStartOptions() StartOptions {
return StartOptions{}
}
@@ -84,8 +81,8 @@ func RunStart(dockerCli command.Cli, opts *StartOptions) error {
}
// 2. Attach to the container.
ctr := opts.Containers[0]
c, err := dockerCli.Client().ContainerInspect(ctx, ctr)
container := opts.Containers[0]
c, err := dockerCli.Client().ContainerInspect(ctx, container)
if err != nil {
return err
}
@@ -93,21 +90,20 @@ func RunStart(dockerCli command.Cli, opts *StartOptions) error {
// We always use c.ID instead of container to maintain consistency during `docker start`
if !c.Config.Tty {
sigc := notifyAllSignals()
go ForwardAllSignals(ctx, dockerCli.Client(), c.ID, sigc)
go ForwardAllSignals(ctx, dockerCli, c.ID, sigc)
defer signal.StopCatch(sigc)
}
detachKeys := dockerCli.ConfigFile().DetachKeys
if opts.DetachKeys != "" {
detachKeys = opts.DetachKeys
dockerCli.ConfigFile().DetachKeys = opts.DetachKeys
}
options := container.AttachOptions{
options := types.ContainerAttachOptions{
Stream: true,
Stdin: opts.OpenStdin && c.Config.OpenStdin,
Stdout: true,
Stderr: true,
DetachKeys: detachKeys,
DetachKeys: dockerCli.ConfigFile().DetachKeys,
}
var in io.ReadCloser
@@ -146,14 +142,14 @@ func RunStart(dockerCli command.Cli, opts *StartOptions) error {
// 3. We should open a channel for receiving status code of the container
// no matter it's detached, removed on daemon side(--rm) or exit normally.
statusChan := waitExitOrRemoved(ctx, dockerCli.Client(), c.ID, c.HostConfig.AutoRemove)
// 4. Start the container.
err = dockerCli.Client().ContainerStart(ctx, c.ID, container.StartOptions{
statusChan := waitExitOrRemoved(ctx, dockerCli, c.ID, c.HostConfig.AutoRemove)
startOptions := types.ContainerStartOptions{
CheckpointID: opts.Checkpoint,
CheckpointDir: opts.CheckpointDir,
})
if err != nil {
}
// 4. Start the container.
if err := dockerCli.Client().ContainerStart(ctx, c.ID, startOptions); err != nil {
cancelFun()
<-cErr
if c.HostConfig.AutoRemove {
@@ -184,11 +180,12 @@ func RunStart(dockerCli command.Cli, opts *StartOptions) error {
if len(opts.Containers) > 1 {
return errors.New("you cannot restore multiple containers at once")
}
ctr := opts.Containers[0]
return dockerCli.Client().ContainerStart(ctx, ctr, container.StartOptions{
container := opts.Containers[0]
startOptions := types.ContainerStartOptions{
CheckpointID: opts.Checkpoint,
CheckpointDir: opts.CheckpointDir,
})
}
return dockerCli.Client().ContainerStart(ctx, container, startOptions)
} else {
// We're not going to attach to anything.
@@ -201,13 +198,13 @@ func RunStart(dockerCli command.Cli, opts *StartOptions) error {
func startContainersWithoutAttachments(ctx context.Context, dockerCli command.Cli, containers []string) error {
var failedContainers []string
for _, ctr := range containers {
if err := dockerCli.Client().ContainerStart(ctx, ctr, container.StartOptions{}); err != nil {
for _, container := range containers {
if err := dockerCli.Client().ContainerStart(ctx, container, types.ContainerStartOptions{}); err != nil {
fmt.Fprintln(dockerCli.Err(), err)
failedContainers = append(failedContainers, ctr)
failedContainers = append(failedContainers, container)
continue
}
fmt.Fprintln(dockerCli.Out(), ctr)
fmt.Fprintln(dockerCli.Out(), container)
}
if len(failedContainers) > 0 {
+9 -10
View File
@@ -14,7 +14,6 @@ import (
"github.com/docker/cli/cli/command/formatter"
flagsHelper "github.com/docker/cli/cli/flags"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
"github.com/pkg/errors"
@@ -111,15 +110,15 @@ func runStats(dockerCli command.Cli, opts *statsOptions) error {
// getContainerList simulates creation event for all previously existing
// containers (only used when calling `docker stats` without arguments).
getContainerList := func() {
options := container.ListOptions{
options := types.ContainerListOptions{
All: opts.all,
}
cs, err := dockerCli.Client().ContainerList(ctx, options)
if err != nil {
closeChan <- err
}
for _, ctr := range cs {
s := NewStats(ctr.ID[:12])
for _, container := range cs {
s := NewStats(container.ID[:12])
if cStats.add(s) {
waitFirst.Add(1)
go collect(ctx, s, dockerCli.Client(), !opts.noStream, waitFirst)
@@ -134,9 +133,9 @@ func runStats(dockerCli command.Cli, opts *statsOptions) error {
// would "miss" a creation.
started := make(chan struct{})
eh := command.InitEventHandler()
eh.Handle(events.ActionCreate, func(e events.Message) {
eh.Handle("create", func(e events.Message) {
if opts.all {
s := NewStats(e.Actor.ID[:12])
s := NewStats(e.ID[:12])
if cStats.add(s) {
waitFirst.Add(1)
go collect(ctx, s, dockerCli.Client(), !opts.noStream, waitFirst)
@@ -144,17 +143,17 @@ func runStats(dockerCli command.Cli, opts *statsOptions) error {
}
})
eh.Handle(events.ActionStart, func(e events.Message) {
s := NewStats(e.Actor.ID[:12])
eh.Handle("start", func(e events.Message) {
s := NewStats(e.ID[:12])
if cStats.add(s) {
waitFirst.Add(1)
go collect(ctx, s, dockerCli.Client(), !opts.noStream, waitFirst)
}
})
eh.Handle(events.ActionDie, func(e events.Message) {
eh.Handle("die", func(e events.Message) {
if !opts.all {
cStats.remove(e.Actor.ID[:12])
cStats.remove(e.ID[:12])
}
})
+2 -2
View File
@@ -9,7 +9,7 @@ import (
"time"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/moby/sys/signal"
"github.com/sirupsen/logrus"
@@ -21,7 +21,7 @@ func resizeTtyTo(ctx context.Context, client client.ContainerAPIClient, id strin
return nil
}
options := container.ResizeOptions{
options := types.ResizeOptions{
Height: height,
Width: width,
}
+2 -2
View File
@@ -7,7 +7,7 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -15,7 +15,7 @@ import (
func TestInitTtySizeErrors(t *testing.T) {
expectedError := "failed to resize tty, using default size\n"
fakeContainerExecResizeFunc := func(id string, options container.ResizeOptions) error {
fakeContainerExecResizeFunc := func(id string, options types.ResizeOptions) error {
return errors.Errorf("Error response from daemon: no such exec")
}
fakeResizeTtyFunc := func(ctx context.Context, cli command.Cli, id string, isExec bool) error {
+9 -9
View File
@@ -4,16 +4,16 @@ import (
"context"
"strconv"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/client"
"github.com/sirupsen/logrus"
)
func waitExitOrRemoved(ctx context.Context, apiClient client.APIClient, containerID string, waitRemove bool) <-chan int {
func waitExitOrRemoved(ctx context.Context, dockerCli command.Cli, containerID string, waitRemove bool) <-chan int {
if len(containerID) == 0 {
// containerID can never be empty
panic("Internal Error: waitExitOrRemoved needs a containerID as parameter")
@@ -22,8 +22,8 @@ func waitExitOrRemoved(ctx context.Context, apiClient client.APIClient, containe
// Older versions used the Events API, and even older versions did not
// support server-side removal. This legacyWaitExitOrRemoved method
// preserves that old behavior and any issues it may have.
if versions.LessThan(apiClient.ClientVersion(), "1.30") {
return legacyWaitExitOrRemoved(ctx, apiClient, containerID, waitRemove)
if versions.LessThan(dockerCli.Client().ClientVersion(), "1.30") {
return legacyWaitExitOrRemoved(ctx, dockerCli, containerID, waitRemove)
}
condition := container.WaitConditionNextExit
@@ -31,7 +31,7 @@ func waitExitOrRemoved(ctx context.Context, apiClient client.APIClient, containe
condition = container.WaitConditionRemoved
}
resultC, errC := apiClient.ContainerWait(ctx, containerID, condition)
resultC, errC := dockerCli.Client().ContainerWait(ctx, containerID, condition)
statusC := make(chan int)
go func() {
@@ -52,7 +52,7 @@ func waitExitOrRemoved(ctx context.Context, apiClient client.APIClient, containe
return statusC
}
func legacyWaitExitOrRemoved(ctx context.Context, apiClient client.APIClient, containerID string, waitRemove bool) <-chan int {
func legacyWaitExitOrRemoved(ctx context.Context, dockerCli command.Cli, containerID string, waitRemove bool) <-chan int {
var removeErr error
statusChan := make(chan int)
exitCode := 125
@@ -65,7 +65,7 @@ func legacyWaitExitOrRemoved(ctx context.Context, apiClient client.APIClient, co
Filters: f,
}
eventCtx, cancel := context.WithCancel(ctx)
eventq, errq := apiClient.Events(eventCtx, options)
eventq, errq := dockerCli.Client().Events(eventCtx, options)
eventProcessor := func(e events.Message) bool {
stopProcessing := false
@@ -84,9 +84,9 @@ func legacyWaitExitOrRemoved(ctx context.Context, apiClient client.APIClient, co
} else {
// If we are talking to an older daemon, `AutoRemove` is not supported.
// We need to fall back to the old behavior, which is client-side removal
if versions.LessThan(apiClient.ClientVersion(), "1.25") {
if versions.LessThan(dockerCli.Client().ClientVersion(), "1.25") {
go func() {
removeErr = apiClient.ContainerRemove(ctx, containerID, container.RemoveOptions{RemoveVolumes: true})
removeErr = dockerCli.Client().ContainerRemove(ctx, containerID, types.ContainerRemoveOptions{RemoveVolumes: true})
if removeErr != nil {
logrus.Errorf("error removing container: %v", removeErr)
cancel() // cancel the event Q
+4 -3
View File
@@ -2,12 +2,13 @@ package container
import (
"context"
"fmt"
"strings"
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api"
"github.com/docker/docker/api/types/container"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@@ -23,7 +24,7 @@ func waitFn(cid string) (<-chan container.WaitResponse, <-chan error) {
res.StatusCode = 42
resC <- res
case strings.Contains(cid, "non-existent"):
err := fmt.Errorf("no such container: %v", cid)
err := errors.Errorf("no such container: %v", cid)
errC <- err
case strings.Contains(cid, "wait-error"):
res.Error = &container.WaitExitError{Message: "removal failed"}
@@ -60,7 +61,7 @@ func TestWaitExitOrRemoved(t *testing.T) {
},
}
client := &fakeClient{waitFunc: waitFn, Version: api.DefaultVersion}
client := test.NewFakeCli(&fakeClient{waitFunc: waitFn, Version: api.DefaultVersion})
for _, testcase := range testcases {
statusC := waitExitOrRemoved(context.Background(), client, testcase.cid, true)
exitCode := <-statusC
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package command
import (
+19 -5
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package context
import (
@@ -51,7 +54,18 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command {
}
flags := cmd.Flags()
flags.StringVar(&opts.Description, "description", "", "Description of the context")
flags.String(
"default-stack-orchestrator", "",
`Default orchestrator for stack operations to use with this context ("swarm", "kubernetes", "all")`,
)
flags.SetAnnotation("default-stack-orchestrator", "deprecated", nil)
flags.SetAnnotation("default-stack-orchestrator", "deprecated", nil)
flags.MarkDeprecated("default-stack-orchestrator", "option will be ignored")
flags.StringToStringVar(&opts.Docker, "docker", nil, "set the docker endpoint")
flags.StringToString("kubernetes", nil, "set the kubernetes endpoint")
flags.SetAnnotation("kubernetes", "kubernetes", nil)
flags.SetAnnotation("kubernetes", "deprecated", nil)
flags.MarkDeprecated("kubernetes", "option will be ignored")
flags.StringVar(&opts.From, "from", "", "create context from a named context")
return cmd
}
@@ -69,7 +83,7 @@ func RunCreate(cli command.Cli, o *CreateOptions) error {
case o.From != "":
err = createFromExistingContext(s, o.From, o)
default:
err = createNewContext(s, o)
err = createNewContext(o, cli, s)
}
if err == nil {
fmt.Fprintln(cli.Out(), o.Name)
@@ -78,11 +92,11 @@ func RunCreate(cli command.Cli, o *CreateOptions) error {
return err
}
func createNewContext(contextStore store.ReaderWriter, o *CreateOptions) error {
func createNewContext(o *CreateOptions, cli command.Cli, s store.Writer) error {
if o.Docker == nil {
return errors.New("docker endpoint configuration is required")
}
dockerEP, dockerTLS, err := getDockerEndpointMetadataAndTLS(contextStore, o.Docker)
dockerEP, dockerTLS, err := getDockerEndpointMetadataAndTLS(cli, o.Docker)
if err != nil {
return errors.Wrap(err, "unable to create docker endpoint config")
}
@@ -104,10 +118,10 @@ func createNewContext(contextStore store.ReaderWriter, o *CreateOptions) error {
if err := validateEndpoints(contextMetadata); err != nil {
return err
}
if err := contextStore.CreateOrUpdate(contextMetadata); err != nil {
if err := s.CreateOrUpdate(contextMetadata); err != nil {
return err
}
return contextStore.ResetTLSMaterial(o.Name, &contextTLSData)
return s.ResetTLSMaterial(o.Name, &contextTLSData)
}
func checkContextNameForCreation(s store.Reader, name string) error {
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package context
import (
+10 -4
View File
@@ -19,14 +19,13 @@ type ExportOptions struct {
}
func newExportCommand(dockerCli command.Cli) *cobra.Command {
return &cobra.Command{
opts := &ExportOptions{}
cmd := &cobra.Command{
Use: "export [OPTIONS] CONTEXT [FILE|-]",
Short: "Export a context to a tar archive FILE or a tar stream on STDOUT.",
Args: cli.RequiresRangeArgs(1, 2),
RunE: func(cmd *cobra.Command, args []string) error {
opts := &ExportOptions{
ContextName: args[0],
}
opts.ContextName = args[0]
if len(args) == 2 {
opts.Dest = args[1]
} else {
@@ -35,6 +34,13 @@ func newExportCommand(dockerCli command.Cli) *cobra.Command {
return RunExport(dockerCli, opts)
},
}
flags := cmd.Flags()
flags.Bool("kubeconfig", false, "Export as a kubeconfig file")
flags.MarkDeprecated("kubeconfig", "option will be ignored")
flags.SetAnnotation("kubeconfig", "kubernetes", nil)
flags.SetAnnotation("kubeconfig", "deprecated", nil)
return cmd
}
func writeTo(dockerCli command.Cli, reader io.Reader, dest string) error {
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package context
import (
+5 -4
View File
@@ -5,6 +5,7 @@ import (
"strconv"
"strings"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/context"
"github.com/docker/cli/cli/context/docker"
"github.com/docker/cli/cli/context/store"
@@ -85,12 +86,12 @@ func validateConfig(config map[string]string, allowedKeys map[string]struct{}) e
return errors.New(strings.Join(errs, "\n"))
}
func getDockerEndpoint(contextStore store.Reader, config map[string]string) (docker.Endpoint, error) {
func getDockerEndpoint(dockerCli command.Cli, config map[string]string) (docker.Endpoint, error) {
if err := validateConfig(config, allowedDockerConfigKeys); err != nil {
return docker.Endpoint{}, err
}
if contextName, ok := config[keyFrom]; ok {
metadata, err := contextStore.GetMetadata(contextName)
metadata, err := dockerCli.ContextStore().GetMetadata(contextName)
if err != nil {
return docker.Endpoint{}, err
}
@@ -125,8 +126,8 @@ func getDockerEndpoint(contextStore store.Reader, config map[string]string) (doc
return ep, nil
}
func getDockerEndpointMetadataAndTLS(contextStore store.Reader, config map[string]string) (docker.EndpointMeta, *store.EndpointTLSData, error) {
ep, err := getDockerEndpoint(contextStore, config)
func getDockerEndpointMetadataAndTLS(dockerCli command.Cli, config map[string]string) (docker.EndpointMeta, *store.EndpointTLSData, error) {
ep, err := getDockerEndpoint(dockerCli, config)
if err != nil {
return docker.EndpointMeta{}, nil, err
}
+11 -1
View File
@@ -47,7 +47,17 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command {
}
flags := cmd.Flags()
flags.StringVar(&opts.Description, "description", "", "Description of the context")
flags.String(
"default-stack-orchestrator", "",
"Default orchestrator for stack operations to use with this context (swarm|kubernetes|all)",
)
flags.SetAnnotation("default-stack-orchestrator", "deprecated", nil)
flags.MarkDeprecated("default-stack-orchestrator", "option will be ignored")
flags.StringToStringVar(&opts.Docker, "docker", nil, "set the docker endpoint")
flags.StringToString("kubernetes", nil, "set the kubernetes endpoint")
flags.SetAnnotation("kubernetes", "kubernetes", nil)
flags.SetAnnotation("kubernetes", "deprecated", nil)
flags.MarkDeprecated("kubernetes", "option will be ignored")
return cmd
}
@@ -74,7 +84,7 @@ func RunUpdate(cli command.Cli, o *UpdateOptions) error {
tlsDataToReset := make(map[string]*store.EndpointTLSData)
if o.Docker != nil {
dockerEP, dockerTLS, err := getDockerEndpointMetadataAndTLS(s, o.Docker)
dockerEP, dockerTLS, err := getDockerEndpointMetadataAndTLS(cli, o.Docker)
if err != nil {
return errors.Wrap(err, "unable to create docker endpoint config")
}
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package command
import (
+3 -6
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package command
import (
@@ -11,12 +14,6 @@ import (
const (
// DefaultContextName is the name reserved for the default context (config & env based)
DefaultContextName = "default"
// EnvOverrideContext is the name of the environment variable that can be
// used to override the context to use. If set, it overrides the context
// that's set in the CLI's configuration file, but takes no effect if the
// "DOCKER_HOST" env-var is set (which takes precedence.
EnvOverrideContext = "DOCKER_CONTEXT"
)
// DefaultContext contains the default context data for all endpoints
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package command
import (
+4 -4
View File
@@ -10,21 +10,21 @@ import (
// EventHandler is abstract interface for user to customize
// own handle functions of each type of events
type EventHandler interface {
Handle(action events.Action, h func(events.Message))
Handle(action string, h func(events.Message))
Watch(c <-chan events.Message)
}
// InitEventHandler initializes and returns an EventHandler
func InitEventHandler() EventHandler {
return &eventHandler{handlers: make(map[events.Action]func(events.Message))}
return &eventHandler{handlers: make(map[string]func(events.Message))}
}
type eventHandler struct {
handlers map[events.Action]func(events.Message)
handlers map[string]func(events.Message)
mu sync.Mutex
}
func (w *eventHandler) Handle(action events.Action, h func(events.Message)) {
func (w *eventHandler) Handle(action string, h func(events.Message)) {
w.mu.Lock()
w.handlers[action] = h
w.mu.Unlock()
+5 -2
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package formatter
import (
@@ -7,7 +10,7 @@ import (
"strings"
"time"
"github.com/distribution/reference"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/go-units"
@@ -247,7 +250,7 @@ func (c *ContainerContext) Labels() string {
var joinLabels []string
for k, v := range c.c.Labels {
joinLabels = append(joinLabels, k+"="+v)
joinLabels = append(joinLabels, fmt.Sprintf("%s=%s", k, v))
}
return strings.Join(joinLabels, ",")
}
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package formatter
import (
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package formatter
import "strings"
+3 -4
View File
@@ -7,9 +7,8 @@ import (
"strings"
"text/template"
"github.com/distribution/reference"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/volume"
units "github.com/docker/go-units"
)
@@ -35,7 +34,7 @@ type DiskUsageContext struct {
Context
Verbose bool
LayersSize int64
Images []*image.Summary
Images []*types.ImageSummary
Containers []*types.Container
Volumes []*volume.Volume
BuildCache []*types.BuildCache
@@ -262,7 +261,7 @@ func (ctx *DiskUsageContext) verboseWriteTable(duc *diskUsageContext) error {
type diskUsageImagesContext struct {
HeaderContext
totalSize int64
images []*image.Summary
images []*types.ImageSummary
}
func (c *diskUsageImagesContext) MarshalJSON() ([]byte, error) {
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package formatter
import (
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package formatter
import (
+10 -9
View File
@@ -4,8 +4,8 @@ import (
"fmt"
"time"
"github.com/distribution/reference"
"github.com/docker/docker/api/types/image"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stringid"
units "github.com/docker/go-units"
)
@@ -26,7 +26,7 @@ type ImageContext struct {
Digest bool
}
func isDangling(image image.Summary) bool {
func isDangling(image types.ImageSummary) bool {
if len(image.RepoTags) == 0 && len(image.RepoDigests) == 0 {
return true
}
@@ -75,7 +75,7 @@ virtual_size: {{.Size}}
}
// ImageWrite writes the formatter images using the ImageContext
func ImageWrite(ctx ImageContext, images []image.Summary) error {
func ImageWrite(ctx ImageContext, images []types.ImageSummary) error {
render := func(format func(subContext SubContext) error) error {
return imageFormat(ctx, images, format)
}
@@ -87,7 +87,7 @@ func needDigest(ctx ImageContext) bool {
return ctx.Digest || ctx.Format.Contains("{{.Digest}}")
}
func imageFormat(ctx ImageContext, images []image.Summary, format func(subContext SubContext) error) error {
func imageFormat(ctx ImageContext, images []types.ImageSummary, format func(subContext SubContext) error) error {
for _, image := range images {
formatted := []*imageContext{}
if isDangling(image) {
@@ -110,7 +110,7 @@ func imageFormat(ctx ImageContext, images []image.Summary, format func(subContex
return nil
}
func imageFormatTaggedAndDigest(ctx ImageContext, image image.Summary) []*imageContext {
func imageFormatTaggedAndDigest(ctx ImageContext, image types.ImageSummary) []*imageContext {
repoTags := map[string][]string{}
repoDigests := map[string][]string{}
images := []*imageContext{}
@@ -137,13 +137,14 @@ func imageFormatTaggedAndDigest(ctx ImageContext, image image.Summary) []*imageC
}
addImage := func(repo, tag, digest string) {
images = append(images, &imageContext{
image := &imageContext{
trunc: ctx.Trunc,
i: image,
repo: repo,
tag: tag,
digest: digest,
})
}
images = append(images, image)
}
for repo, tags := range repoTags {
@@ -187,7 +188,7 @@ func imageFormatTaggedAndDigest(ctx ImageContext, image image.Summary) []*imageC
type imageContext struct {
HeaderContext
trunc bool
i image.Summary
i types.ImageSummary
repo string
tag string
digest string
+16 -16
View File
@@ -8,7 +8,7 @@ import (
"time"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stringid"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -26,66 +26,66 @@ func TestImageContext(t *testing.T) {
call func() string
}{
{
imageCtx: imageContext{i: image.Summary{ID: imageID}, trunc: true},
imageCtx: imageContext{i: types.ImageSummary{ID: imageID}, trunc: true},
expValue: stringid.TruncateID(imageID),
call: ctx.ID,
},
{
imageCtx: imageContext{i: image.Summary{ID: imageID}, trunc: false},
imageCtx: imageContext{i: types.ImageSummary{ID: imageID}, trunc: false},
expValue: imageID,
call: ctx.ID,
},
{
imageCtx: imageContext{i: image.Summary{Size: 10}, trunc: true},
imageCtx: imageContext{i: types.ImageSummary{Size: 10}, trunc: true},
expValue: "10B",
call: ctx.Size,
},
{
imageCtx: imageContext{i: image.Summary{Created: unix}, trunc: true},
imageCtx: imageContext{i: types.ImageSummary{Created: unix}, trunc: true},
expValue: time.Unix(unix, 0).String(), call: ctx.CreatedAt,
},
// FIXME
// {imageContext{
// i: image.Summary{Created: unix},
// i: types.ImageSummary{Created: unix},
// trunc: true,
// }, units.HumanDuration(time.Unix(unix, 0)), createdSinceHeader, ctx.CreatedSince},
{
imageCtx: imageContext{i: image.Summary{}, repo: "busybox"},
imageCtx: imageContext{i: types.ImageSummary{}, repo: "busybox"},
expValue: "busybox",
call: ctx.Repository,
},
{
imageCtx: imageContext{i: image.Summary{}, tag: "latest"},
imageCtx: imageContext{i: types.ImageSummary{}, tag: "latest"},
expValue: "latest",
call: ctx.Tag,
},
{
imageCtx: imageContext{i: image.Summary{}, digest: "sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a"},
imageCtx: imageContext{i: types.ImageSummary{}, digest: "sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a"},
expValue: "sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a",
call: ctx.Digest,
},
{
imageCtx: imageContext{i: image.Summary{Containers: 10}},
imageCtx: imageContext{i: types.ImageSummary{Containers: 10}},
expValue: "10",
call: ctx.Containers,
},
{
imageCtx: imageContext{i: image.Summary{Size: 10000}},
imageCtx: imageContext{i: types.ImageSummary{Size: 10000}},
expValue: "10kB",
call: ctx.VirtualSize, //nolint:staticcheck // ignore SA1019: field is deprecated, but still set on API < v1.44.
},
{
imageCtx: imageContext{i: image.Summary{SharedSize: 10000}},
imageCtx: imageContext{i: types.ImageSummary{SharedSize: 10000}},
expValue: "10kB",
call: ctx.SharedSize,
},
{
imageCtx: imageContext{i: image.Summary{SharedSize: 5000, Size: 20000}},
imageCtx: imageContext{i: types.ImageSummary{SharedSize: 5000, Size: 20000}},
expValue: "15kB",
call: ctx.UniqueSize,
},
{
imageCtx: imageContext{i: image.Summary{Created: zeroTime}},
imageCtx: imageContext{i: types.ImageSummary{Created: zeroTime}},
expValue: "",
call: ctx.CreatedSince,
},
@@ -297,7 +297,7 @@ image_id: imageID3
},
}
images := []image.Summary{
images := []types.ImageSummary{
{ID: "imageID1", RepoTags: []string{"image:tag1"}, RepoDigests: []string{"image@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf"}, Created: unixTime},
{ID: "imageID2", RepoTags: []string{"image:tag2"}, Created: zeroTime},
{ID: "imageID3", RepoTags: []string{"<none>:<none>"}, RepoDigests: []string{"<none>@<none>"}, Created: unixTime},
@@ -320,7 +320,7 @@ image_id: imageID3
func TestImageContextWriteWithNoImage(t *testing.T) {
out := bytes.NewBufferString("")
images := []image.Summary{}
images := []types.ImageSummary{}
cases := []struct {
context ImageContext
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package formatter
import (
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package formatter
import (
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package formatter
import (
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package idresolver
import (
+5 -5
View File
@@ -4,7 +4,7 @@ import (
"context"
"testing"
"github.com/docker/cli/internal/test/builders"
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
"github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
@@ -50,7 +50,7 @@ func TestResolveWithCache(t *testing.T) {
cli := &fakeClient{
nodeInspectFunc: func(nodeID string) (swarm.Node, []byte, error) {
inspectCounter++
return *builders.Node(builders.NodeName("node-foo")), []byte{}, nil
return *Node(NodeName("node-foo")), []byte{}, nil
},
}
@@ -82,14 +82,14 @@ func TestResolveNode(t *testing.T) {
{
nodeID: "nodeID",
nodeInspectFunc: func(string) (swarm.Node, []byte, error) {
return *builders.Node(builders.NodeName("node-foo")), []byte{}, nil
return *Node(NodeName("node-foo")), []byte{}, nil
},
expectedID: "node-foo",
},
{
nodeID: "nodeID",
nodeInspectFunc: func(string) (swarm.Node, []byte, error) {
return *builders.Node(builders.NodeName(""), builders.Hostname("node-hostname")), []byte{}, nil
return *Node(NodeName(""), Hostname("node-hostname")), []byte{}, nil
},
expectedID: "node-hostname",
},
@@ -124,7 +124,7 @@ func TestResolveService(t *testing.T) {
{
serviceID: "serviceID",
serviceInspectFunc: func(string) (swarm.Service, []byte, error) {
return *builders.Service(builders.ServiceName("service-foo")), []byte{}, nil
return *Service(ServiceName("service-foo")), []byte{}, nil
},
expectedID: "service-foo",
},
+4 -2
View File
@@ -14,11 +14,11 @@ import (
"runtime"
"strings"
"github.com/distribution/reference"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/image/build"
"github.com/docker/cli/opts"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
@@ -34,6 +34,8 @@ import (
"github.com/spf13/cobra"
)
var errStdinConflict = errors.New("invalid argument: can't use stdin for both build context and dockerfile")
type buildOptions struct {
context string
dockerfileName string
@@ -187,7 +189,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
if options.dockerfileFromStdin() {
if options.contextFromStdin() {
return errors.New("invalid argument: can't use stdin for both build context and dockerfile")
return errStdinConflict
}
dockerfileCtx = dockerCli.In()
}
+8 -9
View File
@@ -8,7 +8,6 @@ import (
"io"
"net/http"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
@@ -23,6 +22,7 @@ import (
"github.com/docker/docker/pkg/stringid"
"github.com/moby/patternmatcher"
"github.com/pkg/errors"
exec "golang.org/x/sys/execabs"
)
const (
@@ -155,22 +155,19 @@ func GetContextFromReader(rc io.ReadCloser, dockerfileName string) (out io.ReadC
if dockerfileName == "-" {
return nil, "", errors.New("build context is not an archive")
}
if dockerfileName != "" {
return nil, "", errors.New("ambiguous Dockerfile source: both stdin and flag correspond to Dockerfiles")
}
dockerfileDir, err := WriteTempDockerfile(rc)
if err != nil {
return nil, "", err
}
tarArchive, err := archive.Tar(dockerfileDir, archive.Uncompressed)
tar, err := archive.Tar(dockerfileDir, archive.Uncompressed)
if err != nil {
return nil, "", err
}
return ioutils.NewReadCloserWrapper(tarArchive, func() error {
err := tarArchive.Close()
return ioutils.NewReadCloserWrapper(tar, func() error {
err := tar.Close()
os.RemoveAll(dockerfileDir)
return err
}), DefaultDockerfileName, nil
@@ -234,7 +231,8 @@ func GetContextFromURL(out io.Writer, remoteURL, dockerfileName string) (io.Read
// getWithStatusError does an http.Get() and returns an error if the
// status code is 4xx or 5xx.
func getWithStatusError(url string) (resp *http.Response, err error) {
if resp, err = http.Get(url); err != nil { //nolint:gosec // Ignore G107: Potential HTTP request made with variable url
// #nosec G107
if resp, err = http.Get(url); err != nil {
return nil, err
}
if resp.StatusCode < http.StatusBadRequest {
@@ -434,7 +432,8 @@ func Compress(buildCtx io.ReadCloser) (io.ReadCloser, error) {
defer buildCtx.Close()
if _, err := pools.Copy(compressWriter, buildCtx); err != nil {
pipeWriter.CloseWithError(errors.Wrap(err, "failed to compress context"))
pipeWriter.CloseWithError(
errors.Wrap(err, "failed to compress context"))
compressWriter.Close()
return
}
-7
View File
@@ -152,13 +152,6 @@ func TestGetContextFromReaderString(t *testing.T) {
}
}
func TestGetContextFromReaderStringConflict(t *testing.T) {
rdr, relDockerfile, err := GetContextFromReader(io.NopCloser(strings.NewReader(dockerfileContents)), "custom.Dockerfile")
assert.Check(t, is.Equal(rdr, nil))
assert.Check(t, is.Equal(relDockerfile, ""))
assert.Check(t, is.ErrorContains(err, "ambiguous Dockerfile source: both stdin and flag correspond to Dockerfiles"))
}
func TestGetContextFromReaderTar(t *testing.T) {
contextDir := createTestTempDir(t)
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents)
+1
View File
@@ -1,4 +1,5 @@
//go:build !windows
// +build !windows
package build
+11 -12
View File
@@ -9,7 +9,6 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client"
)
@@ -17,13 +16,13 @@ type fakeClient struct {
client.Client
imageTagFunc func(string, string) error
imageSaveFunc func(images []string) (io.ReadCloser, error)
imageRemoveFunc func(image string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error)
imageRemoveFunc func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error)
imagePushFunc func(ref string, options types.ImagePushOptions) (io.ReadCloser, error)
infoFunc func() (system.Info, error)
infoFunc func() (types.Info, error)
imagePullFunc func(ref string, options types.ImagePullOptions) (io.ReadCloser, error)
imagesPruneFunc func(pruneFilter filters.Args) (types.ImagesPruneReport, error)
imageLoadFunc func(input io.Reader, quiet bool) (types.ImageLoadResponse, error)
imageListFunc func(options types.ImageListOptions) ([]image.Summary, error)
imageListFunc func(options types.ImageListOptions) ([]types.ImageSummary, error)
imageInspectFunc func(image string) (types.ImageInspect, []byte, error)
imageImportFunc func(source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error)
imageHistoryFunc func(image string) ([]image.HistoryResponseItem, error)
@@ -44,13 +43,13 @@ func (cli *fakeClient) ImageSave(_ context.Context, images []string) (io.ReadClo
return io.NopCloser(strings.NewReader("")), nil
}
func (cli *fakeClient) ImageRemove(_ context.Context, img string,
func (cli *fakeClient) ImageRemove(_ context.Context, image string,
options types.ImageRemoveOptions,
) ([]image.DeleteResponse, error) {
) ([]types.ImageDeleteResponseItem, error) {
if cli.imageRemoveFunc != nil {
return cli.imageRemoveFunc(img, options)
return cli.imageRemoveFunc(image, options)
}
return []image.DeleteResponse{}, nil
return []types.ImageDeleteResponseItem{}, nil
}
func (cli *fakeClient) ImagePush(_ context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error) {
@@ -60,11 +59,11 @@ func (cli *fakeClient) ImagePush(_ context.Context, ref string, options types.Im
return io.NopCloser(strings.NewReader("")), nil
}
func (cli *fakeClient) Info(_ context.Context) (system.Info, error) {
func (cli *fakeClient) Info(_ context.Context) (types.Info, error) {
if cli.infoFunc != nil {
return cli.infoFunc()
}
return system.Info{}, nil
return types.Info{}, nil
}
func (cli *fakeClient) ImagePull(_ context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error) {
@@ -88,11 +87,11 @@ func (cli *fakeClient) ImageLoad(_ context.Context, input io.Reader, quiet bool)
return types.ImageLoadResponse{}, nil
}
func (cli *fakeClient) ImageList(_ context.Context, options types.ImageListOptions) ([]image.Summary, error) {
func (cli *fakeClient) ImageList(_ context.Context, options types.ImageListOptions) ([]types.ImageSummary, error) {
if cli.imageListFunc != nil {
return cli.imageListFunc(options)
}
return []image.Summary{}, nil
return []types.ImageSummary{}, nil
}
func (cli *fakeClient) ImageInspectWithRaw(_ context.Context, image string) (types.ImageInspect, []byte, error) {
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package image
import (
+8 -9
View File
@@ -8,7 +8,6 @@ import (
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/image"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -20,7 +19,7 @@ func TestNewImagesCommandErrors(t *testing.T) {
name string
args []string
expectedError string
imageListFunc func(options types.ImageListOptions) ([]image.Summary, error)
imageListFunc func(options types.ImageListOptions) ([]types.ImageSummary, error)
}{
{
name: "wrong-args",
@@ -30,8 +29,8 @@ func TestNewImagesCommandErrors(t *testing.T) {
{
name: "failed-list",
expectedError: "something went wrong",
imageListFunc: func(options types.ImageListOptions) ([]image.Summary, error) {
return []image.Summary{}, errors.Errorf("something went wrong")
imageListFunc: func(options types.ImageListOptions) ([]types.ImageSummary, error) {
return []types.ImageSummary{}, errors.Errorf("something went wrong")
},
},
}
@@ -48,7 +47,7 @@ func TestNewImagesCommandSuccess(t *testing.T) {
name string
args []string
imageFormat string
imageListFunc func(options types.ImageListOptions) ([]image.Summary, error)
imageListFunc func(options types.ImageListOptions) ([]types.ImageSummary, error)
}{
{
name: "simple",
@@ -65,17 +64,17 @@ func TestNewImagesCommandSuccess(t *testing.T) {
{
name: "match-name",
args: []string{"image"},
imageListFunc: func(options types.ImageListOptions) ([]image.Summary, error) {
imageListFunc: func(options types.ImageListOptions) ([]types.ImageSummary, error) {
assert.Check(t, is.Equal("image", options.Filters.Get("reference")[0]))
return []image.Summary{}, nil
return []types.ImageSummary{}, nil
},
},
{
name: "filters",
args: []string{"--filter", "name=value"},
imageListFunc: func(options types.ImageListOptions) ([]image.Summary, error) {
imageListFunc: func(options types.ImageListOptions) ([]types.ImageSummary, error) {
assert.Check(t, is.Equal("value", options.Filters.Get("name")[0]))
return []image.Summary{}, nil
return []types.ImageSummary{}, nil
},
},
}
+2 -3
View File
@@ -8,7 +8,6 @@ import (
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -66,7 +65,7 @@ func TestNewPruneCommandSuccess(t *testing.T) {
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) {
assert.Check(t, is.Equal("true", pruneFilter.Get("dangling")[0]))
return types.ImagesPruneReport{
ImagesDeleted: []image.DeleteResponse{{Deleted: "image1"}},
ImagesDeleted: []types.ImageDeleteResponseItem{{Deleted: "image1"}},
SpaceReclaimed: 1,
}, nil
},
@@ -85,7 +84,7 @@ func TestNewPruneCommandSuccess(t *testing.T) {
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) {
assert.Check(t, is.Equal("true", pruneFilter.Get("dangling")[0]))
return types.ImagesPruneReport{
ImagesDeleted: []image.DeleteResponse{{Untagged: "image1"}},
ImagesDeleted: []types.ImageDeleteResponseItem{{Untagged: "image1"}},
SpaceReclaimed: 2,
}, nil
},
+1 -1
View File
@@ -5,11 +5,11 @@ import (
"fmt"
"strings"
"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/trust"
"github.com/docker/distribution/reference"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
+1 -1
View File
@@ -27,7 +27,7 @@ func TestNewPullCommandErrors(t *testing.T) {
},
{
name: "invalid-name",
expectedError: "invalid reference format: repository name (library/UPPERCASE_REPO) must be lowercase",
expectedError: "invalid reference format: repository name must be lowercase",
args: []string{"UPPERCASE_REPO"},
},
{
+2 -2
View File
@@ -5,11 +5,11 @@ import (
"fmt"
"io"
"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/streams"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/pkg/jsonmessage"
@@ -76,7 +76,7 @@ func RunPush(dockerCli command.Cli, opts pushOptions) error {
ctx := context.Background()
// Resolve the Auth config relevant for this server
authConfig := command.ResolveAuthConfig(dockerCli.ConfigFile(), repoInfo.Index)
authConfig := command.ResolveAuthConfig(ctx, dockerCli, repoInfo.Index)
encodedAuth, err := registrytypes.EncodeAuthConfig(authConfig)
if err != nil {
return err
+1 -1
View File
@@ -26,7 +26,7 @@ func TestNewPushCommandErrors(t *testing.T) {
{
name: "invalid-name",
args: []string{"UPPERCASE_REPO"},
expectedError: "invalid reference format: repository name (library/UPPERCASE_REPO) must be lowercase",
expectedError: "invalid reference format: repository name must be lowercase",
},
{
name: "push-failed",
+2 -2
View File
@@ -8,7 +8,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types"
"github.com/docker/docker/errdefs"
apiclient "github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -63,7 +63,7 @@ func runRemove(dockerCli command.Cli, opts removeOptions, images []string) error
for _, img := range images {
dels, err := client.ImageRemove(ctx, img, options)
if err != nil {
if !errdefs.IsNotFound(err) {
if !apiclient.IsErrNotFound(err) {
fatalErr = true
}
errs = append(errs, err.Error())
+23 -22
View File
@@ -7,7 +7,6 @@ import (
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/image"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -22,7 +21,9 @@ func (n notFound) Error() string {
return fmt.Sprintf("Error: No such image: %s", n.imageID)
}
func (n notFound) NotFound() {}
func (n notFound) NotFound() bool {
return true
}
func TestNewRemoveCommandAlias(t *testing.T) {
cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{}))
@@ -36,7 +37,7 @@ func TestNewRemoveCommandErrors(t *testing.T) {
name string
args []string
expectedError string
imageRemoveFunc func(img string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error)
imageRemoveFunc func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error)
}{
{
name: "wrong args",
@@ -46,19 +47,19 @@ func TestNewRemoveCommandErrors(t *testing.T) {
name: "ImageRemove fail with force option",
args: []string{"-f", "image1"},
expectedError: "error removing image",
imageRemoveFunc: func(img string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error) {
assert.Check(t, is.Equal("image1", img))
return []image.DeleteResponse{}, errors.Errorf("error removing image")
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
assert.Check(t, is.Equal("image1", image))
return []types.ImageDeleteResponseItem{}, errors.Errorf("error removing image")
},
},
{
name: "ImageRemove fail",
args: []string{"arg1"},
expectedError: "error removing image",
imageRemoveFunc: func(img string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error) {
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
assert.Check(t, !options.Force)
assert.Check(t, options.PruneChildren)
return []image.DeleteResponse{}, errors.Errorf("error removing image")
return []types.ImageDeleteResponseItem{}, errors.Errorf("error removing image")
},
},
}
@@ -78,24 +79,24 @@ func TestNewRemoveCommandSuccess(t *testing.T) {
testCases := []struct {
name string
args []string
imageRemoveFunc func(img string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error)
imageRemoveFunc func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error)
expectedStderr string
}{
{
name: "Image Deleted",
args: []string{"image1"},
imageRemoveFunc: func(img string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error) {
assert.Check(t, is.Equal("image1", img))
return []image.DeleteResponse{{Deleted: img}}, nil
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
assert.Check(t, is.Equal("image1", image))
return []types.ImageDeleteResponseItem{{Deleted: image}}, nil
},
},
{
name: "Image not found with force option",
args: []string{"-f", "image1"},
imageRemoveFunc: func(img string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error) {
assert.Check(t, is.Equal("image1", img))
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
assert.Check(t, is.Equal("image1", image))
assert.Check(t, is.Equal(true, options.Force))
return []image.DeleteResponse{}, notFound{"image1"}
return []types.ImageDeleteResponseItem{}, notFound{"image1"}
},
expectedStderr: "Error: No such image: image1\n",
},
@@ -103,19 +104,19 @@ func TestNewRemoveCommandSuccess(t *testing.T) {
{
name: "Image Untagged",
args: []string{"image1"},
imageRemoveFunc: func(img string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error) {
assert.Check(t, is.Equal("image1", img))
return []image.DeleteResponse{{Untagged: img}}, nil
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
assert.Check(t, is.Equal("image1", image))
return []types.ImageDeleteResponseItem{{Untagged: image}}, nil
},
},
{
name: "Image Deleted and Untagged",
args: []string{"image1", "image2"},
imageRemoveFunc: func(img string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error) {
if img == "image1" {
return []image.DeleteResponse{{Untagged: img}}, nil
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
if image == "image1" {
return []types.ImageDeleteResponseItem{{Untagged: image}}, nil
}
return []image.DeleteResponse{{Deleted: img}}, nil
return []types.ImageDeleteResponseItem{{Deleted: image}}, nil
},
},
}
+2 -2
View File
@@ -8,10 +8,10 @@ import (
"io"
"sort"
"github.com/distribution/reference"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/streams"
"github.com/docker/cli/cli/trust"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/pkg/jsonmessage"
@@ -339,6 +339,6 @@ func TagTrusted(ctx context.Context, cli command.Cli, trustedRef reference.Canon
// AuthResolver returns an auth resolver function from a command.Cli
func AuthResolver(cli command.Cli) func(ctx context.Context, index *registrytypes.IndexInfo) registrytypes.AuthConfig {
return func(ctx context.Context, index *registrytypes.IndexInfo) registrytypes.AuthConfig {
return command.ResolveAuthConfig(cli.ConfigFile(), index)
return command.ResolveAuthConfig(ctx, cli, index)
}
}
+3
View File
@@ -1,3 +1,6 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19
package inspect
import (

Some files were not shown because too many files have changed in this diff Show More