Compare commits

...

181 Commits

Author SHA1 Message Date
33961a79f1 Merge pull request #4142 from thaJeztah/update_engine2
Some checks failed
build / prepare (push) Has been cancelled
build / build (push) Has been cancelled
build / prepare-plugins (push) Has been cancelled
build / plugins (push) Has been cancelled
e2e / e2e (19.03-dind, non-experimental) (push) Has been cancelled
e2e / e2e (alpine, stable-dind, connhelper-ssh) (push) Has been cancelled
e2e / e2e (alpine, stable-dind, experimental) (push) Has been cancelled
e2e / e2e (alpine, stable-dind, non-experimental) (push) Has been cancelled
e2e / e2e (bullseye, stable-dind, connhelper-ssh) (push) Has been cancelled
e2e / e2e (bullseye, stable-dind, experimental) (push) Has been cancelled
e2e / e2e (bullseye, stable-dind, non-experimental) (push) Has been cancelled
test / ctn (push) Has been cancelled
test / host (macos-11) (push) Has been cancelled
validate / validate (lint) (push) Has been cancelled
validate / validate (shellcheck) (push) Has been cancelled
validate / validate (update-authors) (push) Has been cancelled
validate / validate (validate-vendor) (push) Has been cancelled
validate / validate-make (manpages) (push) Has been cancelled
validate / validate-make (yamldocs) (push) Has been cancelled
vendor: docker/docker master (v24.0.0-dev), containerd v1.6.20
2023-03-31 22:49:28 +02:00
dcb6a0d182 Merge pull request #4147 from crazy-max/fix-racy-help
revert "improve plugins discovery performance"
2023-03-31 12:36:43 -07:00
8e6ac62d53 Merge pull request #4137 from cpuguy83/fix_cp_no_tty
Improve docker cp progress output
2023-03-31 21:06:26 +02:00
e14f5fc1a7 revert "improve plugins discovery performance"
This reverts commit 62f2358b99.

Spawning a goroutine for each iteration in the loop when listing
plugins is racy unfortunately. `plugins` slice is protected with
a mutex so not sure why it fails.

I tried using a channel to collect the plugins instead of a slice
to guarantee that they will be appended to the list in the order
they are processed but no dice.

I also tried without errgroup package and simply use sync.WaitGroup
but same. I have also created an extra channel to receive errors
from the goroutines but racy too.

I think the change in this function is not related to the race
condition but newPlugin is. So revert in the meantime :(

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-31 16:20:42 +02:00
05cffcbedf vendor: github.com/docker/docker 7c93e4a09be1 (v24.0.0-dev)
full diff: 54130b542d...7c93e4a09b

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-31 01:00:05 +02:00
a36a54d3ca vendor: github.com/containerd/containerd v1.6.20
full diff: https://github.com/containerd/containerd/compare/v1.6.19...v1.6.20

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-31 00:58:01 +02:00
f4b22fb6cf vendor: github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b
full diff: 02efb9a75e...3a7f492d3f

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-31 00:57:04 +02:00
eb392ff4ce cp: Do not block transfer on writing to terminal
This moves all the terminal writing to a goroutine that updates the
terminal periodically.
In our MITM copier we just use an atomic to add to the total number of
bytes read/written, the goroutine reads the total and updates the
terminal as needed.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2023-03-30 20:15:16 +00:00
de0d30ff24 Merge pull request #4010 from thaJeztah/update_engine_23.1
vendor: update docker/docker to master (v24.0.0-dev)
2023-03-30 21:18:23 +02:00
92fb47f58a Merge pull request #4140 from thaJeztah/bump_go1.20
update to go1.20.2
2023-03-30 21:17:13 +02:00
7189716d5a replace uses of deprecated api/types.AuthConfig
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 19:57:16 +02:00
bfa79fd75a vendor: github.com/docker/docker master (v24.0.0-dev)
- updates VolumeList() calls for docker/docker master
- update fakeClient signature, and suppress err output in tests

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 19:56:28 +02:00
e86d2f4113 vendor: github.com/moby/buildkit v0.11.5
full diff: https://github.com/moby/buildkit/compare/v0.11.4...v0.11.5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 19:56:28 +02:00
cd9c6a4c02 vendor: github.com/klauspost/compress v1.16.3
full diff: https://github.com/klauspost/compress/compare/v1.15.12...v1.16.3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 19:56:28 +02:00
5843fbd5f5 vendor: github.com/imdario/mergo v0.3.13
full diff: https://github.com/imdario/mergo/compare/v0.3.12...v0.3.13

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 19:56:27 +02:00
149d289638 vendor: golang.org/x/sys v0.6.0
full diff: https://github.com/golang/sys/compare/v0.5.0..v0.6.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 19:56:27 +02:00
6dca335d05 vendor: github.com/moby/swarmkit/v2 v2.0.0-20230315203717-e28e8ba9bc83
full diff: a745a8755c...e28e8ba9bc

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 19:56:27 +02:00
4389c966f8 vendor: github.com/opencontainers/runc v1.1.5
full diff: https://github.com/opencontainers/runc/compare/v1.1.3...v1.1.5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 19:56:26 +02:00
a798282877 update to go1.20.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 19:55:53 +02:00
adbfa8208a Merge pull request #4134 from thaJeztah/update_golangci_lint
update golangci-lint to v1.52.2
2023-03-30 19:55:22 +02:00
dfc98b2dec Merge pull request #4118 from crazy-max/fix-dockerfile-last-stage
Dockerfile: build binary if no target specified
2023-03-30 18:59:53 +02:00
b8747b0f91 update golangci-lint to v1.52.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:11 +02:00
399ded9b98 internal/test: FakeCli: remove name for unused arg (revive)
internal/test/cli.go:184:34: unused-parameter: parameter 'insecure' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *FakeCli) RegistryClient(insecure bool) registryclient.RegistryClient {
                                     ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:10 +02:00
20a70cb530 internal/test/notary: remove name for unused arg (revive)
internal/test/notary/client.go:16:33: unused-parameter: parameter 'imgRefAndAuth' seems to be unused, consider removing or renaming it as _ (revive)
    func GetOfflineNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
                                    ^
    internal/test/notary/client.go:25:45: unused-parameter: parameter 'rootKeyIDs' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
                                                ^
    internal/test/notary/client.go:30:60: unused-parameter: parameter 'rootKeyIDs' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
                                                               ^
    internal/test/notary/client.go:42:44: unused-parameter: parameter 'target' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) AddTarget(target *client.Target, roles ...data.RoleName) error {
                                               ^
    internal/test/notary/client.go:48:47: unused-parameter: parameter 'targetName' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) RemoveTarget(targetName string, roles ...data.RoleName) error {
                                                  ^
    internal/test/notary/client.go:54:46: unused-parameter: parameter 'roles' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
                                                 ^
    internal/test/notary/client.go:59:50: unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
                                                     ^
    internal/test/notary/client.go:65:61: unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
                                                                ^
    internal/test/notary/client.go:85:48: unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) AddDelegation(name data.RoleName, delegationKeys []data.PublicKey, paths []string) error {
                                                   ^
    internal/test/notary/client.go:90:59: unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) AddDelegationRoleAndKeys(name data.RoleName, delegationKeys []data.PublicKey) error {
                                                              ^
    internal/test/notary/client.go:95:53: unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) AddDelegationPaths(name data.RoleName, paths []string) error {
                                                        ^
    internal/test/notary/client.go💯63: unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) RemoveDelegationKeysAndPaths(name data.RoleName, keyIDs, paths []string) error {
                                                                  ^
    internal/test/notary/client.go:105:55: unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) RemoveDelegationRole(name data.RoleName) error {
                                                          ^
    internal/test/notary/client.go:110:56: unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) RemoveDelegationPaths(name data.RoleName, paths []string) error {
                                                           ^
    internal/test/notary/client.go:115:55: unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) RemoveDelegationKeys(name data.RoleName, keyIDs []string) error {
                                                          ^
    internal/test/notary/client.go:120:55: unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) ClearDelegationPaths(name data.RoleName) error {
                                                          ^
    internal/test/notary/client.go:126:42: unused-parameter: parameter 'roles' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) Witness(roles ...data.RoleName) ([]data.RoleName, error) {
                                             ^
    internal/test/notary/client.go:131:44: unused-parameter: parameter 'role' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
                                               ^
    internal/test/notary/client.go:142:52: unused-parameter: parameter 'version' seems to be unused, consider removing or renaming it as _ (revive)
    func (o OfflineNotaryRepository) SetLegacyVersions(version int) {}
                                                       ^
    internal/test/notary/client.go:150:39: unused-parameter: parameter 'imgRefAndAuth' seems to be unused, consider removing or renaming it as _ (revive)
    func GetUninitializedNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
                                          ^
    internal/test/notary/client.go:163:51: unused-parameter: parameter 'rootKeyIDs' seems to be unused, consider removing or renaming it as _ (revive)
    func (u UninitializedNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
                                                      ^
    internal/test/notary/client.go:168:66: unused-parameter: parameter 'rootKeyIDs' seems to be unused, consider removing or renaming it as _ (revive)
    func (u UninitializedNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
                                                                     ^
    internal/test/notary/client.go:180:52: unused-parameter: parameter 'roles' seems to be unused, consider removing or renaming it as _ (revive)
    func (u UninitializedNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
                                                       ^
    internal/test/notary/client.go:185:56: unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
    func (u UninitializedNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
                                                           ^
    internal/test/notary/client.go:191:67: unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
    func (u UninitializedNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
                                                                      ^
    internal/test/notary/client.go:206:50: unused-parameter: parameter 'role' seems to be unused, consider removing or renaming it as _ (revive)
    func (u UninitializedNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
                                                     ^
    internal/test/notary/client.go:211:38: unused-parameter: parameter 'imgRefAndAuth' seems to be unused, consider removing or renaming it as _ (revive)
    func GetEmptyTargetsNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
                                         ^
    internal/test/notary/client.go:223:50: unused-parameter: parameter 'rootKeyIDs' seems to be unused, consider removing or renaming it as _ (revive)
    func (e EmptyTargetsNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
                                                     ^
    internal/test/notary/client.go:228:65: unused-parameter: parameter 'rootKeyIDs' seems to be unused, consider removing or renaming it as _ (revive)
    func (e EmptyTargetsNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
                                                                    ^
    internal/test/notary/client.go:240:51: unused-parameter: parameter 'roles' seems to be unused, consider removing or renaming it as _ (revive)
    func (e EmptyTargetsNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
                                                      ^
    internal/test/notary/client.go:245:68: unused-parameter: parameter 'roles' seems to be unused, consider removing or renaming it as _ (revive)
    func (e EmptyTargetsNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
                                                                       ^
    internal/test/notary/client.go:284:49: unused-parameter: parameter 'role' seems to be unused, consider removing or renaming it as _ (revive)
    func (e EmptyTargetsNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
                                                    ^
    internal/test/notary/client.go:289:32: unused-parameter: parameter 'imgRefAndAuth' seems to be unused, consider removing or renaming it as _ (revive)
    func GetLoadedNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
                                   ^
    internal/test/notary/client.go:509:45: unused-parameter: parameter 'imgRefAndAuth' seems to be unused, consider removing or renaming it as _ (revive)
    func GetLoadedWithNoSignersNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
                                                ^
    internal/test/notary/client.go:532:75: unused-parameter: parameter 'roles' seems to be unused, consider removing or renaming it as _ (revive)
    func (l LoadedWithNoSignersNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
                                                                              ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:10 +02:00
90380d9576 cli/connhelper/commandconn: remove name for unused arg (revive)
cli/connhelper/commandconn/commandconn.go:35:10: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func New(ctx context.Context, cmd string, args ...string) (net.Conn, error) {
             ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:10 +02:00
dd6ede2109 cli/config/configfile: mockNativeStore: remove name for unused arg (revive)
cli/config/configfile/file_test.go:189:33: unused-parameter: parameter 'authConfig' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *mockNativeStore) Store(authConfig types.AuthConfig) error {
                                    ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:10 +02:00
7c8680c69b cli/compose/schema: remove name for unused arg (revive)
cli/compose/schema/schema.go:20:44: unused-parameter: parameter 'input' seems to be unused, consider removing or renaming it as _ (revive)
    func (checker portsFormatChecker) IsFormat(input interface{}) bool {
                                               ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:10 +02:00
6355bcee66 cli/compose/convert: fakeClient: remove name for unused arg (revive)
cli/compose/convert/service_test.go:599:33: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
                                    ^
    cli/compose/convert/service_test.go:606:33: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
                                    ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:10 +02:00
607f290f65 cli/command/volume: remove name for unused arg (revive)
cli/command/volume/prune_test.go:113:22: unused-parameter: parameter 'args' seems to be unused, consider removing or renaming it as _ (revive)
    func simplePruneFunc(args filters.Args) (types.VolumesPruneReport, error) {
                         ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:09 +02:00
546cf6d985 cli/command/trust: fakeClient: remove name for unused arg (revive)
cli/command/trust/inspect_pretty_test.go:30:27: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) Info(ctx context.Context) (types.Info, error) {
                              ^
    cli/command/trust/inspect_pretty_test.go:34:42: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) ImageInspectWithRaw(ctx context.Context, imageID string) (types.ImageInspect, []byte, error) {
                                             ^
    cli/command/trust/inspect_pretty_test.go:38:32: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) ImagePush(ctx context.Context, image string, options types.ImagePushOptions) (io.ReadCloser, error) {
                                   ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:09 +02:00
b32b28041d cli/command/task: fakeClient: remove name for unused arg (revive)
cli/command/task/client_test.go:17:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, ref string) (swarm.Node, []byte, error) {
                                              ^
    cli/command/task/client_test.go:24:46: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ServiceInspectWithRaw(ctx context.Context, ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
                                                 ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:09 +02:00
40a51d5543 cli/command/swarm: fakeClient: remove name for unused arg (revive)
cli/command/swarm/ipnet_slice_test.go:13:14: unused-parameter: parameter 'ip' seems to be unused, consider removing or renaming it as _ (revive)
    func getCIDR(ip net.IP, cidr *net.IPNet, err error) net.IPNet {
                 ^
    cli/command/swarm/client_test.go:24:29: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) Info(ctx context.Context) (types.Info, error) {
                                ^
    cli/command/swarm/client_test.go:31:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, ref string) (swarm.Node, []byte, error) {
                                              ^
    cli/command/swarm/client_test.go:38:34: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) {
                                     ^
    cli/command/swarm/client_test.go:45:37: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) SwarmInspect(ctx context.Context) (swarm.Swarm, error) {
                                        ^
    cli/command/swarm/client_test.go:52:42: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) SwarmGetUnlockKey(ctx context.Context) (types.SwarmUnlockKeyResponse, error) {
                                             ^
    cli/command/swarm/client_test.go:59:34: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) SwarmJoin(ctx context.Context, req swarm.JoinRequest) error {
                                     ^
    cli/command/swarm/client_test.go:66:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) SwarmLeave(ctx context.Context, force bool) error {
                                      ^
    cli/command/swarm/client_test.go:73:36: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) SwarmUpdate(ctx context.Context, version swarm.Version, swarm swarm.Spec, flags swarm.UpdateFlags) error {
                                       ^
    cli/command/swarm/client_test.go:80:36: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) SwarmUnlock(ctx context.Context, req swarm.UnlockRequest) error {
                                       ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:09 +02:00
b0d0b0efcb cli/command/stack: fakeClient: remove name for unused arg (revive)
cli/command/stack/swarm/client_test.go:46:38: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ServerVersion(ctx context.Context) (types.Version, error) {
                                         ^
    cli/command/stack/swarm/client_test.go:57:36: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
                                       ^
    cli/command/stack/swarm/client_test.go:72:36: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
                                       ^
    cli/command/stack/swarm/client_test.go:87:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
                                      ^
    cli/command/stack/swarm/client_test.go:102:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
                                      ^
    cli/command/stack/swarm/client_test.go:117:33: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
                                    ^
    cli/command/stack/swarm/client_test.go:124:33: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
                                    ^
    cli/command/stack/swarm/client_test.go:131:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, ref string) (swarm.Node, []byte, error) {
                                              ^
    cli/command/stack/swarm/client_test.go:138:38: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) {
                                         ^
    cli/command/stack/swarm/client_test.go:146:38: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ServiceRemove(ctx context.Context, serviceID string) error {
                                         ^
    cli/command/stack/swarm/client_test.go:155:38: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NetworkRemove(ctx context.Context, networkID string) error {
                                         ^
    cli/command/stack/swarm/client_test.go:164:37: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) SecretRemove(ctx context.Context, secretID string) error {
                                        ^
    cli/command/stack/swarm/client_test.go:173:37: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ConfigRemove(ctx context.Context, configID string) error {
                                        ^
    cli/command/stack/client_test.go:46:38: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ServerVersion(ctx context.Context) (types.Version, error) {
                                         ^
    cli/command/stack/client_test.go:57:36: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
                                       ^
    cli/command/stack/client_test.go:72:36: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
                                       ^
    cli/command/stack/client_test.go:87:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
                                      ^
    cli/command/stack/client_test.go:102:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
                                      ^
    cli/command/stack/client_test.go:117:33: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
                                    ^
    cli/command/stack/client_test.go:124:33: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
                                    ^
    cli/command/stack/client_test.go:131:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, ref string) (swarm.Node, []byte, error) {
                                              ^
    cli/command/stack/client_test.go:138:38: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) {
                                         ^
    cli/command/stack/client_test.go:146:38: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ServiceRemove(ctx context.Context, serviceID string) error {
                                         ^
    cli/command/stack/client_test.go:155:38: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NetworkRemove(ctx context.Context, networkID string) error {
                                         ^
    cli/command/stack/client_test.go:164:37: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) SecretRemove(ctx context.Context, secretID string) error {
                                        ^
    cli/command/stack/client_test.go:173:37: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ConfigRemove(ctx context.Context, configID string) error {
                                        ^
    cli/command/stack/client_test.go:182:46: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ServiceInspectWithRaw(ctx context.Context, serviceID string, opts types.ServiceInspectOptions) (swarm.Service, []byte, error) {
                                                 ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:08 +02:00
c69640d8c1 cli/command/service: fakeClient: remove name for unused arg (revive)
cli/command/service/update_test.go:507:41: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (s secretAPIClientMock) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
                                            ^
    cli/command/service/update_test.go:511:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (s secretAPIClientMock) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (types.SecretCreateResponse, error) {
                                              ^
    cli/command/service/update_test.go:515:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (s secretAPIClientMock) SecretRemove(ctx context.Context, id string) error {
                                              ^
    cli/command/service/update_test.go:519:51: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (s secretAPIClientMock) SecretInspectWithRaw(ctx context.Context, name string) (swarm.Secret, []byte, error) {
                                                      ^
    cli/command/service/update_test.go:523:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (s secretAPIClientMock) SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error {
                                              ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:08 +02:00
5254081fd6 cli/command/registry: fakeClient: remove name for unused arg (revive)
cli/command/registry/login_test.go:37:26: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c fakeClient) Info(ctx context.Context) (types.Info, error) {
                             ^
    cli/command/registry/login_test.go:41:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c fakeClient) RegistryLogin(ctx context.Context, auth types.AuthConfig) (registrytypes.AuthenticateOKBody, error) {
                                      ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:08 +02:00
da3416c023 cli/command/plugin: fakeClient: remove name for unused arg (revive)
cli/command/plugin/client_test.go:23:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) PluginCreate(ctx context.Context, createContext io.Reader, createOptions types.PluginCreateOptions) error {
                                      ^
    cli/command/plugin/client_test.go:30:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) PluginEnable(ctx context.Context, name string, enableOptions types.PluginEnableOptions) error {
                                      ^
    cli/command/plugin/client_test.go:37:36: unused-parameter: parameter 'context' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) PluginDisable(context context.Context, name string, disableOptions types.PluginDisableOptions) error {
                                       ^
    cli/command/plugin/client_test.go:44:35: unused-parameter: parameter 'context' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) PluginRemove(context context.Context, name string, removeOptions types.PluginRemoveOptions) error {
                                      ^
    cli/command/plugin/client_test.go:51:36: unused-parameter: parameter 'context' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) PluginInstall(context context.Context, name string, installOptions types.PluginInstallOptions) (io.ReadCloser, error) {
                                       ^
    cli/command/plugin/client_test.go:58:33: unused-parameter: parameter 'context' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) PluginList(context context.Context, filter filters.Args) (types.PluginsListResponse, error) {
                                    ^
    cli/command/plugin/client_test.go:66:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) {
                                              ^
    cli/command/plugin/client_test.go:74:27: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) Info(ctx context.Context) (types.Info, error) {
                              ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:08 +02:00
625988c3aa cli/command/node: fakeClient: remove name for unused arg (revive)
cli/command/node/client_test.go:23:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, ref string) (swarm.Node, []byte, error) {
                                              ^
    cli/command/node/client_test.go:30:33: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
                                    ^
    cli/command/node/client_test.go:37:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NodeRemove(ctx context.Context, nodeID string, options types.NodeRemoveOptions) error {
                                      ^
    cli/command/node/client_test.go:44:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error {
                                      ^
    cli/command/node/client_test.go:51:29: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) Info(ctx context.Context) (types.Info, error) {
                                ^
    cli/command/node/client_test.go:58:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) {
                                              ^
    cli/command/node/client_test.go:65:33: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
                                    ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:07 +02:00
92d9e3bf69 cli/command/network: fakeClient: remove name for unused arg (revive)
cli/command/network/client_test.go:55:44: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) NetworkInspectWithRaw(ctx context.Context, network string, options types.NetworkInspectOptions) (types.NetworkResource, []byte, error) {
                                               ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:07 +02:00
316c4992c4 cli/command/image: fakeClient: remove name for unused arg (revive)
cli/command/image/client_test.go:90:34: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ImageList(ctx context.Context, options types.ImageListOptions) ([]types.ImageSummary, error) {
                                     ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:06 +02:00
ae5a86bb8d cli/command/image/build: remove name for unused arg (revive)
cli/command/image/build/context_test.go:21:19: unused-parameter: parameter 't' seems to be unused, consider removing or renaming it as _ (revive)
    func prepareEmpty(t *testing.T) string {
                      ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:06 +02:00
38ef40ee7a cli/command/idresolver: fakeClient: remove name for unused arg (revive)
cli/command/idresolver/client_test.go:17:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) {
                                              ^
    cli/command/idresolver/client_test.go:24:46: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) ServiceInspectWithRaw(ctx context.Context, serviceID string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
                                                 ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:06 +02:00
45b5676acd cli/command/container: fakeClient: remove name for unused arg (revive)
cli/command/container/client_test.go:67:41: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (f *fakeClient) ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error {
                                            ^
    cli/command/container/client_test.go:92:34: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (f *fakeClient) ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) {
                                     ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:05 +02:00
5563c5a91d cli/command/checkpoint: fakeClient: remove name for unused arg (revive)
cli/command/checkpoint/client_test.go:17:41: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) CheckpointCreate(ctx context.Context, container string, options types.CheckpointCreateOptions) error {
                                            ^
    cli/command/checkpoint/client_test.go:24:41: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) CheckpointDelete(ctx context.Context, container string, options types.CheckpointDeleteOptions) error {
                                            ^
    cli/command/checkpoint/client_test.go:31:39: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (cli *fakeClient) CheckpointList(ctx context.Context, container string, options types.CheckpointListOptions) ([]types.Checkpoint, error) {
                                          ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:05 +02:00
9dd012aa5d cli/command/secret: fakeClient: include context in fake client (revive)
I could either remove the name for these contexts, or make the fake functions
more accurately reflect the actual implementation (decided to go for the latter
one)

    cli/command/secret/client_test.go:19:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) SecretCreate(ctx context.Context, spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
                                      ^
    cli/command/secret/client_test.go:26:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) SecretInspectWithRaw(ctx context.Context, id string) (swarm.Secret, []byte, error) {
                                              ^
    cli/command/secret/client_test.go:33:33: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
                                    ^
    cli/command/secret/client_test.go:40:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) SecretRemove(ctx context.Context, name string) error {
                                      ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:22:00 +02:00
66c66bdce7 cli/command/config: fakeClient: include context in fake client (revive)
I could either remove the name for these contexts, or make the fake functions
more accurately reflect the actual implementation (decided to go for the latter
one)

.   cli/command/config/client_test.go:19:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) ConfigCreate(ctx context.Context, spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
                                      ^
    cli/command/config/client_test.go:26:43: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.Config, []byte, error) {
                                              ^
    cli/command/config/client_test.go:33:33: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
                                    ^
    cli/command/config/client_test.go:40:35: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *fakeClient) ConfigRemove(ctx context.Context, name string) error {
                                      ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:05:32 +02:00
ac024a4d8b internal/test/network: FakeClient: embed interface to remove boilerplating
Only a single method of the FakeClient was actually implemented (and used).
This patch embeds the interface it must implement to reduce the boilerplating
for not yet implemented methods.

Calling any of the unimplemented methods will result in a panic, which will
make it clear when they must be implemented :)

This also fixes various linting errors;

    internal/test/network/client.go:17:37: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *FakeClient) NetworkConnect(ctx context.Context, networkID, container string, config *network.EndpointSettings) error {
                                        ^
    internal/test/network/client.go:22:65: unused-parameter: parameter 'options' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *FakeClient) NetworkCreate(_ context.Context, _ string, options types.NetworkCreate) (types.NetworkCreateResponse, error) {
                                                                    ^
    internal/test/network/client.go:27:40: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *FakeClient) NetworkDisconnect(ctx context.Context, networkID, container string, force bool) error {
                                           ^
    internal/test/network/client.go:45:53: unused-parameter: parameter 'options' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *FakeClient) NetworkList(_ context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
                                                        ^
    internal/test/network/client.go:50:36: unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *FakeClient) NetworkRemove(ctx context.Context, networkID string) error {
                                       ^
    internal/test/network/client.go:55:55: unused-parameter: parameter 'pruneFilter' seems to be unused, consider removing or renaming it as _ (revive)
    func (c *FakeClient) NetworksPrune(_ context.Context, pruneFilter filters.Args) (types.NetworksPruneReport, error) {
                                                          ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:05:31 +02:00
a2d532819d cli/trust: remove name for unused args (revive)
These method must implements an interface, but don't use the argument.

    cli/trust/trust.go:85:40: unused-parameter: parameter 'u' seems to be unused, consider removing or renaming it as _ (revive)
    func (scs simpleCredentialStore) Basic(u *url.URL) (string, string) {
                                           ^
    cli/trust/trust.go:89:47: unused-parameter: parameter 'u' seems to be unused, consider removing or renaming it as _ (revive)
    func (scs simpleCredentialStore) RefreshToken(u *url.URL, service string) string {
                                                  ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:05:31 +02:00
f5fad186c0 opts: NormalizeCapability(): fix redefinition of the built-in function (revive)
opts/capabilities.go:25:2: redefines-builtin-id: redefinition of the built-in function cap (revive)
        cap = strings.ToUpper(strings.TrimSpace(cap))
        ^
    opts/capabilities.go:30:3: redefines-builtin-id: redefinition of the built-in function cap (revive)
            cap = "CAP_" + cap
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:05:31 +02:00
9252fae838 cli/registry/client: AuthorizeRequest(): remove name for unused arg (revive)
This method implements the interface defined in distribution, but doesn't
use the argument.

    cli/registry/client/endpoint.go:123:69: unused-parameter: parameter 'params' seems to be unused, consider removing or renaming it as _ (revive)
    func (th *existingTokenHandler) AuthorizeRequest(req *http.Request, params map[string]string) error {
                                                                        ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:05:31 +02:00
92506afd49 cli/command/service/progress: remove name for unused parameter (revive)
This function must match the interface, but doesn't use the firs argument.

    cli/command/service/progress/progress.go:417:40: unused-parameter: parameter 'service' seems to be unused, consider removing or renaming it as _ (revive)
    func (u *globalProgressUpdater) update(service swarm.Service, tasks []swarm.Task, activeNodes map[string]struct{}, rollback bool) (bool, error) {
                                           ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:05:31 +02:00
c3d7f167bd cli/command: RunPrune(): remove name for unused "all" parameter (revive)
These functions must have the same signature, but only some of them accept
an "all" boolean argument;
88924b1802/cli/command/system/prune.go (L79)

    cli/command/container/prune.go:78:38: unused-parameter: parameter 'all' seems to be unused, consider removing or renaming it as _ (revive)
    func RunPrune(dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error) {
                                         ^
    cli/command/network/prune.go:73:38: unused-parameter: parameter 'all' seems to be unused, consider removing or renaming it as _ (revive)
    func RunPrune(dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error) {
                                         ^
    cli/command/volume/prune.go:78:38: unused-parameter: parameter 'all' seems to be unused, consider removing or renaming it as _ (revive)
    func RunPrune(dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error) {
                                         ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:05:30 +02:00
b4aff3a14d cli/command/completion: NoComplete(): remove unused argument (revive)
cli/command/completion/functions.go:97:17: unused-parameter: parameter 'cmd' seems to be unused, consider removing or renaming it as _ (revive)
    func NoComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
                    ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:05:30 +02:00
f08252c10a cli/command/stack: deprecate now obsolete wrappers
These wrappers were added to abstract stack deploy to k8s and swarm. Now
that support for deploying to k8s was removed, we can remove these wrappers.

This deprecates:

- RunDeploy()
- RunPs()
- RunRemove()
- GetServices()

This also addresses some linting failers, due to these functions having
unused arguments:

    cli/command/stack/deploy.go:51:39: unused-parameter: parameter 'flags' seems to be unused, consider removing or renaming it as _ (revive)
    func RunDeploy(dockerCli command.Cli, flags *pflag.FlagSet, config *composetypes.Config, opts options.Deploy) error {
                                              ^
    cli/command/stack/ps.go:42:35: unused-parameter: parameter 'flags' seems to be unused, consider removing or renaming it as _ (revive)
    func RunPs(dockerCli command.Cli, flags *pflag.FlagSet, opts options.PS) error {
                                      ^
    cli/command/stack/remove.go:35:39: unused-parameter: parameter 'flags' seems to be unused, consider removing or renaming it as _ (revive)
    func RunRemove(dockerCli command.Cli, flags *pflag.FlagSet, opts options.Remove) error {
                                          ^
    cli/command/stack/list.go:37:14: unused-parameter: parameter 'cmd' seems to be unused, consider removing or renaming it as _ (revive)
    func RunList(cmd *cobra.Command, dockerCli command.Cli, opts options.List) error {
                 ^
    cli/command/stack/services.go:56:41: unused-parameter: parameter 'flags' seems to be unused, consider removing or renaming it as _ (revive)
    func GetServices(dockerCli command.Cli, flags *pflag.FlagSet, opts options.Services) ([]swarmtypes.Service, error) {
                                            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:05:29 +02:00
78c474539b cli/command/context: remove redundant if ...; err != nil check (revive)
cli/command/context/create.go:121:2: if-return: redundant if ...; err != nil check, just return error instead. (revive)
        if err := s.ResetTLSMaterial(o.Name, &contextTLSData); err != nil {
            return err
        }

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:05:29 +02:00
be97731f1a cli/command/container: fix redefinition of the built-in function close (revive)
cli/command/container/run.go:176:3: redefines-builtin-id: redefinition of the built-in function close (revive)
            close, err := attachContainer(ctx, dockerCli, &errCh, config, createResponse.ID)
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 17:05:29 +02:00
a9fff59809 Merge pull request #4129 from crazy-max/fix-perf-reg-2
improve and load plugin command stubs when required
2023-03-30 17:05:16 +02:00
378e35e915 Merge pull request #4138 from thaJeztah/fix_go_version
gha: align stray go 1.19.4 version
2023-03-30 17:02:52 +02:00
b9a1b0928a cp: Make gocyclo happy
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2023-03-30 14:52:20 +00:00
90b7bc36d4 cp: Reduce number of progress updates
Only show progress updates after a time threshold has elapsed in order
to reduce the number of writes to the terminal.
This improves readability of the progress.

Also moves cursor show/hide into the progress printer to reduce chances
if messing up the user's terminal in case of cancellation.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2023-03-30 14:52:20 +00:00
efd011b793 cp: reduce branching in progress printer
This just makes it easier to reason about what is happening.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2023-03-30 14:51:50 +00:00
e4436853e8 gha: align stray go 1.19.4 version
looks like this one was forgotten to be updated :)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-30 16:50:29 +02:00
fc6703bd3d Merge pull request #4121 from developerjake/fix-docs-grammar
Fix grammar in docs by adding omitted word
2023-03-30 15:37:15 +02:00
9335690a66 Fix grammar in docs by adding omitted word
Edited second paragraph under ### Daemon configuration file to change "regardless their value" to "regardless of their value"

Signed-off-by: Jake Stokes <contactjake@developerjake.com>
2023-03-30 15:19:55 +02:00
ccae6e9299 cp: Improve tty flashing on progress updates
- Instead of rewriting the entire line every time only clear and write
the parts that changed.
- Hide the cursor while writing progress

Both these things make the progress updates significantly easier to
read.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2023-03-29 23:47:50 +00:00
f27927d934 cp: do not emit progress if stderr is not a term
This fixes a case where a non-tty will have control characters + the log
line for every single read operation.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2023-03-29 23:24:18 +00:00
88924b1802 Merge pull request #4133 from thaJeztah/engine_23.0.2
vendor: github.com/docker/docker v23.0.2
2023-03-29 13:29:45 +02:00
a39958846d vendor: github.com/docker/docker v23.0.2
- migrate away from things deprecated in Go 1.20 (removes use of archive/tar.TypeRegA)

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

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-28 18:35:05 +02:00
69c54641f7 Merge pull request #4130 from crazy-max/ci-split-build
ci: enhanced build workflow
2023-03-28 17:33:38 +02:00
c39c711a18 load plugin command stubs when required
We are currently loading plugin command stubs for every
invocation which still has a significant performance hit.
With this change we are doing this operation only if cobra
completion arg request is found.

- 20.10.23: `docker --version` takes ~15ms
- 23.0.1: `docker --version` takes ~93ms

With this change `docker --version` takes ~9ms

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-28 06:16:55 +02:00
62f2358b99 improve plugins discovery performance
We are currently loading plugin commands stubs for every
command invocation to add support for Cobra v2 completion.
This cause a significant performance hit if there is a
lot of plugins in the user space (7 atm in Docker Desktop):

`docker --version` takes in current 23.0.1 ~93ms

Instead of removing completion for plugins to fix the
regression, we can slightly improve plugins discovery by
spawning a goroutine for each iteration in the loop when
listing plugins:

`docker --version` now takes ~38ms

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-28 06:16:55 +02:00
bebdb6fa2a ci: enhanced build workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-28 04:59:09 +02:00
21653863b1 Merge pull request #4122 from crazy-max/fix-bake
don't use null values in the bake definition
2023-03-27 16:10:16 +02:00
bec5d37e91 don't use null values in the bake definition
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-27 14:32:14 +02:00
7f11449f35 Merge pull request #4123 from crazy-max/e2e-fix-certs
e2e: update notary certificates
2023-03-27 14:01:10 +02:00
b201ce5efd e2e: update notary certificates
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-27 13:28:00 +02:00
c6c33380da e2e: increase tests certificates duration (10 years)
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-27 13:28:00 +02:00
d234a81de7 bake target to generate certs for e2e tets
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-27 13:27:59 +02:00
59ec357996 Merge pull request #4117 from crazy-max/align-go-ver
Dockerfile: align go version
2023-03-26 16:56:33 +02:00
3ce95c7af0 Dockerfile: build binary if no target specified
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-24 21:14:41 +01:00
b854eff300 Dockerfile: align go version
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-24 21:11:53 +01:00
f5d698a331 Merge pull request #4114 from thaJeztah/remove_registry_service_step2
cli/trust: remove special handling for "plugin" Class
2023-03-23 19:34:49 +01:00
0ba820ed0b cli/trust: remove special handling for "plugin" Class
This code depended on the registry Service interface, which has been removed,
so needed to be refactored. Digging further into the reason this code existed,
it looked like the Class=plugin was previously required on Docker Hub to handle
plugins, but this requirement is no longer there, so we can remove this special
handling.

This patch removes the special handling to both remove the use of the registry.Service
interface, as well as removing complexity that is no longer needed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-23 13:44:48 +01:00
14482589df Merge pull request #4110 from thaJeztah/remove_ElectAuthServer
cli/command: remove deprecated ElectAuthServer()
2023-03-22 19:30:38 +01:00
a3d56e7d06 cli/command: remove deprecated ElectAuthServer()
This function was deprecated in b4ca1c7368,
which is part of the v23.0 release, and is no longer used, so we can remove it.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-22 14:31:03 +01:00
bfe87fd39b Merge pull request #4105 from thaJeztah/fix_comments
cli/command: ElectAuthServer: fix deprecation comment
2023-03-21 17:52:26 +01:00
742881fc58 cli/command: fix imports formatting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-21 16:55:34 +01:00
e3fa7280ad cli/command: ElectAuthServer: fix deprecation comment
The comment was not formatted correctly, and because of that not picked up as
being deprecated.

updates b4ca1c7368

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-21 16:53:03 +01:00
235b501b71 Merge pull request #4094 from crazy-max/plugins-completion
Add bash completion for available plugins
2023-03-21 16:45:08 +01:00
ac38a77ff9 Merge pull request #4104 from thaJeztah/volume_tests_discard
cli/command/volume: suppress err output in tests
2023-03-21 16:42:21 +01:00
3c9e0073dd Merge pull request #4099 from docker/dependabot/github_actions/actions/setup-go-4
build(deps): bump actions/setup-go from 3 to 4
2023-03-21 13:41:22 +01:00
db827d583b cli/command/volume: suppress err output in tests
These tests were deliberately producing errors as part of the test, but
printing those errors could be confusing / make it more difficult to find
actual test-failures.

Before this patch:

    === RUN   TestVolumeCreateErrors
    Error: conflicting options: either specify --name or provide positional arg, not both
    Error: "create" requires at most 1 argument.
    See 'create --help'.

    Usage:  create [OPTIONS] [VOLUME] [flags]

    Create a volume
    Error: error creating volume
    --- PASS: TestVolumeCreateErrors (0.00s)
    PASS

With this patch applied:

    === RUN   TestVolumeCreateErrors
    --- PASS: TestVolumeCreateErrors (0.00s)
    PASS

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-21 13:21:20 +01:00
166de0ec97 Merge pull request #4098 from thaJeztah/update_deps
update dependencies in preparation of updating engine
2023-03-21 13:05:16 +01:00
aa0aa4a6dc Add bash completion for available plugins
Signed-off-by: CrazyMax <github@crazymax.dev>
2023-03-17 15:04:09 +01:00
8805f8ea2d build(deps): bump actions/setup-go from 3 to 4
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 3 to 4.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v3...v4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-16 09:07:41 +00:00
e60c748c14 vendor: github.com/moby/buildkit v0.11.4
full diff: https://github.com/moby/buildkit/compare/v0.10.6..v0.11.4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-15 01:42:09 +01:00
6c8cc226f0 vendor: google.golang.org/grpc v1.50.1
full diff: https://github.com/grpc/grpc-go/compare/v1.48.0...v1.50.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-15 01:42:09 +01:00
d213548bd0 vendor: golang.org/x/net v0.7.0
full diff: https://github.com/golang/net/compare/v0.5.0...v0.7.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-15 01:42:00 +01:00
3a0d492d1c vendor: golang.org/x/term v0.5.0
full diff: https://github.com/golang/term/compare/v0.4.0...v0.5.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-15 01:38:48 +01:00
f40bbf4f7f vendor: golang.org/x/time v0.3.0
full diff: https://github.com/golang/time/compare/v0.1.0...v0.3.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-15 01:35:57 +01:00
a85537d346 vendor: golang.org/x/text v0.7.0
full diff: https://github.com/golang/text/compare/v0.6.0...v0.7.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-15 01:34:10 +01:00
3e9c6e84ce vendor: golang.org/x/sys v0.5.0
full diff: https://github.com/golang/sys/compare/v0.4.0...v0.5.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-15 01:32:29 +01:00
ca8783ef43 vendor: github.com/moby/swarmkit/v2 v2.0.0-20230309194213-a745a8755ce3
full diff: 904c221ac2...a745a8755c

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-15 01:03:04 +01:00
33806760a4 vendor: github.com/containerd/containerd v1.6.19
full diff: https://github.com/containerd/containerd/compare/v1.6.16...v1.6.19

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-15 01:03:04 +01:00
71e495aa54 vendor: github.com/docker/docker v23.0.1
full diff: https://github.com/docker/docker/compare/v23.0.0...v23.0.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-15 01:02:58 +01:00
12c6126a67 Merge pull request #4085 from thaJeztah/bump_go1.19.7
update to go1.19.7
2023-03-10 13:03:50 +01:00
078b99feb4 Merge pull request #4087 from thaJeztah/update_buildx
Dockerfile: update buildx to v0.10.4
2023-03-10 12:53:54 +01:00
74c4ed4171 Dockerfile: update buildx to v0.10.4
release notes: https://github.com/docker/buildx/releases/tag/v0.10.4

full diff: https://github.com/docker/buildx/compare/v0.10.3...v0.10.4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-10 12:31:44 +01:00
23da1cec6c update to go1.19.7
Includes a security fix for crypto/elliptic (CVE-2023-24532).

> go1.19.7 (released 2023-03-07) includes a security fix to the crypto/elliptic
> package, as well as bug fixes to the linker, the runtime, and the crypto/x509
> and syscall packages. See the Go 1.19.7 milestone on our issue tracker for
> details.

https://go.dev/doc/devel/release#go1.19.minor

From the announcement:

> We have just released Go versions 1.20.2 and 1.19.7, minor point releases.
>
> These minor releases include 1 security fixes following the security policy:
>
> - crypto/elliptic: incorrect P-256 ScalarMult and ScalarBaseMult results
    >
    >   The ScalarMult and ScalarBaseMult methods of the P256 Curve may return an
    >   incorrect result if called with some specific unreduced scalars (a scalar larger
    >   than the order of the curve).
    >
    >   This does not impact usages of crypto/ecdsa or crypto/ecdh.
>
> This is CVE-2023-24532 and Go issue https://go.dev/issue/58647.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-03-10 10:22:54 +01:00
677aac9011 Merge pull request #4081 from vvoland/windows-drive-cwd-env
stack/loader: Ignore cmd.exe special env variables
2023-03-09 20:35:55 +01:00
012b77952e stack: Change unexpected environment variable error
Make the error more specific by stating that it's caused by a specific
environment variable and not an environment as a whole.
Also don't escape the variable to make it more readable.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-03-09 16:56:34 +01:00
a47058bbd5 stack/loader: Ignore cmd.exe special env variables
On Windows, ignore all variables that start with "=" when building an
environment variables map for stack.
For MS-DOS compatibility cmd.exe can set some special environment
variables that start with a "=" characters, which breaks the general
assumption that the first encountered "=" separates a variable name from
variable value and causes trouble when parsing.

These variables don't seem to be documented anywhere, but they are
described by some third-party sources and confirmed empirically on my
Windows installation.

Useful sources:
https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133
https://ss64.com/nt/syntax-variables.html

Known variables:

- `=ExitCode` stores the exit code returned by external command (in hex
  format)
- `=ExitCodeAscii` - same as above, except the value is the ASCII
  representation of the code (so exit code 65 (0x41) becomes 'A').
- `=::=::\` and friends - store drive specific working directory.
  There is one env variable for each separate drive letter that was
  accessed in the shell session and stores the working directory for that
  specific drive.
  The general format for these is:
    `=<DRIVE_LETTER>:=<CWD>`  (key=`=<DRIVE_LETTER>:`, value=`<CWD>`)
  where <CWD> is a working directory for the drive that is assigned to
  the letter <DRIVE_LETTER>

  A couple of examples:
    `=C:=C:\some\dir`  (key: `=C:`, value: `C:\some\dir`)
    `=D:=D:\some\other\dir`  (key: `=C:`, value: `C:\some\dir`)
    `=Z:=Z:\`  (key: `=Z:`, value: `Z:\`)

  `=::=::\` is the one that seems to be always set and I'm not exactly
  sure what this one is for (what's drive `::`?). Others are set as
  soon as you CD to a path on some drive. Considering that you start a
  cmd.exe also has some working directory, there are 2 of these on start.

All these variables can be safely ignored because they can't be
deliberately set by the user, their meaning is only relevant to the
cmd.exe session and they're all are related to the MS-DOS/Batch feature
that are irrelevant for us.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-03-09 16:48:55 +01:00
c549fd7360 Merge pull request #4067 from laurazard/size-flag-ps
Don't automatically request size if `--size` was explicitly set to `false`
2023-03-06 12:09:59 +01:00
9733334487 Don't automatically request size if --size was explicitly set to false
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2023-03-03 18:26:20 +01:00
cb5463a728 Merge pull request #4069 from vvoland/deprecate-buildinfo
docs: Deprecate buildkit's build information
2023-03-03 16:29:03 +01:00
8bc1aaceae docs: Deprecate buildkit's build information
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-03-03 11:12:15 +01:00
179bc7a638 Merge pull request #4038 from thaJeztah/bump_go_1.19.6
update to go1.19.6
2023-03-02 14:34:23 +01:00
934dd5b5ce Merge pull request #4043 from desoss/master
Dockerfile: update buildx to v0.10.3
2023-03-02 14:33:49 +01:00
881c353576 Merge pull request #4046 from vvoland/dangling-images-none
formatter: Consider empty RepoTags and RepoDigests as dangling
2023-03-01 00:43:43 +01:00
89687d5b3f formatter: Consider empty RepoTags and RepoDigests as dangling
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-02-24 17:00:55 +01:00
b244ad61cc Merge pull request #4050 from vvoland/test-fakecli-images-mock
test/cli: Use empty array as empty output of images/json
2023-02-24 16:06:58 +01:00
a1953e19b2 test/cli: Use empty array as empty output of images/json
Tests mocking the output of GET images/json with fakeClient used an
array with one empty element as an empty response.
Change it to just an empty array.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-02-24 15:05:32 +01:00
0b05d28815 Merge pull request #4042 from nicks/nicks/write-file
context: adjust the file write logic to avoid corrupt context meta.json files
2023-02-23 17:27:59 +01:00
f5ac664f8a Merge pull request #4019 from neersighted/graphdriver_misleading
docs: drop dated comments about graphdrivers
2023-02-23 17:23:19 +01:00
e636747a14 docs: drop dated comments about graphdrivers
Signed-off-by: Bjorn Neergaard <bneergaard@mirantis.com>
2023-02-22 18:36:39 -07:00
dac79b19a7 Dockerfile: update buildx to v0.10.3
release notes: https://github.com/docker/buildx/releases/tag/v0.10.3

Signed-off-by: Jacopo Rigoli <rigoli.jacopo@gmail.com>
2023-02-23 00:52:26 +01:00
c2487c2997 context: avoid corrupt file writes
Write to a tempfile then move, so that if the
process dies mid-write it doesn't corrupt the store.

Also improve error messaging so that if a file does
get corrupted, the user has some hope of figuring
out which file is broken.

For background, see:
https://github.com/docker/for-win/issues/13180
https://github.com/docker/for-win/issues/12561

For a repro case, see:
https://github.com/nicks/contextstore-sandbox

Signed-off-by: Nick Santos <nick.santos@docker.com>
2023-02-21 10:37:56 -05:00
e921e103a4 update to go1.19.6
go1.19.6 (released 2023-02-14) includes security fixes to the crypto/tls,
mime/multipart, net/http, and path/filepath packages, as well as bug fixes to
the go command, the linker, the runtime, and the crypto/x509, net/http, and
time packages. See the Go 1.19.6 milestone on our issue tracker for details:

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

From the announcement on the security mailing:

We have just released Go versions 1.20.1 and 1.19.6, minor point releases.

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

- path/filepath: path traversal in filepath.Clean on Windows

  On Windows, the filepath.Clean function could transform an invalid path such
  as a/../c:/b into the valid path c:\b. This transformation of a relative (if
  invalid) path into an absolute path could enable a directory traversal attack.
  The filepath.Clean function will now transform this path into the relative
  (but still invalid) path .\c:\b.

  This is CVE-2022-41722 and Go issue https://go.dev/issue/57274.

- net/http, mime/multipart: denial of service from excessive resource
  consumption

  Multipart form parsing with mime/multipart.Reader.ReadForm can consume largely
  unlimited amounts of memory and disk files. This also affects form parsing in
  the net/http package with the Request methods FormFile, FormValue,
  ParseMultipartForm, and PostFormValue.

  ReadForm takes a maxMemory parameter, and is documented as storing "up to
  maxMemory bytes +10MB (reserved for non-file parts) in memory". File parts
  which cannot be stored in memory are stored on disk in temporary files. The
  unconfigurable 10MB reserved for non-file parts is excessively large and can
  potentially open a denial of service vector on its own. However, ReadForm did
  not properly account for all memory consumed by a parsed form, such as map
  ntry overhead, part names, and MIME headers, permitting a maliciously crafted
  form to consume well over 10MB. In addition, ReadForm contained no limit on
  the number of disk files created, permitting a relatively small request body
  to create a large number of disk temporary files.

  ReadForm now properly accounts for various forms of memory overhead, and
  should now stay within its documented limit of 10MB + maxMemory bytes of
  memory consumption. Users should still be aware that this limit is high and
  may still be hazardous.

  ReadForm now creates at most one on-disk temporary file, combining multiple
  form parts into a single temporary file. The mime/multipart.File interface
  type's documentation states, "If stored on disk, the File's underlying
  concrete type will be an *os.File.". This is no longer the case when a form
  contains more than one file part, due to this coalescing of parts into a
  single file. The previous behavior of using distinct files for each form part
  may be reenabled with the environment variable
  GODEBUG=multipartfiles=distinct.

  Users should be aware that multipart.ReadForm and the http.Request methods
  that call it do not limit the amount of disk consumed by temporary files.
  Callers can limit the size of form data with http.MaxBytesReader.

  This is CVE-2022-41725 and Go issue https://go.dev/issue/58006.

- crypto/tls: large handshake records may cause panics

  Both clients and servers may send large TLS handshake records which cause
  servers and clients, respectively, to panic when attempting to construct
  responses.

  This affects all TLS 1.3 clients, TLS 1.2 clients which explicitly enable
  session resumption (by setting Config.ClientSessionCache to a non-nil value),
  and TLS 1.3 servers which request client certificates (by setting
  Config.ClientAuth
  > = RequestClientCert).

  This is CVE-2022-41724 and Go issue https://go.dev/issue/58001.

- net/http: avoid quadratic complexity in HPACK decoding

  A maliciously crafted HTTP/2 stream could cause excessive CPU consumption
  in the HPACK decoder, sufficient to cause a denial of service from a small
  number of small requests.

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

  This is CVE-2022-41723 and Go issue https://go.dev/issue/57855.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-02-17 01:05:16 +01:00
dfb36eaef8 Merge pull request #4031 from thaJeztah/carry_4027
changed the container name in docker stats page (carry 4027)
2023-02-15 11:51:06 +01:00
d2f726d5ad changed the container name in docker stats page
Signed-off-by: Aslam Ahemad <aslamahemad@gmail.com>
2023-02-14 18:45:54 +01:00
c173316515 Merge pull request #4017 from crazy-max/fix-ci-events
ci: fix branch filter pattern
2023-02-09 19:53:57 +01:00
0f39598687 ci: fix branch filter pattern
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-02-09 18:03:11 +01:00
24b4924410 Merge pull request #4011 from neersighted/new_curator
MAINTAINERS: add myself as curator
2023-02-08 00:25:46 +01:00
4254cd19b9 MAINTAINERS: add myself as curator
Also remove a duplicate entry for @thaJeztah.

Signed-off-by: Bjorn Neergaard <bneergaard@mirantis.com>
2023-02-07 10:13:53 -07:00
f42e1ad1a7 Merge pull request #4002 from thaJeztah/update_engine
vendor: github.com/docker/docker v23.0.0
2023-02-06 14:44:38 +01:00
6872164e45 Merge pull request #3965 from scop/fix/bash-completion-nounset
contrib/completion: bash `nounset` mode fixes
2023-02-06 12:34:44 +01:00
7abb189120 Merge pull request #4001 from corhere/run-eisdir
cli/command/container: exit 126 on EISDIR error
2023-02-06 12:33:34 +01:00
a04dee2638 Merge pull request #3999 from akerouanton/fix/throttledevice-key
Fix bad ThrottleDevice path
2023-02-06 12:32:21 +01:00
bbebebaedf vendor: github.com/docker/docker v23.0.0
- client: improve error messaging on crash

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

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-02-04 13:30:07 +01:00
5195db1ff5 vendor: github.com/containerd/containerd v1.6.16
no changes in vendored code

full diff: https://github.com/containerd/containerd/compare/v1.6.15...v1.6.16

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-02-04 13:28:11 +01:00
9b5ceb52b0 cli/command/container: exit 126 on EISDIR error
The error returned from "os/exec".Command when attempting to execute a
directory has been changed from syscall.EACCESS to syscall.EISDIR on
Go 1.20. 2b8f214094
Consequently, any runc runtime built against Go 1.20 will return an
error containing 'is a directory' and not 'permission denied'. Update
the string matching so the CLI exits with status code 126 on 'is a
directory' errors (EISDIR) in addition to 'permission denied' (EACCESS).

Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-02-03 17:55:43 -05:00
56051b84b0 Fix bad ThrottleDevice path
Fixes moby/moby#44904.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2023-02-03 11:39:51 +01:00
e92dd87c32 Merge pull request #3996 from laurazard/skip-broken-credentials
Some checks failed
build / build (cross, ) (push) Has been cancelled
build / build (cross, glibc) (push) Has been cancelled
build / build (dynbinary-cross, ) (push) Has been cancelled
build / build (dynbinary-cross, glibc) (push) Has been cancelled
build / plugins (push) Has been cancelled
e2e / e2e (19.03-dind, non-experimental) (push) Has been cancelled
e2e / e2e (alpine, stable-dind, connhelper-ssh) (push) Has been cancelled
e2e / e2e (alpine, stable-dind, experimental) (push) Has been cancelled
e2e / e2e (alpine, stable-dind, non-experimental) (push) Has been cancelled
e2e / e2e (bullseye, stable-dind, connhelper-ssh) (push) Has been cancelled
e2e / e2e (bullseye, stable-dind, experimental) (push) Has been cancelled
e2e / e2e (bullseye, stable-dind, non-experimental) (push) Has been cancelled
test / ctn (push) Has been cancelled
test / host (macos-11) (push) Has been cancelled
validate / validate (lint) (push) Has been cancelled
validate / validate (shellcheck) (push) Has been cancelled
validate / validate (update-authors) (push) Has been cancelled
validate / validate (validate-vendor) (push) Has been cancelled
validate / validate-make (manpages) (push) Has been cancelled
validate / validate-make (yamldocs) (push) Has been cancelled
Fix issue where one bad credential helper causes no credentials to be returned
2023-01-31 17:45:07 +01:00
9e3d5d1528 Fix issue where one bad credential helper causes none to be returned
Instead, skip bad credential helpers (and warn the user about the error)

Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2023-01-31 17:14:30 +01:00
3ae101f41e Merge pull request #3991 from dvdksn/docs/refactor-docs-dir
docs: move doc generation scripts to subdir
2023-01-31 13:27:37 +01:00
3a118309b8 Merge pull request #3990 from jedevc/manifest-oci
Add OCI support to manifest subcommand
2023-01-31 13:24:39 +01:00
1e3622c50c docs: move doc generation scripts to subdir
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2023-01-31 06:33:23 +01:00
4a500f690f Merge pull request #3986 from AkihiroSuda/docker-container-remove
rm: allow `docker container remove` as an alias
2023-01-30 10:56:34 +01:00
9b54d860cd rm: allow docker container remove as an alias
Fix issue 3985

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2023-01-29 08:46:08 +09:00
0288f7f724 Merge pull request #3992 from neersighted/mke_ca_note
docs: add note about MKE CA rotation, which is potentially dangerous
2023-01-27 20:57:34 +01:00
00070e6e23 docs: add note about MKE CA rotation, which is potentially dangerous
Signed-off-by: Bjorn Neergaard <bneergaard@mirantis.com>
2023-01-27 08:19:27 -07:00
67b9617898 manifest: save raw manifest content on download
This prevents us needing to attempt to reconstruct the exact indentation
registry side, which is not canonical - so may differ.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-27 13:56:17 +00:00
285e137aa4 manifest: explicitly error if whitespace reconstruction has failed
This behavior should not break any more use cases than before.
Previously, if the mismatch occured, we would actually push a manifest
that we then never referred to in the manifest list! If this was done in
a new repository, the command would fail with an obscure error from the
registry - the content wouldn't exist with the descriptor we expect it
to.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-27 13:51:57 +00:00
070825bc74 manifest: add support for oci image types
Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-27 13:51:57 +00:00
645395cc77 Merge pull request #3987 from craig-osterhout/fix-exec-doc-typo
Fix typo in reference doc for docker exec
2023-01-24 08:41:29 +01:00
551c4e9ab9 Fix typo in reference doc for docker
Signed-off-by: Craig Osterhou <craig.osterhout@docker.com>

Signed-off-by: craig-osterhout <craig.osterhout@docker.com>
2023-01-23 14:05:21 -08:00
5f9c58ffa0 Merge pull request #3984 from thaJeztah/engine_23.0.0-rc.3
vendor: github.com/docker/docker v23.0.0-rc.3
2023-01-23 13:38:32 +01:00
8672540f8c vendor: github.com/docker/docker v23.0.0-rc.3
full diff: https://github.com/docker/docker/compare/v23.0.0-rc.2...v23.0.0-rc.3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-23 11:59:16 +01:00
c4fff9da13 vendor: github.com/moby/swarmkit/v2 v2.0.0-20230119195359-904c221ac281
full diff: 0da442b278...904c221ac2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-23 11:59:16 +01:00
526e5e7c95 vendor: golang.org/x/net v0.5.0
full diff: https://github.com/golang/net/compare/v0.4.0...v0.5.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-23 11:59:15 +01:00
d7f21ea9c8 vendor: golang.org/x/term v0.4.0
full diff: https://github.com/golang/term/compare/v0.3.0...v0.4.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-23 11:59:01 +01:00
ae43eb0e04 vendor: golang.org/x/text v0.6.0
no changes in vendored code

full diff: https://github.com/golang/text/compare/v0.5.0...v0.6.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-23 11:48:03 +01:00
caf8b152c6 vendor: golang.org/x/sys v0.4.0
full diff: https://github.com/golang/sys/compare/v0.3.0...v0.4.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-23 11:45:55 +01:00
e1152b2418 Merge pull request #3977 from alirostami01/master
Some checks failed
build / build (cross, ) (push) Has been cancelled
build / build (cross, glibc) (push) Has been cancelled
build / build (dynbinary-cross, ) (push) Has been cancelled
build / build (dynbinary-cross, glibc) (push) Has been cancelled
build / plugins (push) Has been cancelled
e2e / e2e (19.03-dind, non-experimental) (push) Has been cancelled
e2e / e2e (alpine, stable-dind, connhelper-ssh) (push) Has been cancelled
e2e / e2e (alpine, stable-dind, experimental) (push) Has been cancelled
e2e / e2e (alpine, stable-dind, non-experimental) (push) Has been cancelled
e2e / e2e (bullseye, stable-dind, connhelper-ssh) (push) Has been cancelled
e2e / e2e (bullseye, stable-dind, experimental) (push) Has been cancelled
e2e / e2e (bullseye, stable-dind, non-experimental) (push) Has been cancelled
test / ctn (push) Has been cancelled
test / host (macos-11) (push) Has been cancelled
validate / validate (lint) (push) Has been cancelled
validate / validate (shellcheck) (push) Has been cancelled
validate / validate (update-authors) (push) Has been cancelled
validate / validate (validate-vendor) (push) Has been cancelled
validate / validate-make (manpages) (push) Has been cancelled
validate / validate-make (yamldocs) (push) Has been cancelled
Fix section docker ps --size
2023-01-18 16:46:09 +01:00
be30cb370e Fix section docker ps --size
Remove the extra item "Size"

Signed-off-by: Ali Rostami <rostami.ali@gmail.com>
2023-01-18 13:17:35 +03:30
f7c322edba Merge pull request #1900 from yuchengwu/8831-doc-user-restrict
note `--user` args usage restriction
2023-01-17 23:03:07 +01:00
5d04b1c49e note --user args usage restriction
Signed-off-by: Yucheng Wu <wyc123wyc@gmail.com>
2023-01-17 22:45:23 +01:00
8627a6df16 Merge pull request #3971 from thaJeztah/sync_cobra_streams
cli: pass dockerCLI's in/out/err to cobra cmds
2023-01-17 17:57:03 +01:00
fe694e8219 Merge pull request #3973 from thaJeztah/no_escape
cli: additionalHelp() don't decorate output if it's piped, and add extra newline
2023-01-17 17:56:07 +01:00
1493806509 Merge pull request #3968 from crazy-max/fix-badges
README: fix badges
2023-01-17 15:57:20 +01:00
9bb70217f8 Add extra newline after additionalHelp output
The additionalHelp message is printed at the end of the --help output;

    To get more help with docker, check out our guides at https://docs.docker.com/go/guides/
    PS>

As this message may contain an URL, users may copy/paste the URL to open it
in their browser, but can easily end up copying their prompt (as there's
no whitespace after it), and as a result end up on a broken URL, for example:

    https://docs.docker.com/go/guides/PS

This patch adds an extra newline at the end to provide some whitespace
around the message, making it less error-prone to copy the URL;

    To get more help with docker, check out our guides at https://docs.docker.com/go/guides/

    PS>

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-15 15:23:06 +01:00
59e74b44ae cli: additionalHelp() don't decorate output if it's piped
This prevents the escape-characters being included when piping the
output, e.g. `docker --help > output.txt`, or `docker --help | something`.
These control-characters could cause issues if users copy/pasted the URL
from the output, resulting in them becoming part of the URL they tried
to visit, which would fail, e.g. when copying the output from:

    To get more help with docker, check out our guides at https://docs.docker.com/go/guides/

Users ended up on URLs like;

    https://docs.docker.com/go/guides/ESC
    https://docs.docker.com/go/guides/%1B[0m

Before this patch, control characters ("bold") would be printed, even if
no TTY was attached;

    docker --help > output.txt
    cat output.txt | grep 'For more help' | od -c
    0000000 033   [   1   m   F   o   r       m   o   r   e       h   e   l
    0000020   p       o   n       h   o   w       t   o       u   s   e
    0000040   D   o   c   k   e   r   ,       h   e   a   d       t   o
    0000060   h   t   t   p   s   :   /   /   d   o   c   s   .   d   o   c
    0000100   k   e   r   .   c   o   m   /   g   o   /   g   u   i   d   e
    0000120   s   / 033   [   0   m  \n
    0000127

    docker --help | grep 'For more help' | od -c
    0000000 033   [   1   m   F   o   r       m   o   r   e       h   e   l
    0000020   p       o   n       h   o   w       t   o       u   s   e
    0000040   D   o   c   k   e   r   ,       h   e   a   d       t   o
    0000060   h   t   t   p   s   :   /   /   d   o   c   s   .   d   o   c
    0000100   k   e   r   .   c   o   m   /   g   o   /   g   u   i   d   e
    0000120   s   / 033   [   0   m  \n
    0000127

With this patch, no control characters are included:

    docker --help > output.txt
    cat output.txt | grep 'For more help' | od -c
    0000000   F   o   r       m   o   r   e       h   e   l   p       o   n
    0000020       h   o   w       t   o       u   s   e       D   o   c   k
    0000040   e   r   ,       h   e   a   d       t   o       h   t   t   p
    0000060   s   :   /   /   d   o   c   s   .   d   o   c   k   e   r   .
    0000100   c   o   m   /   g   o   /   g   u   i   d   e   s   /  \n
    0000117

    docker --help | grep 'For more help' | od -c
    0000000   F   o   r       m   o   r   e       h   e   l   p       o   n
    0000020       h   o   w       t   o       u   s   e       D   o   c   k
    0000040   e   r   ,       h   e   a   d       t   o       h   t   t   p
    0000060   s   :   /   /   d   o   c   s   .   d   o   c   k   e   r   .
    0000100   c   o   m   /   g   o   /   g   u   i   d   e   s   /  \n
    0000117

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-15 15:14:57 +01:00
fc6be6ad30 cli: pass dockerCLI's in/out/err to cobra cmds
Both the DockerCLI and Cobra Commands provide accessors for Input, Output,
and Error streams (usually STDIN, STDOUT, STDERR). While we were already
passing DockerCLI's Output to Cobra, we were not doing so for the other
streams (and were passing none for plugin commands), potentially resulting
in DockerCLI output/input to mean something else than a Cobra Command's
intput/output/error.

This patch sets them to the same streams when constructing the Cobra
command.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-15 13:44:33 +01:00
d347678cde README: fix badges
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-01-13 19:18:26 +01:00
d0a4b6f497 Merge pull request #3966 from crazy-max/fix-docs-anchore
docs: fix duplicated format anchor in plugin_ls
2023-01-13 18:15:32 +01:00
e04f3dd0df docs: fix duplicated format anchor in plugin_ls
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-01-13 16:22:26 +01:00
1af9f22c7e Merge pull request #2998 from pseyfert/completion/zsh/volume
[completion/zsh] add volume completion
2023-01-13 12:22:14 +01:00
2753057c40 contrib/completion: bash nounset mode fixes
Signed-off-by: Ville Skyttä <ville.skytta@iki.fi>
2023-01-12 17:27:24 +02:00
f1f12a3332 Merge pull request #3963 from thaJeztah/engine_23.0_rc2
vendor: github.com/docker/docker v23.0.0-rc.2
2023-01-12 14:08:40 +01:00
c453cc6873 vendor: github.com/docker/docker v23.0.0-rc.2
full diff: https://github.com/docker/docker/compare/v23.0.0-rc.1...v23.0.0-rc.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-12 13:45:27 +01:00
0d16330dd2 vendor: github.com/containerd/containerd v1.6.15
no changes to vendored code

full diff: https://github.com/conainerd/containerd/compare/v1.6.14...v1.6.15

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-12 13:43:35 +01:00
35b42efad3 [completion/zsh] add volume completion
This provides completion for `docker run ... -v <TAB>`.
This closes (part of) #1997.

Signed-off-by: Paul Seyfert <pseyfert.mathphys@gmail.com>
2021-03-04 22:50:38 +01:00
429 changed files with 9004 additions and 4867 deletions

View File

@ -9,20 +9,41 @@ on:
push:
branches:
- 'master'
- '[0-9]+.[0-9]{2}'
- '[0-9]+.[0-9]+'
tags:
- 'v*'
pull_request:
jobs:
prepare:
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.platforms.outputs.matrix }}
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Create matrix
id: platforms
run: |
echo "matrix=$(docker buildx bake cross --print | jq -cr '.target."cross".platforms')" >>${GITHUB_OUTPUT}
-
name: Show matrix
run: |
echo ${{ steps.platforms.outputs.matrix }}
build:
runs-on: ubuntu-20.04
needs:
- prepare
strategy:
fail-fast: false
matrix:
target:
- cross
- dynbinary-cross
- binary
- dynbinary
platform: ${{ fromJson(needs.prepare.outputs.matrix) }}
use_glibc:
- ""
- glibc
@ -36,22 +57,22 @@ jobs:
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Run ${{ matrix.target }}
name: Build
uses: docker/bake-action@v2
with:
targets: ${{ matrix.target }}
set: |
*.platform=${{ matrix.platform }}
env:
USE_GLIBC: ${{ matrix.use_glibc }}
-
name: Flatten artifacts
name: Create tarball
working-directory: ./build
run: |
for dir in */; do
base=$(basename "$dir")
echo "Creating ${base}.tar.gz ..."
tar -cvzf "${base}.tar.gz" "$dir"
rm -rf "$dir"
done
mkdir /tmp/out
platform=${{ matrix.platform }}
platformPair=${platform//\//-}
tar -cvzf "/tmp/out/docker-${platformPair}.tar.gz" .
if [ -z "${{ matrix.use_glibc }}" ]; then
echo "ARTIFACT_NAME=${{ matrix.target }}" >> $GITHUB_ENV
else
@ -62,11 +83,35 @@ jobs:
uses: actions/upload-artifact@v3
with:
name: ${{ env.ARTIFACT_NAME }}
path: ./build/*
path: /tmp/out/*
if-no-files-found: error
prepare-plugins:
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.platforms.outputs.matrix }}
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Create matrix
id: platforms
run: |
echo "matrix=$(docker buildx bake plugins-cross --print | jq -cr '.target."plugins-cross".platforms')" >>${GITHUB_OUTPUT}
-
name: Show matrix
run: |
echo ${{ steps.platforms.outputs.matrix }}
plugins:
runs-on: ubuntu-20.04
needs:
- prepare-plugins
strategy:
fail-fast: false
matrix:
platform: ${{ fromJson(needs.prepare-plugins.outputs.matrix) }}
steps:
-
name: Checkout
@ -75,7 +120,9 @@ jobs:
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build plugins
name: Build
uses: docker/bake-action@v2
with:
targets: plugins-cross
set: |
*.platform=${{ matrix.platform }}

View File

@ -9,7 +9,7 @@ on:
push:
branches:
- 'master'
- '[0-9]+.[0-9]{2}'
- '[0-9]+.[0-9]+'
tags:
- 'v*'
pull_request:

View File

@ -9,7 +9,7 @@ on:
push:
branches:
- 'master'
- '[0-9]+.[0-9]{2}'
- '[0-9]+.[0-9]+'
tags:
- 'v*'
pull_request:
@ -61,9 +61,9 @@ jobs:
path: ${{ env.GOPATH }}/src/github.com/docker/cli
-
name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v4
with:
go-version: 1.19.4
go-version: 1.20.2
-
name: Test
run: |

View File

@ -9,7 +9,7 @@ on:
push:
branches:
- 'master'
- '[0-9]+.[0-9]{2}'
- '[0-9]+.[0-9]+'
tags:
- 'v*'
pull_request:

View File

@ -1,12 +1,12 @@
# syntax=docker/dockerfile:1
ARG BASE_VARIANT=alpine
ARG GO_VERSION=1.19.5
ARG GO_VERSION=1.20.2
ARG ALPINE_VERSION=3.16
ARG XX_VERSION=1.1.1
ARG GOVERSIONINFO_VERSION=v1.3.0
ARG GOTESTSUM_VERSION=v1.8.2
ARG BUILDX_VERSION=0.9.1
ARG BUILDX_VERSION=0.10.4
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
@ -125,8 +125,8 @@ CMD ./scripts/test/e2e/entry
FROM build-base-${BASE_VARIANT} AS dev
COPY . .
FROM scratch AS binary
COPY --from=build /out .
FROM scratch AS plugins
COPY --from=build-plugins /out .
FROM scratch AS binary
COPY --from=build /out .

View File

@ -49,9 +49,9 @@
people = [
"bsousaa",
"neersighted",
"programmerq",
"sam-thibault",
"thajeztah",
"vvoland"
]
@ -103,6 +103,11 @@
Email = "nicolas.deloof@gmail.com"
GitHub = "ndeloof"
[people.neersighted]
Name = "Bjorn Neergaard"
Email = "bneergaard@mirantis.com"
GitHub = "neersighted"
[people.programmerq]
Name = "Jeff Anderson"
Email = "jeff@docker.com"

View File

@ -1,10 +1,10 @@
# Docker CLI
[![PkgGoDev](https://img.shields.io/badge/go.dev-docs-007d9c?logo=go&logoColor=white)](https://pkg.go.dev/github.com/docker/cli)
[![Build Status](https://img.shields.io/github/workflow/status/docker/cli/build?label=build&logo=github)](https://github.com/docker/cli/actions?query=workflow%3Abuild)
[![Test Status](https://img.shields.io/github/workflow/status/docker/cli/test?label=test&logo=github)](https://github.com/docker/cli/actions?query=workflow%3Atest)
[![Build Status](https://img.shields.io/github/actions/workflow/status/docker/cli/build.yml?branch=master&label=build&logo=github)](https://github.com/docker/cli/actions?query=workflow%3Abuild)
[![Test Status](https://img.shields.io/github/actions/workflow/status/docker/cli/test.yml?branch=master&label=test&logo=github)](https://github.com/docker/cli/actions?query=workflow%3Atest)
[![Go Report Card](https://goreportcard.com/badge/github.com/docker/cli)](https://goreportcard.com/report/github.com/docker/cli)
[![Codecov](https://codecov.io/gh/docker/cli/branch/master/graph/badge.svg)](https://codecov.io/gh/docker/cli)
[![Codecov](https://img.shields.io/codecov/c/github/docker/cli?logo=codecov)](https://codecov.io/gh/docker/cli)
## About

View File

@ -3,6 +3,7 @@ package manager
import (
"fmt"
"os"
"sync"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
@ -31,64 +32,69 @@ const (
CommandAnnotationPluginInvalid = "com.docker.cli.plugin-invalid"
)
var pluginCommandStubsOnce sync.Once
// AddPluginCommandStubs adds a stub cobra.Commands for each valid and invalid
// plugin. The command stubs will have several annotations added, see
// `CommandAnnotationPlugin*`.
func AddPluginCommandStubs(dockerCli command.Cli, rootCmd *cobra.Command) error {
plugins, err := ListPlugins(dockerCli, rootCmd)
if err != nil {
return err
}
for _, p := range plugins {
p := p
vendor := p.Vendor
if vendor == "" {
vendor = "unknown"
func AddPluginCommandStubs(dockerCli command.Cli, rootCmd *cobra.Command) (err error) {
pluginCommandStubsOnce.Do(func() {
var plugins []Plugin
plugins, err = ListPlugins(dockerCli, rootCmd)
if err != nil {
return
}
annotations := map[string]string{
CommandAnnotationPlugin: "true",
CommandAnnotationPluginVendor: vendor,
CommandAnnotationPluginVersion: p.Version,
}
if p.Err != nil {
annotations[CommandAnnotationPluginInvalid] = p.Err.Error()
}
rootCmd.AddCommand(&cobra.Command{
Use: p.Name,
Short: p.ShortDescription,
Run: func(_ *cobra.Command, _ []string) {},
Annotations: annotations,
DisableFlagParsing: true,
RunE: func(cmd *cobra.Command, args []string) error {
flags := rootCmd.PersistentFlags()
flags.SetOutput(nil)
err := flags.Parse(args)
if err != nil {
return err
}
if flags.Changed("help") {
cmd.HelpFunc()(rootCmd, args)
return nil
}
return fmt.Errorf("docker: '%s' is not a docker command.\nSee 'docker --help'", cmd.Name())
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
// Delegate completion to plugin
cargs := []string{p.Path, cobra.ShellCompRequestCmd, p.Name}
cargs = append(cargs, args...)
cargs = append(cargs, toComplete)
os.Args = cargs
runCommand, err := PluginRunCommand(dockerCli, p.Name, cmd)
if err != nil {
for _, p := range plugins {
p := p
vendor := p.Vendor
if vendor == "" {
vendor = "unknown"
}
annotations := map[string]string{
CommandAnnotationPlugin: "true",
CommandAnnotationPluginVendor: vendor,
CommandAnnotationPluginVersion: p.Version,
}
if p.Err != nil {
annotations[CommandAnnotationPluginInvalid] = p.Err.Error()
}
rootCmd.AddCommand(&cobra.Command{
Use: p.Name,
Short: p.ShortDescription,
Run: func(_ *cobra.Command, _ []string) {},
Annotations: annotations,
DisableFlagParsing: true,
RunE: func(cmd *cobra.Command, args []string) error {
flags := rootCmd.PersistentFlags()
flags.SetOutput(nil)
perr := flags.Parse(args)
if perr != nil {
return err
}
if flags.Changed("help") {
cmd.HelpFunc()(rootCmd, args)
return nil
}
return fmt.Errorf("docker: '%s' is not a docker command.\nSee 'docker --help'", cmd.Name())
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
// Delegate completion to plugin
cargs := []string{p.Path, cobra.ShellCompRequestCmd, p.Name}
cargs = append(cargs, args...)
cargs = append(cargs, toComplete)
os.Args = cargs
runCommand, runErr := PluginRunCommand(dockerCli, p.Name, cmd)
if runErr != nil {
return nil, cobra.ShellCompDirectiveError
}
runErr = runCommand.Run()
if runErr == nil {
os.Exit(0) // plugin already rendered complete data
}
return nil, cobra.ShellCompDirectiveError
}
err = runCommand.Run()
if err == nil {
os.Exit(0) // plugin already rendered complete data
}
return nil, cobra.ShellCompDirectiveError
},
})
}
return nil
},
})
}
})
return err
}

View File

@ -133,7 +133,9 @@ func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta
}
opts, flags := cli.SetupPluginRootCommand(cmd)
cmd.SetIn(dockerCli.In())
cmd.SetOut(dockerCli.Out())
cmd.SetErr(dockerCli.Err())
cmd.AddCommand(
plugin,

View File

@ -204,6 +204,16 @@ func DisableFlagsInUseLine(cmd *cobra.Command) {
})
}
// HasCompletionArg returns true if a cobra completion arg request is found.
func HasCompletionArg(args []string) bool {
for _, arg := range args {
if arg == cobra.ShellCompRequestCmd || arg == cobra.ShellCompNoDescRequestCmd {
return true
}
}
return false
}
var helpCommand = &cobra.Command{
Use: "help [command]",
Short: "Help about the command",
@ -234,9 +244,13 @@ func isExperimental(cmd *cobra.Command) bool {
}
func additionalHelp(cmd *cobra.Command) string {
if additionalHelp, ok := cmd.Annotations["additionalHelp"]; ok {
if msg, ok := cmd.Annotations["additionalHelp"]; ok {
out := cmd.OutOrStderr()
if _, isTerminal := term.GetFdInfo(out); !isTerminal {
return msg
}
style := aec.EmptyBuilder.Bold().ANSI
return style.Apply(additionalHelp)
return style.Apply(msg)
}
return ""
}
@ -507,6 +521,7 @@ Run '{{.CommandPath}} COMMAND --help' for more information on a command.
{{- if hasAdditionalHelp .}}
{{ additionalHelp . }}
{{- end}}
`

View File

@ -14,21 +14,21 @@ type fakeClient struct {
checkpointListFunc func(container string, options types.CheckpointListOptions) ([]types.Checkpoint, error)
}
func (cli *fakeClient) CheckpointCreate(ctx context.Context, container string, options types.CheckpointCreateOptions) 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(ctx context.Context, container string, options types.CheckpointDeleteOptions) 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(ctx context.Context, container string, options types.CheckpointListOptions) ([]types.Checkpoint, error) {
func (cli *fakeClient) CheckpointList(_ context.Context, container string, options types.CheckpointListOptions) ([]types.Checkpoint, error) {
if cli.checkpointListFunc != nil {
return cli.checkpointListFunc(container, options)
}

View File

@ -191,7 +191,7 @@ func (cli *DockerCli) ManifestStore() manifeststore.Store {
// RegistryClient returns a client for communicating with a Docker distribution
// registry
func (cli *DockerCli) RegistryClient(allowInsecure bool) registryclient.RegistryClient {
resolver := func(ctx context.Context, index *registry.IndexInfo) types.AuthConfig {
resolver := func(ctx context.Context, index *registry.IndexInfo) registry.AuthConfig {
return ResolveAuthConfig(ctx, cli, index)
}
return registryclient.NewRegistryClient(resolver, UserAgent(), allowInsecure)

View File

@ -6,7 +6,7 @@ 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/filters"
"github.com/docker/docker/api/types/volume"
"github.com/spf13/cobra"
)
@ -66,13 +66,13 @@ func ContainerNames(dockerCli command.Cli, all bool, filters ...func(types.Conta
// VolumeNames offers completion for volumes
func VolumeNames(dockerCli command.Cli) ValidArgsFn {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, err := dockerCli.Client().VolumeList(cmd.Context(), filters.Args{})
list, err := dockerCli.Client().VolumeList(cmd.Context(), volume.ListOptions{})
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
var names []string
for _, volume := range list.Volumes {
names = append(names, volume.Name)
for _, vol := range list.Volumes {
names = append(names, vol.Name)
}
return names, cobra.ShellCompDirectiveNoFileComp
}
@ -94,6 +94,6 @@ func NetworkNames(dockerCli command.Cli) ValidArgsFn {
}
// NoComplete is used for commands where there's no relevant completion
func NoComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
func NoComplete(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveNoFileComp
}

View File

@ -10,34 +10,34 @@ import (
type fakeClient struct {
client.Client
configCreateFunc func(swarm.ConfigSpec) (types.ConfigCreateResponse, error)
configInspectFunc func(string) (swarm.Config, []byte, error)
configListFunc func(types.ConfigListOptions) ([]swarm.Config, error)
configCreateFunc func(context.Context, swarm.ConfigSpec) (types.ConfigCreateResponse, error)
configInspectFunc func(context.Context, string) (swarm.Config, []byte, error)
configListFunc func(context.Context, types.ConfigListOptions) ([]swarm.Config, error)
configRemoveFunc func(string) error
}
func (c *fakeClient) ConfigCreate(ctx context.Context, spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
if c.configCreateFunc != nil {
return c.configCreateFunc(spec)
return c.configCreateFunc(ctx, spec)
}
return types.ConfigCreateResponse{}, nil
}
func (c *fakeClient) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.Config, []byte, error) {
if c.configInspectFunc != nil {
return c.configInspectFunc(id)
return c.configInspectFunc(ctx, id)
}
return swarm.Config{}, nil, nil
}
func (c *fakeClient) ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
if c.configListFunc != nil {
return c.configListFunc(options)
return c.configListFunc(ctx, options)
}
return []swarm.Config{}, nil
}
func (c *fakeClient) ConfigRemove(ctx context.Context, name string) error {
func (c *fakeClient) ConfigRemove(_ context.Context, name string) error {
if c.configRemoveFunc != nil {
return c.configRemoveFunc(name)
}

View File

@ -1,6 +1,7 @@
package config
import (
"context"
"io"
"os"
"path/filepath"
@ -22,7 +23,7 @@ const configDataFile = "config-create-with-name.golden"
func TestConfigCreateErrors(t *testing.T) {
testCases := []struct {
args []string
configCreateFunc func(swarm.ConfigSpec) (types.ConfigCreateResponse, error)
configCreateFunc func(context.Context, swarm.ConfigSpec) (types.ConfigCreateResponse, error)
expectedError string
}{
{
@ -35,7 +36,7 @@ func TestConfigCreateErrors(t *testing.T) {
},
{
args: []string{"name", filepath.Join("testdata", configDataFile)},
configCreateFunc: func(configSpec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
configCreateFunc: func(_ context.Context, configSpec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
return types.ConfigCreateResponse{}, errors.Errorf("error creating config")
},
expectedError: "error creating config",
@ -57,7 +58,7 @@ func TestConfigCreateWithName(t *testing.T) {
name := "foo"
var actual []byte
cli := test.NewFakeCli(&fakeClient{
configCreateFunc: func(spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
configCreateFunc: func(_ context.Context, spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
if spec.Name != name {
return types.ConfigCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
}
@ -96,7 +97,7 @@ func TestConfigCreateWithLabels(t *testing.T) {
}
cli := test.NewFakeCli(&fakeClient{
configCreateFunc: func(spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
configCreateFunc: func(_ context.Context, spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
if !reflect.DeepEqual(spec, expected) {
return types.ConfigCreateResponse{}, errors.Errorf("expected %+v, got %+v", expected, spec)
}
@ -122,7 +123,7 @@ func TestConfigCreateWithTemplatingDriver(t *testing.T) {
name := "foo"
cli := test.NewFakeCli(&fakeClient{
configCreateFunc: func(spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
configCreateFunc: func(_ context.Context, spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
if spec.Name != name {
return types.ConfigCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
}

View File

@ -1,6 +1,7 @@
package config
import (
"context"
"fmt"
"io"
"testing"
@ -18,7 +19,7 @@ func TestConfigInspectErrors(t *testing.T) {
testCases := []struct {
args []string
flags map[string]string
configInspectFunc func(configID string) (swarm.Config, []byte, error)
configInspectFunc func(_ context.Context, configID string) (swarm.Config, []byte, error)
expectedError string
}{
{
@ -26,7 +27,7 @@ func TestConfigInspectErrors(t *testing.T) {
},
{
args: []string{"foo"},
configInspectFunc: func(configID string) (swarm.Config, []byte, error) {
configInspectFunc: func(_ context.Context, configID string) (swarm.Config, []byte, error) {
return swarm.Config{}, nil, errors.Errorf("error while inspecting the config")
},
expectedError: "error while inspecting the config",
@ -40,7 +41,7 @@ func TestConfigInspectErrors(t *testing.T) {
},
{
args: []string{"foo", "bar"},
configInspectFunc: func(configID string) (swarm.Config, []byte, error) {
configInspectFunc: func(_ context.Context, configID string) (swarm.Config, []byte, error) {
if configID == "foo" {
return *Config(ConfigName("foo")), nil, nil
}
@ -68,12 +69,12 @@ func TestConfigInspectWithoutFormat(t *testing.T) {
testCases := []struct {
name string
args []string
configInspectFunc func(configID string) (swarm.Config, []byte, error)
configInspectFunc func(_ context.Context, configID string) (swarm.Config, []byte, error)
}{
{
name: "single-config",
args: []string{"foo"},
configInspectFunc: func(name string) (swarm.Config, []byte, error) {
configInspectFunc: func(_ context.Context, name string) (swarm.Config, []byte, error) {
if name != "foo" {
return swarm.Config{}, nil, errors.Errorf("Invalid name, expected %s, got %s", "foo", name)
}
@ -83,7 +84,7 @@ func TestConfigInspectWithoutFormat(t *testing.T) {
{
name: "multiple-configs-with-labels",
args: []string{"foo", "bar"},
configInspectFunc: func(name string) (swarm.Config, []byte, error) {
configInspectFunc: func(_ context.Context, name string) (swarm.Config, []byte, error) {
return *Config(ConfigID("ID-"+name), ConfigName(name), ConfigLabels(map[string]string{
"label1": "label-foo",
})), nil, nil
@ -100,7 +101,7 @@ func TestConfigInspectWithoutFormat(t *testing.T) {
}
func TestConfigInspectWithFormat(t *testing.T) {
configInspectFunc := func(name string) (swarm.Config, []byte, error) {
configInspectFunc := func(_ context.Context, name string) (swarm.Config, []byte, error) {
return *Config(ConfigName("foo"), ConfigLabels(map[string]string{
"label1": "label-foo",
})), nil, nil
@ -109,7 +110,7 @@ func TestConfigInspectWithFormat(t *testing.T) {
name string
format string
args []string
configInspectFunc func(name string) (swarm.Config, []byte, error)
configInspectFunc func(_ context.Context, name string) (swarm.Config, []byte, error)
}{
{
name: "simple-template",
@ -139,11 +140,11 @@ func TestConfigInspectWithFormat(t *testing.T) {
func TestConfigInspectPretty(t *testing.T) {
testCases := []struct {
name string
configInspectFunc func(string) (swarm.Config, []byte, error)
configInspectFunc func(context.Context, string) (swarm.Config, []byte, error)
}{
{
name: "simple",
configInspectFunc: func(id string) (swarm.Config, []byte, error) {
configInspectFunc: func(_ context.Context, id string) (swarm.Config, []byte, error) {
return *Config(
ConfigLabels(map[string]string{
"lbl1": "value1",

View File

@ -1,6 +1,7 @@
package config
import (
"context"
"io"
"testing"
"time"
@ -19,7 +20,7 @@ import (
func TestConfigListErrors(t *testing.T) {
testCases := []struct {
args []string
configListFunc func(types.ConfigListOptions) ([]swarm.Config, error)
configListFunc func(context.Context, types.ConfigListOptions) ([]swarm.Config, error)
expectedError string
}{
{
@ -27,7 +28,7 @@ func TestConfigListErrors(t *testing.T) {
expectedError: "accepts no argument",
},
{
configListFunc: func(options types.ConfigListOptions) ([]swarm.Config, error) {
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
return []swarm.Config{}, errors.Errorf("error listing configs")
},
expectedError: "error listing configs",
@ -47,7 +48,7 @@ func TestConfigListErrors(t *testing.T) {
func TestConfigList(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(options types.ConfigListOptions) ([]swarm.Config, error) {
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
return []swarm.Config{
*Config(ConfigID("ID-1-foo"),
ConfigName("1-foo"),
@ -77,7 +78,7 @@ func TestConfigList(t *testing.T) {
func TestConfigListWithQuietOption(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(options types.ConfigListOptions) ([]swarm.Config, error) {
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
return []swarm.Config{
*Config(ConfigID("ID-foo"), ConfigName("foo")),
*Config(ConfigID("ID-bar"), ConfigName("bar"), ConfigLabels(map[string]string{
@ -94,7 +95,7 @@ func TestConfigListWithQuietOption(t *testing.T) {
func TestConfigListWithConfigFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(options types.ConfigListOptions) ([]swarm.Config, error) {
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
return []swarm.Config{
*Config(ConfigID("ID-foo"), ConfigName("foo")),
*Config(ConfigID("ID-bar"), ConfigName("bar"), ConfigLabels(map[string]string{
@ -113,7 +114,7 @@ func TestConfigListWithConfigFormat(t *testing.T) {
func TestConfigListWithFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(options types.ConfigListOptions) ([]swarm.Config, error) {
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
return []swarm.Config{
*Config(ConfigID("ID-foo"), ConfigName("foo")),
*Config(ConfigID("ID-bar"), ConfigName("bar"), ConfigLabels(map[string]string{
@ -130,7 +131,7 @@ func TestConfigListWithFormat(t *testing.T) {
func TestConfigListWithFilter(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(options types.ConfigListOptions) ([]swarm.Config, error) {
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
assert.Check(t, is.Equal("foo", options.Filters.Get("name")[0]))
assert.Check(t, is.Equal("lbl1=Label-bar", options.Filters.Get("label")[0]))
return []swarm.Config{

View File

@ -64,7 +64,7 @@ func (f *fakeClient) ContainerExecInspect(_ context.Context, execID string) (typ
return types.ContainerExecInspect{}, nil
}
func (f *fakeClient) ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error {
func (f *fakeClient) ContainerExecStart(context.Context, string, types.ExecStartCheck) error {
return nil
}
@ -89,7 +89,7 @@ func (f *fakeClient) ContainerRemove(ctx context.Context, container string, opti
return nil
}
func (f *fakeClient) ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) {
func (f *fakeClient) ImageCreate(_ context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) {
if f.imageCreateFunc != nil {
return f.imageCreateFunc(parentReference, options)
}

View File

@ -1,15 +1,20 @@
package container
import (
"bytes"
"context"
"fmt"
"io"
"os"
"os/signal"
"path/filepath"
"strings"
"sync/atomic"
"time"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/streams"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/system"
@ -48,26 +53,73 @@ type cpConfig struct {
// copying files to/from a container.
type copyProgressPrinter struct {
io.ReadCloser
toContainer bool
total *float64
writer io.Writer
total *int64
}
const (
copyToContainerHeader = "Copying to container - "
copyFromContainerHeader = "Copying from container - "
copyProgressUpdateThreshold = 75 * time.Millisecond
)
func (pt *copyProgressPrinter) Read(p []byte) (int, error) {
n, err := pt.ReadCloser.Read(p)
*pt.total += float64(n)
atomic.AddInt64(pt.total, int64(n))
return n, err
}
if err == nil {
fmt.Fprint(pt.writer, aec.Restore)
fmt.Fprint(pt.writer, aec.EraseLine(aec.EraseModes.All))
if pt.toContainer {
fmt.Fprintln(pt.writer, "Copying to container - "+units.HumanSize(*pt.total))
} else {
fmt.Fprintln(pt.writer, "Copying from container - "+units.HumanSize(*pt.total))
}
func copyProgress(ctx context.Context, dst io.Writer, header string, total *int64) (func(), <-chan struct{}) {
done := make(chan struct{})
if !streams.NewOut(dst).IsTerminal() {
close(done)
return func() {}, done
}
return n, err
fmt.Fprint(dst, aec.Save)
fmt.Fprint(dst, "Preparing to copy...")
restore := func() {
fmt.Fprint(dst, aec.Restore)
fmt.Fprint(dst, aec.EraseLine(aec.EraseModes.All))
}
go func() {
defer close(done)
fmt.Fprint(dst, aec.Hide)
defer fmt.Fprint(dst, aec.Show)
fmt.Fprint(dst, aec.Restore)
fmt.Fprint(dst, aec.EraseLine(aec.EraseModes.All))
fmt.Fprint(dst, header)
var last int64
fmt.Fprint(dst, progressHumanSize(last))
buf := bytes.NewBuffer(nil)
ticker := time.NewTicker(copyProgressUpdateThreshold)
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
n := atomic.LoadInt64(total)
if n == last {
// Don't write to the terminal, if we don't need to.
continue
}
// Write to the buffer first to avoid flickering and context switching
fmt.Fprint(buf, aec.Column(uint(len(header)+1)))
fmt.Fprint(buf, aec.EraseLine(aec.EraseModes.Tail))
fmt.Fprint(buf, progressHumanSize(n))
buf.WriteTo(dst)
buf.Reset()
last += n
}
}
}()
return restore, done
}
// NewCopyCommand creates a new `docker cp` command
@ -113,6 +165,10 @@ func NewCopyCommand(dockerCli command.Cli) *cobra.Command {
return cmd
}
func progressHumanSize(n int64) string {
return units.HumanSizeWithPrecision(float64(n), 3)
}
func runCopy(dockerCli command.Cli, opts copyOptions) error {
srcContainer, srcPath := splitCpArg(opts.source)
destContainer, destPath := splitCpArg(opts.destination)
@ -153,7 +209,7 @@ func resolveLocalPath(localPath string) (absPath string, err error) {
if absPath, err = filepath.Abs(localPath); err != nil {
return
}
return archive.PreserveTrailingDotOrSeparator(absPath, localPath, filepath.Separator), nil
return archive.PreserveTrailingDotOrSeparator(absPath, localPath), nil
}
func copyFromContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpConfig) (err error) {
@ -193,6 +249,9 @@ func copyFromContainer(ctx context.Context, dockerCli command.Cli, copyConfig cp
}
ctx, cancel := signal.NotifyContext(ctx, os.Interrupt)
defer cancel()
content, stat, err := client.CopyFromContainer(ctx, copyConfig.container, srcPath)
if err != nil {
return err
@ -211,13 +270,11 @@ func copyFromContainer(ctx context.Context, dockerCli command.Cli, copyConfig cp
RebaseName: rebaseName,
}
var copiedSize float64
var copiedSize int64
if !copyConfig.quiet {
content = &copyProgressPrinter{
ReadCloser: content,
toContainer: false,
writer: dockerCli.Err(),
total: &copiedSize,
ReadCloser: content,
total: &copiedSize,
}
}
@ -231,12 +288,12 @@ func copyFromContainer(ctx context.Context, dockerCli command.Cli, copyConfig cp
return archive.CopyTo(preArchive, srcInfo, dstPath)
}
fmt.Fprint(dockerCli.Err(), aec.Save)
fmt.Fprintln(dockerCli.Err(), "Preparing to copy...")
restore, done := copyProgress(ctx, dockerCli.Err(), copyFromContainerHeader, &copiedSize)
res := archive.CopyTo(preArchive, srcInfo, dstPath)
fmt.Fprint(dockerCli.Err(), aec.Restore)
fmt.Fprint(dockerCli.Err(), aec.EraseLine(aec.EraseModes.All))
fmt.Fprintln(dockerCli.Err(), "Successfully copied", units.HumanSize(copiedSize), "to", dstPath)
cancel()
<-done
restore()
fmt.Fprintln(dockerCli.Err(), "Successfully copied", progressHumanSize(copiedSize), "to", dstPath)
return res
}
@ -293,7 +350,7 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpCo
var (
content io.ReadCloser
resolvedDstPath string
copiedSize float64
copiedSize int64
)
if srcPath == "-" {
@ -337,10 +394,8 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpCo
content = preparedArchive
if !copyConfig.quiet {
content = &copyProgressPrinter{
ReadCloser: content,
toContainer: true,
writer: dockerCli.Err(),
total: &copiedSize,
ReadCloser: content,
total: &copiedSize,
}
}
}
@ -354,12 +409,13 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpCo
return client.CopyToContainer(ctx, copyConfig.container, resolvedDstPath, content, options)
}
fmt.Fprint(dockerCli.Err(), aec.Save)
fmt.Fprintln(dockerCli.Err(), "Preparing to copy...")
ctx, cancel := signal.NotifyContext(ctx, os.Interrupt)
restore, done := copyProgress(ctx, dockerCli.Err(), copyToContainerHeader, &copiedSize)
res := client.CopyToContainer(ctx, copyConfig.container, resolvedDstPath, content, options)
fmt.Fprint(dockerCli.Err(), aec.Restore)
fmt.Fprint(dockerCli.Err(), aec.EraseLine(aec.EraseModes.All))
fmt.Fprintln(dockerCli.Err(), "Successfully copied", units.HumanSize(copiedSize), "to", copyConfig.container+":"+dstInfo.Path)
cancel()
<-done
restore()
fmt.Fprintln(dockerCli.Err(), "Successfully copied", progressHumanSize(copiedSize), "to", copyConfig.container+":"+dstInfo.Path)
return res
}

View File

@ -227,7 +227,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && !opts.untrusted {
var err error
trustedRef, err = image.TrustedReference(ctx, dockerCli, taggedRef, nil)
trustedRef, err = image.TrustedReference(ctx, dockerCli, taggedRef)
if err != nil {
return nil, err
}

View File

@ -17,14 +17,15 @@ import (
)
type psOptions struct {
quiet bool
size bool
all bool
noTrunc bool
nLatest bool
last int
format string
filter opts.FilterOpt
quiet bool
size bool
sizeChanged bool
all bool
noTrunc bool
nLatest bool
last int
format string
filter opts.FilterOpt
}
// NewPsCommand creates a new cobra.Command for `docker ps`
@ -36,6 +37,7 @@ func NewPsCommand(dockerCli command.Cli) *cobra.Command {
Short: "List containers",
Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
options.sizeChanged = cmd.Flags().Changed("size")
return runPs(dockerCli, &options)
},
Annotations: map[string]string{
@ -78,13 +80,8 @@ func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, er
options.Limit = 1
}
if !opts.quiet && !options.Size && len(opts.format) > 0 {
// The --size option isn't set, but .Size may be used in the template.
// Parse and execute the given template to detect if the .Size field is
// used. If it is, then automatically enable the --size option. See #24696
//
// Only requesting container size information when needed is an optimization,
// because calculating the size is a costly operation.
// always validate template when `--format` is used, for consistency
if len(opts.format) > 0 {
tmpl, err := templates.NewParse("", opts.format)
if err != nil {
return nil, errors.Wrap(err, "failed to parse template")
@ -98,8 +95,19 @@ func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, er
return nil, errors.Wrap(err, "failed to execute template")
}
if _, ok := optionsProcessor.FieldsUsed["Size"]; ok {
options.Size = true
// if `size` was not explicitly set to false (with `--size=false`)
// and `--quiet` is not set, request size if the template requires it
if !opts.quiet && !options.Size && !opts.sizeChanged {
// The --size option isn't set, but .Size may be used in the template.
// Parse and execute the given template to detect if the .Size field is
// used. If it is, then automatically enable the --size option. See #24696
//
// Only requesting container size information when needed is an optimization,
// because calculating the size is a costly operation.
if _, ok := optionsProcessor.FieldsUsed["Size"]; ok {
options.Size = true
}
}
}

View File

@ -231,15 +231,56 @@ func TestContainerListFormatTemplateWithArg(t *testing.T) {
}
func TestContainerListFormatSizeSetsOption(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(options types.ContainerListOptions) ([]types.Container, error) {
assert.Check(t, options.Size)
return []types.Container{}, nil
tests := []struct {
doc, format, sizeFlag string
sizeExpected bool
}{
{
doc: "detect with all fields",
format: `{{json .}}`,
sizeExpected: true,
},
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", `{{.Size}}`)
assert.NilError(t, cmd.Execute())
{
doc: "detect with explicit field",
format: `{{.Size}}`,
sizeExpected: true,
},
{
doc: "detect no size",
format: `{{.Names}}`,
sizeExpected: false,
},
{
doc: "override enable",
format: `{{.Names}}`,
sizeFlag: "true",
sizeExpected: true,
},
{
doc: "override disable",
format: `{{.Size}}`,
sizeFlag: "false",
sizeExpected: false,
},
}
for _, tc := range tests {
tc := tc
t.Run(tc.doc, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(options types.ContainerListOptions) ([]types.Container, error) {
assert.Check(t, is.Equal(options.Size, tc.sizeExpected))
return []types.Container{}, nil
},
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", tc.format)
if tc.sizeFlag != "" {
cmd.Flags().Set("size", tc.sizeFlag)
}
assert.NilError(t, cmd.Execute())
})
}
}
func TestContainerListWithConfigFormat(t *testing.T) {

View File

@ -75,6 +75,6 @@ func runPrune(dockerCli command.Cli, options pruneOptions) (spaceReclaimed uint6
// RunPrune calls the Container Prune API
// This returns the amount of space reclaimed and a detailed output string
func RunPrune(dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error) {
func RunPrune(dockerCli command.Cli, _ bool, filter opts.FilterOpt) (uint64, string, error) {
return runPrune(dockerCli, pruneOptions{force: true, filter: filter})
}

View File

@ -27,15 +27,16 @@ func NewRmCommand(dockerCli command.Cli) *cobra.Command {
var opts rmOptions
cmd := &cobra.Command{
Use: "rm [OPTIONS] CONTAINER [CONTAINER...]",
Short: "Remove one or more containers",
Args: cli.RequiresMinArgs(1),
Use: "rm [OPTIONS] CONTAINER [CONTAINER...]",
Aliases: []string{"remove"},
Short: "Remove one or more containers",
Args: cli.RequiresMinArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.containers = args
return runRm(dockerCli, &opts)
},
Annotations: map[string]string{
"aliases": "docker container rm, docker rm",
"aliases": "docker container rm, docker container remove, docker rm",
},
ValidArgsFunction: completion.ContainerNames(dockerCli, true),
}

View File

@ -173,11 +173,11 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio
dockerCli.ConfigFile().DetachKeys = opts.detachKeys
}
close, err := attachContainer(ctx, dockerCli, &errCh, config, createResponse.ID)
closeFn, err := attachContainer(ctx, dockerCli, &errCh, config, createResponse.ID)
if err != nil {
return err
}
defer close()
defer closeFn()
}
statusChan := waitExitOrRemoved(ctx, dockerCli, createResponse.ID, copts.autoRemove)
@ -308,7 +308,8 @@ func runStartContainerErr(err error) error {
strings.Contains(trimmedErr, "no such file or directory") ||
strings.Contains(trimmedErr, "system cannot find the file specified") {
statusError = cli.StatusError{StatusCode: 127}
} else if strings.Contains(trimmedErr, syscall.EACCES.Error()) {
} else if strings.Contains(trimmedErr, syscall.EACCES.Error()) ||
strings.Contains(trimmedErr, syscall.EISDIR.Error()) {
statusError = cli.StatusError{StatusCode: 126}
}

View File

@ -118,10 +118,7 @@ func createNewContext(o *CreateOptions, cli command.Cli, s store.Writer) error {
if err := s.CreateOrUpdate(contextMetadata); err != nil {
return err
}
if err := s.ResetTLSMaterial(o.Name, &contextTLSData); err != nil {
return err
}
return nil
return s.ResetTLSMaterial(o.Name, &contextTLSData)
}
func checkContextNameForCreation(s store.Reader, name string) error {

View File

@ -27,6 +27,9 @@ type ImageContext struct {
}
func isDangling(image types.ImageSummary) bool {
if len(image.RepoTags) == 0 && len(image.RepoDigests) == 0 {
return true
}
return len(image.RepoTags) == 1 && image.RepoTags[0] == "<none>:<none>" && len(image.RepoDigests) == 1 && image.RepoDigests[0] == "<none>@<none>"
}

View File

@ -14,14 +14,14 @@ type fakeClient struct {
serviceInspectFunc func(string) (swarm.Service, []byte, error)
}
func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) {
func (cli *fakeClient) NodeInspectWithRaw(_ context.Context, nodeID string) (swarm.Node, []byte, error) {
if cli.nodeInspectFunc != nil {
return cli.nodeInspectFunc(nodeID)
}
return swarm.Node{}, []byte{}, nil
}
func (cli *fakeClient) ServiceInspectWithRaw(ctx context.Context, serviceID string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
func (cli *fakeClient) ServiceInspectWithRaw(_ context.Context, serviceID string, _ types.ServiceInspectOptions) (swarm.Service, []byte, error) {
if cli.serviceInspectFunc != nil {
return cli.serviceInspectFunc(serviceID)
}

View File

@ -22,6 +22,7 @@ import (
"github.com/docker/docker/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/builder/remotecontext/urlutil"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/idtools"
@ -279,7 +280,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
var resolvedTags []*resolvedTag
if !options.untrusted {
translator := func(ctx context.Context, ref reference.NamedTagged) (reference.Canonical, error) {
return TrustedReference(ctx, dockerCli, ref, nil)
return TrustedReference(ctx, dockerCli, ref)
}
// if there is a tar wrapper, the dockerfile needs to be replaced inside it
if buildCtx != nil {
@ -322,9 +323,9 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
configFile := dockerCli.ConfigFile()
creds, _ := configFile.GetAllCredentials()
authConfigs := make(map[string]types.AuthConfig, len(creds))
authConfigs := make(map[string]registrytypes.AuthConfig, len(creds))
for k, auth := range creds {
authConfigs[k] = types.AuthConfig(auth)
authConfigs[k] = registrytypes.AuthConfig(auth)
}
buildOptions := imageBuildOptions(dockerCli, options)
buildOptions.Version = types.BuilderV1

View File

@ -18,7 +18,7 @@ import (
const dockerfileContents = "FROM busybox"
func prepareEmpty(t *testing.T) string {
func prepareEmpty(_ *testing.T) string {
return ""
}

View File

@ -87,11 +87,11 @@ func (cli *fakeClient) ImageLoad(_ context.Context, input io.Reader, quiet bool)
return types.ImageLoadResponse{}, nil
}
func (cli *fakeClient) ImageList(ctx context.Context, options types.ImageListOptions) ([]types.ImageSummary, error) {
func (cli *fakeClient) ImageList(_ context.Context, options types.ImageListOptions) ([]types.ImageSummary, error) {
if cli.imageListFunc != nil {
return cli.imageListFunc(options)
}
return []types.ImageSummary{{}}, nil
return []types.ImageSummary{}, nil
}
func (cli *fakeClient) ImageInspectWithRaw(_ context.Context, image string) (types.ImageInspect, []byte, error) {

View File

@ -30,7 +30,7 @@ func TestNewImagesCommandErrors(t *testing.T) {
name: "failed-list",
expectedError: "something went wrong",
imageListFunc: func(options types.ImageListOptions) ([]types.ImageSummary, error) {
return []types.ImageSummary{{}}, errors.Errorf("something went wrong")
return []types.ImageSummary{}, errors.Errorf("something went wrong")
},
},
}
@ -66,7 +66,7 @@ func TestNewImagesCommandSuccess(t *testing.T) {
args: []string{"image"},
imageListFunc: func(options types.ImageListOptions) ([]types.ImageSummary, error) {
assert.Check(t, is.Equal("image", options.Filters.Get("reference")[0]))
return []types.ImageSummary{{}}, nil
return []types.ImageSummary{}, nil
},
},
{
@ -74,7 +74,7 @@ func TestNewImagesCommandSuccess(t *testing.T) {
args: []string{"--filter", "name=value"},
imageListFunc: func(options types.ImageListOptions) ([]types.ImageSummary, error) {
assert.Check(t, is.Equal("value", options.Filters.Get("name")[0]))
return []types.ImageSummary{{}}, nil
return []types.ImageSummary{}, nil
},
},
}

View File

@ -69,7 +69,7 @@ func RunPull(cli command.Cli, opts PullOptions) error {
}
ctx := context.Background()
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, AuthResolver(cli), distributionRef.String())
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), distributionRef.String())
if err != nil {
return err
}

View File

@ -30,7 +30,7 @@ type target struct {
}
// TrustedPush handles content trust pushing of an image
func TrustedPush(ctx context.Context, cli command.Cli, repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig types.AuthConfig, options types.ImagePushOptions) error {
func TrustedPush(ctx context.Context, cli command.Cli, repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig registrytypes.AuthConfig, options types.ImagePushOptions) error {
responseBody, err := cli.Client().ImagePush(ctx, reference.FamiliarString(ref), options)
if err != nil {
return err
@ -44,7 +44,7 @@ func TrustedPush(ctx context.Context, cli command.Cli, repoInfo *registry.Reposi
// PushTrustedReference pushes a canonical reference to the trust server.
//
//nolint:gocyclo
func PushTrustedReference(streams command.Streams, repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig types.AuthConfig, in io.Reader) error {
func PushTrustedReference(streams command.Streams, repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig registrytypes.AuthConfig, in io.Reader) error {
// If it is a trusted push we would like to find the target entry which match the
// tag provided in the function and then do an AddTarget later.
target := &client.Target{}
@ -186,7 +186,7 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image
if err != nil {
return err
}
updatedImgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, AuthResolver(cli), trustedRef.String())
updatedImgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), trustedRef.String())
if err != nil {
return err
}
@ -289,8 +289,8 @@ func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth tru
}
// TrustedReference returns the canonical trusted reference for an image reference
func TrustedReference(ctx context.Context, cli command.Cli, ref reference.NamedTagged, rs registry.Service) (reference.Canonical, error) {
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, rs, AuthResolver(cli), ref.String())
func TrustedReference(ctx context.Context, cli command.Cli, ref reference.NamedTagged) (reference.Canonical, error) {
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), ref.String())
if err != nil {
return nil, err
}
@ -340,8 +340,8 @@ 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) types.AuthConfig {
return func(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig {
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(ctx, cli, index)
}
}

View File

@ -12,6 +12,7 @@ import (
registryclient "github.com/docker/cli/cli/registry/client"
"github.com/docker/distribution"
"github.com/docker/distribution/manifest/manifestlist"
"github.com/docker/distribution/manifest/ocischema"
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/reference"
"github.com/docker/docker/registry"
@ -217,18 +218,53 @@ func buildPutManifestRequest(imageManifest types.ImageManifest, targetRef refere
return mountRequest{}, err
}
// This indentation has to be added to ensure sha parity with the registry
v2ManifestBytes, err := json.MarshalIndent(imageManifest.SchemaV2Manifest, "", " ")
if err != nil {
return mountRequest{}, err
// Attempt to reconstruct indentation of the manifest to ensure sha parity
// with the registry - if we haven't preserved the raw content.
//
// This is necessary because our previous internal storage format did not
// preserve whitespace. If we don't have the newer format present, we can
// attempt the reconstruction like before, but explicitly error if the
// reconstruction failed!
switch {
case imageManifest.SchemaV2Manifest != nil:
dt := imageManifest.Raw
if len(dt) == 0 {
dt, err = json.MarshalIndent(imageManifest.SchemaV2Manifest, "", " ")
if err != nil {
return mountRequest{}, err
}
}
dig := imageManifest.Descriptor.Digest
if dig2 := dig.Algorithm().FromBytes(dt); dig != dig2 {
return mountRequest{}, errors.Errorf("internal digest mismatch for %s: expected %s, got %s", imageManifest.Ref, dig, dig2)
}
var manifest schema2.DeserializedManifest
if err = manifest.UnmarshalJSON(dt); err != nil {
return mountRequest{}, err
}
imageManifest.SchemaV2Manifest = &manifest
case imageManifest.OCIManifest != nil:
dt := imageManifest.Raw
if len(dt) == 0 {
dt, err = json.MarshalIndent(imageManifest.OCIManifest, "", " ")
if err != nil {
return mountRequest{}, err
}
}
dig := imageManifest.Descriptor.Digest
if dig2 := dig.Algorithm().FromBytes(dt); dig != dig2 {
return mountRequest{}, errors.Errorf("internal digest mismatch for %s: expected %s, got %s", imageManifest.Ref, dig, dig2)
}
var manifest ocischema.DeserializedManifest
if err = manifest.UnmarshalJSON(dt); err != nil {
return mountRequest{}, err
}
imageManifest.OCIManifest = &manifest
}
// indent only the DeserializedManifest portion of this, in order to maintain parity with the registry
// and not alter the sha
var v2Manifest schema2.DeserializedManifest
if err = v2Manifest.UnmarshalJSON(v2ManifestBytes); err != nil {
return mountRequest{}, err
}
imageManifest.SchemaV2Manifest = &v2Manifest
return mountRequest{ref: mountRef, manifest: imageManifest}, err
}

View File

@ -14,6 +14,7 @@
"variant": "v7"
}
},
"Raw": "ewogICAic2NoZW1hVmVyc2lvbiI6IDIsCiAgICJtZWRpYVR5cGUiOiAiYXBwbGljYXRpb24vdm5kLmRvY2tlci5kaXN0cmlidXRpb24ubWFuaWZlc3QudjIranNvbiIsCiAgICJjb25maWciOiB7CiAgICAgICJtZWRpYVR5cGUiOiAiYXBwbGljYXRpb24vdm5kLmRvY2tlci5jb250YWluZXIuaW1hZ2UudjEranNvbiIsCiAgICAgICJzaXplIjogMTUyMCwKICAgICAgImRpZ2VzdCI6ICJzaGEyNTY6NzMyOGY2ZjhiNDE4OTA1OTc1NzVjYmFhZGM4ODRlNzM4NmFlMGFjYzUzYjc0NzQwMWViY2U1Y2YwZDYyNDU2MCIKICAgfSwKICAgImxheWVycyI6IFsKICAgICAgewogICAgICAgICAibWVkaWFUeXBlIjogImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuaW1hZ2Uucm9vdGZzLmRpZmYudGFyLmd6aXAiLAogICAgICAgICAic2l6ZSI6IDE5OTA0MDIsCiAgICAgICAgICJkaWdlc3QiOiAic2hhMjU2Ojg4Mjg2ZjQxNTMwZTkzZGZmZDRiOTY0ZTFkYjIyY2U0OTM5ZmZmYTRhNGM2NjVkYWI4NTkxZmJhYjAzZDQ5MjYiCiAgICAgIH0KICAgXQp9",
"SchemaV2Manifest": {
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",

View File

@ -76,6 +76,8 @@ func getManifest(ctx context.Context, dockerCli command.Cli, listRef, namedRef r
return dockerCli.RegistryClient(insecure).GetManifest(ctx, namedRef)
case err != nil:
return types.ImageManifest{}, err
case len(data.Raw) == 0:
return dockerCli.RegistryClient(insecure).GetManifest(ctx, namedRef)
default:
return data, nil
}

View File

@ -52,6 +52,6 @@ func (c *fakeClient) NetworkRemove(ctx context.Context, networkID string) error
return nil
}
func (c *fakeClient) NetworkInspectWithRaw(ctx context.Context, network string, options types.NetworkInspectOptions) (types.NetworkResource, []byte, error) {
func (c *fakeClient) NetworkInspectWithRaw(context.Context, string, types.NetworkInspectOptions) (types.NetworkResource, []byte, error) {
return types.NetworkResource{}, nil, nil
}

View File

@ -70,7 +70,7 @@ func runPrune(dockerCli command.Cli, options pruneOptions) (output string, err e
// RunPrune calls the Network Prune API
// This returns the amount of space reclaimed and a detailed output string
func RunPrune(dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error) {
func RunPrune(dockerCli command.Cli, _ bool, filter opts.FilterOpt) (uint64, string, error) {
output, err := runPrune(dockerCli, pruneOptions{force: true, filter: filter})
return 0, output, err
}

View File

@ -20,49 +20,49 @@ type fakeClient struct {
serviceInspectFunc func(ctx context.Context, serviceID string, opts types.ServiceInspectOptions) (swarm.Service, []byte, error)
}
func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, ref string) (swarm.Node, []byte, error) {
func (cli *fakeClient) NodeInspectWithRaw(context.Context, string) (swarm.Node, []byte, error) {
if cli.nodeInspectFunc != nil {
return cli.nodeInspectFunc()
}
return swarm.Node{}, []byte{}, nil
}
func (cli *fakeClient) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
func (cli *fakeClient) NodeList(context.Context, types.NodeListOptions) ([]swarm.Node, error) {
if cli.nodeListFunc != nil {
return cli.nodeListFunc()
}
return []swarm.Node{}, nil
}
func (cli *fakeClient) NodeRemove(ctx context.Context, nodeID string, options types.NodeRemoveOptions) error {
func (cli *fakeClient) NodeRemove(context.Context, string, types.NodeRemoveOptions) error {
if cli.nodeRemoveFunc != nil {
return cli.nodeRemoveFunc()
}
return nil
}
func (cli *fakeClient) NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error {
func (cli *fakeClient) NodeUpdate(_ context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error {
if cli.nodeUpdateFunc != nil {
return cli.nodeUpdateFunc(nodeID, version, node)
}
return nil
}
func (cli *fakeClient) Info(ctx context.Context) (types.Info, error) {
func (cli *fakeClient) Info(context.Context) (types.Info, error) {
if cli.infoFunc != nil {
return cli.infoFunc()
}
return types.Info{}, nil
}
func (cli *fakeClient) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) {
func (cli *fakeClient) TaskInspectWithRaw(_ context.Context, taskID string) (swarm.Task, []byte, error) {
if cli.taskInspectFunc != nil {
return cli.taskInspectFunc(taskID)
}
return swarm.Task{}, []byte{}, nil
}
func (cli *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
func (cli *fakeClient) TaskList(_ context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
if cli.taskListFunc != nil {
return cli.taskListFunc(options)
}

View File

@ -20,42 +20,42 @@ type fakeClient struct {
pluginInspectFunc func(name string) (*types.Plugin, []byte, error)
}
func (c *fakeClient) PluginCreate(ctx context.Context, createContext io.Reader, createOptions types.PluginCreateOptions) error {
func (c *fakeClient) PluginCreate(_ context.Context, createContext io.Reader, createOptions types.PluginCreateOptions) error {
if c.pluginCreateFunc != nil {
return c.pluginCreateFunc(createContext, createOptions)
}
return nil
}
func (c *fakeClient) PluginEnable(ctx context.Context, name string, enableOptions types.PluginEnableOptions) error {
func (c *fakeClient) PluginEnable(_ context.Context, name string, enableOptions types.PluginEnableOptions) error {
if c.pluginEnableFunc != nil {
return c.pluginEnableFunc(name, enableOptions)
}
return nil
}
func (c *fakeClient) PluginDisable(context context.Context, name string, disableOptions types.PluginDisableOptions) error {
func (c *fakeClient) PluginDisable(_ context.Context, name string, disableOptions types.PluginDisableOptions) error {
if c.pluginDisableFunc != nil {
return c.pluginDisableFunc(name, disableOptions)
}
return nil
}
func (c *fakeClient) PluginRemove(context context.Context, name string, removeOptions types.PluginRemoveOptions) error {
func (c *fakeClient) PluginRemove(_ context.Context, name string, removeOptions types.PluginRemoveOptions) error {
if c.pluginRemoveFunc != nil {
return c.pluginRemoveFunc(name, removeOptions)
}
return nil
}
func (c *fakeClient) PluginInstall(context context.Context, name string, installOptions types.PluginInstallOptions) (io.ReadCloser, error) {
func (c *fakeClient) PluginInstall(_ context.Context, name string, installOptions types.PluginInstallOptions) (io.ReadCloser, error) {
if c.pluginInstallFunc != nil {
return c.pluginInstallFunc(name, installOptions)
}
return nil, nil
}
func (c *fakeClient) PluginList(context context.Context, filter filters.Args) (types.PluginsListResponse, error) {
func (c *fakeClient) PluginList(_ context.Context, filter filters.Args) (types.PluginsListResponse, error) {
if c.pluginListFunc != nil {
return c.pluginListFunc(filter)
}
@ -63,7 +63,7 @@ func (c *fakeClient) PluginList(context context.Context, filter filters.Args) (t
return types.PluginsListResponse{}, nil
}
func (c *fakeClient) PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) {
func (c *fakeClient) PluginInspectWithRaw(_ context.Context, name string) (*types.Plugin, []byte, error) {
if c.pluginInspectFunc != nil {
return c.pluginInspectFunc(name)
}
@ -71,6 +71,6 @@ func (c *fakeClient) PluginInspectWithRaw(ctx context.Context, name string) (*ty
return nil, nil, nil
}
func (c *fakeClient) Info(ctx context.Context) (types.Info, error) {
func (c *fakeClient) Info(context.Context) (types.Info, error) {
return types.Info{}, nil
}

View File

@ -54,26 +54,6 @@ func newInstallCommand(dockerCli command.Cli) *cobra.Command {
return cmd
}
type pluginRegistryService struct {
registry.Service
}
func (s pluginRegistryService) ResolveRepository(name reference.Named) (*registry.RepositoryInfo, error) {
repoInfo, err := s.Service.ResolveRepository(name)
if repoInfo != nil {
repoInfo.Class = "plugin"
}
return repoInfo, err
}
func newRegistryService() (registry.Service, error) {
svc, err := registry.NewService(registry.ServiceOptions{})
if err != nil {
return nil, err
}
return pluginRegistryService{Service: svc}, nil
}
func buildPullConfig(ctx context.Context, dockerCli command.Cli, opts pluginOptions, cmdName string) (types.PluginInstallOptions, error) {
// Names with both tag and digest will be treated by the daemon
// as a pull by digest with a local name for the tag
@ -98,12 +78,7 @@ func buildPullConfig(ctx context.Context, dockerCli command.Cli, opts pluginOpti
return types.PluginInstallOptions{}, errors.Errorf("invalid name: %s", ref.String())
}
ctx := context.Background()
svc, err := newRegistryService()
if err != nil {
return types.PluginInstallOptions{}, err
}
trusted, err := image.TrustedReference(ctx, dockerCli, nt, svc)
trusted, err := image.TrustedReference(context.Background(), dockerCli, nt)
if err != nil {
return types.PluginInstallOptions{}, err
}

View File

@ -68,7 +68,6 @@ func runPush(dockerCli command.Cli, opts pushOptions) error {
defer responseBody.Close()
if !opts.untrusted {
repoInfo.Class = "plugin"
return image.PushTrustedReference(dockerCli, repoInfo, named, authConfig, responseBody)
}

View File

@ -21,14 +21,8 @@ import (
"github.com/pkg/errors"
)
// ElectAuthServer returns the default registry to use
// Deprecated: use registry.IndexServer instead
func ElectAuthServer(_ context.Context, _ Cli) string {
return registry.IndexServer
}
// EncodeAuthToBase64 serializes the auth configuration as JSON base64 payload
func EncodeAuthToBase64(authConfig types.AuthConfig) (string, error) {
func EncodeAuthToBase64(authConfig registrytypes.AuthConfig) (string, error) {
buf, err := json.Marshal(authConfig)
if err != nil {
return "", err
@ -58,19 +52,19 @@ func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInf
// ResolveAuthConfig is like registry.ResolveAuthConfig, but if using the
// default index, it uses the default index name for the daemon's platform,
// not the client's platform.
func ResolveAuthConfig(_ context.Context, cli Cli, index *registrytypes.IndexInfo) types.AuthConfig {
func ResolveAuthConfig(_ context.Context, cli Cli, index *registrytypes.IndexInfo) registrytypes.AuthConfig {
configKey := index.Name
if index.Official {
configKey = registry.IndexServer
}
a, _ := cli.ConfigFile().GetAuthConfig(configKey)
return types.AuthConfig(a)
return registrytypes.AuthConfig(a)
}
// GetDefaultAuthConfig gets the default auth config given a serverAddress
// If credentials for given serverAddress exists in the credential store, the configuration will be populated with values in it
func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, isDefaultRegistry bool) (types.AuthConfig, error) {
func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, isDefaultRegistry bool) (registrytypes.AuthConfig, error) {
if !isDefaultRegistry {
serverAddress = registry.ConvertToHostname(serverAddress)
}
@ -79,19 +73,19 @@ func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, is
if checkCredStore {
authconfig, err = cli.ConfigFile().GetAuthConfig(serverAddress)
if err != nil {
return types.AuthConfig{
return registrytypes.AuthConfig{
ServerAddress: serverAddress,
}, err
}
}
authconfig.ServerAddress = serverAddress
authconfig.IdentityToken = ""
res := types.AuthConfig(authconfig)
res := registrytypes.AuthConfig(authconfig)
return res, nil
}
// ConfigureAuth handles prompting of user's username and password if needed
func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *types.AuthConfig, isDefaultRegistry bool) error {
func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *registrytypes.AuthConfig, isDefaultRegistry bool) error {
// On Windows, force the use of the regular OS stdin stream. Fixes #14336/#14210
if runtime.GOOS == "windows" {
cli.SetIn(streams.NewIn(os.Stdin))
@ -181,14 +175,14 @@ func RetrieveAuthTokenFromImage(ctx context.Context, cli Cli, image string) (str
}
// resolveAuthConfigFromImage retrieves that AuthConfig using the image string
func resolveAuthConfigFromImage(ctx context.Context, cli Cli, image string) (types.AuthConfig, error) {
func resolveAuthConfigFromImage(ctx context.Context, cli Cli, image string) (registrytypes.AuthConfig, error) {
registryRef, err := reference.ParseNormalizedNamed(image)
if err != nil {
return types.AuthConfig{}, err
return registrytypes.AuthConfig{}, err
}
repoInfo, err := registry.ParseRepositoryInfo(registryRef)
if err != nil {
return types.AuthConfig{}, err
return registrytypes.AuthConfig{}, err
}
return ResolveAuthConfig(ctx, cli, repoInfo.Index), nil
}

View File

@ -10,7 +10,6 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
configtypes "github.com/docker/cli/cli/config/types"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/client"
"github.com/docker/docker/errdefs"
@ -164,7 +163,7 @@ func runLogin(dockerCli command.Cli, opts loginOptions) error { //nolint:gocyclo
return nil
}
func loginWithCredStoreCreds(ctx context.Context, dockerCli command.Cli, authConfig *types.AuthConfig) (registrytypes.AuthenticateOKBody, error) {
func loginWithCredStoreCreds(ctx context.Context, dockerCli command.Cli, authConfig *registrytypes.AuthConfig) (registrytypes.AuthenticateOKBody, error) {
fmt.Fprintf(dockerCli.Out(), "Authenticating with existing credentials...\n")
cliClient := dockerCli.Client()
response, err := cliClient.RegistryLogin(ctx, *authConfig)
@ -178,7 +177,7 @@ func loginWithCredStoreCreds(ctx context.Context, dockerCli command.Cli, authCon
return response, err
}
func loginClientSide(ctx context.Context, auth types.AuthConfig) (registrytypes.AuthenticateOKBody, error) {
func loginClientSide(ctx context.Context, auth registrytypes.AuthConfig) (registrytypes.AuthenticateOKBody, error) {
svc, err := registry.NewService(registry.ServiceOptions{})
if err != nil {
return registrytypes.AuthenticateOKBody{}, err

View File

@ -34,11 +34,11 @@ type fakeClient struct {
client.Client
}
func (c fakeClient) Info(ctx context.Context) (types.Info, error) {
func (c fakeClient) Info(context.Context) (types.Info, error) {
return types.Info{}, nil
}
func (c fakeClient) RegistryLogin(ctx context.Context, auth types.AuthConfig) (registrytypes.AuthenticateOKBody, error) {
func (c fakeClient) RegistryLogin(_ context.Context, auth registrytypes.AuthConfig) (registrytypes.AuthenticateOKBody, error) {
if auth.Password == expiredPassword {
return registrytypes.AuthenticateOKBody{}, fmt.Errorf("Invalid Username or Password")
}
@ -53,16 +53,16 @@ func (c fakeClient) RegistryLogin(ctx context.Context, auth types.AuthConfig) (r
func TestLoginWithCredStoreCreds(t *testing.T) {
testCases := []struct {
inputAuthConfig types.AuthConfig
inputAuthConfig registrytypes.AuthConfig
expectedMsg string
expectedErr string
}{
{
inputAuthConfig: types.AuthConfig{},
inputAuthConfig: registrytypes.AuthConfig{},
expectedMsg: "Authenticating with existing credentials...\n",
},
{
inputAuthConfig: types.AuthConfig{
inputAuthConfig: registrytypes.AuthConfig{
Username: userErr,
},
expectedMsg: "Authenticating with existing credentials...\n",

View File

@ -6,16 +6,14 @@ import (
"fmt"
"testing"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
// Prevents a circular import with "github.com/docker/cli/internal/test"
. "github.com/docker/cli/cli/command"
. "github.com/docker/cli/cli/command" // Prevents a circular import with "github.com/docker/cli/internal/test"
configtypes "github.com/docker/cli/cli/config/types"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
type fakeClient struct {
@ -23,7 +21,7 @@ type fakeClient struct {
infoFunc func() (types.Info, error)
}
var testAuthConfigs = []types.AuthConfig{
var testAuthConfigs = []registry.AuthConfig{
{
ServerAddress: "https://index.docker.io/v1/",
Username: "u0",
@ -48,13 +46,13 @@ func TestGetDefaultAuthConfig(t *testing.T) {
checkCredStore bool
inputServerAddress string
expectedErr string
expectedAuthConfig types.AuthConfig
expectedAuthConfig registry.AuthConfig
}{
{
checkCredStore: false,
inputServerAddress: "",
expectedErr: "",
expectedAuthConfig: types.AuthConfig{
expectedAuthConfig: registry.AuthConfig{
ServerAddress: "",
Username: "",
Password: "",
@ -104,7 +102,7 @@ func TestGetDefaultAuthConfig_HelperError(t *testing.T) {
cli.SetErr(errBuf)
cli.ConfigFile().CredentialsStore = "fake-does-not-exist"
serverAddress := "test-server-address"
expectedAuthConfig := types.AuthConfig{
expectedAuthConfig := registry.AuthConfig{
ServerAddress: serverAddress,
}
authconfig, err := GetDefaultAuthConfig(cli, true, serverAddress, serverAddress == "https://index.docker.io/v1/")

View File

@ -10,36 +10,36 @@ import (
type fakeClient struct {
client.Client
secretCreateFunc func(swarm.SecretSpec) (types.SecretCreateResponse, error)
secretInspectFunc func(string) (swarm.Secret, []byte, error)
secretListFunc func(types.SecretListOptions) ([]swarm.Secret, error)
secretRemoveFunc func(string) error
secretCreateFunc func(context.Context, swarm.SecretSpec) (types.SecretCreateResponse, error)
secretInspectFunc func(context.Context, string) (swarm.Secret, []byte, error)
secretListFunc func(context.Context, types.SecretListOptions) ([]swarm.Secret, error)
secretRemoveFunc func(context.Context, string) error
}
func (c *fakeClient) SecretCreate(ctx context.Context, spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
if c.secretCreateFunc != nil {
return c.secretCreateFunc(spec)
return c.secretCreateFunc(ctx, spec)
}
return types.SecretCreateResponse{}, nil
}
func (c *fakeClient) SecretInspectWithRaw(ctx context.Context, id string) (swarm.Secret, []byte, error) {
if c.secretInspectFunc != nil {
return c.secretInspectFunc(id)
return c.secretInspectFunc(ctx, id)
}
return swarm.Secret{}, nil, nil
}
func (c *fakeClient) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
if c.secretListFunc != nil {
return c.secretListFunc(options)
return c.secretListFunc(ctx, options)
}
return []swarm.Secret{}, nil
}
func (c *fakeClient) SecretRemove(ctx context.Context, name string) error {
if c.secretRemoveFunc != nil {
return c.secretRemoveFunc(name)
return c.secretRemoveFunc(ctx, name)
}
return nil
}

View File

@ -1,6 +1,7 @@
package secret
import (
"context"
"io"
"os"
"path/filepath"
@ -21,7 +22,7 @@ const secretDataFile = "secret-create-with-name.golden"
func TestSecretCreateErrors(t *testing.T) {
testCases := []struct {
args []string
secretCreateFunc func(swarm.SecretSpec) (types.SecretCreateResponse, error)
secretCreateFunc func(context.Context, swarm.SecretSpec) (types.SecretCreateResponse, error)
expectedError string
}{
{
@ -34,7 +35,7 @@ func TestSecretCreateErrors(t *testing.T) {
},
{
args: []string{"name", filepath.Join("testdata", secretDataFile)},
secretCreateFunc: func(secretSpec swarm.SecretSpec) (types.SecretCreateResponse, error) {
secretCreateFunc: func(_ context.Context, secretSpec swarm.SecretSpec) (types.SecretCreateResponse, error) {
return types.SecretCreateResponse{}, errors.Errorf("error creating secret")
},
expectedError: "error creating secret",
@ -66,7 +67,7 @@ func TestSecretCreateWithName(t *testing.T) {
}
cli := test.NewFakeCli(&fakeClient{
secretCreateFunc: func(spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
secretCreateFunc: func(_ context.Context, spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
if !reflect.DeepEqual(spec, expected) {
return types.SecretCreateResponse{}, errors.Errorf("expected %+v, got %+v", expected, spec)
}
@ -89,7 +90,7 @@ func TestSecretCreateWithDriver(t *testing.T) {
name := "foo"
cli := test.NewFakeCli(&fakeClient{
secretCreateFunc: func(spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
secretCreateFunc: func(_ context.Context, spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
if spec.Name != name {
return types.SecretCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
}
@ -118,7 +119,7 @@ func TestSecretCreateWithTemplatingDriver(t *testing.T) {
name := "foo"
cli := test.NewFakeCli(&fakeClient{
secretCreateFunc: func(spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
secretCreateFunc: func(_ context.Context, spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
if spec.Name != name {
return types.SecretCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
}
@ -148,7 +149,7 @@ func TestSecretCreateWithLabels(t *testing.T) {
name := "foo"
cli := test.NewFakeCli(&fakeClient{
secretCreateFunc: func(spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
secretCreateFunc: func(_ context.Context, spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
if spec.Name != name {
return types.SecretCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
}

View File

@ -1,6 +1,7 @@
package secret
import (
"context"
"fmt"
"io"
"testing"
@ -18,7 +19,7 @@ func TestSecretInspectErrors(t *testing.T) {
testCases := []struct {
args []string
flags map[string]string
secretInspectFunc func(secretID string) (swarm.Secret, []byte, error)
secretInspectFunc func(ctx context.Context, secretID string) (swarm.Secret, []byte, error)
expectedError string
}{
{
@ -26,7 +27,7 @@ func TestSecretInspectErrors(t *testing.T) {
},
{
args: []string{"foo"},
secretInspectFunc: func(secretID string) (swarm.Secret, []byte, error) {
secretInspectFunc: func(_ context.Context, secretID string) (swarm.Secret, []byte, error) {
return swarm.Secret{}, nil, errors.Errorf("error while inspecting the secret")
},
expectedError: "error while inspecting the secret",
@ -40,7 +41,7 @@ func TestSecretInspectErrors(t *testing.T) {
},
{
args: []string{"foo", "bar"},
secretInspectFunc: func(secretID string) (swarm.Secret, []byte, error) {
secretInspectFunc: func(_ context.Context, secretID string) (swarm.Secret, []byte, error) {
if secretID == "foo" {
return *Secret(SecretName("foo")), nil, nil
}
@ -68,12 +69,12 @@ func TestSecretInspectWithoutFormat(t *testing.T) {
testCases := []struct {
name string
args []string
secretInspectFunc func(secretID string) (swarm.Secret, []byte, error)
secretInspectFunc func(ctx context.Context, secretID string) (swarm.Secret, []byte, error)
}{
{
name: "single-secret",
args: []string{"foo"},
secretInspectFunc: func(name string) (swarm.Secret, []byte, error) {
secretInspectFunc: func(_ context.Context, name string) (swarm.Secret, []byte, error) {
if name != "foo" {
return swarm.Secret{}, nil, errors.Errorf("Invalid name, expected %s, got %s", "foo", name)
}
@ -83,7 +84,7 @@ func TestSecretInspectWithoutFormat(t *testing.T) {
{
name: "multiple-secrets-with-labels",
args: []string{"foo", "bar"},
secretInspectFunc: func(name string) (swarm.Secret, []byte, error) {
secretInspectFunc: func(_ context.Context, name string) (swarm.Secret, []byte, error) {
return *Secret(SecretID("ID-"+name), SecretName(name), SecretLabels(map[string]string{
"label1": "label-foo",
})), nil, nil
@ -102,7 +103,7 @@ func TestSecretInspectWithoutFormat(t *testing.T) {
}
func TestSecretInspectWithFormat(t *testing.T) {
secretInspectFunc := func(name string) (swarm.Secret, []byte, error) {
secretInspectFunc := func(_ context.Context, name string) (swarm.Secret, []byte, error) {
return *Secret(SecretName("foo"), SecretLabels(map[string]string{
"label1": "label-foo",
})), nil, nil
@ -111,7 +112,7 @@ func TestSecretInspectWithFormat(t *testing.T) {
name string
format string
args []string
secretInspectFunc func(name string) (swarm.Secret, []byte, error)
secretInspectFunc func(_ context.Context, name string) (swarm.Secret, []byte, error)
}{
{
name: "simple-template",
@ -141,11 +142,11 @@ func TestSecretInspectWithFormat(t *testing.T) {
func TestSecretInspectPretty(t *testing.T) {
testCases := []struct {
name string
secretInspectFunc func(string) (swarm.Secret, []byte, error)
secretInspectFunc func(context.Context, string) (swarm.Secret, []byte, error)
}{
{
name: "simple",
secretInspectFunc: func(id string) (swarm.Secret, []byte, error) {
secretInspectFunc: func(_ context.Context, id string) (swarm.Secret, []byte, error) {
return *Secret(
SecretLabels(map[string]string{
"lbl1": "value1",

View File

@ -1,6 +1,7 @@
package secret
import (
"context"
"io"
"testing"
"time"
@ -19,7 +20,7 @@ import (
func TestSecretListErrors(t *testing.T) {
testCases := []struct {
args []string
secretListFunc func(types.SecretListOptions) ([]swarm.Secret, error)
secretListFunc func(context.Context, types.SecretListOptions) ([]swarm.Secret, error)
expectedError string
}{
{
@ -27,7 +28,7 @@ func TestSecretListErrors(t *testing.T) {
expectedError: "accepts no argument",
},
{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
return []swarm.Secret{}, errors.Errorf("error listing secrets")
},
expectedError: "error listing secrets",
@ -47,7 +48,7 @@ func TestSecretListErrors(t *testing.T) {
func TestSecretList(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
return []swarm.Secret{
*Secret(SecretID("ID-1-foo"),
SecretName("1-foo"),
@ -79,7 +80,7 @@ func TestSecretList(t *testing.T) {
func TestSecretListWithQuietOption(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
return []swarm.Secret{
*Secret(SecretID("ID-foo"), SecretName("foo")),
*Secret(SecretID("ID-bar"), SecretName("bar"), SecretLabels(map[string]string{
@ -96,7 +97,7 @@ func TestSecretListWithQuietOption(t *testing.T) {
func TestSecretListWithConfigFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
return []swarm.Secret{
*Secret(SecretID("ID-foo"), SecretName("foo")),
*Secret(SecretID("ID-bar"), SecretName("bar"), SecretLabels(map[string]string{
@ -115,7 +116,7 @@ func TestSecretListWithConfigFormat(t *testing.T) {
func TestSecretListWithFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
return []swarm.Secret{
*Secret(SecretID("ID-foo"), SecretName("foo")),
*Secret(SecretID("ID-bar"), SecretName("bar"), SecretLabels(map[string]string{
@ -132,7 +133,7 @@ func TestSecretListWithFormat(t *testing.T) {
func TestSecretListWithFilter(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
assert.Check(t, is.Equal("foo", options.Filters.Get("name")[0]), "foo")
assert.Check(t, is.Equal("lbl1=Label-bar", options.Filters.Get("label")[0]))
return []swarm.Secret{

View File

@ -1,6 +1,7 @@
package secret
import (
"context"
"io"
"strings"
"testing"
@ -14,7 +15,7 @@ import (
func TestSecretRemoveErrors(t *testing.T) {
testCases := []struct {
args []string
secretRemoveFunc func(string) error
secretRemoveFunc func(context.Context, string) error
expectedError string
}{
{
@ -23,7 +24,7 @@ func TestSecretRemoveErrors(t *testing.T) {
},
{
args: []string{"foo"},
secretRemoveFunc: func(name string) error {
secretRemoveFunc: func(_ context.Context, name string) error {
return errors.Errorf("error removing secret")
},
expectedError: "error removing secret",
@ -45,7 +46,7 @@ func TestSecretRemoveWithName(t *testing.T) {
names := []string{"foo", "bar"}
var removedSecrets []string
cli := test.NewFakeCli(&fakeClient{
secretRemoveFunc: func(name string) error {
secretRemoveFunc: func(_ context.Context, name string) error {
removedSecrets = append(removedSecrets, name)
return nil
},
@ -62,7 +63,7 @@ func TestSecretRemoveContinueAfterError(t *testing.T) {
var removedSecrets []string
cli := test.NewFakeCli(&fakeClient{
secretRemoveFunc: func(name string) error {
secretRemoveFunc: func(_ context.Context, name string) error {
removedSecrets = append(removedSecrets, name)
if name == "foo" {
return errors.Errorf("error removing secret: %s", name)

View File

@ -414,7 +414,7 @@ type globalProgressUpdater struct {
done bool
}
func (u *globalProgressUpdater) update(service swarm.Service, tasks []swarm.Task, activeNodes map[string]struct{}, rollback bool) (bool, error) {
func (u *globalProgressUpdater) update(_ swarm.Service, tasks []swarm.Task, activeNodes map[string]struct{}, rollback bool) (bool, error) {
tasksByNode := u.tasksByNode(tasks)
// We don't have perfect knowledge of how many nodes meet the

View File

@ -504,23 +504,23 @@ type secretAPIClientMock struct {
listResult []swarm.Secret
}
func (s secretAPIClientMock) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
func (s secretAPIClientMock) SecretList(context.Context, types.SecretListOptions) ([]swarm.Secret, error) {
return s.listResult, nil
}
func (s secretAPIClientMock) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (types.SecretCreateResponse, error) {
func (s secretAPIClientMock) SecretCreate(context.Context, swarm.SecretSpec) (types.SecretCreateResponse, error) {
return types.SecretCreateResponse{}, nil
}
func (s secretAPIClientMock) SecretRemove(ctx context.Context, id string) error {
func (s secretAPIClientMock) SecretRemove(context.Context, string) error {
return nil
}
func (s secretAPIClientMock) SecretInspectWithRaw(ctx context.Context, name string) (swarm.Secret, []byte, error) {
func (s secretAPIClientMock) SecretInspectWithRaw(context.Context, string) (swarm.Secret, []byte, error) {
return swarm.Secret{}, []byte{}, nil
}
func (s secretAPIClientMock) SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error {
func (s secretAPIClientMock) SecretUpdate(context.Context, string, swarm.Version, swarm.SecretSpec) error {
return nil
}

View File

@ -43,7 +43,7 @@ type fakeClient struct {
configRemoveFunc func(configID string) error
}
func (cli *fakeClient) ServerVersion(ctx context.Context) (types.Version, error) {
func (cli *fakeClient) ServerVersion(context.Context) (types.Version, error) {
return types.Version{
Version: "docker-dev",
APIVersion: api.DefaultVersion,
@ -54,7 +54,7 @@ func (cli *fakeClient) ClientVersion() string {
return cli.version
}
func (cli *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
func (cli *fakeClient) ServiceList(_ context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
if cli.serviceListFunc != nil {
return cli.serviceListFunc(options)
}
@ -69,7 +69,7 @@ func (cli *fakeClient) ServiceList(ctx context.Context, options types.ServiceLis
return servicesList, nil
}
func (cli *fakeClient) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
func (cli *fakeClient) NetworkList(_ context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
if cli.networkListFunc != nil {
return cli.networkListFunc(options)
}
@ -84,7 +84,7 @@ func (cli *fakeClient) NetworkList(ctx context.Context, options types.NetworkLis
return networksList, nil
}
func (cli *fakeClient) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
func (cli *fakeClient) SecretList(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
if cli.secretListFunc != nil {
return cli.secretListFunc(options)
}
@ -99,7 +99,7 @@ func (cli *fakeClient) SecretList(ctx context.Context, options types.SecretListO
return secretsList, nil
}
func (cli *fakeClient) ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
func (cli *fakeClient) ConfigList(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
if cli.configListFunc != nil {
return cli.configListFunc(options)
}
@ -114,28 +114,28 @@ func (cli *fakeClient) ConfigList(ctx context.Context, options types.ConfigListO
return configsList, nil
}
func (cli *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
func (cli *fakeClient) TaskList(_ context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
if cli.taskListFunc != nil {
return cli.taskListFunc(options)
}
return []swarm.Task{}, nil
}
func (cli *fakeClient) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
func (cli *fakeClient) NodeList(_ context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
if cli.nodeListFunc != nil {
return cli.nodeListFunc(options)
}
return []swarm.Node{}, nil
}
func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, ref string) (swarm.Node, []byte, error) {
func (cli *fakeClient) NodeInspectWithRaw(_ context.Context, ref string) (swarm.Node, []byte, error) {
if cli.nodeInspectWithRaw != nil {
return cli.nodeInspectWithRaw(ref)
}
return swarm.Node{}, nil, nil
}
func (cli *fakeClient) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) {
func (cli *fakeClient) ServiceUpdate(_ context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) {
if cli.serviceUpdateFunc != nil {
return cli.serviceUpdateFunc(serviceID, version, service, options)
}
@ -143,7 +143,7 @@ func (cli *fakeClient) ServiceUpdate(ctx context.Context, serviceID string, vers
return types.ServiceUpdateResponse{}, nil
}
func (cli *fakeClient) ServiceRemove(ctx context.Context, serviceID string) error {
func (cli *fakeClient) ServiceRemove(_ context.Context, serviceID string) error {
if cli.serviceRemoveFunc != nil {
return cli.serviceRemoveFunc(serviceID)
}
@ -152,7 +152,7 @@ func (cli *fakeClient) ServiceRemove(ctx context.Context, serviceID string) erro
return nil
}
func (cli *fakeClient) NetworkRemove(ctx context.Context, networkID string) error {
func (cli *fakeClient) NetworkRemove(_ context.Context, networkID string) error {
if cli.networkRemoveFunc != nil {
return cli.networkRemoveFunc(networkID)
}
@ -161,7 +161,7 @@ func (cli *fakeClient) NetworkRemove(ctx context.Context, networkID string) erro
return nil
}
func (cli *fakeClient) SecretRemove(ctx context.Context, secretID string) error {
func (cli *fakeClient) SecretRemove(_ context.Context, secretID string) error {
if cli.secretRemoveFunc != nil {
return cli.secretRemoveFunc(secretID)
}
@ -170,7 +170,7 @@ func (cli *fakeClient) SecretRemove(ctx context.Context, secretID string) error
return nil
}
func (cli *fakeClient) ConfigRemove(ctx context.Context, configID string) error {
func (cli *fakeClient) ConfigRemove(_ context.Context, configID string) error {
if cli.configRemoveFunc != nil {
return cli.configRemoveFunc(configID)
}
@ -179,7 +179,7 @@ func (cli *fakeClient) ConfigRemove(ctx context.Context, configID string) error
return nil
}
func (cli *fakeClient) ServiceInspectWithRaw(ctx context.Context, serviceID string, opts types.ServiceInspectOptions) (swarm.Service, []byte, error) {
func (cli *fakeClient) ServiceInspectWithRaw(_ context.Context, serviceID string, _ types.ServiceInspectOptions) (swarm.Service, []byte, error) {
return swarm.Service{
ID: serviceID,
Spec: swarm.ServiceSpec{

View File

@ -28,7 +28,7 @@ func newDeployCommand(dockerCli command.Cli) *cobra.Command {
if err != nil {
return err
}
return RunDeploy(dockerCli, cmd.Flags(), config, opts)
return swarm.RunDeploy(dockerCli, opts, config)
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return completeNames(dockerCli)(cmd, args, toComplete)
@ -47,7 +47,9 @@ func newDeployCommand(dockerCli command.Cli) *cobra.Command {
return cmd
}
// RunDeploy performs a stack deploy against the specified swarm cluster
func RunDeploy(dockerCli command.Cli, flags *pflag.FlagSet, config *composetypes.Config, opts options.Deploy) error {
// RunDeploy performs a stack deploy against the specified swarm cluster.
//
// Deprecated: use [swarm.RunDeploy] instead.
func RunDeploy(dockerCli command.Cli, _ *pflag.FlagSet, config *composetypes.Config, opts options.Deploy) error {
return swarm.RunDeploy(dockerCli, opts, config)
}

View File

@ -23,7 +23,7 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
Short: "List stacks",
Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return RunList(cmd, dockerCli, opts)
return RunList(dockerCli, opts)
},
ValidArgsFunction: completion.NoComplete,
}
@ -34,24 +34,24 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
}
// RunList performs a stack list against the specified swarm cluster
func RunList(cmd *cobra.Command, dockerCli command.Cli, opts options.List) error {
stacks := []*formatter.Stack{}
func RunList(dockerCli command.Cli, opts options.List) error {
ss, err := swarm.GetStacks(dockerCli)
if err != nil {
return err
}
stacks := make([]*formatter.Stack, 0, len(ss))
stacks = append(stacks, ss...)
return format(dockerCli, opts, stacks)
}
func format(dockerCli command.Cli, opts options.List, stacks []*formatter.Stack) error {
format := formatter.Format(opts.Format)
if format == "" || format == formatter.TableFormatKey {
format = formatter.SwarmStackTableFormat
fmt := formatter.Format(opts.Format)
if fmt == "" || fmt == formatter.TableFormatKey {
fmt = formatter.SwarmStackTableFormat
}
stackCtx := formatter.Context{
Output: dockerCli.Out(),
Format: format,
Format: fmt,
}
sort.Slice(stacks, func(i, j int) bool {
return sortorder.NaturalLess(stacks[i].Name, stacks[j].Name) ||

View File

@ -5,6 +5,7 @@ import (
"io"
"os"
"path/filepath"
"runtime"
"sort"
"strings"
@ -104,9 +105,22 @@ func GetConfigDetails(composefiles []string, stdin io.Reader) (composetypes.Conf
func buildEnvironment(env []string) (map[string]string, error) {
result := make(map[string]string, len(env))
for _, s := range env {
if runtime.GOOS == "windows" && len(s) > 0 {
// cmd.exe can have special environment variables which names start with "=".
// They are only there for MS-DOS compatibility and we should ignore them.
// See TestBuildEnvironment for examples.
//
// https://ss64.com/nt/syntax-variables.html
// https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133
// https://github.com/docker/cli/issues/4078
if s[0] == '=' {
continue
}
}
k, v, ok := strings.Cut(s, "=")
if !ok || k == "" {
return result, errors.Errorf("unexpected environment %q", s)
return result, errors.Errorf("unexpected environment variable '%s'", s)
}
// value may be set, but empty if "s" is like "K=", not "K".
result[k] = v

View File

@ -3,6 +3,7 @@ package loader
import (
"os"
"path/filepath"
"runtime"
"strings"
"testing"
@ -45,3 +46,34 @@ services:
assert.Check(t, is.Equal("3.0", details.ConfigFiles[0].Config["version"]))
assert.Check(t, is.Len(details.Environment, len(os.Environ())))
}
func TestBuildEnvironment(t *testing.T) {
inputEnv := []string{
"LEGIT_VAR=LEGIT_VALUE",
"EMPTY_VARIABLE=",
}
if runtime.GOOS == "windows" {
inputEnv = []string{
"LEGIT_VAR=LEGIT_VALUE",
// cmd.exe has some special environment variables which start with "=".
// These should be ignored as they're only there for MS-DOS compatibility.
"=ExitCode=00000041",
"=ExitCodeAscii=A",
`=C:=C:\some\dir`,
`=D:=D:\some\different\dir`,
`=X:=X:\`,
`=::=::\`,
"EMPTY_VARIABLE=",
}
}
env, err := buildEnvironment(inputEnv)
assert.NilError(t, err)
assert.Check(t, is.Len(env, 2))
assert.Check(t, is.Equal("LEGIT_VALUE", env["LEGIT_VAR"]))
assert.Check(t, is.Equal("", env["EMPTY_VARIABLE"]))
}

View File

@ -23,7 +23,7 @@ func newPsCommand(dockerCli command.Cli) *cobra.Command {
if err := validateStackName(opts.Namespace); err != nil {
return err
}
return RunPs(dockerCli, cmd.Flags(), opts)
return swarm.RunPS(dockerCli, opts)
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return completeNames(dockerCli)(cmd, args, toComplete)
@ -38,7 +38,9 @@ func newPsCommand(dockerCli command.Cli) *cobra.Command {
return cmd
}
// RunPs performs a stack ps against the specified swarm cluster
func RunPs(dockerCli command.Cli, flags *pflag.FlagSet, opts options.PS) error {
// RunPs performs a stack ps against the specified swarm cluster.
//
// Deprecated: use [swarm.RunPS] instead.
func RunPs(dockerCli command.Cli, _ *pflag.FlagSet, opts options.PS) error {
return swarm.RunPS(dockerCli, opts)
}

View File

@ -22,7 +22,7 @@ func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
if err := validateStackNames(opts.Namespaces); err != nil {
return err
}
return RunRemove(dockerCli, cmd.Flags(), opts)
return swarm.RunRemove(dockerCli, opts)
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return completeNames(dockerCli)(cmd, args, toComplete)
@ -31,7 +31,9 @@ func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
return cmd
}
// RunRemove performs a stack remove against the specified swarm cluster
func RunRemove(dockerCli command.Cli, flags *pflag.FlagSet, opts options.Remove) error {
// RunRemove performs a stack remove against the specified swarm cluster.
//
// Deprecated: use [swarm.RunRemove] instead.
func RunRemove(dockerCli command.Cli, _ *pflag.FlagSet, opts options.Remove) error {
return swarm.RunRemove(dockerCli, opts)
}

View File

@ -30,7 +30,7 @@ func newServicesCommand(dockerCli command.Cli) *cobra.Command {
if err := validateStackName(opts.Namespace); err != nil {
return err
}
return RunServices(dockerCli, cmd.Flags(), opts)
return RunServices(dockerCli, opts)
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return completeNames(dockerCli)(cmd, args, toComplete)
@ -44,16 +44,18 @@ func newServicesCommand(dockerCli command.Cli) *cobra.Command {
}
// RunServices performs a stack services against the specified swarm cluster
func RunServices(dockerCli command.Cli, flags *pflag.FlagSet, opts options.Services) error {
services, err := GetServices(dockerCli, flags, opts)
func RunServices(dockerCli command.Cli, opts options.Services) error {
services, err := swarm.GetServices(dockerCli, opts)
if err != nil {
return err
}
return formatWrite(dockerCli, services, opts)
}
// GetServices returns the services for the specified swarm cluster
func GetServices(dockerCli command.Cli, flags *pflag.FlagSet, opts options.Services) ([]swarmtypes.Service, error) {
// GetServices returns the services for the specified swarm cluster.
//
// Deprecated: use [swarm.GetServices] instead.
func GetServices(dockerCli command.Cli, _ *pflag.FlagSet, opts options.Services) ([]swarmtypes.Service, error) {
return swarm.GetServices(dockerCli, opts)
}

View File

@ -43,7 +43,7 @@ type fakeClient struct {
configRemoveFunc func(configID string) error
}
func (cli *fakeClient) ServerVersion(ctx context.Context) (types.Version, error) {
func (cli *fakeClient) ServerVersion(context.Context) (types.Version, error) {
return types.Version{
Version: "docker-dev",
APIVersion: api.DefaultVersion,
@ -54,7 +54,7 @@ func (cli *fakeClient) ClientVersion() string {
return cli.version
}
func (cli *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
func (cli *fakeClient) ServiceList(_ context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
if cli.serviceListFunc != nil {
return cli.serviceListFunc(options)
}
@ -69,7 +69,7 @@ func (cli *fakeClient) ServiceList(ctx context.Context, options types.ServiceLis
return servicesList, nil
}
func (cli *fakeClient) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
func (cli *fakeClient) NetworkList(_ context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
if cli.networkListFunc != nil {
return cli.networkListFunc(options)
}
@ -84,7 +84,7 @@ func (cli *fakeClient) NetworkList(ctx context.Context, options types.NetworkLis
return networksList, nil
}
func (cli *fakeClient) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
func (cli *fakeClient) SecretList(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
if cli.secretListFunc != nil {
return cli.secretListFunc(options)
}
@ -99,7 +99,7 @@ func (cli *fakeClient) SecretList(ctx context.Context, options types.SecretListO
return secretsList, nil
}
func (cli *fakeClient) ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
func (cli *fakeClient) ConfigList(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
if cli.configListFunc != nil {
return cli.configListFunc(options)
}
@ -114,28 +114,28 @@ func (cli *fakeClient) ConfigList(ctx context.Context, options types.ConfigListO
return configsList, nil
}
func (cli *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
func (cli *fakeClient) TaskList(_ context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
if cli.taskListFunc != nil {
return cli.taskListFunc(options)
}
return []swarm.Task{}, nil
}
func (cli *fakeClient) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
func (cli *fakeClient) NodeList(_ context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
if cli.nodeListFunc != nil {
return cli.nodeListFunc(options)
}
return []swarm.Node{}, nil
}
func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, ref string) (swarm.Node, []byte, error) {
func (cli *fakeClient) NodeInspectWithRaw(_ context.Context, ref string) (swarm.Node, []byte, error) {
if cli.nodeInspectWithRaw != nil {
return cli.nodeInspectWithRaw(ref)
}
return swarm.Node{}, nil, nil
}
func (cli *fakeClient) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) {
func (cli *fakeClient) ServiceUpdate(_ context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) {
if cli.serviceUpdateFunc != nil {
return cli.serviceUpdateFunc(serviceID, version, service, options)
}
@ -143,7 +143,7 @@ func (cli *fakeClient) ServiceUpdate(ctx context.Context, serviceID string, vers
return types.ServiceUpdateResponse{}, nil
}
func (cli *fakeClient) ServiceRemove(ctx context.Context, serviceID string) error {
func (cli *fakeClient) ServiceRemove(_ context.Context, serviceID string) error {
if cli.serviceRemoveFunc != nil {
return cli.serviceRemoveFunc(serviceID)
}
@ -152,7 +152,7 @@ func (cli *fakeClient) ServiceRemove(ctx context.Context, serviceID string) erro
return nil
}
func (cli *fakeClient) NetworkRemove(ctx context.Context, networkID string) error {
func (cli *fakeClient) NetworkRemove(_ context.Context, networkID string) error {
if cli.networkRemoveFunc != nil {
return cli.networkRemoveFunc(networkID)
}
@ -161,7 +161,7 @@ func (cli *fakeClient) NetworkRemove(ctx context.Context, networkID string) erro
return nil
}
func (cli *fakeClient) SecretRemove(ctx context.Context, secretID string) error {
func (cli *fakeClient) SecretRemove(_ context.Context, secretID string) error {
if cli.secretRemoveFunc != nil {
return cli.secretRemoveFunc(secretID)
}
@ -170,7 +170,7 @@ func (cli *fakeClient) SecretRemove(ctx context.Context, secretID string) error
return nil
}
func (cli *fakeClient) ConfigRemove(ctx context.Context, configID string) error {
func (cli *fakeClient) ConfigRemove(_ context.Context, configID string) error {
if cli.configRemoveFunc != nil {
return cli.configRemoveFunc(configID)
}

View File

@ -21,63 +21,63 @@ type fakeClient struct {
swarmUnlockFunc func(req swarm.UnlockRequest) error
}
func (cli *fakeClient) Info(ctx context.Context) (types.Info, error) {
func (cli *fakeClient) Info(context.Context) (types.Info, error) {
if cli.infoFunc != nil {
return cli.infoFunc()
}
return types.Info{}, nil
}
func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, ref string) (swarm.Node, []byte, error) {
func (cli *fakeClient) NodeInspectWithRaw(context.Context, string) (swarm.Node, []byte, error) {
if cli.nodeInspectFunc != nil {
return cli.nodeInspectFunc()
}
return swarm.Node{}, []byte{}, nil
}
func (cli *fakeClient) SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) {
func (cli *fakeClient) SwarmInit(context.Context, swarm.InitRequest) (string, error) {
if cli.swarmInitFunc != nil {
return cli.swarmInitFunc()
}
return "", nil
}
func (cli *fakeClient) SwarmInspect(ctx context.Context) (swarm.Swarm, error) {
func (cli *fakeClient) SwarmInspect(context.Context) (swarm.Swarm, error) {
if cli.swarmInspectFunc != nil {
return cli.swarmInspectFunc()
}
return swarm.Swarm{}, nil
}
func (cli *fakeClient) SwarmGetUnlockKey(ctx context.Context) (types.SwarmUnlockKeyResponse, error) {
func (cli *fakeClient) SwarmGetUnlockKey(context.Context) (types.SwarmUnlockKeyResponse, error) {
if cli.swarmGetUnlockKeyFunc != nil {
return cli.swarmGetUnlockKeyFunc()
}
return types.SwarmUnlockKeyResponse{}, nil
}
func (cli *fakeClient) SwarmJoin(ctx context.Context, req swarm.JoinRequest) error {
func (cli *fakeClient) SwarmJoin(context.Context, swarm.JoinRequest) error {
if cli.swarmJoinFunc != nil {
return cli.swarmJoinFunc()
}
return nil
}
func (cli *fakeClient) SwarmLeave(ctx context.Context, force bool) error {
func (cli *fakeClient) SwarmLeave(context.Context, bool) error {
if cli.swarmLeaveFunc != nil {
return cli.swarmLeaveFunc()
}
return nil
}
func (cli *fakeClient) SwarmUpdate(ctx context.Context, version swarm.Version, swarm swarm.Spec, flags swarm.UpdateFlags) error {
func (cli *fakeClient) SwarmUpdate(_ context.Context, _ swarm.Version, swarm swarm.Spec, flags swarm.UpdateFlags) error {
if cli.swarmUpdateFunc != nil {
return cli.swarmUpdateFunc(swarm, flags)
}
return nil
}
func (cli *fakeClient) SwarmUnlock(ctx context.Context, req swarm.UnlockRequest) error {
func (cli *fakeClient) SwarmUnlock(_ context.Context, req swarm.UnlockRequest) error {
if cli.swarmUnlockFunc != nil {
return cli.swarmUnlockFunc(req)
}

View File

@ -10,7 +10,7 @@ import (
)
// Helper function to set static slices
func getCIDR(ip net.IP, cidr *net.IPNet, err error) net.IPNet {
func getCIDR(_ net.IP, cidr *net.IPNet, _ error) net.IPNet {
return *cidr
}

View File

@ -14,14 +14,14 @@ type fakeClient struct {
serviceInspectWithRaw func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error)
}
func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, ref string) (swarm.Node, []byte, error) {
func (cli *fakeClient) NodeInspectWithRaw(_ context.Context, ref string) (swarm.Node, []byte, error) {
if cli.nodeInspectWithRaw != nil {
return cli.nodeInspectWithRaw(ref)
}
return swarm.Node{}, nil, nil
}
func (cli *fakeClient) ServiceInspectWithRaw(ctx context.Context, ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
func (cli *fakeClient) ServiceInspectWithRaw(_ context.Context, ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
if cli.serviceInspectWithRaw != nil {
return cli.serviceInspectWithRaw(ref, options)
}

View File

@ -53,7 +53,7 @@ type trustKey struct {
// This information is to be pretty printed or serialized into a machine-readable format.
func lookupTrustInfo(cli command.Cli, remote string) ([]trustTagRow, []client.RoleWithSignatures, []data.Role, error) {
ctx := context.Background()
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, image.AuthResolver(cli), remote)
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), remote)
if err != nil {
return []trustTagRow{}, []client.RoleWithSignatures{}, []data.Role{}, err
}

View File

@ -27,15 +27,15 @@ type fakeClient struct {
apiclient.Client
}
func (c *fakeClient) Info(ctx context.Context) (types.Info, error) {
func (c *fakeClient) Info(context.Context) (types.Info, error) {
return types.Info{}, nil
}
func (c *fakeClient) ImageInspectWithRaw(ctx context.Context, imageID string) (types.ImageInspect, []byte, error) {
func (c *fakeClient) ImageInspectWithRaw(context.Context, string) (types.ImageInspect, []byte, error) {
return types.ImageInspect{}, []byte{}, nil
}
func (c *fakeClient) ImagePush(ctx context.Context, image string, options types.ImagePushOptions) (io.ReadCloser, error) {
func (c *fakeClient) ImagePush(context.Context, string, types.ImagePushOptions) (io.ReadCloser, error) {
return &utils.NoopCloser{Reader: bytes.NewBuffer([]byte{})}, nil
}

View File

@ -36,7 +36,7 @@ func newRevokeCommand(dockerCli command.Cli) *cobra.Command {
func revokeTrust(cli command.Cli, remote string, options revokeOptions) error {
ctx := context.Background()
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, image.AuthResolver(cli), remote)
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), remote)
if err != nil {
return err
}

View File

@ -43,7 +43,7 @@ func newSignCommand(dockerCli command.Cli) *cobra.Command {
func runSignImage(cli command.Cli, options signOptions) error {
imageName := options.imageName
ctx := context.Background()
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, image.AuthResolver(cli), imageName)
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), imageName)
if err != nil {
return err
}

View File

@ -81,7 +81,7 @@ func addSigner(cli command.Cli, options signerAddOptions) error {
func addSignerToRepo(cli command.Cli, signerName string, repoName string, signerPubKeys []data.PublicKey) error {
ctx := context.Background()
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, image.AuthResolver(cli), repoName)
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), repoName)
if err != nil {
return err
}

View File

@ -80,7 +80,7 @@ func isLastSignerForReleases(roleWithSig data.Role, allRoles []client.RoleWithSi
// The signer not being removed doesn't necessarily raise an error e.g. user choosing "No" when prompted for confirmation.
func removeSingleSigner(cli command.Cli, repoName, signerName string, forceYes bool) (bool, error) {
ctx := context.Background()
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, image.AuthResolver(cli), repoName)
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), repoName)
if err != nil {
return false, err
}

View File

@ -32,9 +32,9 @@ func (c *fakeClient) VolumeInspect(_ context.Context, volumeID string) (volume.V
return volume.Volume{}, nil
}
func (c *fakeClient) VolumeList(_ context.Context, filter filters.Args) (volume.ListResponse, error) {
func (c *fakeClient) VolumeList(_ context.Context, options volume.ListOptions) (volume.ListResponse, error) {
if c.volumeListFunc != nil {
return c.volumeListFunc(filter)
return c.volumeListFunc(options.Filters)
}
return volume.ListResponse{}, nil
}

View File

@ -50,6 +50,7 @@ func TestVolumeCreateErrors(t *testing.T) {
cmd.Flags().Set(key, value)
}
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}

View File

@ -62,6 +62,7 @@ func TestVolumeInspectErrors(t *testing.T) {
cmd.Flags().Set(key, value)
}
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}

View File

@ -10,6 +10,7 @@ import (
"github.com/docker/cli/cli/command/formatter"
flagsHelper "github.com/docker/cli/cli/flags"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/volume"
"github.com/fvbommel/sortorder"
"github.com/spf13/cobra"
)
@ -52,7 +53,7 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
func runList(dockerCli command.Cli, options listOptions) error {
client := dockerCli.Client()
volumes, err := client.VolumeList(context.Background(), options.filter.Value())
volumes, err := client.VolumeList(context.Background(), volume.ListOptions{Filters: options.filter.Value()})
if err != nil {
return err
}
@ -70,9 +71,9 @@ func runList(dockerCli command.Cli, options listOptions) error {
// trick for filtering in place
n := 0
for _, volume := range volumes.Volumes {
if volume.ClusterVolume != nil {
volumes.Volumes[n] = volume
for _, vol := range volumes.Volumes {
if vol.ClusterVolume != nil {
volumes.Volumes[n] = vol
n++
}
}

View File

@ -43,6 +43,7 @@ func TestVolumeListErrors(t *testing.T) {
cmd.Flags().Set(key, value)
}
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}

View File

@ -75,6 +75,6 @@ func runPrune(dockerCli command.Cli, options pruneOptions) (spaceReclaimed uint6
// RunPrune calls the Volume Prune API
// This returns the amount of space reclaimed and a detailed output string
func RunPrune(dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error) {
func RunPrune(dockerCli command.Cli, _ bool, filter opts.FilterOpt) (uint64, string, error) {
return runPrune(dockerCli, pruneOptions{force: true, filter: filter})
}

View File

@ -49,6 +49,7 @@ func TestVolumePruneErrors(t *testing.T) {
cmd.Flags().Set(key, value)
}
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -109,7 +110,7 @@ func TestVolumePrunePromptNo(t *testing.T) {
}
}
func simplePruneFunc(args filters.Args) (types.VolumesPruneReport, error) {
func simplePruneFunc(filters.Args) (types.VolumesPruneReport, error) {
return types.VolumesPruneReport{
VolumesDeleted: []string{
"foo", "bar", "baz",

View File

@ -33,6 +33,7 @@ func TestVolumeRemoveErrors(t *testing.T) {
}))
cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}

View File

@ -596,14 +596,14 @@ type fakeClient struct {
configListFunc func(types.ConfigListOptions) ([]swarm.Config, error)
}
func (c *fakeClient) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
func (c *fakeClient) SecretList(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
if c.secretListFunc != nil {
return c.secretListFunc(options)
}
return []swarm.Secret{}, nil
}
func (c *fakeClient) ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
func (c *fakeClient) ConfigList(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
if c.configListFunc != nil {
return c.configListFunc(options)
}

View File

@ -17,7 +17,7 @@ const (
type portsFormatChecker struct{}
func (checker portsFormatChecker) IsFormat(input interface{}) bool {
func (checker portsFormatChecker) IsFormat(_ interface{}) bool {
// TODO: implement this
return true
}

View File

@ -300,7 +300,8 @@ func (configFile *ConfigFile) GetAllCredentials() (map[string]types.AuthConfig,
for registryHostname := range configFile.CredentialHelpers {
newAuth, err := configFile.GetAuthConfig(registryHostname)
if err != nil {
return nil, err
logrus.WithError(err).Warnf("Failed to get credentials for registry: %s", registryHostname)
continue
}
auths[registryHostname] = newAuth
}

View File

@ -3,6 +3,7 @@ package configfile
import (
"bytes"
"encoding/json"
"errors"
"os"
"testing"
@ -166,8 +167,9 @@ func TestConfigFile(t *testing.T) {
}
type mockNativeStore struct {
GetAllCallCount int
authConfigs map[string]types.AuthConfig
GetAllCallCount int
authConfigs map[string]types.AuthConfig
authConfigErrors map[string]error
}
func (c *mockNativeStore) Erase(registryHostname string) error {
@ -176,7 +178,7 @@ func (c *mockNativeStore) Erase(registryHostname string) error {
}
func (c *mockNativeStore) Get(registryHostname string) (types.AuthConfig, error) {
return c.authConfigs[registryHostname], nil
return c.authConfigs[registryHostname], c.authConfigErrors[registryHostname]
}
func (c *mockNativeStore) GetAll() (map[string]types.AuthConfig, error) {
@ -184,15 +186,15 @@ func (c *mockNativeStore) GetAll() (map[string]types.AuthConfig, error) {
return c.authConfigs, nil
}
func (c *mockNativeStore) Store(authConfig types.AuthConfig) error {
func (c *mockNativeStore) Store(_ types.AuthConfig) error {
return nil
}
// make sure it satisfies the interface
var _ credentials.Store = (*mockNativeStore)(nil)
func NewMockNativeStore(authConfigs map[string]types.AuthConfig) credentials.Store {
return &mockNativeStore{authConfigs: authConfigs}
func NewMockNativeStore(authConfigs map[string]types.AuthConfig, authConfigErrors map[string]error) credentials.Store {
return &mockNativeStore{authConfigs: authConfigs, authConfigErrors: authConfigErrors}
}
func TestGetAllCredentialsFileStoreOnly(t *testing.T) {
@ -220,7 +222,7 @@ func TestGetAllCredentialsCredsStore(t *testing.T) {
Password: "pass",
}
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{testRegistryHostname: expectedAuth})
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{testRegistryHostname: expectedAuth}, nil)
tmpNewNativeStore := newNativeStore
defer func() { newNativeStore = tmpNewNativeStore }()
@ -237,6 +239,48 @@ func TestGetAllCredentialsCredsStore(t *testing.T) {
assert.Check(t, is.Equal(1, testCredsStore.(*mockNativeStore).GetAllCallCount))
}
func TestGetAllCredentialsCredStoreErrorHandling(t *testing.T) {
const (
workingHelperRegistryHostname = "working-helper.example.com"
brokenHelperRegistryHostname = "broken-helper.example.com"
)
configFile := New("filename")
configFile.CredentialHelpers = map[string]string{
workingHelperRegistryHostname: "cred_helper",
brokenHelperRegistryHostname: "broken_cred_helper",
}
expectedAuth := types.AuthConfig{
Username: "username",
Password: "pass",
}
// configure the mock store to throw an error
// when calling the helper for this registry
authErrors := map[string]error{
brokenHelperRegistryHostname: errors.New("an error"),
}
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{
workingHelperRegistryHostname: expectedAuth,
// configure an auth entry for the "broken" credential
// helper that will throw an error
brokenHelperRegistryHostname: {},
}, authErrors)
tmpNewNativeStore := newNativeStore
defer func() { newNativeStore = tmpNewNativeStore }()
newNativeStore = func(configFile *ConfigFile, helperSuffix string) credentials.Store {
return testCredsStore
}
authConfigs, err := configFile.GetAllCredentials()
// make sure we're still returning the expected credentials
// and skipping the ones throwing an error
assert.NilError(t, err)
assert.Check(t, is.Equal(1, len(authConfigs)))
assert.Check(t, is.DeepEqual(expectedAuth, authConfigs[workingHelperRegistryHostname]))
}
func TestGetAllCredentialsCredHelper(t *testing.T) {
const (
testCredHelperSuffix = "test_cred_helper"
@ -261,7 +305,7 @@ func TestGetAllCredentialsCredHelper(t *testing.T) {
// Add in an extra auth entry which doesn't appear in CredentialHelpers section of the configFile.
// This verifies that only explicitly configured registries are being requested from the cred helpers.
testExtraCredHelperRegistryHostname: unexpectedCredHelperAuth,
})
}, nil)
tmpNewNativeStore := newNativeStore
defer func() { newNativeStore = tmpNewNativeStore }()
@ -298,7 +342,7 @@ func TestGetAllCredentialsFileStoreAndCredHelper(t *testing.T) {
configFile.CredentialHelpers = map[string]string{testCredHelperRegistryHostname: testCredHelperSuffix}
configFile.AuthConfigs[testFileStoreRegistryHostname] = expectedFileStoreAuth
testCredHelper := NewMockNativeStore(map[string]types.AuthConfig{testCredHelperRegistryHostname: expectedCredHelperAuth})
testCredHelper := NewMockNativeStore(map[string]types.AuthConfig{testCredHelperRegistryHostname: expectedCredHelperAuth}, nil)
newNativeStore = func(configFile *ConfigFile, helperSuffix string) credentials.Store {
return testCredHelper
@ -337,8 +381,8 @@ func TestGetAllCredentialsCredStoreAndCredHelper(t *testing.T) {
Password: "cred_helper_pass",
}
testCredHelper := NewMockNativeStore(map[string]types.AuthConfig{testCredHelperRegistryHostname: expectedCredHelperAuth})
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{testCredStoreRegistryHostname: expectedCredStoreAuth})
testCredHelper := NewMockNativeStore(map[string]types.AuthConfig{testCredHelperRegistryHostname: expectedCredHelperAuth}, nil)
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{testCredStoreRegistryHostname: expectedCredStoreAuth}, nil)
tmpNewNativeStore := newNativeStore
defer func() { newNativeStore = tmpNewNativeStore }()
@ -380,8 +424,8 @@ func TestGetAllCredentialsCredHelperOverridesDefaultStore(t *testing.T) {
Password: "cred_helper_pass",
}
testCredHelper := NewMockNativeStore(map[string]types.AuthConfig{testRegistryHostname: expectedCredHelperAuth})
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{testRegistryHostname: unexpectedCredStoreAuth})
testCredHelper := NewMockNativeStore(map[string]types.AuthConfig{testRegistryHostname: expectedCredHelperAuth}, nil)
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{testRegistryHostname: unexpectedCredStoreAuth}, nil)
tmpNewNativeStore := newNativeStore
defer func() { newNativeStore = tmpNewNativeStore }()

View File

@ -32,7 +32,7 @@ import (
)
// New returns net.Conn
func New(ctx context.Context, cmd string, args ...string) (net.Conn, error) {
func New(_ context.Context, cmd string, args ...string) (net.Conn, error) {
var (
c commandConn
err error

View File

@ -2,12 +2,14 @@ package store
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"reflect"
"sort"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/ioutils"
"github.com/fvbommel/sortorder"
"github.com/pkg/errors"
)
@ -35,7 +37,7 @@ func (s *metadataStore) createOrUpdate(meta Metadata) error {
if err != nil {
return err
}
return os.WriteFile(filepath.Join(contextDir, metaFile), bytes, 0o644)
return ioutils.AtomicWriteFile(filepath.Join(contextDir, metaFile), bytes, 0o644)
}
func parseTypedOrMap(payload []byte, getter TypeGetter) (interface{}, error) {
@ -65,7 +67,8 @@ func (s *metadataStore) get(name string) (Metadata, error) {
}
func (s *metadataStore) getByID(id contextdir) (Metadata, error) {
bytes, err := os.ReadFile(filepath.Join(s.contextDir(id), metaFile))
fileName := filepath.Join(s.contextDir(id), metaFile)
bytes, err := os.ReadFile(fileName)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return Metadata{}, errdefs.NotFound(errors.Wrap(err, "context not found"))
@ -77,15 +80,15 @@ func (s *metadataStore) getByID(id contextdir) (Metadata, error) {
Endpoints: make(map[string]interface{}),
}
if err := json.Unmarshal(bytes, &untyped); err != nil {
return Metadata{}, err
return Metadata{}, fmt.Errorf("parsing %s: %v", fileName, err)
}
r.Name = untyped.Name
if r.Metadata, err = parseTypedOrMap(untyped.Metadata, s.config.contextType); err != nil {
return Metadata{}, err
return Metadata{}, fmt.Errorf("parsing %s: %v", fileName, err)
}
for k, v := range untyped.Endpoints {
if r.Endpoints[k], err = parseTypedOrMap(v, s.config.endpointTypes[k]); err != nil {
return Metadata{}, err
return Metadata{}, fmt.Errorf("parsing %s: %v", fileName, err)
}
}
return r, err

View File

@ -7,9 +7,11 @@ import (
"bytes"
"crypto/rand"
"encoding/json"
"fmt"
"io"
"os"
"path"
"path/filepath"
"testing"
"github.com/docker/docker/errdefs"
@ -230,3 +232,28 @@ func TestImportZipInvalid(t *testing.T) {
err = Import("zipInvalid", s, r)
assert.ErrorContains(t, err, "unexpected context file")
}
func TestCorruptMetadata(t *testing.T) {
tempDir := t.TempDir()
s := New(tempDir, testCfg)
err := s.CreateOrUpdate(
Metadata{
Endpoints: map[string]interface{}{
"ep1": endpoint{Foo: "bar"},
},
Metadata: context{Bar: "baz"},
Name: "source",
})
assert.NilError(t, err)
// Simulate the meta.json file getting corrupted
// by some external process.
contextDir := s.meta.contextDir(contextdirOf("source"))
contextFile := filepath.Join(contextDir, metaFile)
err = os.WriteFile(contextFile, nil, 0o600)
assert.NilError(t, err)
// Assert that the error message gives the user some clue where to look.
_, err = s.GetMetadata("source")
assert.ErrorContains(t, err, fmt.Sprintf("parsing %s: unexpected end of JSON input", contextFile))
}

View File

@ -5,6 +5,7 @@ import (
"path/filepath"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/ioutils"
"github.com/pkg/errors"
)
@ -31,7 +32,7 @@ func (s *tlsStore) createOrUpdate(name, endpointName, filename string, data []by
if err := os.MkdirAll(endpointDir, 0o700); err != nil {
return err
}
return os.WriteFile(filepath.Join(endpointDir, filename), data, 0o600)
return ioutils.AtomicWriteFile(filepath.Join(endpointDir, filename), data, 0o600)
}
func (s *tlsStore) getData(name, endpointName, filename string) ([]byte, error) {

View File

@ -5,6 +5,7 @@ import (
"github.com/docker/distribution"
"github.com/docker/distribution/manifest/manifestlist"
"github.com/docker/distribution/manifest/ocischema"
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/reference"
"github.com/opencontainers/go-digest"
@ -16,10 +17,12 @@ import (
type ImageManifest struct {
Ref *SerializableNamed
Descriptor ocispec.Descriptor
Raw []byte `json:",omitempty"`
// SchemaV2Manifest is used for inspection
// TODO: Deprecate this and store manifest blobs
SchemaV2Manifest *schema2.DeserializedManifest `json:",omitempty"`
// OCIManifest is used for inspection
OCIManifest *ocischema.DeserializedManifest `json:",omitempty"`
}
// OCIPlatform creates an OCI platform from a manifest list platform spec
@ -53,8 +56,15 @@ func PlatformSpecFromOCI(p *ocispec.Platform) *manifestlist.PlatformSpec {
// Blobs returns the digests for all the blobs referenced by this manifest
func (i ImageManifest) Blobs() []digest.Digest {
digests := []digest.Digest{}
for _, descriptor := range i.SchemaV2Manifest.References() {
digests = append(digests, descriptor.Digest)
switch {
case i.SchemaV2Manifest != nil:
for _, descriptor := range i.SchemaV2Manifest.References() {
digests = append(digests, descriptor.Digest)
}
case i.OCIManifest != nil:
for _, descriptor := range i.OCIManifest.References() {
digests = append(digests, descriptor.Digest)
}
}
return digests
}
@ -65,6 +75,8 @@ func (i ImageManifest) Payload() (string, []byte, error) {
switch {
case i.SchemaV2Manifest != nil:
return i.SchemaV2Manifest.Payload()
case i.OCIManifest != nil:
return i.OCIManifest.Payload()
default:
return "", nil, errors.Errorf("%s has no payload", i.Ref)
}
@ -76,6 +88,8 @@ func (i ImageManifest) References() []distribution.Descriptor {
switch {
case i.SchemaV2Manifest != nil:
return i.SchemaV2Manifest.References()
case i.OCIManifest != nil:
return i.OCIManifest.References()
default:
return nil
}
@ -84,13 +98,35 @@ func (i ImageManifest) References() []distribution.Descriptor {
// NewImageManifest returns a new ImageManifest object. The values for Platform
// are initialized from those in the image
func NewImageManifest(ref reference.Named, desc ocispec.Descriptor, manifest *schema2.DeserializedManifest) ImageManifest {
raw, err := manifest.MarshalJSON()
if err != nil {
raw = nil
}
return ImageManifest{
Ref: &SerializableNamed{Named: ref},
Descriptor: desc,
Raw: raw,
SchemaV2Manifest: manifest,
}
}
// NewOCIImageManifest returns a new ImageManifest object. The values for
// Platform are initialized from those in the image
func NewOCIImageManifest(ref reference.Named, desc ocispec.Descriptor, manifest *ocischema.DeserializedManifest) ImageManifest {
raw, err := manifest.MarshalJSON()
if err != nil {
raw = nil
}
return ImageManifest{
Ref: &SerializableNamed{Named: ref},
Descriptor: desc,
Raw: raw,
OCIManifest: manifest,
}
}
// SerializableNamed is a reference.Named that can be serialized and deserialized
// from JSON
type SerializableNamed struct {

View File

@ -10,7 +10,6 @@ import (
"github.com/docker/distribution"
"github.com/docker/distribution/reference"
distributionclient "github.com/docker/distribution/registry/client"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
@ -36,7 +35,7 @@ func NewRegistryClient(resolver AuthConfigResolver, userAgent string, insecure b
}
// AuthConfigResolver returns Auth Configuration for an index
type AuthConfigResolver func(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig
type AuthConfigResolver func(ctx context.Context, index *registrytypes.IndexInfo) registrytypes.AuthConfig
// PutManifestOptions is the data sent to push a manifest
type PutManifestOptions struct {

View File

@ -9,7 +9,7 @@ import (
"github.com/docker/distribution/reference"
"github.com/docker/distribution/registry/client/auth"
"github.com/docker/distribution/registry/client/transport"
authtypes "github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/registry"
"github.com/pkg/errors"
)
@ -74,7 +74,7 @@ func getDefaultEndpointFromRepoInfo(repoInfo *registry.RepositoryInfo) (registry
}
// getHTTPTransport builds a transport for use in communicating with a registry
func getHTTPTransport(authConfig authtypes.AuthConfig, endpoint registry.APIEndpoint, repoName string, userAgent string) (http.RoundTripper, error) {
func getHTTPTransport(authConfig registrytypes.AuthConfig, endpoint registry.APIEndpoint, repoName string, userAgent string) (http.RoundTripper, error) {
// get the http transport, this will be used in a client to upload manifest
base := &http.Transport{
Proxy: http.ProxyFromEnvironment,
@ -120,7 +120,7 @@ type existingTokenHandler struct {
token string
}
func (th *existingTokenHandler) AuthorizeRequest(req *http.Request, params map[string]string) error {
func (th *existingTokenHandler) AuthorizeRequest(req *http.Request, _ map[string]string) error {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", th.token))
return nil
}

View File

@ -7,6 +7,7 @@ import (
"github.com/docker/cli/cli/manifest/types"
"github.com/docker/distribution"
"github.com/docker/distribution/manifest/manifestlist"
"github.com/docker/distribution/manifest/ocischema"
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/reference"
"github.com/docker/distribution/registry/api/errcode"
@ -35,6 +36,12 @@ func fetchManifest(ctx context.Context, repo distribution.Repository, ref refere
return types.ImageManifest{}, err
}
return imageManifest, nil
case *ocischema.DeserializedManifest:
imageManifest, err := pullManifestOCISchema(ctx, ref, repo, *v)
if err != nil {
return types.ImageManifest{}, err
}
return imageManifest, nil
case *manifestlist.DeserializedManifestList:
return types.ImageManifest{}, errors.Errorf("%s is a manifest list", ref)
}
@ -94,6 +101,28 @@ func pullManifestSchemaV2(ctx context.Context, ref reference.Named, repo distrib
return types.NewImageManifest(ref, manifestDesc, &mfst), nil
}
func pullManifestOCISchema(ctx context.Context, ref reference.Named, repo distribution.Repository, mfst ocischema.DeserializedManifest) (types.ImageManifest, error) {
manifestDesc, err := validateManifestDigest(ref, mfst)
if err != nil {
return types.ImageManifest{}, err
}
configJSON, err := pullManifestSchemaV2ImageConfig(ctx, mfst.Target().Digest, repo)
if err != nil {
return types.ImageManifest{}, err
}
if manifestDesc.Platform == nil {
manifestDesc.Platform = &ocispec.Platform{}
}
// Fill in os and architecture fields from config JSON
if err := json.Unmarshal(configJSON, manifestDesc.Platform); err != nil {
return types.ImageManifest{}, err
}
return types.NewOCIImageManifest(ref, manifestDesc, &mfst), nil
}
func pullManifestSchemaV2ImageConfig(ctx context.Context, dgst digest.Digest, repo distribution.Repository) ([]byte, error) {
blobs := repo.Blobs(ctx)
configJSON, err := blobs.Get(ctx, dgst)
@ -153,16 +182,21 @@ func pullManifestList(ctx context.Context, ref reference.Named, repo distributio
if err != nil {
return nil, err
}
v, ok := manifest.(*schema2.DeserializedManifest)
if !ok {
return nil, errors.Errorf("unsupported manifest format: %v", v)
}
manifestRef, err := reference.WithDigest(ref, manifestDescriptor.Digest)
if err != nil {
return nil, err
}
imageManifest, err := pullManifestSchemaV2(ctx, manifestRef, repo, *v)
var imageManifest types.ImageManifest
switch v := manifest.(type) {
case *schema2.DeserializedManifest:
imageManifest, err = pullManifestSchemaV2(ctx, manifestRef, repo, *v)
case *ocischema.DeserializedManifest:
imageManifest, err = pullManifestOCISchema(ctx, manifestRef, repo, *v)
default:
err = errors.Errorf("unsupported manifest type: %T", manifest)
}
if err != nil {
return nil, err
}

View File

@ -17,7 +17,6 @@ import (
"github.com/docker/distribution/registry/client/auth"
"github.com/docker/distribution/registry/client/auth/challenge"
"github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/registry"
"github.com/docker/go-connections/tlsconfig"
@ -79,24 +78,23 @@ func Server(index *registrytypes.IndexInfo) (string, error) {
}
type simpleCredentialStore struct {
auth types.AuthConfig
auth registrytypes.AuthConfig
}
func (scs simpleCredentialStore) Basic(u *url.URL) (string, string) {
func (scs simpleCredentialStore) Basic(*url.URL) (string, string) {
return scs.auth.Username, scs.auth.Password
}
func (scs simpleCredentialStore) RefreshToken(u *url.URL, service string) string {
func (scs simpleCredentialStore) RefreshToken(*url.URL, string) string {
return scs.auth.IdentityToken
}
func (scs simpleCredentialStore) SetRefreshToken(*url.URL, string, string) {
}
func (scs simpleCredentialStore) SetRefreshToken(*url.URL, string, string) {}
// GetNotaryRepository returns a NotaryRepository which stores all the
// information needed to operate on a notary repository.
// It creates an HTTP transport providing authentication support.
func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo *registry.RepositoryInfo, authConfig *types.AuthConfig, actions ...string) (client.Repository, error) {
func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo *registry.RepositoryInfo, authConfig *registrytypes.AuthConfig, actions ...string) (client.Repository, error) {
server, err := Server(repoInfo.Index)
if err != nil {
return nil, err
@ -160,7 +158,7 @@ func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo
scope := auth.RepositoryScope{
Repository: repoInfo.Name.Name(),
Actions: actions,
Class: repoInfo.Class,
Class: repoInfo.Class, // TODO(thaJeztah): Class is no longer needed for plugins and can likely be removed; see https://github.com/docker/cli/pull/4114#discussion_r1145430825
}
creds := simpleCredentialStore{auth: *authConfig}
tokenHandlerOptions := auth.TokenHandlerOptions{
@ -292,7 +290,7 @@ func GetSignableRoles(repo client.Repository, target *client.Target) ([]data.Rol
// ImageRefAndAuth contains all reference information and the auth config for an image request
type ImageRefAndAuth struct {
original string
authConfig *types.AuthConfig
authConfig *registrytypes.AuthConfig
reference reference.Named
repoInfo *registry.RepositoryInfo
tag string
@ -301,8 +299,8 @@ type ImageRefAndAuth struct {
// GetImageReferencesAndAuth retrieves the necessary reference and auth information for an image name
// as an ImageRefAndAuth struct
func GetImageReferencesAndAuth(ctx context.Context, rs registry.Service,
authResolver func(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig,
func GetImageReferencesAndAuth(ctx context.Context,
authResolver func(ctx context.Context, index *registrytypes.IndexInfo) registrytypes.AuthConfig,
imgName string,
) (ImageRefAndAuth, error) {
ref, err := reference.ParseNormalizedNamed(imgName)
@ -311,13 +309,7 @@ func GetImageReferencesAndAuth(ctx context.Context, rs registry.Service,
}
// Resolve the Repository name from fqn to RepositoryInfo
var repoInfo *registry.RepositoryInfo
if rs != nil {
repoInfo, err = rs.ResolveRepository(ref)
} else {
repoInfo, err = registry.ParseRepositoryInfo(ref)
}
repoInfo, err := registry.ParseRepositoryInfo(ref)
if err != nil {
return ImageRefAndAuth{}, err
}
@ -356,7 +348,7 @@ func getDigest(ref reference.Named) digest.Digest {
}
// AuthConfig returns the auth information (username, etc) for a given ImageRefAndAuth
func (imgRefAuth *ImageRefAndAuth) AuthConfig() *types.AuthConfig {
func (imgRefAuth *ImageRefAndAuth) AuthConfig() *registrytypes.AuthConfig {
return imgRefAuth.authConfig
}

View File

@ -51,6 +51,10 @@ func newDockerCommand(dockerCli *command.DockerCli) *cli.TopLevelCommand {
DisableDescriptions: true,
},
}
cmd.SetIn(dockerCli.In())
cmd.SetOut(dockerCli.Out())
cmd.SetErr(dockerCli.Err())
opts, flags, helpCmd = cli.SetupRootCommand(cmd)
registerCompletionFuncForGlobalFlags(dockerCli, cmd)
flags.BoolP("version", "v", false, "Print version information and quit")
@ -129,13 +133,20 @@ func tryRunPluginHelp(dockerCli command.Cli, ccmd *cobra.Command, cargs []string
func setHelpFunc(dockerCli command.Cli, cmd *cobra.Command) {
defaultHelpFunc := cmd.HelpFunc()
cmd.SetHelpFunc(func(ccmd *cobra.Command, args []string) {
if pluginmanager.IsPluginCommand(ccmd) {
if err := pluginmanager.AddPluginCommandStubs(dockerCli, ccmd.Root()); err != nil {
ccmd.Println(err)
return
}
if len(args) >= 1 {
err := tryRunPluginHelp(dockerCli, ccmd, args)
if err == nil {
return
}
if !pluginmanager.IsNotFound(err) {
ccmd.Println(err)
return
}
cmd.PrintErrf("unknown help topic: %v\n", ccmd.Name())
return
}
if err := isSupported(ccmd, dockerCli); err != nil {
@ -223,9 +234,14 @@ func runDocker(dockerCli *command.DockerCli) error {
return err
}
err = pluginmanager.AddPluginCommandStubs(dockerCli, cmd)
if err != nil {
return err
if cli.HasCompletionArg(args) {
// We add plugin command stubs early only for completion. We don't
// want to add them for normal command execution as it would cause
// a significant performance hit.
err = pluginmanager.AddPluginCommandStubs(dockerCli, cmd)
if err != nil {
return err
}
}
if len(args) > 0 {

View File

@ -84,13 +84,13 @@ __docker_q() {
# precedence over the environment setting.
__docker_configs() {
local format
if [ "$1" = "--id" ] ; then
if [ "${1-}" = "--id" ] ; then
format='{{.ID}}'
shift
elif [ "$1" = "--name" ] ; then
elif [ "${1-}" = "--name" ] ; then
format='{{.Name}}'
shift
elif [ "$DOCKER_COMPLETION_SHOW_CONFIG_IDS" = yes ] ; then
elif [ "${DOCKER_COMPLETION_SHOW_CONFIG_IDS-}" = yes ] ; then
format='{{.ID}} {{.Name}}'
else
format='{{.Name}}'
@ -120,13 +120,13 @@ __docker_complete_configs() {
# precedence over the environment setting.
__docker_containers() {
local format
if [ "$1" = "--id" ] ; then
if [ "${1-}" = "--id" ] ; then
format='{{.ID}}'
shift
elif [ "$1" = "--name" ] ; then
elif [ "${1-}" = "--name" ] ; then
format='{{.Names}}'
shift
elif [ "${DOCKER_COMPLETION_SHOW_CONTAINER_IDS}" = yes ] ; then
elif [ "${DOCKER_COMPLETION_SHOW_CONTAINER_IDS-}" = yes ] ; then
format='{{.ID}} {{.Names}}'
else
format='{{.Names}}'
@ -139,7 +139,7 @@ __docker_containers() {
# Additional filters may be appended, see `__docker_containers`.
__docker_complete_containers() {
local current="$cur"
if [ "$1" = "--cur" ] ; then
if [ "${1-}" = "--cur" ] ; then
current="$2"
shift 2
fi
@ -191,7 +191,7 @@ __docker_complete_container_ids() {
__docker_contexts() {
local add=()
while true ; do
case "$1" in
case "${1-}" in
--add)
add+=("$2")
shift 2
@ -236,12 +236,12 @@ __docker_images() {
local all
local format
if [ "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" = "all" ] ; then
if [ "${DOCKER_COMPLETION_SHOW_IMAGE_IDS-}" = "all" ] ; then
all='--all'
fi
while true ; do
case "$1" in
case "${1-}" in
--repo)
format+="$repo_format\n"
shift
@ -253,7 +253,7 @@ __docker_images() {
shift
;;
--id)
if [[ $DOCKER_COMPLETION_SHOW_IMAGE_IDS =~ ^(all|non-intermediate)$ ]] ; then
if [[ ${DOCKER_COMPLETION_SHOW_IMAGE_IDS-} =~ ^(all|non-intermediate)$ ]] ; then
format+="$id_format\n"
fi
shift
@ -269,7 +269,7 @@ __docker_images() {
esac
done
__docker_q image ls --no-trunc --format "${format%\\n}" $all "$@" | grep -v '<none>$'
__docker_q image ls --no-trunc --format "${format%\\n}" ${all-} "$@" | grep -v '<none>$'
}
# __docker_complete_images applies completion of images based on the current value of `$cur` or
@ -277,7 +277,7 @@ __docker_images() {
# See __docker_images for customization of the returned items.
__docker_complete_images() {
local current="$cur"
if [ "$1" = "--cur" ] ; then
if [ "${1-}" = "--cur" ] ; then
current="$2"
shift 2
fi
@ -295,13 +295,13 @@ __docker_complete_images() {
# precedence over the environment setting.
__docker_networks() {
local format
if [ "$1" = "--id" ] ; then
if [ "${1-}" = "--id" ] ; then
format='{{.ID}}'
shift
elif [ "$1" = "--name" ] ; then
elif [ "${1-}" = "--name" ] ; then
format='{{.Name}}'
shift
elif [ "${DOCKER_COMPLETION_SHOW_NETWORK_IDS}" = yes ] ; then
elif [ "${DOCKER_COMPLETION_SHOW_NETWORK_IDS-}" = yes ] ; then
format='{{.ID}} {{.Name}}'
else
format='{{.Name}}'
@ -314,7 +314,7 @@ __docker_networks() {
# Additional filters may be appended, see `__docker_networks`.
__docker_complete_networks() {
local current="$cur"
if [ "$1" = "--cur" ] ; then
if [ "${1-}" = "--cur" ] ; then
current="$2"
shift 2
fi
@ -340,7 +340,7 @@ __docker_volumes() {
# Additional filters may be appended, see `__docker_volumes`.
__docker_complete_volumes() {
local current="$cur"
if [ "$1" = "--cur" ] ; then
if [ "${1-}" = "--cur" ] ; then
current="$2"
shift 2
fi
@ -356,7 +356,7 @@ __docker_complete_volumes() {
__docker_plugins_bundled() {
local type add=() remove=()
while true ; do
case "$1" in
case "${1-}" in
--type)
type="$2"
shift 2
@ -390,7 +390,7 @@ __docker_plugins_bundled() {
# `__docker_complete_plugins_installed`.
__docker_complete_plugins_bundled() {
local current="$cur"
if [ "$1" = "--cur" ] ; then
if [ "${1-}" = "--cur" ] ; then
current="$2"
shift 2
fi
@ -406,7 +406,7 @@ __docker_complete_plugins_bundled() {
# For built-in pugins, see `__docker_plugins_bundled`.
__docker_plugins_installed() {
local format
if [ "$DOCKER_COMPLETION_SHOW_PLUGIN_IDS" = yes ] ; then
if [ "${DOCKER_COMPLETION_SHOW_PLUGIN_IDS-}" = yes ] ; then
format='{{.ID}} {{.Name}}'
else
format='{{.Name}}'
@ -421,7 +421,7 @@ __docker_plugins_installed() {
# For completion of built-in pugins, see `__docker_complete_plugins_bundled`.
__docker_complete_plugins_installed() {
local current="$cur"
if [ "$1" = "--cur" ] ; then
if [ "${1-}" = "--cur" ] ; then
current="$2"
shift 2
fi
@ -446,13 +446,13 @@ __docker_complete_runtimes() {
# precedence over the environment setting.
__docker_secrets() {
local format
if [ "$1" = "--id" ] ; then
if [ "${1-}" = "--id" ] ; then
format='{{.ID}}'
shift
elif [ "$1" = "--name" ] ; then
elif [ "${1-}" = "--name" ] ; then
format='{{.Name}}'
shift
elif [ "$DOCKER_COMPLETION_SHOW_SECRET_IDS" = yes ] ; then
elif [ "${DOCKER_COMPLETION_SHOW_SECRET_IDS-}" = yes ] ; then
format='{{.ID}} {{.Name}}'
else
format='{{.Name}}'
@ -465,7 +465,7 @@ __docker_secrets() {
# of `$cur` or the value of the optional first option `--cur`, if given.
__docker_complete_secrets() {
local current="$cur"
if [ "$1" = "--cur" ] ; then
if [ "${1-}" = "--cur" ] ; then
current="$2"
shift 2
fi
@ -481,7 +481,7 @@ __docker_stacks() {
# of `$cur` or the value of the optional first option `--cur`, if given.
__docker_complete_stacks() {
local current="$cur"
if [ "$1" = "--cur" ] ; then
if [ "${1-}" = "--cur" ] ; then
current="$2"
shift 2
fi
@ -499,7 +499,7 @@ __docker_complete_stacks() {
# Completions may be added with `--add`, e.g. `--add self`.
__docker_nodes() {
local format
if [ "$DOCKER_COMPLETION_SHOW_NODE_IDS" = yes ] ; then
if [ "${DOCKER_COMPLETION_SHOW_NODE_IDS-}" = yes ] ; then
format='{{.ID}} {{.Hostname}}'
else
format='{{.Hostname}}'
@ -508,7 +508,7 @@ __docker_nodes() {
local add=()
while true ; do
case "$1" in
case "${1-}" in
--id)
format='{{.ID}}'
shift
@ -535,7 +535,7 @@ __docker_nodes() {
# Additional filters may be appended, see `__docker_nodes`.
__docker_complete_nodes() {
local current="$cur"
if [ "$1" = "--cur" ] ; then
if [ "${1-}" = "--cur" ] ; then
current="$2"
shift 2
fi
@ -552,12 +552,12 @@ __docker_complete_nodes() {
# precedence over the environment setting.
__docker_services() {
local format='{{.Name}}' # default: service name only
[ "${DOCKER_COMPLETION_SHOW_SERVICE_IDS}" = yes ] && format='{{.ID}} {{.Name}}' # ID & name
[ "${DOCKER_COMPLETION_SHOW_SERVICE_IDS-}" = yes ] && format='{{.ID}} {{.Name}}' # ID & name
if [ "$1" = "--id" ] ; then
if [ "${1-}" = "--id" ] ; then
format='{{.ID}}' # IDs only
shift
elif [ "$1" = "--name" ] ; then
elif [ "${1-}" = "--name" ] ; then
format='{{.Name}}' # names only
shift
fi
@ -570,7 +570,7 @@ __docker_services() {
# Additional filters may be appended, see `__docker_services`.
__docker_complete_services() {
local current="$cur"
if [ "$1" = "--cur" ] ; then
if [ "${1-}" = "--cur" ] ; then
current="$2"
shift 2
fi
@ -601,7 +601,7 @@ __docker_append_to_completions() {
# several variables with the results.
# The result is cached for the duration of one invocation of bash completion.
__docker_fetch_info() {
if [ -z "$info_fetched" ] ; then
if [ -z "${info_fetched-}" ] ; then
read -r server_experimental server_os <<< "$(__docker_q version -f '{{.Server.Experimental}} {{.Server.Os}}')"
info_fetched=true
fi
@ -629,7 +629,7 @@ __docker_server_os_is() {
# you should pass a glob describing those options, e.g. "--option1|-o|--option2"
# Use this function to restrict completions to exact positions after the argument list.
__docker_pos_first_nonflag() {
local argument_flags=$1
local argument_flags=${1-}
local counter=$((${subcommand_pos:-${command_pos}} + 1))
while [ "$counter" -le "$cword" ]; do
@ -766,7 +766,7 @@ __docker_local_interfaces() {
command -v ip >/dev/null 2>&1 || return
local format
if [ "$1" = "--ip-only" ] ; then
if [ "${1-}" = "--ip-only" ] ; then
format='\1'
shift
else
@ -781,7 +781,7 @@ __docker_local_interfaces() {
# An additional value can be added to the possible completions with an `--add` argument.
__docker_complete_local_interfaces() {
local additional_interface
if [ "$1" = "--add" ] ; then
if [ "${1-}" = "--add" ] ; then
additional_interface="$2"
shift 2
fi
@ -1125,7 +1125,7 @@ __docker_complete_ulimits() {
sigpending
stack
"
if [ "$1" = "--rm" ] ; then
if [ "${1-}" = "--rm" ] ; then
COMPREPLY=( $( compgen -W "$limits" -- "$cur" ) )
else
COMPREPLY=( $( compgen -W "$limits" -S = -- "$cur" ) )
@ -1142,6 +1142,29 @@ __docker_complete_user_group() {
fi
}
DOCKER_PLUGINS_PATH=$(docker info --format '{{range .ClientInfo.Plugins}}{{.Path}}:{{end}}')
__docker_complete_plugin() {
local path=$1
local completionCommand="__completeNoDesc"
local resultArray=($path $completionCommand)
for value in "${words[@]:2}"; do
if [ -z "$value" ]; then
resultArray+=( "''" )
else
resultArray+=( "$value" )
fi
done
local result=$(eval "${resultArray[*]}" 2> /dev/null | grep -v '^:[0-9]*$')
# if result empty, just use filename completion as fallback
if [ -z "$result" ]; then
_filedir
else
COMPREPLY=( $(compgen -W "${result}" -- "${current-}") )
fi
}
_docker_docker() {
# global options that may appear after the docker command
local boolean_options="
@ -2785,7 +2808,7 @@ _docker_image_build() {
"
fi
if [ "$DOCKER_BUILDKIT" = "1" ] ; then
if [ "${DOCKER_BUILDKIT-}" = "1" ] ; then
options_with_args+="
--output -o
--progress
@ -3133,7 +3156,7 @@ _docker_inspect() {
local preselected_type
local type
if [ "$1" = "--type" ] ; then
if [ "${1-}" = "--type" ] ; then
preselected_type=yes
type="$2"
else
@ -5395,23 +5418,6 @@ _docker_wait() {
_docker_container_wait
}
COMPOSE_PLUGIN_PATH=$(docker info --format '{{range .ClientInfo.Plugins}}{{if eq .Name "compose"}}{{.Path}}{{end}}{{end}}')
_docker_compose() {
local completionCommand="__completeNoDesc"
local resultArray=($COMPOSE_PLUGIN_PATH $completionCommand compose)
for value in "${words[@]:2}"; do
if [ -z "$value" ]; then
resultArray+=( "''" )
else
resultArray+=( "$value" )
fi
done
local result=$(eval "${resultArray[*]}" 2> /dev/null | grep -v '^:[0-9]*$')
COMPREPLY=( $(compgen -W "${result}" -- "$current") )
}
_docker() {
local previous_extglob_setting=$(shopt -p extglob)
shopt -s extglob
@ -5481,18 +5487,23 @@ _docker() {
wait
)
# Create completion functions for all registered plugins
local known_plugin_commands=()
if [ -f "$COMPOSE_PLUGIN_PATH" ] ; then
known_plugin_commands+=("compose")
fi
local plugin_name=""
for plugin_path in ${DOCKER_PLUGINS_PATH//:/ }; do
plugin_name=$(basename "$plugin_path" | sed 's/ *$//')
plugin_name=${plugin_name#docker-}
plugin_name=${plugin_name%%.*}
eval "_docker_${plugin_name}() { __docker_complete_plugin \"${plugin_path}\"; }"
known_plugin_commands+=(${plugin_name})
done
local experimental_server_commands=(
checkpoint
)
local commands=(${management_commands[*]} ${top_level_commands[*]} ${known_plugin_commands[*]})
[ -z "$DOCKER_HIDE_LEGACY_COMMANDS" ] && commands+=(${legacy_commands[*]})
[ -z "${DOCKER_HIDE_LEGACY_COMMANDS-}" ] && commands+=(${legacy_commands[*]})
# These options are valid as global options for all client commands
# and valid as command options for `docker daemon`

View File

@ -662,7 +662,7 @@ __docker_container_subcommand() {
"($help)*--ulimit=[ulimit options]:ulimit: "
"($help)--userns=[Container user namespace]:user namespace:(host)"
"($help)--tmpfs[mount tmpfs]"
"($help)*-v[Bind mount a volume]:volume: "
"($help)*-v[Bind mount a volume]:volume:_directories -W / -P '/' -S '\:' -r '/ '"
"($help)--volume-driver=[Optional volume driver for the container]:volume driver:(local)"
"($help)*--volumes-from=[Mount volumes from the specified container]:volume: "
"($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories"

View File

@ -1,5 +1,5 @@
variable "GO_VERSION" {
default = "1.19.5"
default = "1.20.2"
}
variable "VERSION" {
default = ""
@ -52,7 +52,7 @@ target "binary" {
platforms = ["local"]
output = ["build"]
args = {
BASE_VARIANT = USE_GLIBC != "" ? "bullseye" : "alpine"
BASE_VARIANT = USE_GLIBC == "1" ? "bullseye" : "alpine"
VERSION = VERSION
PACKAGER_NAME = PACKAGER_NAME
GO_STRIP = STRIP_TARGET
@ -72,7 +72,7 @@ target "plugins" {
platforms = ["local"]
output = ["build"]
args = {
BASE_VARIANT = USE_GLIBC != "" ? "bullseye" : "alpine"
BASE_VARIANT = USE_GLIBC == "1" ? "bullseye" : "alpine"
VERSION = VERSION
GO_STRIP = STRIP_TARGET
}
@ -155,7 +155,13 @@ target "e2e-image" {
output = ["type=docker"]
tags = ["${IMAGE_NAME}"]
args = {
BASE_VARIANT = USE_GLIBC != "" ? "bullseye" : "alpine"
BASE_VARIANT = USE_GLIBC == "1" ? "bullseye" : "alpine"
VERSION = VERSION
}
}
target "e2e-gencerts" {
inherits = ["_common"]
dockerfile = "./e2e/testdata/Dockerfile.gencerts"
output = ["./e2e/testdata"]
}

View File

@ -1,9 +1,9 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.19.5
ARG GO_VERSION=1.20.2
ARG ALPINE_VERSION=3.16
ARG BUILDX_VERSION=0.9.1
ARG BUILDX_VERSION=0.10.4
FROM docker/buildx-bin:${BUILDX_VERSION} AS buildx
FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS golang

View File

@ -1,8 +1,8 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.19.5
ARG GO_VERSION=1.20.2
ARG ALPINE_VERSION=3.16
ARG GOLANGCI_LINT_VERSION=v1.49.0
ARG GOLANGCI_LINT_VERSION=v1.52.2
FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint

View File

@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.19.4
ARG GO_VERSION=1.20.2
ARG ALPINE_VERSION=3.16
ARG MODOUTDATED_VERSION=v0.8.0

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