From 2d17b338f5207d7b28df8e545956bb614b5f10a1 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 17 Dec 2024 12:10:27 +0100 Subject: [PATCH 1/3] vendor: moby master Signed-off-by: Sebastiaan van Stijn --- go.mod | 3 + go.sum | 4 +- util/dockerutil/client.go | 3 +- vendor/github.com/docker/docker/api/common.go | 2 +- .../github.com/docker/docker/api/swagger.yaml | 160 ++++++--- .../docker/docker/api/types/client.go | 27 +- .../docker/api/types/container/container.go | 133 ++++++++ .../docker/api/types/container/health.go | 26 ++ .../docker/api/types/container/hostconfig.go | 2 +- .../api/types/container/network_settings.go | 56 ++++ .../docker/api/types/{ => container}/port.go | 2 +- .../docker/docker/api/types/filters/errors.go | 13 - .../docker/docker/api/types/filters/parse.go | 16 +- .../docker/api/types/image/image_inspect.go | 130 ++++++++ .../docker/docker/api/types/image/opts.go | 27 +- .../docker/docker/api/types/image/summary.go | 9 + .../docker/api/types/network/endpoint.go | 6 + .../docker/api/types/network/network.go | 4 +- .../docker/api/types/registry/authconfig.go | 13 + .../docker/api/types/registry/registry.go | 28 +- .../docker/api/types/registry/search.go | 9 +- .../driver_data.go} | 8 +- .../docker/docker/api/types/system/info.go | 9 +- .../docker/docker/api/types/types.go | 314 +----------------- .../docker/api/types/types_deprecated.go | 241 ++++---------- .../docker/docker/client/build_prune.go | 3 +- .../docker/docker/client/container_create.go | 52 ++- .../docker/docker/client/container_inspect.go | 20 +- .../docker/docker/client/container_list.go | 5 +- .../docker/docker/client/container_prune.go | 11 +- .../docker/docker/client/container_resize.go | 5 +- .../docker/docker/client/image_build.go | 118 ++++--- .../docker/docker/client/image_history.go | 21 +- .../docker/docker/client/image_import.go | 16 +- .../docker/docker/client/image_inspect.go | 12 +- .../docker/docker/client/image_load.go | 28 +- .../docker/docker/client/image_prune.go | 11 +- .../docker/docker/client/image_save.go | 15 +- .../docker/docker/client/interface.go | 14 +- .../docker/docker/client/network_prune.go | 11 +- .../github.com/docker/docker/client/ping.go | 4 +- .../github.com/docker/docker/client/utils.go | 44 +++ .../docker/docker/client/volume_prune.go | 11 +- .../docker/docker/errdefs/http_helpers.go | 29 +- .../docker/docker/pkg/archive/archive.go | 152 ++++----- .../docker/pkg/archive/archive_linux.go | 6 +- .../docker/pkg/archive/changes_linux.go | 6 +- .../docker/docker/pkg/idtools/idtools.go | 22 +- .../docker/pkg/idtools/usergroupadd_linux.go | 2 +- .../docker/pkg/jsonmessage/jsonmessage.go | 2 +- .../docker/docker/pkg/stringid/stringid.go | 54 ++- .../docker/docker/pkg/system/init_windows.go | 4 +- .../docker/docker/pkg/system/lstat_unix.go | 4 +- .../docker/docker/pkg/system/lstat_windows.go | 2 + .../docker/docker/pkg/system/mknod.go | 2 + .../docker/docker/pkg/system/mknod_freebsd.go | 2 + .../docker/docker/pkg/system/mknod_unix.go | 2 + .../docker/docker/pkg/system/stat_linux.go | 2 + .../docker/docker/pkg/system/stat_unix.go | 6 +- .../docker/docker/pkg/system/stat_windows.go | 6 +- .../github.com/docker/docker/registry/auth.go | 33 +- .../docker/docker/registry/config.go | 110 ++---- .../docker/docker/registry/service.go | 26 +- .../docker/docker/registry/service_v2.go | 59 ++-- .../docker/docker/registry/types.go | 21 -- vendor/modules.txt | 4 +- 66 files changed, 1146 insertions(+), 1056 deletions(-) create mode 100644 vendor/github.com/docker/docker/api/types/container/health.go create mode 100644 vendor/github.com/docker/docker/api/types/container/network_settings.go rename vendor/github.com/docker/docker/api/types/{ => container}/port.go (96%) create mode 100644 vendor/github.com/docker/docker/api/types/image/image_inspect.go rename vendor/github.com/docker/docker/api/types/{graph_driver_data.go => storage/driver_data.go} (75%) diff --git a/go.mod b/go.mod index 93ca0f25946..dd529b3f82b 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,9 @@ module github.com/docker/buildx go 1.22.0 +// FIXME(thaJeztah): testing moby master +replace github.com/docker/docker => github.com/docker/docker v27.0.2-0.20241217103611-726b327b83bb+incompatible + require ( github.com/Masterminds/semver/v3 v3.2.1 github.com/Microsoft/go-winio v0.6.2 diff --git a/go.sum b/go.sum index 806e39ccb10..d052442f33f 100644 --- a/go.sum +++ b/go.sum @@ -132,8 +132,8 @@ github.com/docker/cli-docs-tool v0.8.0/go.mod h1:8TQQ3E7mOXoYUs811LiPdUnAhXrcVsB github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.4.0+incompatible h1:I9z7sQ5qyzO0BfAb9IMOawRkAGxhYsidKiTMcm0DU+A= -github.com/docker/docker v27.4.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.0.2-0.20241217103611-726b327b83bb+incompatible h1:POWgeNKhbpPC5FMSP5ztYL+sr9ytSdoC+q72dawLR/0= +github.com/docker/docker v27.0.2-0.20241217103611-726b327b83bb+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= diff --git a/util/dockerutil/client.go b/util/dockerutil/client.go index ff3f7d7e82b..b17f71ae18e 100644 --- a/util/dockerutil/client.go +++ b/util/dockerutil/client.go @@ -7,6 +7,7 @@ import ( "github.com/docker/buildx/util/progress" "github.com/docker/cli/cli/command" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/client" ) @@ -52,7 +53,7 @@ func (c *Client) LoadImage(ctx context.Context, name string, status progress.Wri w.mu.Unlock() } - resp, err := dapi.ImageLoad(ctx, pr, false) + resp, err := dapi.ImageLoad(ctx, pr, image.LoadOptions{}) defer close(done) if err != nil { handleErr(err) diff --git a/vendor/github.com/docker/docker/api/common.go b/vendor/github.com/docker/docker/api/common.go index 93d64cd8d5f..2c62cd4032e 100644 --- a/vendor/github.com/docker/docker/api/common.go +++ b/vendor/github.com/docker/docker/api/common.go @@ -3,7 +3,7 @@ package api // import "github.com/docker/docker/api" // Common constants for daemon and client. const ( // DefaultVersion of the current REST API. - DefaultVersion = "1.47" + DefaultVersion = "1.48" // MinSupportedAPIVersion is the minimum API version that can be supported // by the API server, specified as "major.minor". Note that the daemon diff --git a/vendor/github.com/docker/docker/api/swagger.yaml b/vendor/github.com/docker/docker/api/swagger.yaml index cfd52ae95de..79bb6575561 100644 --- a/vendor/github.com/docker/docker/api/swagger.yaml +++ b/vendor/github.com/docker/docker/api/swagger.yaml @@ -19,10 +19,10 @@ produces: consumes: - "application/json" - "text/plain" -basePath: "/v1.47" +basePath: "/v1.48" info: title: "Docker Engine API" - version: "1.47" + version: "1.48" x-logo: url: "https://docs.docker.com/assets/images/logo-docker-main.png" description: | @@ -55,8 +55,8 @@ info: the URL is not supported by the daemon, a HTTP `400 Bad Request` error message is returned. - If you omit the version-prefix, the current version of the API (v1.47) is used. - For example, calling `/info` is the same as calling `/v1.47/info`. Using the + If you omit the version-prefix, the current version of the API (v1.48) is used. + For example, calling `/info` is the same as calling `/v1.48/info`. Using the API without a version-prefix is deprecated and will be removed in a future release. Engine releases in the near future should support this version of the API, @@ -1917,7 +1917,7 @@ definitions: type: "string" example: "4443" - GraphDriverData: + DriverData: description: | Information about the storage driver used to store the container's and image's filesystem. @@ -1991,6 +1991,18 @@ definitions: type: "string" x-nullable: false example: "sha256:ec3f0931a6e6b6855d76b2d7b0be30e81860baccd891b2e243280bf1cd8ad710" + Descriptor: + description: | + Descriptor is an OCI descriptor of the image target. + In case of a multi-platform image, this descriptor points to the OCI index + or a manifest list. + + This field is only present if the daemon provides a multi-platform image store. + + WARNING: This is experimental and may change at any time without any backward + compatibility. + x-nullable: true + $ref: "#/definitions/OCIDescriptor" RepoTags: description: | List of image names/tags in the local image cache that reference this @@ -2107,7 +2119,7 @@ definitions: format: "int64" example: 1239828 GraphDriver: - $ref: "#/definitions/GraphDriverData" + $ref: "#/definitions/DriverData" RootFS: description: | Information about the image's RootFS, including the layer IDs. @@ -2278,6 +2290,18 @@ definitions: x-omitempty: true items: $ref: "#/definitions/ImageManifestSummary" + Descriptor: + description: | + Descriptor is an OCI descriptor of the image target. + In case of a multi-platform image, this descriptor points to the OCI index + or a manifest list. + + This field is only present if the daemon provides a multi-platform image store. + + WARNING: This is experimental and may change at any time without any backward + compatibility. + x-nullable: true + $ref: "#/definitions/OCIDescriptor" AuthConfig: type: "object" @@ -2497,6 +2521,11 @@ definitions: `overlay`). type: "string" example: "overlay" + EnableIPv4: + description: | + Whether the network was created with IPv4 enabled. + type: "boolean" + example: true EnableIPv6: description: | Whether the network was created with IPv6 enabled. @@ -2898,6 +2927,16 @@ definitions: example: com.example.some-label: "some-value" com.example.some-other-label: "some-other-value" + GwPriority: + description: | + This property determines which endpoint will provide the default + gateway for a container. The endpoint with the highest priority will + be used. If multiple endpoints have the same priority, endpoints are + lexicographically sorted based on their network name, and the one + that sorts first is picked. + type: "number" + example: + - 10 # Operational data NetworkID: @@ -5820,8 +5859,6 @@ definitions: type: "string" example: - "WARNING: No memory limit support" - - "WARNING: bridge-nf-call-iptables is disabled" - - "WARNING: bridge-nf-call-ip6tables is disabled" CDISpecDirs: description: | List of directories where (Container Device Interface) CDI @@ -5944,55 +5981,27 @@ definitions: List of IP ranges to which nondistributable artifacts can be pushed, using the CIDR syntax [RFC 4632](https://tools.ietf.org/html/4632). - Some images (for example, Windows base images) contain artifacts - whose distribution is restricted by license. When these images are - pushed to a registry, restricted artifacts are not included. - - This configuration override this behavior, and enables the daemon to - push nondistributable artifacts to all registries whose resolved IP - address is within the subnet described by the CIDR syntax. - - This option is useful when pushing images containing - nondistributable artifacts to a registry on an air-gapped network so - hosts on that network can pull the images without connecting to - another server. - - > **Warning**: Nondistributable artifacts typically have restrictions - > on how and where they can be distributed and shared. Only use this - > feature to push artifacts to private registries and ensure that you - > are in compliance with any terms that cover redistributing - > nondistributable artifacts. +


+ > **Deprecated**: Pushing nondistributable artifacts is now always enabled + > and this field is always `null`. This field will be removed in a API v1.49. type: "array" items: type: "string" - example: ["::1/128", "127.0.0.0/8"] + example: [] AllowNondistributableArtifactsHostnames: description: | List of registry hostnames to which nondistributable artifacts can be pushed, using the format `[:]` or `[:]`. - Some images (for example, Windows base images) contain artifacts - whose distribution is restricted by license. When these images are - pushed to a registry, restricted artifacts are not included. - - This configuration override this behavior for the specified - registries. - - This option is useful when pushing images containing - nondistributable artifacts to a registry on an air-gapped network so - hosts on that network can pull the images without connecting to - another server. +


- > **Warning**: Nondistributable artifacts typically have restrictions - > on how and where they can be distributed and shared. Only use this - > feature to push artifacts to private registries and ensure that you - > are in compliance with any terms that cover redistributing - > nondistributable artifacts. + > **Deprecated**: Pushing nondistributable artifacts is now always enabled + > and this field is always `null`. This field will be removed in a API v1.49. type: "array" items: type: "string" - example: ["registry.internal.corp.example.com:3000", "[2001:db8:a0b:12f0::1]:443"] + example: [] InsecureRegistryCIDRs: description: | List of IP ranges of insecure registries, using the CIDR syntax @@ -6000,7 +6009,7 @@ definitions: accept un-encrypted (HTTP) and/or untrusted (HTTPS with certificates from unknown CAs) communication. - By default, local registries (`127.0.0.0/8`) are configured as + By default, local registries (`::1/128` and `127.0.0.0/8`) are configured as insecure. All other registries are secure. Communicating with an insecure registry is not possible if the daemon assumes that registry is secure. @@ -6165,6 +6174,8 @@ definitions: Expected: description: | Commit ID of external tool expected by dockerd as set at build time. + + **Deprecated**: This field is deprecated and will be omitted in a API v1.49. type: "string" example: "2d41c047c83e09a6d61d464906feb2a2f3c52aa4" @@ -7235,6 +7246,14 @@ paths: type: "string" Platform: type: "string" + ImageManifestDescriptor: + $ref: "#/definitions/OCIDescriptor" + description: | + OCI descriptor of the platform-specific manifest of the image + the container was created from. + + Note: Only available if the daemon provides a multi-platform + image store. MountLabel: type: "string" ProcessLabel: @@ -7250,7 +7269,7 @@ paths: HostConfig: $ref: "#/definitions/HostConfig" GraphDriver: - $ref: "#/definitions/GraphDriverData" + $ref: "#/definitions/DriverData" SizeRw: description: | The size of files that have been created or changed by this @@ -9199,6 +9218,20 @@ paths: description: "Image name or ID" type: "string" required: true + - name: "platform" + type: "string" + in: "query" + description: | + JSON-encoded OCI platform to select the platform-variant. + If omitted, it defaults to any locally available platform, + prioritizing the daemon's host platform. + + If the daemon provides a multi-platform image store, this selects + the platform-variant to show the history for. If the image is + a single-platform image, or if the multi-platform image does not + provide a variant matching the given platform, an error is returned. + + Example: `{"os": "linux", "architecture": "arm", "variant": "v5"}` tags: ["Image"] /images/{name}/push: post: @@ -9563,7 +9596,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -9619,7 +9652,7 @@ paths: type: "string" example: "(empty)" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -9952,7 +9985,16 @@ paths: description: "Image name or ID" type: "string" required: true - tags: ["Image"] + - name: "platform" + type: "string" + in: "query" + description: | + JSON encoded OCI platform describing a platform which will be used + to select a platform-specific image to be saved if the image is + multi-platform. + If not provided, the full multi-platform image will be saved. + + Example: `{"os": "linux", "architecture": "arm", "variant": "v5"}` /images/get: get: summary: "Export several images" @@ -10019,6 +10061,16 @@ paths: description: "Suppress progress details during load." type: "boolean" default: false + - name: "platform" + type: "string" + in: "query" + description: | + JSON encoded OCI platform describing a platform which will be used + to select a platform-specific image to be load if the image is + multi-platform. + If not provided, the full multi-platform image will be loaded. + + Example: `{"os": "linux", "architecture": "arm", "variant": "v5"}` tags: ["Image"] /containers/{id}/exec: post: @@ -10532,6 +10584,7 @@ paths: Created: "2016-10-19T06:21:00.416543526Z" Scope: "local" Driver: "bridge" + EnableIPv4: true EnableIPv6: false Internal: false Attachable: false @@ -10553,6 +10606,7 @@ paths: Created: "0001-01-01T00:00:00Z" Scope: "local" Driver: "null" + EnableIPv4: false EnableIPv6: false Internal: false Attachable: false @@ -10567,6 +10621,7 @@ paths: Created: "0001-01-01T00:00:00Z" Scope: "local" Driver: "host" + EnableIPv4: false EnableIPv6: false Internal: false Attachable: false @@ -10752,6 +10807,12 @@ paths: IPAM: description: "Optional custom IP scheme for the network." $ref: "#/definitions/IPAM" + EnableIPv4: + description: | + Enable IPv4 on the network. + To disable IPv4, the daemon must be started with experimental features enabled. + type: "boolean" + example: true EnableIPv6: description: "Enable IPv6 on the network." type: "boolean" @@ -10829,6 +10890,7 @@ paths: IPv4Address: "172.24.56.89" IPv6Address: "2001:db8::5689" MacAddress: "02:42:ac:12:05:02" + Priority: 100 tags: ["Network"] /networks/{id}/disconnect: diff --git a/vendor/github.com/docker/docker/api/types/client.go b/vendor/github.com/docker/docker/api/types/client.go index df791f02a0c..dce8260f328 100644 --- a/vendor/github.com/docker/docker/api/types/client.go +++ b/vendor/github.com/docker/docker/api/types/client.go @@ -11,7 +11,7 @@ import ( "github.com/docker/docker/api/types/registry" ) -// NewHijackedResponse intializes a HijackedResponse type +// NewHijackedResponse initializes a [HijackedResponse] type. func NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse { return HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType} } @@ -129,14 +129,6 @@ type ImageBuildResponse struct { OSType string } -// RequestPrivilegeFunc is a function interface that -// clients can supply to retry operations after -// getting an authorization error. -// This function returns the registry authentication -// header value in base 64 format, or an error -// if the privilege request fails. -type RequestPrivilegeFunc func(context.Context) (string, error) - // NodeListOptions holds parameters to list nodes with. type NodeListOptions struct { Filters filters.Args @@ -235,11 +227,18 @@ type PluginDisableOptions struct { // PluginInstallOptions holds parameters to install a plugin. type PluginInstallOptions struct { - Disabled bool - AcceptAllPermissions bool - RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry - RemoteRef string // RemoteRef is the plugin name on the registry - PrivilegeFunc RequestPrivilegeFunc + Disabled bool + AcceptAllPermissions bool + RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry + RemoteRef string // RemoteRef is the plugin name on the registry + + // PrivilegeFunc is a function that clients can supply to retry operations + // after getting an authorization error. This function returns the registry + // authentication header value in base64 encoded format, or an error if the + // privilege request fails. + // + // For details, refer to [github.com/docker/docker/api/types/registry.RequestAuthConfig]. + PrivilegeFunc func(context.Context) (string, error) AcceptPermissionsFunc func(context.Context, PluginPrivileges) (bool, error) Args []string } diff --git a/vendor/github.com/docker/docker/api/types/container/container.go b/vendor/github.com/docker/docker/api/types/container/container.go index 711af12c992..0244a3549a1 100644 --- a/vendor/github.com/docker/docker/api/types/container/container.go +++ b/vendor/github.com/docker/docker/api/types/container/container.go @@ -4,6 +4,10 @@ import ( "io" "os" "time" + + "github.com/docker/docker/api/types/mount" + "github.com/docker/docker/api/types/storage" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // PruneReport contains the response for Engine API: @@ -42,3 +46,132 @@ type StatsResponseReader struct { Body io.ReadCloser `json:"body"` OSType string `json:"ostype"` } + +// MountPoint represents a mount point configuration inside the container. +// This is used for reporting the mountpoints in use by a container. +type MountPoint struct { + // Type is the type of mount, see `Type` definitions in + // github.com/docker/docker/api/types/mount.Type + Type mount.Type `json:",omitempty"` + + // Name is the name reference to the underlying data defined by `Source` + // e.g., the volume name. + Name string `json:",omitempty"` + + // Source is the source location of the mount. + // + // For volumes, this contains the storage location of the volume (within + // `/var/lib/docker/volumes/`). For bind-mounts, and `npipe`, this contains + // the source (host) part of the bind-mount. For `tmpfs` mount points, this + // field is empty. + Source string + + // Destination is the path relative to the container root (`/`) where the + // Source is mounted inside the container. + Destination string + + // Driver is the volume driver used to create the volume (if it is a volume). + Driver string `json:",omitempty"` + + // Mode is a comma separated list of options supplied by the user when + // creating the bind/volume mount. + // + // The default is platform-specific (`"z"` on Linux, empty on Windows). + Mode string + + // RW indicates whether the mount is mounted writable (read-write). + RW bool + + // Propagation describes how mounts are propagated from the host into the + // mount point, and vice-versa. Refer to the Linux kernel documentation + // for details: + // https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt + // + // This field is not used on Windows. + Propagation mount.Propagation +} + +// State stores container's running state +// it's part of ContainerJSONBase and returned by "inspect" command +type State struct { + Status string // String representation of the container state. Can be one of "created", "running", "paused", "restarting", "removing", "exited", or "dead" + Running bool + Paused bool + Restarting bool + OOMKilled bool + Dead bool + Pid int + ExitCode int + Error string + StartedAt string + FinishedAt string + Health *Health `json:",omitempty"` +} + +// Summary contains response of Engine API: +// GET "/containers/json" +type Summary struct { + ID string `json:"Id"` + Names []string + Image string + ImageID string + Command string + Created int64 + Ports []Port + SizeRw int64 `json:",omitempty"` + SizeRootFs int64 `json:",omitempty"` + Labels map[string]string + State string + Status string + HostConfig struct { + NetworkMode string `json:",omitempty"` + Annotations map[string]string `json:",omitempty"` + } + NetworkSettings *NetworkSettingsSummary + Mounts []MountPoint +} + +// ContainerJSONBase contains response of Engine API GET "/containers/{name:.*}/json" +// for API version 1.18 and older. +// +// TODO(thaJeztah): combine ContainerJSONBase and InspectResponse into a single struct. +// The split between ContainerJSONBase (ContainerJSONBase) and InspectResponse (InspectResponse) +// was done in commit 6deaa58ba5f051039643cedceee97c8695e2af74 (https://github.com/moby/moby/pull/13675). +// ContainerJSONBase contained all fields for API < 1.19, and InspectResponse +// held fields that were added in API 1.19 and up. Given that the minimum +// supported API version is now 1.24, we no longer use the separate type. +type ContainerJSONBase struct { + ID string `json:"Id"` + Created string + Path string + Args []string + State *State + Image string + ResolvConfPath string + HostnamePath string + HostsPath string + LogPath string + Name string + RestartCount int + Driver string + Platform string + MountLabel string + ProcessLabel string + AppArmorProfile string + ExecIDs []string + HostConfig *HostConfig + GraphDriver storage.DriverData + SizeRw *int64 `json:",omitempty"` + SizeRootFs *int64 `json:",omitempty"` +} + +// InspectResponse is the response for the GET "/containers/{name:.*}/json" +// endpoint. +type InspectResponse struct { + *ContainerJSONBase + Mounts []MountPoint + Config *Config + NetworkSettings *NetworkSettings + // ImageManifestDescriptor is the descriptor of a platform-specific manifest of the image used to create the container. + ImageManifestDescriptor *ocispec.Descriptor `json:",omitempty"` +} diff --git a/vendor/github.com/docker/docker/api/types/container/health.go b/vendor/github.com/docker/docker/api/types/container/health.go new file mode 100644 index 00000000000..93663746f61 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/health.go @@ -0,0 +1,26 @@ +package container + +import "time" + +// Health states +const ( + NoHealthcheck = "none" // Indicates there is no healthcheck + Starting = "starting" // Starting indicates that the container is not yet ready + Healthy = "healthy" // Healthy indicates that the container is running correctly + Unhealthy = "unhealthy" // Unhealthy indicates that the container has a problem +) + +// Health stores information about the container's healthcheck results +type Health struct { + Status string // Status is one of [Starting], [Healthy] or [Unhealthy]. + FailingStreak int // FailingStreak is the number of consecutive failures + Log []*HealthcheckResult // Log contains the last few results (oldest first) +} + +// HealthcheckResult stores information about a single run of a healthcheck probe +type HealthcheckResult struct { + Start time.Time // Start is the time this check started + End time.Time // End is the time this check ended + ExitCode int // ExitCode meanings: 0=healthy, 1=unhealthy, 2=reserved (considered unhealthy), else=error running probe + Output string // Output from last check +} diff --git a/vendor/github.com/docker/docker/api/types/container/hostconfig.go b/vendor/github.com/docker/docker/api/types/container/hostconfig.go index 03648fb7b5d..83198305e7a 100644 --- a/vendor/github.com/docker/docker/api/types/container/hostconfig.go +++ b/vendor/github.com/docker/docker/api/types/container/hostconfig.go @@ -10,7 +10,7 @@ import ( "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/strslice" "github.com/docker/go-connections/nat" - units "github.com/docker/go-units" + "github.com/docker/go-units" ) // CgroupnsMode represents the cgroup namespace mode of the container diff --git a/vendor/github.com/docker/docker/api/types/container/network_settings.go b/vendor/github.com/docker/docker/api/types/container/network_settings.go new file mode 100644 index 00000000000..afec0e54323 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/network_settings.go @@ -0,0 +1,56 @@ +package container + +import ( + "github.com/docker/docker/api/types/network" + "github.com/docker/go-connections/nat" +) + +// NetworkSettings exposes the network settings in the api +type NetworkSettings struct { + NetworkSettingsBase + DefaultNetworkSettings + Networks map[string]*network.EndpointSettings +} + +// NetworkSettingsBase holds networking state for a container when inspecting it. +type NetworkSettingsBase struct { + Bridge string // Bridge contains the name of the default bridge interface iff it was set through the daemon --bridge flag. + SandboxID string // SandboxID uniquely represents a container's network stack + SandboxKey string // SandboxKey identifies the sandbox + Ports nat.PortMap // Ports is a collection of PortBinding indexed by Port + + // HairpinMode specifies if hairpin NAT should be enabled on the virtual interface + // + // Deprecated: This field is never set and will be removed in a future release. + HairpinMode bool + // LinkLocalIPv6Address is an IPv6 unicast address using the link-local prefix + // + // Deprecated: This field is never set and will be removed in a future release. + LinkLocalIPv6Address string + // LinkLocalIPv6PrefixLen is the prefix length of an IPv6 unicast address + // + // Deprecated: This field is never set and will be removed in a future release. + LinkLocalIPv6PrefixLen int + SecondaryIPAddresses []network.Address // Deprecated: This field is never set and will be removed in a future release. + SecondaryIPv6Addresses []network.Address // Deprecated: This field is never set and will be removed in a future release. +} + +// DefaultNetworkSettings holds network information +// during the 2 release deprecation period. +// It will be removed in Docker 1.11. +type DefaultNetworkSettings struct { + EndpointID string // EndpointID uniquely represents a service endpoint in a Sandbox + Gateway string // Gateway holds the gateway address for the network + GlobalIPv6Address string // GlobalIPv6Address holds network's global IPv6 address + GlobalIPv6PrefixLen int // GlobalIPv6PrefixLen represents mask length of network's global IPv6 address + IPAddress string // IPAddress holds the IPv4 address for the network + IPPrefixLen int // IPPrefixLen represents mask length of network's IPv4 address + IPv6Gateway string // IPv6Gateway holds gateway address specific for IPv6 + MacAddress string // MacAddress holds the MAC address for the network +} + +// NetworkSettingsSummary provides a summary of container's networks +// in /containers/json +type NetworkSettingsSummary struct { + Networks map[string]*network.EndpointSettings +} diff --git a/vendor/github.com/docker/docker/api/types/port.go b/vendor/github.com/docker/docker/api/types/container/port.go similarity index 96% rename from vendor/github.com/docker/docker/api/types/port.go rename to vendor/github.com/docker/docker/api/types/container/port.go index d91234744c6..895043cfe94 100644 --- a/vendor/github.com/docker/docker/api/types/port.go +++ b/vendor/github.com/docker/docker/api/types/container/port.go @@ -1,4 +1,4 @@ -package types +package container // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command diff --git a/vendor/github.com/docker/docker/api/types/filters/errors.go b/vendor/github.com/docker/docker/api/types/filters/errors.go index f52f6944089..b8a690d67ab 100644 --- a/vendor/github.com/docker/docker/api/types/filters/errors.go +++ b/vendor/github.com/docker/docker/api/types/filters/errors.go @@ -22,16 +22,3 @@ func (e invalidFilter) Error() string { // InvalidParameter marks this error as ErrInvalidParameter func (e invalidFilter) InvalidParameter() {} - -// unreachableCode is an error indicating that the code path was not expected to be reached. -type unreachableCode struct { - Filter string - Value []string -} - -// System marks this error as ErrSystem -func (e unreachableCode) System() {} - -func (e unreachableCode) Error() string { - return fmt.Sprintf("unreachable code reached for filter: %q with values: %s", e.Filter, e.Value) -} diff --git a/vendor/github.com/docker/docker/api/types/filters/parse.go b/vendor/github.com/docker/docker/api/types/filters/parse.go index 0914b2a4410..2085ff38f2f 100644 --- a/vendor/github.com/docker/docker/api/types/filters/parse.go +++ b/vendor/github.com/docker/docker/api/types/filters/parse.go @@ -200,7 +200,6 @@ func (args Args) Match(field, source string) bool { // Error is not nil only if the filter values are not valid boolean or are conflicting. func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) { fieldValues, ok := args.fields[key] - if !ok { return defaultValue, nil } @@ -211,20 +210,11 @@ func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) { isFalse := fieldValues["0"] || fieldValues["false"] isTrue := fieldValues["1"] || fieldValues["true"] - - conflicting := isFalse && isTrue - invalid := !isFalse && !isTrue - - if conflicting || invalid { + if isFalse == isTrue { + // Either no or conflicting truthy/falsy value were provided return defaultValue, &invalidFilter{key, args.Get(key)} - } else if isFalse { - return false, nil - } else if isTrue { - return true, nil } - - // This code shouldn't be reached. - return defaultValue, &unreachableCode{Filter: key, Value: args.Get(key)} + return isTrue, nil } // ExactMatch returns true if the source matches exactly one of the values. diff --git a/vendor/github.com/docker/docker/api/types/image/image_inspect.go b/vendor/github.com/docker/docker/api/types/image/image_inspect.go new file mode 100644 index 00000000000..5d24dd62a22 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/image/image_inspect.go @@ -0,0 +1,130 @@ +package image + +import ( + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/storage" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +// RootFS returns Image's RootFS description including the layer IDs. +type RootFS struct { + Type string `json:",omitempty"` + Layers []string `json:",omitempty"` +} + +// InspectResponse contains response of Engine API: +// GET "/images/{name:.*}/json" +type InspectResponse struct { + // ID is the content-addressable ID of an image. + // + // This identifier is a content-addressable digest calculated from the + // image's configuration (which includes the digests of layers used by + // the image). + // + // Note that this digest differs from the `RepoDigests` below, which + // holds digests of image manifests that reference the image. + ID string `json:"Id"` + + // RepoTags is a list of image names/tags in the local image cache that + // reference this image. + // + // Multiple image tags can refer to the same image, and this list may be + // empty if no tags reference the image, in which case the image is + // "untagged", in which case it can still be referenced by its ID. + RepoTags []string + + // RepoDigests is a list of content-addressable digests of locally available + // image manifests that the image is referenced from. Multiple manifests can + // refer to the same image. + // + // These digests are usually only available if the image was either pulled + // from a registry, or if the image was pushed to a registry, which is when + // the manifest is generated and its digest calculated. + RepoDigests []string + + // Parent is the ID of the parent image. + // + // Depending on how the image was created, this field may be empty and + // is only set for images that were built/created locally. This field + // is empty if the image was pulled from an image registry. + Parent string + + // Comment is an optional message that can be set when committing or + // importing the image. + Comment string + + // Created is the date and time at which the image was created, formatted in + // RFC 3339 nano-seconds (time.RFC3339Nano). + // + // This information is only available if present in the image, + // and omitted otherwise. + Created string `json:",omitempty"` + + // Container is the ID of the container that was used to create the image. + // + // Depending on how the image was created, this field may be empty. + // + // Deprecated: this field is omitted in API v1.45, but kept for backward compatibility. + Container string `json:",omitempty"` + + // ContainerConfig is an optional field containing the configuration of the + // container that was last committed when creating the image. + // + // Previous versions of Docker builder used this field to store build cache, + // and it is not in active use anymore. + // + // Deprecated: this field is omitted in API v1.45, but kept for backward compatibility. + ContainerConfig *container.Config `json:",omitempty"` + + // DockerVersion is the version of Docker that was used to build the image. + // + // Depending on how the image was created, this field may be empty. + DockerVersion string + + // Author is the name of the author that was specified when committing the + // image, or as specified through MAINTAINER (deprecated) in the Dockerfile. + Author string + Config *container.Config + + // Architecture is the hardware CPU architecture that the image runs on. + Architecture string + + // Variant is the CPU architecture variant (presently ARM-only). + Variant string `json:",omitempty"` + + // OS is the Operating System the image is built to run on. + Os string + + // OsVersion is the version of the Operating System the image is built to + // run on (especially for Windows). + OsVersion string `json:",omitempty"` + + // Size is the total size of the image including all layers it is composed of. + Size int64 + + // VirtualSize is the total size of the image including all layers it is + // composed of. + // + // Deprecated: this field is omitted in API v1.44, but kept for backward compatibility. Use Size instead. + VirtualSize int64 `json:"VirtualSize,omitempty"` + + // GraphDriver holds information about the storage driver used to store the + // container's and image's filesystem. + GraphDriver storage.DriverData + + // RootFS contains information about the image's RootFS, including the + // layer IDs. + RootFS RootFS + + // Metadata of the image in the local cache. + // + // This information is local to the daemon, and not part of the image itself. + Metadata Metadata + + // Descriptor is the OCI descriptor of the image target. + // It's only set if the daemon provides a multi-platform image store. + // + // WARNING: This is experimental and may change at any time without any backward + // compatibility. + Descriptor *ocispec.Descriptor `json:"Descriptor,omitempty"` +} diff --git a/vendor/github.com/docker/docker/api/types/image/opts.go b/vendor/github.com/docker/docker/api/types/image/opts.go index 923ebe5a06a..06365830210 100644 --- a/vendor/github.com/docker/docker/api/types/image/opts.go +++ b/vendor/github.com/docker/docker/api/types/image/opts.go @@ -38,7 +38,7 @@ type PullOptions struct { // authentication header value in base64 encoded format, or an error if the // privilege request fails. // - // Also see [github.com/docker/docker/api/types.RequestPrivilegeFunc]. + // For details, refer to [github.com/docker/docker/api/types/registry.RequestAuthConfig]. PrivilegeFunc func(context.Context) (string, error) Platform string } @@ -53,7 +53,7 @@ type PushOptions struct { // authentication header value in base64 encoded format, or an error if the // privilege request fails. // - // Also see [github.com/docker/docker/api/types.RequestPrivilegeFunc]. + // For details, refer to [github.com/docker/docker/api/types/registry.RequestAuthConfig]. PrivilegeFunc func(context.Context) (string, error) // Platform is an optional field that selects a specific platform to push @@ -86,3 +86,26 @@ type RemoveOptions struct { Force bool PruneChildren bool } + +// HistoryOptions holds parameters to get image history. +type HistoryOptions struct { + // Platform from the manifest list to use for history. + Platform *ocispec.Platform +} + +// LoadOptions holds parameters to load images. +type LoadOptions struct { + // Quiet suppresses progress output + Quiet bool + + // Platforms selects the platforms to load if the image is a + // multi-platform image and has multiple variants. + Platforms []ocispec.Platform +} + +// SaveOptions holds parameters to save images. +type SaveOptions struct { + // Platforms selects the platforms to save if the image is a + // multi-platform image and has multiple variants. + Platforms []ocispec.Platform +} diff --git a/vendor/github.com/docker/docker/api/types/image/summary.go b/vendor/github.com/docker/docker/api/types/image/summary.go index e87e216a28b..c5ae6ab9ca1 100644 --- a/vendor/github.com/docker/docker/api/types/image/summary.go +++ b/vendor/github.com/docker/docker/api/types/image/summary.go @@ -1,5 +1,7 @@ package image +import ocispec "github.com/opencontainers/image-spec/specs-go/v1" + type Summary struct { // Number of containers using this image. Includes both stopped and running @@ -42,6 +44,13 @@ type Summary struct { // Required: true ParentID string `json:"ParentId"` + // Descriptor is the OCI descriptor of the image target. + // It's only set if the daemon provides a multi-platform image store. + // + // WARNING: This is experimental and may change at any time without any backward + // compatibility. + Descriptor *ocispec.Descriptor `json:"Descriptor,omitempty"` + // Manifests is a list of image manifests available in this image. It // provides a more detailed view of the platform-specific image manifests or // other image-attached data like build attestations. diff --git a/vendor/github.com/docker/docker/api/types/network/endpoint.go b/vendor/github.com/docker/docker/api/types/network/endpoint.go index 0fbb40b351c..167ac70ab56 100644 --- a/vendor/github.com/docker/docker/api/types/network/endpoint.go +++ b/vendor/github.com/docker/docker/api/types/network/endpoint.go @@ -19,6 +19,12 @@ type EndpointSettings struct { // generated address). MacAddress string DriverOpts map[string]string + + // GwPriority determines which endpoint will provide the default gateway + // for the container. The endpoint with the highest priority will be used. + // If multiple endpoints have the same priority, they are lexicographically + // sorted based on their network name, and the one that sorts first is picked. + GwPriority int // Operational data NetworkID string EndpointID string diff --git a/vendor/github.com/docker/docker/api/types/network/network.go b/vendor/github.com/docker/docker/api/types/network/network.go index c8db97a7e67..d34b8ab7249 100644 --- a/vendor/github.com/docker/docker/api/types/network/network.go +++ b/vendor/github.com/docker/docker/api/types/network/network.go @@ -33,6 +33,7 @@ type CreateRequest struct { type CreateOptions struct { Driver string // Driver is the driver-name used to create the network (e.g. `bridge`, `overlay`) Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level). + EnableIPv4 *bool `json:",omitempty"` // EnableIPv4 represents whether to enable IPv4. EnableIPv6 *bool `json:",omitempty"` // EnableIPv6 represents whether to enable IPv6. IPAM *IPAM // IPAM is the network's IP Address Management. Internal bool // Internal represents if the network is used internal only. @@ -76,7 +77,8 @@ type Inspect struct { Created time.Time // Created is the time the network created Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level) Driver string // Driver is the Driver name used to create the network (e.g. `bridge`, `overlay`) - EnableIPv6 bool // EnableIPv6 represents whether to enable IPv6 + EnableIPv4 bool // EnableIPv4 represents whether IPv4 is enabled + EnableIPv6 bool // EnableIPv6 represents whether IPv6 is enabled IPAM IPAM // IPAM is the network's IP Address Management Internal bool // Internal represents if the network is used internal only Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode. diff --git a/vendor/github.com/docker/docker/api/types/registry/authconfig.go b/vendor/github.com/docker/docker/api/types/registry/authconfig.go index 8e383f6e60c..2f49428890e 100644 --- a/vendor/github.com/docker/docker/api/types/registry/authconfig.go +++ b/vendor/github.com/docker/docker/api/types/registry/authconfig.go @@ -1,5 +1,6 @@ package registry // import "github.com/docker/docker/api/types/registry" import ( + "context" "encoding/base64" "encoding/json" "io" @@ -12,6 +13,18 @@ import ( // authorization credentials for registry operations (push/pull). const AuthHeader = "X-Registry-Auth" +// RequestAuthConfig is a function interface that clients can supply +// to retry operations after getting an authorization error. +// +// The function must return the [AuthHeader] value ([AuthConfig]), encoded +// in base64url format ([RFC4648, section 5]), which can be decoded by +// [DecodeAuthConfig]. +// +// It must return an error if the privilege request fails. +// +// [RFC4648, section 5]: https://tools.ietf.org/html/rfc4648#section-5 +type RequestAuthConfig func(context.Context) (string, error) + // AuthConfig contains authorization information for connecting to a Registry. type AuthConfig struct { Username string `json:"username,omitempty"` diff --git a/vendor/github.com/docker/docker/api/types/registry/registry.go b/vendor/github.com/docker/docker/api/types/registry/registry.go index 75ee07b15f9..b0a4d604f5f 100644 --- a/vendor/github.com/docker/docker/api/types/registry/registry.go +++ b/vendor/github.com/docker/docker/api/types/registry/registry.go @@ -9,11 +9,29 @@ import ( // ServiceConfig stores daemon registry services configuration. type ServiceConfig struct { - AllowNondistributableArtifactsCIDRs []*NetIPNet - AllowNondistributableArtifactsHostnames []string - InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"` - IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"` - Mirrors []string + AllowNondistributableArtifactsCIDRs []*NetIPNet `json:"AllowNondistributableArtifactsCIDRs,omitempty"` // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release. + AllowNondistributableArtifactsHostnames []string `json:"AllowNondistributableArtifactsHostnames,omitempty"` // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release. + + InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"` + IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"` + Mirrors []string +} + +// MarshalJSON implements a custom marshaler to include legacy fields +// in API responses. +func (sc ServiceConfig) MarshalJSON() ([]byte, error) { + tmp := map[string]interface{}{ + "InsecureRegistryCIDRs": sc.InsecureRegistryCIDRs, + "IndexConfigs": sc.IndexConfigs, + "Mirrors": sc.Mirrors, + } + if sc.AllowNondistributableArtifactsCIDRs != nil { + tmp["AllowNondistributableArtifactsCIDRs"] = nil + } + if sc.AllowNondistributableArtifactsHostnames != nil { + tmp["AllowNondistributableArtifactsHostnames"] = nil + } + return json.Marshal(tmp) } // NetIPNet is the net.IPNet type, which can be marshalled and diff --git a/vendor/github.com/docker/docker/api/types/registry/search.go b/vendor/github.com/docker/docker/api/types/registry/search.go index a0a1eec5441..994ca4c6f96 100644 --- a/vendor/github.com/docker/docker/api/types/registry/search.go +++ b/vendor/github.com/docker/docker/api/types/registry/search.go @@ -10,11 +10,12 @@ import ( type SearchOptions struct { RegistryAuth string - // PrivilegeFunc is a [types.RequestPrivilegeFunc] the client can - // supply to retry operations after getting an authorization error. + // PrivilegeFunc is a function that clients can supply to retry operations + // after getting an authorization error. This function returns the registry + // authentication header value in base64 encoded format, or an error if the + // privilege request fails. // - // It must return the registry authentication header value in base64 - // format, or an error if the privilege request fails. + // For details, refer to [github.com/docker/docker/api/types/registry.RequestAuthConfig]. PrivilegeFunc func(context.Context) (string, error) Filters filters.Args Limit int diff --git a/vendor/github.com/docker/docker/api/types/graph_driver_data.go b/vendor/github.com/docker/docker/api/types/storage/driver_data.go similarity index 75% rename from vendor/github.com/docker/docker/api/types/graph_driver_data.go rename to vendor/github.com/docker/docker/api/types/storage/driver_data.go index ce3deb331c5..009e2130950 100644 --- a/vendor/github.com/docker/docker/api/types/graph_driver_data.go +++ b/vendor/github.com/docker/docker/api/types/storage/driver_data.go @@ -1,13 +1,13 @@ -package types +package storage // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command -// GraphDriverData Information about the storage driver used to store the container's and +// DriverData Information about the storage driver used to store the container's and // image's filesystem. // -// swagger:model GraphDriverData -type GraphDriverData struct { +// swagger:model DriverData +type DriverData struct { // Low-level storage metadata, provided as key/value pairs. // diff --git a/vendor/github.com/docker/docker/api/types/system/info.go b/vendor/github.com/docker/docker/api/types/system/info.go index c66a2afb8bb..4704edfba73 100644 --- a/vendor/github.com/docker/docker/api/types/system/info.go +++ b/vendor/github.com/docker/docker/api/types/system/info.go @@ -137,8 +137,13 @@ type PluginsInfo struct { // Commit holds the Git-commit (SHA1) that a binary was built from, as reported // in the version-string of external tools, such as containerd, or runC. type Commit struct { - ID string // ID is the actual commit ID of external tool. - Expected string // Expected is the commit ID of external tool expected by dockerd as set at build time. + // ID is the actual commit ID or version of external tool. + ID string + + // Expected is the commit ID of external tool expected by dockerd as set at build time. + // + // Deprecated: this field is no longer used in API v1.49, but kept for backward-compatibility with older API versions. + Expected string } // NetworkAddressPool is a temp struct used by [Info] struct. diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/docker/docker/api/types/types.go index ea55813e638..eb6831c5f39 100644 --- a/vendor/github.com/docker/docker/api/types/types.go +++ b/vendor/github.com/docker/docker/api/types/types.go @@ -6,11 +6,8 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/image" - "github.com/docker/docker/api/types/mount" - "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/volume" - "github.com/docker/go-connections/nat" ) const ( @@ -21,145 +18,6 @@ const ( MediaTypeMultiplexedStream = "application/vnd.docker.multiplexed-stream" ) -// RootFS returns Image's RootFS description including the layer IDs. -type RootFS struct { - Type string `json:",omitempty"` - Layers []string `json:",omitempty"` -} - -// ImageInspect contains response of Engine API: -// GET "/images/{name:.*}/json" -type ImageInspect struct { - // ID is the content-addressable ID of an image. - // - // This identifier is a content-addressable digest calculated from the - // image's configuration (which includes the digests of layers used by - // the image). - // - // Note that this digest differs from the `RepoDigests` below, which - // holds digests of image manifests that reference the image. - ID string `json:"Id"` - - // RepoTags is a list of image names/tags in the local image cache that - // reference this image. - // - // Multiple image tags can refer to the same image, and this list may be - // empty if no tags reference the image, in which case the image is - // "untagged", in which case it can still be referenced by its ID. - RepoTags []string - - // RepoDigests is a list of content-addressable digests of locally available - // image manifests that the image is referenced from. Multiple manifests can - // refer to the same image. - // - // These digests are usually only available if the image was either pulled - // from a registry, or if the image was pushed to a registry, which is when - // the manifest is generated and its digest calculated. - RepoDigests []string - - // Parent is the ID of the parent image. - // - // Depending on how the image was created, this field may be empty and - // is only set for images that were built/created locally. This field - // is empty if the image was pulled from an image registry. - Parent string - - // Comment is an optional message that can be set when committing or - // importing the image. - Comment string - - // Created is the date and time at which the image was created, formatted in - // RFC 3339 nano-seconds (time.RFC3339Nano). - // - // This information is only available if present in the image, - // and omitted otherwise. - Created string `json:",omitempty"` - - // Container is the ID of the container that was used to create the image. - // - // Depending on how the image was created, this field may be empty. - // - // Deprecated: this field is omitted in API v1.45, but kept for backward compatibility. - Container string `json:",omitempty"` - - // ContainerConfig is an optional field containing the configuration of the - // container that was last committed when creating the image. - // - // Previous versions of Docker builder used this field to store build cache, - // and it is not in active use anymore. - // - // Deprecated: this field is omitted in API v1.45, but kept for backward compatibility. - ContainerConfig *container.Config `json:",omitempty"` - - // DockerVersion is the version of Docker that was used to build the image. - // - // Depending on how the image was created, this field may be empty. - DockerVersion string - - // Author is the name of the author that was specified when committing the - // image, or as specified through MAINTAINER (deprecated) in the Dockerfile. - Author string - Config *container.Config - - // Architecture is the hardware CPU architecture that the image runs on. - Architecture string - - // Variant is the CPU architecture variant (presently ARM-only). - Variant string `json:",omitempty"` - - // OS is the Operating System the image is built to run on. - Os string - - // OsVersion is the version of the Operating System the image is built to - // run on (especially for Windows). - OsVersion string `json:",omitempty"` - - // Size is the total size of the image including all layers it is composed of. - Size int64 - - // VirtualSize is the total size of the image including all layers it is - // composed of. - // - // Deprecated: this field is omitted in API v1.44, but kept for backward compatibility. Use Size instead. - VirtualSize int64 `json:"VirtualSize,omitempty"` - - // GraphDriver holds information about the storage driver used to store the - // container's and image's filesystem. - GraphDriver GraphDriverData - - // RootFS contains information about the image's RootFS, including the - // layer IDs. - RootFS RootFS - - // Metadata of the image in the local cache. - // - // This information is local to the daemon, and not part of the image itself. - Metadata image.Metadata -} - -// Container contains response of Engine API: -// GET "/containers/json" -type Container struct { - ID string `json:"Id"` - Names []string - Image string - ImageID string - Command string - Created int64 - Ports []Port - SizeRw int64 `json:",omitempty"` - SizeRootFs int64 `json:",omitempty"` - Labels map[string]string - State string - Status string - HostConfig struct { - NetworkMode string `json:",omitempty"` - Annotations map[string]string `json:",omitempty"` - } - NetworkSettings *SummaryNetworkSettings - Mounts []MountPoint -} - // Ping contains response of Engine API: // GET "/_ping" type Ping struct { @@ -205,176 +63,6 @@ type Version struct { BuildTime string `json:",omitempty"` } -// HealthcheckResult stores information about a single run of a healthcheck probe -type HealthcheckResult struct { - Start time.Time // Start is the time this check started - End time.Time // End is the time this check ended - ExitCode int // ExitCode meanings: 0=healthy, 1=unhealthy, 2=reserved (considered unhealthy), else=error running probe - Output string // Output from last check -} - -// Health states -const ( - NoHealthcheck = "none" // Indicates there is no healthcheck - Starting = "starting" // Starting indicates that the container is not yet ready - Healthy = "healthy" // Healthy indicates that the container is running correctly - Unhealthy = "unhealthy" // Unhealthy indicates that the container has a problem -) - -// Health stores information about the container's healthcheck results -type Health struct { - Status string // Status is one of Starting, Healthy or Unhealthy - FailingStreak int // FailingStreak is the number of consecutive failures - Log []*HealthcheckResult // Log contains the last few results (oldest first) -} - -// ContainerState stores container's running state -// it's part of ContainerJSONBase and will return by "inspect" command -type ContainerState struct { - Status string // String representation of the container state. Can be one of "created", "running", "paused", "restarting", "removing", "exited", or "dead" - Running bool - Paused bool - Restarting bool - OOMKilled bool - Dead bool - Pid int - ExitCode int - Error string - StartedAt string - FinishedAt string - Health *Health `json:",omitempty"` -} - -// ContainerJSONBase contains response of Engine API: -// GET "/containers/{name:.*}/json" -type ContainerJSONBase struct { - ID string `json:"Id"` - Created string - Path string - Args []string - State *ContainerState - Image string - ResolvConfPath string - HostnamePath string - HostsPath string - LogPath string - Node *ContainerNode `json:",omitempty"` // Deprecated: Node was only propagated by Docker Swarm standalone API. It sill be removed in the next release. - Name string - RestartCount int - Driver string - Platform string - MountLabel string - ProcessLabel string - AppArmorProfile string - ExecIDs []string - HostConfig *container.HostConfig - GraphDriver GraphDriverData - SizeRw *int64 `json:",omitempty"` - SizeRootFs *int64 `json:",omitempty"` -} - -// ContainerJSON is newly used struct along with MountPoint -type ContainerJSON struct { - *ContainerJSONBase - Mounts []MountPoint - Config *container.Config - NetworkSettings *NetworkSettings -} - -// NetworkSettings exposes the network settings in the api -type NetworkSettings struct { - NetworkSettingsBase - DefaultNetworkSettings - Networks map[string]*network.EndpointSettings -} - -// SummaryNetworkSettings provides a summary of container's networks -// in /containers/json -type SummaryNetworkSettings struct { - Networks map[string]*network.EndpointSettings -} - -// NetworkSettingsBase holds networking state for a container when inspecting it. -type NetworkSettingsBase struct { - Bridge string // Bridge contains the name of the default bridge interface iff it was set through the daemon --bridge flag. - SandboxID string // SandboxID uniquely represents a container's network stack - SandboxKey string // SandboxKey identifies the sandbox - Ports nat.PortMap // Ports is a collection of PortBinding indexed by Port - - // HairpinMode specifies if hairpin NAT should be enabled on the virtual interface - // - // Deprecated: This field is never set and will be removed in a future release. - HairpinMode bool - // LinkLocalIPv6Address is an IPv6 unicast address using the link-local prefix - // - // Deprecated: This field is never set and will be removed in a future release. - LinkLocalIPv6Address string - // LinkLocalIPv6PrefixLen is the prefix length of an IPv6 unicast address - // - // Deprecated: This field is never set and will be removed in a future release. - LinkLocalIPv6PrefixLen int - SecondaryIPAddresses []network.Address // Deprecated: This field is never set and will be removed in a future release. - SecondaryIPv6Addresses []network.Address // Deprecated: This field is never set and will be removed in a future release. -} - -// DefaultNetworkSettings holds network information -// during the 2 release deprecation period. -// It will be removed in Docker 1.11. -type DefaultNetworkSettings struct { - EndpointID string // EndpointID uniquely represents a service endpoint in a Sandbox - Gateway string // Gateway holds the gateway address for the network - GlobalIPv6Address string // GlobalIPv6Address holds network's global IPv6 address - GlobalIPv6PrefixLen int // GlobalIPv6PrefixLen represents mask length of network's global IPv6 address - IPAddress string // IPAddress holds the IPv4 address for the network - IPPrefixLen int // IPPrefixLen represents mask length of network's IPv4 address - IPv6Gateway string // IPv6Gateway holds gateway address specific for IPv6 - MacAddress string // MacAddress holds the MAC address for the network -} - -// MountPoint represents a mount point configuration inside the container. -// This is used for reporting the mountpoints in use by a container. -type MountPoint struct { - // Type is the type of mount, see `Type` definitions in - // github.com/docker/docker/api/types/mount.Type - Type mount.Type `json:",omitempty"` - - // Name is the name reference to the underlying data defined by `Source` - // e.g., the volume name. - Name string `json:",omitempty"` - - // Source is the source location of the mount. - // - // For volumes, this contains the storage location of the volume (within - // `/var/lib/docker/volumes/`). For bind-mounts, and `npipe`, this contains - // the source (host) part of the bind-mount. For `tmpfs` mount points, this - // field is empty. - Source string - - // Destination is the path relative to the container root (`/`) where the - // Source is mounted inside the container. - Destination string - - // Driver is the volume driver used to create the volume (if it is a volume). - Driver string `json:",omitempty"` - - // Mode is a comma separated list of options supplied by the user when - // creating the bind/volume mount. - // - // The default is platform-specific (`"z"` on Linux, empty on Windows). - Mode string - - // RW indicates whether the mount is mounted writable (read-write). - RW bool - - // Propagation describes how mounts are propagated from the host into the - // mount point, and vice-versa. Refer to the Linux kernel documentation - // for details: - // https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt - // - // This field is not used on Windows. - Propagation mount.Propagation -} - // DiskUsageObject represents an object type used for disk usage query filtering. type DiskUsageObject string @@ -401,7 +89,7 @@ type DiskUsageOptions struct { type DiskUsage struct { LayersSize int64 Images []*image.Summary - Containers []*Container + Containers []*container.Summary Volumes []*volume.Volume BuildCache []*BuildCache BuilderSize int64 `json:",omitempty"` // Deprecated: deprecated in API 1.38, and no longer used since API 1.40. diff --git a/vendor/github.com/docker/docker/api/types/types_deprecated.go b/vendor/github.com/docker/docker/api/types/types_deprecated.go index 43ffe104aa1..170a65b8b9f 100644 --- a/vendor/github.com/docker/docker/api/types/types_deprecated.go +++ b/vendor/github.com/docker/docker/api/types/types_deprecated.go @@ -1,210 +1,109 @@ package types import ( + "context" + "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/image" - "github.com/docker/docker/api/types/network" - "github.com/docker/docker/api/types/registry" - "github.com/docker/docker/api/types/volume" + "github.com/docker/docker/api/types/storage" ) -// ImagesPruneReport contains the response for Engine API: -// POST "/images/prune" -// -// Deprecated: use [image.PruneReport]. -type ImagesPruneReport = image.PruneReport - -// VolumesPruneReport contains the response for Engine API: -// POST "/volumes/prune". -// -// Deprecated: use [volume.PruneReport]. -type VolumesPruneReport = volume.PruneReport - -// NetworkCreateRequest is the request message sent to the server for network create call. -// -// Deprecated: use [network.CreateRequest]. -type NetworkCreateRequest = network.CreateRequest - -// NetworkCreate is the expected body of the "create network" http request message -// -// Deprecated: use [network.CreateOptions]. -type NetworkCreate = network.CreateOptions - -// NetworkListOptions holds parameters to filter the list of networks with. -// -// Deprecated: use [network.ListOptions]. -type NetworkListOptions = network.ListOptions - -// NetworkCreateResponse is the response message sent by the server for network create call. -// -// Deprecated: use [network.CreateResponse]. -type NetworkCreateResponse = network.CreateResponse - -// NetworkInspectOptions holds parameters to inspect network. -// -// Deprecated: use [network.InspectOptions]. -type NetworkInspectOptions = network.InspectOptions - -// NetworkConnect represents the data to be used to connect a container to the network +// ContainerJSONBase contains response of Engine API GET "/containers/{name:.*}/json" +// for API version 1.18 and older. // -// Deprecated: use [network.ConnectOptions]. -type NetworkConnect = network.ConnectOptions +// Deprecated: use [container.InspectResponse] or [container.ContainerJSONBase]. It will be removed in the next release. +type ContainerJSONBase = container.ContainerJSONBase -// NetworkDisconnect represents the data to be used to disconnect a container from the network +// ContainerJSON is the response for the GET "/containers/{name:.*}/json" +// endpoint. // -// Deprecated: use [network.DisconnectOptions]. -type NetworkDisconnect = network.DisconnectOptions +// Deprecated: use [container.InspectResponse]. It will be removed in the next release. +type ContainerJSON = container.InspectResponse -// EndpointResource contains network resources allocated and used for a container in a network. +// Container contains response of Engine API: +// GET "/containers/json" // -// Deprecated: use [network.EndpointResource]. -type EndpointResource = network.EndpointResource +// Deprecated: use [container.Summary]. +type Container = container.Summary -// NetworkResource is the body of the "get network" http response message/ +// ContainerState stores container's running state // -// Deprecated: use [network.Inspect] or [network.Summary] (for list operations). -type NetworkResource = network.Inspect +// Deprecated: use [container.State]. +type ContainerState = container.State -// NetworksPruneReport contains the response for Engine API: -// POST "/networks/prune" +// NetworkSettings exposes the network settings in the api. // -// Deprecated: use [network.PruneReport]. -type NetworksPruneReport = network.PruneReport +// Deprecated: use [container.NetworkSettings]. +type NetworkSettings = container.NetworkSettings -// ExecConfig is a small subset of the Config struct that holds the configuration -// for the exec feature of docker. +// NetworkSettingsBase holds networking state for a container when inspecting it. // -// Deprecated: use [container.ExecOptions]. -type ExecConfig = container.ExecOptions +// Deprecated: use [container.NetworkSettingsBase]. +type NetworkSettingsBase = container.NetworkSettingsBase -// ExecStartCheck is a temp struct used by execStart -// Config fields is part of ExecConfig in runconfig package +// DefaultNetworkSettings holds network information +// during the 2 release deprecation period. +// It will be removed in Docker 1.11. // -// Deprecated: use [container.ExecStartOptions] or [container.ExecAttachOptions]. -type ExecStartCheck = container.ExecStartOptions +// Deprecated: use [container.DefaultNetworkSettings]. +type DefaultNetworkSettings = container.DefaultNetworkSettings -// ContainerExecInspect holds information returned by exec inspect. +// SummaryNetworkSettings provides a summary of container's networks +// in /containers/json. // -// Deprecated: use [container.ExecInspect]. -type ContainerExecInspect = container.ExecInspect +// Deprecated: use [container.NetworkSettingsSummary]. +type SummaryNetworkSettings = container.NetworkSettingsSummary -// ContainersPruneReport contains the response for Engine API: -// POST "/containers/prune" -// -// Deprecated: use [container.PruneReport]. -type ContainersPruneReport = container.PruneReport - -// ContainerPathStat is used to encode the header from -// GET "/containers/{name:.*}/archive" -// "Name" is the file or directory name. -// -// Deprecated: use [container.PathStat]. -type ContainerPathStat = container.PathStat - -// CopyToContainerOptions holds information -// about files to copy into a container. -// -// Deprecated: use [container.CopyToContainerOptions], -type CopyToContainerOptions = container.CopyToContainerOptions - -// ContainerStats contains response of Engine API: -// GET "/stats" -// -// Deprecated: use [container.StatsResponseReader]. -type ContainerStats = container.StatsResponseReader - -// ThrottlingData stores CPU throttling stats of one running container. -// Not used on Windows. -// -// Deprecated: use [container.ThrottlingData]. -type ThrottlingData = container.ThrottlingData - -// CPUUsage stores All CPU stats aggregated since container inception. -// -// Deprecated: use [container.CPUUsage]. -type CPUUsage = container.CPUUsage - -// CPUStats aggregates and wraps all CPU related info of container -// -// Deprecated: use [container.CPUStats]. -type CPUStats = container.CPUStats - -// MemoryStats aggregates all memory stats since container inception on Linux. -// Windows returns stats for commit and private working set only. -// -// Deprecated: use [container.MemoryStats]. -type MemoryStats = container.MemoryStats - -// BlkioStatEntry is one small entity to store a piece of Blkio stats -// Not used on Windows. -// -// Deprecated: use [container.BlkioStatEntry]. -type BlkioStatEntry = container.BlkioStatEntry - -// BlkioStats stores All IO service stats for data read and write. -// This is a Linux specific structure as the differences between expressing -// block I/O on Windows and Linux are sufficiently significant to make -// little sense attempting to morph into a combined structure. -// -// Deprecated: use [container.BlkioStats]. -type BlkioStats = container.BlkioStats - -// StorageStats is the disk I/O stats for read/write on Windows. -// -// Deprecated: use [container.StorageStats]. -type StorageStats = container.StorageStats - -// NetworkStats aggregates the network stats of one container -// -// Deprecated: use [container.NetworkStats]. -type NetworkStats = container.NetworkStats +// Health states +const ( + NoHealthcheck = container.NoHealthcheck // Deprecated: use [container.NoHealthcheck]. + Starting = container.Starting // Deprecated: use [container.Starting]. + Healthy = container.Healthy // Deprecated: use [container.Healthy]. + Unhealthy = container.Unhealthy // Deprecated: use [container.Unhealthy]. +) -// PidsStats contains the stats of a container's pids +// Health stores information about the container's healthcheck results. // -// Deprecated: use [container.PidsStats]. -type PidsStats = container.PidsStats +// Deprecated: use [container.Health]. +type Health = container.Health -// Stats is Ultimate struct aggregating all types of stats of one container +// HealthcheckResult stores information about a single run of a healthcheck probe. // -// Deprecated: use [container.Stats]. -type Stats = container.Stats +// Deprecated: use [container.HealthcheckResult]. +type HealthcheckResult = container.HealthcheckResult -// StatsJSON is newly used Networks +// MountPoint represents a mount point configuration inside the container. +// This is used for reporting the mountpoints in use by a container. // -// Deprecated: use [container.StatsResponse]. -type StatsJSON = container.StatsResponse +// Deprecated: use [container.MountPoint]. +type MountPoint = container.MountPoint -// EventsOptions holds parameters to filter events with. +// Port An open port on a container // -// Deprecated: use [events.ListOptions]. -type EventsOptions = events.ListOptions +// Deprecated: use [container.Port]. +type Port = container.Port -// ImageSearchOptions holds parameters to search images with. +// GraphDriverData Information about the storage driver used to store the container's and +// image's filesystem. // -// Deprecated: use [registry.SearchOptions]. -type ImageSearchOptions = registry.SearchOptions +// Deprecated: use [storage.DriverData]. +type GraphDriverData = storage.DriverData -// ImageImportSource holds source information for ImageImport +// RootFS returns Image's RootFS description including the layer IDs. // -// Deprecated: use [image.ImportSource]. -type ImageImportSource image.ImportSource +// Deprecated: use [image.RootFS]. +type RootFS = image.RootFS -// ImageLoadResponse returns information to the client about a load process. +// ImageInspect contains response of Engine API: +// GET "/images/{name:.*}/json" // -// Deprecated: use [image.LoadResponse]. -type ImageLoadResponse = image.LoadResponse +// Deprecated: use [image.InspectResponse]. +type ImageInspect = image.InspectResponse -// ContainerNode stores information about the node that a container -// is running on. It's only used by the Docker Swarm standalone API. +// RequestPrivilegeFunc is a function interface that clients can supply to +// retry operations after getting an authorization error. +// This function returns the registry authentication header value in base64 +// format, or an error if the privilege request fails. // -// Deprecated: ContainerNode was used for the classic Docker Swarm standalone API. It will be removed in the next release. -type ContainerNode struct { - ID string - IPAddress string `json:"IP"` - Addr string - Name string - Cpus int - Memory int64 - Labels map[string]string -} +// Deprecated: moved to [github.com/docker/docker/api/types/registry.RequestAuthConfig]. +type RequestPrivilegeFunc func(context.Context) (string, error) diff --git a/vendor/github.com/docker/docker/client/build_prune.go b/vendor/github.com/docker/docker/client/build_prune.go index 1a830f4135f..f732852964c 100644 --- a/vendor/github.com/docker/docker/client/build_prune.go +++ b/vendor/github.com/docker/docker/client/build_prune.go @@ -17,8 +17,6 @@ func (cli *Client) BuildCachePrune(ctx context.Context, opts types.BuildCachePru return nil, err } - report := types.BuildCachePruneReport{} - query := url.Values{} if opts.All { query.Set("all", "1") @@ -37,6 +35,7 @@ func (cli *Client) BuildCachePrune(ctx context.Context, opts types.BuildCachePru return nil, err } + report := types.BuildCachePruneReport{} if err := json.NewDecoder(serverResp.body).Decode(&report); err != nil { return nil, errors.Wrap(err, "error retrieving disk usage") } diff --git a/vendor/github.com/docker/docker/client/container_create.go b/vendor/github.com/docker/docker/client/container_create.go index 5442d4267d0..94925d7b7f7 100644 --- a/vendor/github.com/docker/docker/client/container_create.go +++ b/vendor/github.com/docker/docker/client/container_create.go @@ -5,6 +5,8 @@ import ( "encoding/json" "net/url" "path" + "sort" + "strings" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" @@ -12,12 +14,6 @@ import ( ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) -type configWrapper struct { - *container.Config - HostConfig *container.HostConfig - NetworkingConfig *network.NetworkingConfig -} - // ContainerCreate creates a new container based on the given configuration. // It can be associated with a name, but it's not mandatory. func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) { @@ -58,6 +54,9 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config // When using API under 1.42, the Linux daemon doesn't respect the ConsoleSize hostConfig.ConsoleSize = [2]uint{0, 0} } + + hostConfig.CapAdd = normalizeCapabilities(hostConfig.CapAdd) + hostConfig.CapDrop = normalizeCapabilities(hostConfig.CapDrop) } // Since API 1.44, the container-wide MacAddress is deprecated and will trigger a WARNING if it's specified. @@ -74,7 +73,7 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config query.Set("name", containerName) } - body := configWrapper{ + body := container.CreateRequest{ Config: config, HostConfig: hostConfig, NetworkingConfig: networkingConfig, @@ -114,3 +113,42 @@ func hasEndpointSpecificMacAddress(networkingConfig *network.NetworkingConfig) b } return false } + +// allCapabilities is a magic value for "all capabilities" +const allCapabilities = "ALL" + +// normalizeCapabilities normalizes capabilities to their canonical form, +// removes duplicates, and sorts the results. +// +// It is similar to [github.com/docker/docker/oci/caps.NormalizeLegacyCapabilities], +// but performs no validation based on supported capabilities. +func normalizeCapabilities(caps []string) []string { + var normalized []string + + unique := make(map[string]struct{}) + for _, c := range caps { + c = normalizeCap(c) + if _, ok := unique[c]; ok { + continue + } + unique[c] = struct{}{} + normalized = append(normalized, c) + } + + sort.Strings(normalized) + return normalized +} + +// normalizeCap normalizes a capability to its canonical format by upper-casing +// and adding a "CAP_" prefix (if not yet present). It also accepts the "ALL" +// magic-value. +func normalizeCap(cap string) string { + cap = strings.ToUpper(cap) + if cap == allCapabilities { + return cap + } + if !strings.HasPrefix(cap, "CAP_") { + cap = "CAP_" + cap + } + return cap +} diff --git a/vendor/github.com/docker/docker/client/container_inspect.go b/vendor/github.com/docker/docker/client/container_inspect.go index d48f0d3a685..fa342e16b58 100644 --- a/vendor/github.com/docker/docker/client/container_inspect.go +++ b/vendor/github.com/docker/docker/client/container_inspect.go @@ -7,29 +7,29 @@ import ( "io" "net/url" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" ) // ContainerInspect returns the container information. -func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) { +func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (container.InspectResponse, error) { if containerID == "" { - return types.ContainerJSON{}, objectNotFoundError{object: "container", id: containerID} + return container.InspectResponse{}, objectNotFoundError{object: "container", id: containerID} } serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil) defer ensureReaderClosed(serverResp) if err != nil { - return types.ContainerJSON{}, err + return container.InspectResponse{}, err } - var response types.ContainerJSON + var response container.InspectResponse err = json.NewDecoder(serverResp.body).Decode(&response) return response, err } // ContainerInspectWithRaw returns the container information and its raw representation. -func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (types.ContainerJSON, []byte, error) { +func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (container.InspectResponse, []byte, error) { if containerID == "" { - return types.ContainerJSON{}, nil, objectNotFoundError{object: "container", id: containerID} + return container.InspectResponse{}, nil, objectNotFoundError{object: "container", id: containerID} } query := url.Values{} if getSize { @@ -38,15 +38,15 @@ func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID stri serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil) defer ensureReaderClosed(serverResp) if err != nil { - return types.ContainerJSON{}, nil, err + return container.InspectResponse{}, nil, err } body, err := io.ReadAll(serverResp.body) if err != nil { - return types.ContainerJSON{}, nil, err + return container.InspectResponse{}, nil, err } - var response types.ContainerJSON + var response container.InspectResponse rdr := bytes.NewReader(body) err = json.NewDecoder(rdr).Decode(&response) return response, body, err diff --git a/vendor/github.com/docker/docker/client/container_list.go b/vendor/github.com/docker/docker/client/container_list.go index 782e1b3c62e..46c6950cd3a 100644 --- a/vendor/github.com/docker/docker/client/container_list.go +++ b/vendor/github.com/docker/docker/client/container_list.go @@ -6,13 +6,12 @@ import ( "net/url" "strconv" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" ) // ContainerList returns the list of containers in the docker host. -func (cli *Client) ContainerList(ctx context.Context, options container.ListOptions) ([]types.Container, error) { +func (cli *Client) ContainerList(ctx context.Context, options container.ListOptions) ([]container.Summary, error) { query := url.Values{} if options.All { @@ -51,7 +50,7 @@ func (cli *Client) ContainerList(ctx context.Context, options container.ListOpti return nil, err } - var containers []types.Container + var containers []container.Summary err = json.NewDecoder(resp.body).Decode(&containers) return containers, err } diff --git a/vendor/github.com/docker/docker/client/container_prune.go b/vendor/github.com/docker/docker/client/container_prune.go index 29c922da77e..ce38ad9bf5b 100644 --- a/vendor/github.com/docker/docker/client/container_prune.go +++ b/vendor/github.com/docker/docker/client/container_prune.go @@ -11,25 +11,24 @@ import ( // ContainersPrune requests the daemon to delete unused data func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) { - var report container.PruneReport - if err := cli.NewVersionError(ctx, "1.25", "container prune"); err != nil { - return report, err + return container.PruneReport{}, err } query, err := getFiltersQuery(pruneFilters) if err != nil { - return report, err + return container.PruneReport{}, err } serverResp, err := cli.post(ctx, "/containers/prune", query, nil, nil) defer ensureReaderClosed(serverResp) if err != nil { - return report, err + return container.PruneReport{}, err } + var report container.PruneReport if err := json.NewDecoder(serverResp.body).Decode(&report); err != nil { - return report, fmt.Errorf("Error retrieving disk usage: %v", err) + return container.PruneReport{}, fmt.Errorf("Error retrieving disk usage: %v", err) } return report, nil diff --git a/vendor/github.com/docker/docker/client/container_resize.go b/vendor/github.com/docker/docker/client/container_resize.go index 5cfd01d4798..6f1a8f5605c 100644 --- a/vendor/github.com/docker/docker/client/container_resize.go +++ b/vendor/github.com/docker/docker/client/container_resize.go @@ -19,9 +19,10 @@ func (cli *Client) ContainerExecResize(ctx context.Context, execID string, optio } func (cli *Client) resize(ctx context.Context, basePath string, height, width uint) error { + // FIXME(thaJeztah): the API / backend accepts uint32, but container.ResizeOptions uses uint. query := url.Values{} - query.Set("h", strconv.Itoa(int(height))) - query.Set("w", strconv.Itoa(int(width))) + query.Set("h", strconv.FormatUint(uint64(height), 10)) + query.Set("w", strconv.FormatUint(uint64(width), 10)) resp, err := cli.post(ctx, basePath+"/resize", query, nil, nil) ensureReaderClosed(resp) diff --git a/vendor/github.com/docker/docker/client/image_build.go b/vendor/github.com/docker/docker/client/image_build.go index d294ddc8b2c..62037c7f946 100644 --- a/vendor/github.com/docker/docker/client/image_build.go +++ b/vendor/github.com/docker/docker/client/image_build.go @@ -12,6 +12,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/network" ) // ImageBuild sends a request to the daemon to build images. @@ -44,10 +45,15 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio } func (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options types.ImageBuildOptions) (url.Values, error) { - query := url.Values{ - "t": options.Tags, - "securityopt": options.SecurityOpt, - "extrahosts": options.ExtraHosts, + query := url.Values{} + if len(options.Tags) > 0 { + query["t"] = options.Tags + } + if len(options.SecurityOpt) > 0 { + query["securityopt"] = options.SecurityOpt + } + if len(options.ExtraHosts) > 0 { + query["extrahosts"] = options.ExtraHosts } if options.SuppressOutput { query.Set("q", "1") @@ -58,9 +64,11 @@ func (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options types.I if options.NoCache { query.Set("nocache", "1") } - if options.Remove { - query.Set("rm", "1") - } else { + if !options.Remove { + // only send value when opting out because the daemon's default is + // to remove intermediate containers after a successful build, + // + // TODO(thaJeztah): deprecate "Remove" option, and provide a "NoRemove" or "Keep" option instead. query.Set("rm", "0") } @@ -83,42 +91,70 @@ func (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options types.I query.Set("isolation", string(options.Isolation)) } - query.Set("cpusetcpus", options.CPUSetCPUs) - query.Set("networkmode", options.NetworkMode) - query.Set("cpusetmems", options.CPUSetMems) - query.Set("cpushares", strconv.FormatInt(options.CPUShares, 10)) - query.Set("cpuquota", strconv.FormatInt(options.CPUQuota, 10)) - query.Set("cpuperiod", strconv.FormatInt(options.CPUPeriod, 10)) - query.Set("memory", strconv.FormatInt(options.Memory, 10)) - query.Set("memswap", strconv.FormatInt(options.MemorySwap, 10)) - query.Set("cgroupparent", options.CgroupParent) - query.Set("shmsize", strconv.FormatInt(options.ShmSize, 10)) - query.Set("dockerfile", options.Dockerfile) - query.Set("target", options.Target) - - ulimitsJSON, err := json.Marshal(options.Ulimits) - if err != nil { - return query, err + if options.CPUSetCPUs != "" { + query.Set("cpusetcpus", options.CPUSetCPUs) } - query.Set("ulimits", string(ulimitsJSON)) - - buildArgsJSON, err := json.Marshal(options.BuildArgs) - if err != nil { - return query, err + if options.NetworkMode != "" && options.NetworkMode != network.NetworkDefault { + query.Set("networkmode", options.NetworkMode) } - query.Set("buildargs", string(buildArgsJSON)) - - labelsJSON, err := json.Marshal(options.Labels) - if err != nil { - return query, err + if options.CPUSetMems != "" { + query.Set("cpusetmems", options.CPUSetMems) } - query.Set("labels", string(labelsJSON)) - - cacheFromJSON, err := json.Marshal(options.CacheFrom) - if err != nil { - return query, err + if options.CPUShares != 0 { + query.Set("cpushares", strconv.FormatInt(options.CPUShares, 10)) + } + if options.CPUQuota != 0 { + query.Set("cpuquota", strconv.FormatInt(options.CPUQuota, 10)) + } + if options.CPUPeriod != 0 { + query.Set("cpuperiod", strconv.FormatInt(options.CPUPeriod, 10)) + } + if options.Memory != 0 { + query.Set("memory", strconv.FormatInt(options.Memory, 10)) + } + if options.MemorySwap != 0 { + query.Set("memswap", strconv.FormatInt(options.MemorySwap, 10)) + } + if options.CgroupParent != "" { + query.Set("cgroupparent", options.CgroupParent) + } + if options.ShmSize != 0 { + query.Set("shmsize", strconv.FormatInt(options.ShmSize, 10)) + } + if options.Dockerfile != "" { + query.Set("dockerfile", options.Dockerfile) + } + if options.Target != "" { + query.Set("target", options.Target) + } + if len(options.Ulimits) != 0 { + ulimitsJSON, err := json.Marshal(options.Ulimits) + if err != nil { + return query, err + } + query.Set("ulimits", string(ulimitsJSON)) + } + if len(options.BuildArgs) != 0 { + buildArgsJSON, err := json.Marshal(options.BuildArgs) + if err != nil { + return query, err + } + query.Set("buildargs", string(buildArgsJSON)) + } + if len(options.Labels) != 0 { + labelsJSON, err := json.Marshal(options.Labels) + if err != nil { + return query, err + } + query.Set("labels", string(labelsJSON)) + } + if len(options.CacheFrom) != 0 { + cacheFromJSON, err := json.Marshal(options.CacheFrom) + if err != nil { + return query, err + } + query.Set("cachefrom", string(cacheFromJSON)) } - query.Set("cachefrom", string(cacheFromJSON)) if options.SessionID != "" { query.Set("session", options.SessionID) } @@ -131,7 +167,9 @@ func (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options types.I if options.BuildID != "" { query.Set("buildid", options.BuildID) } - query.Set("version", string(options.Version)) + if options.Version != "" { + query.Set("version", string(options.Version)) + } if options.Outputs != nil { outputsJSON, err := json.Marshal(options.Outputs) diff --git a/vendor/github.com/docker/docker/client/image_history.go b/vendor/github.com/docker/docker/client/image_history.go index b5bea10d8f6..747a569bab6 100644 --- a/vendor/github.com/docker/docker/client/image_history.go +++ b/vendor/github.com/docker/docker/client/image_history.go @@ -9,14 +9,27 @@ import ( ) // ImageHistory returns the changes in an image in history format. -func (cli *Client) ImageHistory(ctx context.Context, imageID string) ([]image.HistoryResponseItem, error) { - var history []image.HistoryResponseItem - serverResp, err := cli.get(ctx, "/images/"+imageID+"/history", url.Values{}, nil) +func (cli *Client) ImageHistory(ctx context.Context, imageID string, opts image.HistoryOptions) ([]image.HistoryResponseItem, error) { + query := url.Values{} + if opts.Platform != nil { + if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil { + return nil, err + } + + p, err := encodePlatform(opts.Platform) + if err != nil { + return nil, err + } + query.Set("platform", p) + } + + serverResp, err := cli.get(ctx, "/images/"+imageID+"/history", query, nil) defer ensureReaderClosed(serverResp) if err != nil { - return history, err + return nil, err } + var history []image.HistoryResponseItem err = json.NewDecoder(serverResp.body).Decode(&history) return history, err } diff --git a/vendor/github.com/docker/docker/client/image_import.go b/vendor/github.com/docker/docker/client/image_import.go index 43d55eda8ec..dea3626872b 100644 --- a/vendor/github.com/docker/docker/client/image_import.go +++ b/vendor/github.com/docker/docker/client/image_import.go @@ -21,10 +21,18 @@ func (cli *Client) ImageImport(ctx context.Context, source image.ImportSource, r } query := url.Values{} - query.Set("fromSrc", source.SourceName) - query.Set("repo", ref) - query.Set("tag", options.Tag) - query.Set("message", options.Message) + if source.SourceName != "" { + query.Set("fromSrc", source.SourceName) + } + if ref != "" { + query.Set("repo", ref) + } + if options.Tag != "" { + query.Set("tag", options.Tag) + } + if options.Message != "" { + query.Set("message", options.Message) + } if options.Platform != "" { query.Set("platform", strings.ToLower(options.Platform)) } diff --git a/vendor/github.com/docker/docker/client/image_inspect.go b/vendor/github.com/docker/docker/client/image_inspect.go index 1de10e5a080..69949f3e8b7 100644 --- a/vendor/github.com/docker/docker/client/image_inspect.go +++ b/vendor/github.com/docker/docker/client/image_inspect.go @@ -6,26 +6,26 @@ import ( "encoding/json" "io" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/image" ) // ImageInspectWithRaw returns the image information and its raw representation. -func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string) (types.ImageInspect, []byte, error) { +func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string) (image.InspectResponse, []byte, error) { if imageID == "" { - return types.ImageInspect{}, nil, objectNotFoundError{object: "image", id: imageID} + return image.InspectResponse{}, nil, objectNotFoundError{object: "image", id: imageID} } serverResp, err := cli.get(ctx, "/images/"+imageID+"/json", nil, nil) defer ensureReaderClosed(serverResp) if err != nil { - return types.ImageInspect{}, nil, err + return image.InspectResponse{}, nil, err } body, err := io.ReadAll(serverResp.body) if err != nil { - return types.ImageInspect{}, nil, err + return image.InspectResponse{}, nil, err } - var response types.ImageInspect + var response image.InspectResponse rdr := bytes.NewReader(body) err = json.NewDecoder(rdr).Decode(&response) return response, body, err diff --git a/vendor/github.com/docker/docker/client/image_load.go b/vendor/github.com/docker/docker/client/image_load.go index c68f0013e63..50cce4fd01b 100644 --- a/vendor/github.com/docker/docker/client/image_load.go +++ b/vendor/github.com/docker/docker/client/image_load.go @@ -12,13 +12,29 @@ import ( // ImageLoad loads an image in the docker host from the client host. // It's up to the caller to close the io.ReadCloser in the // ImageLoadResponse returned by this function. -func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (image.LoadResponse, error) { - v := url.Values{} - v.Set("quiet", "0") - if quiet { - v.Set("quiet", "1") +// +// Platform is an optional parameter that specifies the platform to load from +// the provided multi-platform image. This is only has effect if the input image +// is a multi-platform image. +func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, opts image.LoadOptions) (image.LoadResponse, error) { + query := url.Values{} + query.Set("quiet", "0") + if opts.Quiet { + query.Set("quiet", "1") } - resp, err := cli.postRaw(ctx, "/images/load", v, input, http.Header{ + if len(opts.Platforms) > 0 { + if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil { + return image.LoadResponse{}, err + } + + p, err := encodePlatforms(opts.Platforms...) + if err != nil { + return image.LoadResponse{}, err + } + query["platform"] = p + } + + resp, err := cli.postRaw(ctx, "/images/load", query, input, http.Header{ "Content-Type": {"application/x-tar"}, }) if err != nil { diff --git a/vendor/github.com/docker/docker/client/image_prune.go b/vendor/github.com/docker/docker/client/image_prune.go index 5ee987e248a..c731f19396d 100644 --- a/vendor/github.com/docker/docker/client/image_prune.go +++ b/vendor/github.com/docker/docker/client/image_prune.go @@ -11,25 +11,24 @@ import ( // ImagesPrune requests the daemon to delete unused data func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (image.PruneReport, error) { - var report image.PruneReport - if err := cli.NewVersionError(ctx, "1.25", "image prune"); err != nil { - return report, err + return image.PruneReport{}, err } query, err := getFiltersQuery(pruneFilters) if err != nil { - return report, err + return image.PruneReport{}, err } serverResp, err := cli.post(ctx, "/images/prune", query, nil, nil) defer ensureReaderClosed(serverResp) if err != nil { - return report, err + return image.PruneReport{}, err } + var report image.PruneReport if err := json.NewDecoder(serverResp.body).Decode(&report); err != nil { - return report, fmt.Errorf("Error retrieving disk usage: %v", err) + return image.PruneReport{}, fmt.Errorf("Error retrieving disk usage: %v", err) } return report, nil diff --git a/vendor/github.com/docker/docker/client/image_save.go b/vendor/github.com/docker/docker/client/image_save.go index d1314e4b22f..1b378c32b7d 100644 --- a/vendor/github.com/docker/docker/client/image_save.go +++ b/vendor/github.com/docker/docker/client/image_save.go @@ -4,15 +4,28 @@ import ( "context" "io" "net/url" + + "github.com/docker/docker/api/types/image" ) // ImageSave retrieves one or more images from the docker host as an io.ReadCloser. // It's up to the caller to store the images and close the stream. -func (cli *Client) ImageSave(ctx context.Context, imageIDs []string) (io.ReadCloser, error) { +func (cli *Client) ImageSave(ctx context.Context, imageIDs []string, opts image.SaveOptions) (io.ReadCloser, error) { query := url.Values{ "names": imageIDs, } + if len(opts.Platforms) > 0 { + if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil { + return nil, err + } + p, err := encodePlatforms(opts.Platforms...) + if err != nil { + return nil, err + } + query["platform"] = p + } + resp, err := cli.get(ctx, "/images/get", query, nil) if err != nil { return nil, err diff --git a/vendor/github.com/docker/docker/client/interface.go b/vendor/github.com/docker/docker/client/interface.go index cc60a5d13b4..470923a243d 100644 --- a/vendor/github.com/docker/docker/client/interface.go +++ b/vendor/github.com/docker/docker/client/interface.go @@ -56,10 +56,10 @@ type ContainerAPIClient interface { ContainerExecResize(ctx context.Context, execID string, options container.ResizeOptions) error ContainerExecStart(ctx context.Context, execID string, options container.ExecStartOptions) error ContainerExport(ctx context.Context, container string) (io.ReadCloser, error) - ContainerInspect(ctx context.Context, container string) (types.ContainerJSON, error) - ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (types.ContainerJSON, []byte, error) + ContainerInspect(ctx context.Context, container string) (container.InspectResponse, error) + ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (container.InspectResponse, []byte, error) ContainerKill(ctx context.Context, container, signal string) error - ContainerList(ctx context.Context, options container.ListOptions) ([]types.Container, error) + ContainerList(ctx context.Context, options container.ListOptions) ([]container.Summary, error) ContainerLogs(ctx context.Context, container string, options container.LogsOptions) (io.ReadCloser, error) ContainerPause(ctx context.Context, container string) error ContainerRemove(ctx context.Context, container string, options container.RemoveOptions) error @@ -91,16 +91,16 @@ type ImageAPIClient interface { BuildCachePrune(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error) BuildCancel(ctx context.Context, id string) error ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error) - ImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, error) + ImageHistory(ctx context.Context, image string, opts image.HistoryOptions) ([]image.HistoryResponseItem, error) ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) - ImageInspectWithRaw(ctx context.Context, image string) (types.ImageInspect, []byte, error) + ImageInspectWithRaw(ctx context.Context, image string) (image.InspectResponse, []byte, error) ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error) - ImageLoad(ctx context.Context, input io.Reader, quiet bool) (image.LoadResponse, error) + ImageLoad(ctx context.Context, input io.Reader, opts image.LoadOptions) (image.LoadResponse, error) ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error) ImagePush(ctx context.Context, ref string, options image.PushOptions) (io.ReadCloser, error) ImageRemove(ctx context.Context, image string, options image.RemoveOptions) ([]image.DeleteResponse, error) + ImageSave(ctx context.Context, images []string, opts image.SaveOptions) (io.ReadCloser, error) ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error) - ImageSave(ctx context.Context, images []string) (io.ReadCloser, error) ImageTag(ctx context.Context, image, ref string) error ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error) } diff --git a/vendor/github.com/docker/docker/client/network_prune.go b/vendor/github.com/docker/docker/client/network_prune.go index 708cc61a4b2..4f089438ce6 100644 --- a/vendor/github.com/docker/docker/client/network_prune.go +++ b/vendor/github.com/docker/docker/client/network_prune.go @@ -11,25 +11,24 @@ import ( // NetworksPrune requests the daemon to delete unused networks func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters filters.Args) (network.PruneReport, error) { - var report network.PruneReport - if err := cli.NewVersionError(ctx, "1.25", "network prune"); err != nil { - return report, err + return network.PruneReport{}, err } query, err := getFiltersQuery(pruneFilters) if err != nil { - return report, err + return network.PruneReport{}, err } serverResp, err := cli.post(ctx, "/networks/prune", query, nil, nil) defer ensureReaderClosed(serverResp) if err != nil { - return report, err + return network.PruneReport{}, err } + var report network.PruneReport if err := json.NewDecoder(serverResp.body).Decode(&report); err != nil { - return report, fmt.Errorf("Error retrieving network prune report: %v", err) + return network.PruneReport{}, fmt.Errorf("Error retrieving network prune report: %v", err) } return report, nil diff --git a/vendor/github.com/docker/docker/client/ping.go b/vendor/github.com/docker/docker/client/ping.go index bf3e9b1cd6d..7c43268b3a0 100644 --- a/vendor/github.com/docker/docker/client/ping.go +++ b/vendor/github.com/docker/docker/client/ping.go @@ -56,8 +56,8 @@ func parsePingResponse(cli *Client, resp serverResponse) (types.Ping, error) { err := cli.checkResponseErr(resp) return ping, errdefs.FromStatusCode(err, resp.statusCode) } - ping.APIVersion = resp.header.Get("API-Version") - ping.OSType = resp.header.Get("OSType") + ping.APIVersion = resp.header.Get("Api-Version") + ping.OSType = resp.header.Get("Ostype") if resp.header.Get("Docker-Experimental") == "true" { ping.Experimental = true } diff --git a/vendor/github.com/docker/docker/client/utils.go b/vendor/github.com/docker/docker/client/utils.go index 7f3ff44eb80..0fea7c82068 100644 --- a/vendor/github.com/docker/docker/client/utils.go +++ b/vendor/github.com/docker/docker/client/utils.go @@ -1,10 +1,14 @@ package client // import "github.com/docker/docker/client" import ( + "encoding/json" + "fmt" "net/url" "regexp" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/errdefs" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) var headerRegexp = regexp.MustCompile(`\ADocker/.+\s\((.+)\)\z`) @@ -32,3 +36,43 @@ func getFiltersQuery(f filters.Args) (url.Values, error) { } return query, nil } + +// encodePlatforms marshals the given platform(s) to JSON format, to +// be used for query-parameters for filtering / selecting platforms. +func encodePlatforms(platform ...ocispec.Platform) ([]string, error) { + if len(platform) == 0 { + return []string{}, nil + } + if len(platform) == 1 { + p, err := encodePlatform(&platform[0]) + if err != nil { + return nil, err + } + return []string{p}, nil + } + + seen := make(map[string]struct{}, len(platform)) + out := make([]string, 0, len(platform)) + for i := range platform { + p, err := encodePlatform(&platform[i]) + if err != nil { + return nil, err + } + if _, ok := seen[p]; !ok { + out = append(out, p) + seen[p] = struct{}{} + } + } + return out, nil +} + +// encodePlatform marshals the given platform to JSON format, to +// be used for query-parameters for filtering / selecting platforms. It +// is used as a helper for encodePlatforms, +func encodePlatform(platform *ocispec.Platform) (string, error) { + p, err := json.Marshal(platform) + if err != nil { + return "", errdefs.InvalidParameter(fmt.Errorf("invalid platform: %v", err)) + } + return string(p), nil +} diff --git a/vendor/github.com/docker/docker/client/volume_prune.go b/vendor/github.com/docker/docker/client/volume_prune.go index 9b09c30fa6f..df70389eb27 100644 --- a/vendor/github.com/docker/docker/client/volume_prune.go +++ b/vendor/github.com/docker/docker/client/volume_prune.go @@ -11,25 +11,24 @@ import ( // VolumesPrune requests the daemon to delete unused data func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters filters.Args) (volume.PruneReport, error) { - var report volume.PruneReport - if err := cli.NewVersionError(ctx, "1.25", "volume prune"); err != nil { - return report, err + return volume.PruneReport{}, err } query, err := getFiltersQuery(pruneFilters) if err != nil { - return report, err + return volume.PruneReport{}, err } serverResp, err := cli.post(ctx, "/volumes/prune", query, nil, nil) defer ensureReaderClosed(serverResp) if err != nil { - return report, err + return volume.PruneReport{}, err } + var report volume.PruneReport if err := json.NewDecoder(serverResp.body).Decode(&report); err != nil { - return report, fmt.Errorf("Error retrieving volume prune report: %v", err) + return volume.PruneReport{}, fmt.Errorf("Error retrieving volume prune report: %v", err) } return report, nil diff --git a/vendor/github.com/docker/docker/errdefs/http_helpers.go b/vendor/github.com/docker/docker/errdefs/http_helpers.go index ebcd7893027..0a8fadd48f1 100644 --- a/vendor/github.com/docker/docker/errdefs/http_helpers.go +++ b/vendor/github.com/docker/docker/errdefs/http_helpers.go @@ -11,36 +11,37 @@ func FromStatusCode(err error, statusCode int) error { } switch statusCode { case http.StatusNotFound: - err = NotFound(err) + return NotFound(err) case http.StatusBadRequest: - err = InvalidParameter(err) + return InvalidParameter(err) case http.StatusConflict: - err = Conflict(err) + return Conflict(err) case http.StatusUnauthorized: - err = Unauthorized(err) + return Unauthorized(err) case http.StatusServiceUnavailable: - err = Unavailable(err) + return Unavailable(err) case http.StatusForbidden: - err = Forbidden(err) + return Forbidden(err) case http.StatusNotModified: - err = NotModified(err) + return NotModified(err) case http.StatusNotImplemented: - err = NotImplemented(err) + return NotImplemented(err) case http.StatusInternalServerError: - if !IsSystem(err) && !IsUnknown(err) && !IsDataLoss(err) && !IsDeadline(err) && !IsCancelled(err) { - err = System(err) + if IsCancelled(err) || IsSystem(err) || IsUnknown(err) || IsDataLoss(err) || IsDeadline(err) { + return err } + return System(err) default: switch { case statusCode >= 200 && statusCode < 400: // it's a client error + return err case statusCode >= 400 && statusCode < 500: - err = InvalidParameter(err) + return InvalidParameter(err) case statusCode >= 500 && statusCode < 600: - err = System(err) + return System(err) default: - err = Unknown(err) + return Unknown(err) } } - return err } diff --git a/vendor/github.com/docker/docker/pkg/archive/archive.go b/vendor/github.com/docker/docker/pkg/archive/archive.go index cde64f08ebc..77868900eb9 100644 --- a/vendor/github.com/docker/docker/pkg/archive/archive.go +++ b/vendor/github.com/docker/docker/pkg/archive/archive.go @@ -9,26 +9,27 @@ import ( "compress/gzip" "context" "encoding/binary" + "errors" "fmt" "io" "os" "os/exec" "path/filepath" "runtime" + "runtime/debug" "strconv" "strings" + "sync/atomic" "syscall" "time" "github.com/containerd/log" "github.com/docker/docker/pkg/idtools" - "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/pools" "github.com/docker/docker/pkg/system" "github.com/klauspost/compress/zstd" "github.com/moby/patternmatcher" "github.com/moby/sys/sequential" - "github.com/pkg/errors" ) // ImpliedDirectoryMode represents the mode (Unix permissions) applied to directories that are implied by files in a @@ -215,11 +216,22 @@ func gzDecompress(ctx context.Context, buf io.Reader) (io.ReadCloser, error) { return cmdStream(exec.CommandContext(ctx, unpigzPath, "-d", "-c"), buf) } -func wrapReadCloser(readBuf io.ReadCloser, cancel context.CancelFunc) io.ReadCloser { - return ioutils.NewReadCloserWrapper(readBuf, func() error { - cancel() - return readBuf.Close() - }) +type readCloserWrapper struct { + io.Reader + closer func() error + closed atomic.Bool +} + +func (r *readCloserWrapper) Close() error { + if !r.closed.CompareAndSwap(false, true) { + log.G(context.TODO()).Error("subsequent attempt to close readCloserWrapper") + if log.GetLevel() >= log.DebugLevel { + log.G(context.TODO()).Errorf("stack trace: %s", string(debug.Stack())) + } + + return nil + } + return r.closer() } // DecompressStream decompresses the archive and returns a ReaderCloser with the decompressed archive. @@ -237,11 +249,26 @@ func DecompressStream(archive io.Reader) (io.ReadCloser, error) { return nil, err } + wrapReader := func(r io.Reader, cancel context.CancelFunc) io.ReadCloser { + return &readCloserWrapper{ + Reader: r, + closer: func() error { + if cancel != nil { + cancel() + } + if readCloser, ok := r.(io.ReadCloser); ok { + readCloser.Close() + } + p.Put(buf) + return nil + }, + } + } + compression := DetectCompression(bs) switch compression { case Uncompressed: - readBufWrapper := p.NewReadCloserWrapper(buf, buf) - return readBufWrapper, nil + return wrapReader(buf, nil), nil case Gzip: ctx, cancel := context.WithCancel(context.Background()) @@ -250,12 +277,10 @@ func DecompressStream(archive io.Reader) (io.ReadCloser, error) { cancel() return nil, err } - readBufWrapper := p.NewReadCloserWrapper(buf, gzReader) - return wrapReadCloser(readBufWrapper, cancel), nil + return wrapReader(gzReader, cancel), nil case Bzip2: bz2Reader := bzip2.NewReader(buf) - readBufWrapper := p.NewReadCloserWrapper(buf, bz2Reader) - return readBufWrapper, nil + return wrapReader(bz2Reader, nil), nil case Xz: ctx, cancel := context.WithCancel(context.Background()) @@ -264,15 +289,13 @@ func DecompressStream(archive io.Reader) (io.ReadCloser, error) { cancel() return nil, err } - readBufWrapper := p.NewReadCloserWrapper(buf, xzReader) - return wrapReadCloser(readBufWrapper, cancel), nil + return wrapReader(xzReader, cancel), nil case Zstd: zstdReader, err := zstd.NewReader(buf) if err != nil { return nil, err } - readBufWrapper := p.NewReadCloserWrapper(buf, zstdReader) - return readBufWrapper, nil + return wrapReader(zstdReader, nil), nil default: return nil, fmt.Errorf("Unsupported compression format %s", (&compression).Extension()) } @@ -531,15 +554,6 @@ func newTarAppender(idMapping idtools.IdentityMapping, writer io.Writer, chownOp } } -// CanonicalTarNameForPath canonicalizes relativePath to a POSIX-style path using -// forward slashes. It is an alias for [filepath.ToSlash], which is a no-op on -// Linux and Unix. -// -// Deprecated: use [filepath.ToSlash]. This function will be removed in the next release. -func CanonicalTarNameForPath(relativePath string) string { - return filepath.ToSlash(relativePath) -} - // canonicalTarName provides a platform-independent and consistent POSIX-style // path for files and directories to be archived regardless of the platform. func canonicalTarName(name string, isDir bool) string { @@ -654,7 +668,7 @@ func (ta *tarAppender) addTarFile(path, name string) error { ta.Buffer.Reset(ta.TarWriter) defer ta.Buffer.Reset(nil) - _, err = io.Copy(ta.Buffer, file) + _, err = pools.Copy(ta.Buffer, file) file.Close() if err != nil { return err @@ -705,7 +719,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, o if err != nil { return err } - if _, err := io.Copy(file, reader); err != nil { + if _, err := pools.Copy(file, reader); err != nil { file.Close() return err } @@ -771,11 +785,11 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, o chownOpts = &idtools.Identity{UID: hdr.Uid, GID: hdr.Gid} } if err := os.Lchown(path, chownOpts.UID, chownOpts.GID); err != nil { - msg := "failed to Lchown %q for UID %d, GID %d" + var msg string if inUserns && errors.Is(err, syscall.EINVAL) { - msg += " (try increasing the number of subordinate IDs in /etc/subuid and /etc/subgid)" + msg = " (try increasing the number of subordinate IDs in /etc/subuid and /etc/subgid)" } - return errors.Wrapf(err, msg, path, hdr.Uid, hdr.Gid) + return fmt.Errorf("failed to Lchown %q for UID %d, GID %d%s: %w", path, hdr.Uid, hdr.Gid, msg, err) } } @@ -1375,7 +1389,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) { if err := tw.WriteHeader(hdr); err != nil { return err } - if _, err := io.Copy(tw, srcF); err != nil { + if _, err := pools.Copy(tw, srcF); err != nil { return err } return nil @@ -1433,68 +1447,14 @@ func cmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, error) { close(done) }() - return ioutils.NewReadCloserWrapper(pipeR, func() error { - // Close pipeR, and then wait for the command to complete before returning. We have to close pipeR first, as - // cmd.Wait waits for any non-file stdout/stderr/stdin to close. - err := pipeR.Close() - <-done - return err - }), nil -} - -// NewTempArchive reads the content of src into a temporary file, and returns the contents -// of that file as an archive. The archive can only be read once - as soon as reading completes, -// the file will be deleted. -// -// Deprecated: NewTempArchive is only used in tests and will be removed in the next release. -func NewTempArchive(src io.Reader, dir string) (*TempArchive, error) { - f, err := os.CreateTemp(dir, "") - if err != nil { - return nil, err - } - if _, err := io.Copy(f, src); err != nil { - return nil, err - } - if _, err := f.Seek(0, 0); err != nil { - return nil, err - } - st, err := f.Stat() - if err != nil { - return nil, err - } - size := st.Size() - return &TempArchive{File: f, Size: size}, nil -} - -// TempArchive is a temporary archive. The archive can only be read once - as soon as reading completes, -// the file will be deleted. -// -// Deprecated: TempArchive is only used in tests and will be removed in the next release. -type TempArchive struct { - *os.File - Size int64 // Pre-computed from Stat().Size() as a convenience - read int64 - closed bool -} - -// Close closes the underlying file if it's still open, or does a no-op -// to allow callers to try to close the TempArchive multiple times safely. -func (archive *TempArchive) Close() error { - if archive.closed { - return nil - } - - archive.closed = true - - return archive.File.Close() -} - -func (archive *TempArchive) Read(data []byte) (int, error) { - n, err := archive.File.Read(data) - archive.read += int64(n) - if err != nil || archive.read == archive.Size { - archive.Close() - os.Remove(archive.File.Name()) - } - return n, err + return &readCloserWrapper{ + Reader: pipeR, + closer: func() error { + // Close pipeR, and then wait for the command to complete before returning. We have to close pipeR first, as + // cmd.Wait waits for any non-file stdout/stderr/stdin to close. + err := pipeR.Close() + <-done + return err + }, + }, nil } diff --git a/vendor/github.com/docker/docker/pkg/archive/archive_linux.go b/vendor/github.com/docker/docker/pkg/archive/archive_linux.go index b9d2a538ab0..061564991c6 100644 --- a/vendor/github.com/docker/docker/pkg/archive/archive_linux.go +++ b/vendor/github.com/docker/docker/pkg/archive/archive_linux.go @@ -2,13 +2,13 @@ package archive // import "github.com/docker/docker/pkg/archive" import ( "archive/tar" + "fmt" "os" "path/filepath" "strings" "github.com/docker/docker/pkg/system" "github.com/moby/sys/userns" - "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -79,7 +79,7 @@ func (c overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (boo err := unix.Setxattr(dir, opaqueXattrName, []byte{'y'}, 0) if err != nil { - return false, errors.Wrapf(err, "setxattr(%q, %s=y)", dir, opaqueXattrName) + return false, fmt.Errorf("setxattr('%s', %s=y): %w", dir, opaqueXattrName, err) } // don't write the file itself return false, err @@ -91,7 +91,7 @@ func (c overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (boo originalPath := filepath.Join(dir, originalBase) if err := unix.Mknod(originalPath, unix.S_IFCHR, 0); err != nil { - return false, errors.Wrapf(err, "failed to mknod(%q, S_IFCHR, 0)", originalPath) + return false, fmt.Errorf("failed to mknod('%s', S_IFCHR, 0): %w", originalPath, err) } if err := os.Chown(originalPath, hdr.Uid, hdr.Gid); err != nil { return false, err diff --git a/vendor/github.com/docker/docker/pkg/archive/changes_linux.go b/vendor/github.com/docker/docker/pkg/archive/changes_linux.go index 81fcbc5bab5..877ec785589 100644 --- a/vendor/github.com/docker/docker/pkg/archive/changes_linux.go +++ b/vendor/github.com/docker/docker/pkg/archive/changes_linux.go @@ -261,13 +261,13 @@ func readdirnames(dirname string) (names []nameIno, err error) { func parseDirent(buf []byte, names []nameIno) (consumed int, newnames []nameIno) { origlen := len(buf) for len(buf) > 0 { - dirent := (*unix.Dirent)(unsafe.Pointer(&buf[0])) + dirent := (*unix.Dirent)(unsafe.Pointer(&buf[0])) // #nosec G103 -- Ignore "G103: Use of unsafe calls should be audited" buf = buf[dirent.Reclen:] if dirent.Ino == 0 { // File absent in directory. continue } - bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) - name := string(bytes[0:clen(bytes[:])]) + b := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) // #nosec G103 -- Ignore "G103: Use of unsafe calls should be audited" + name := string(b[0:clen(b[:])]) if name == "." || name == ".." { // Useless names continue } diff --git a/vendor/github.com/docker/docker/pkg/idtools/idtools.go b/vendor/github.com/docker/docker/pkg/idtools/idtools.go index 79d682c6945..82b325a2b72 100644 --- a/vendor/github.com/docker/docker/pkg/idtools/idtools.go +++ b/vendor/github.com/docker/docker/pkg/idtools/idtools.go @@ -22,11 +22,11 @@ type subIDRange struct { Length int } -type ranges []subIDRange +type subIDRanges []subIDRange -func (e ranges) Len() int { return len(e) } -func (e ranges) Swap(i, j int) { e[i], e[j] = e[j], e[i] } -func (e ranges) Less(i, j int) bool { return e[i].Start < e[j].Start } +func (e subIDRanges) Len() int { return len(e) } +func (e subIDRanges) Swap(i, j int) { e[i], e[j] = e[j], e[i] } +func (e subIDRanges) Less(i, j int) bool { return e[i].Start < e[j].Start } const ( subuidFileName = "/etc/subuid" @@ -162,7 +162,7 @@ func (i IdentityMapping) Empty() bool { return len(i.UIDMaps) == 0 && len(i.GIDMaps) == 0 } -func createIDMap(subidRanges ranges) []IDMap { +func createIDMap(subidRanges subIDRanges) []IDMap { idMap := []IDMap{} containerID := 0 @@ -177,19 +177,19 @@ func createIDMap(subidRanges ranges) []IDMap { return idMap } -func parseSubuid(username string) (ranges, error) { +func parseSubuid(username string) (subIDRanges, error) { return parseSubidFile(subuidFileName, username) } -func parseSubgid(username string) (ranges, error) { +func parseSubgid(username string) (subIDRanges, error) { return parseSubidFile(subgidFileName, username) } // parseSubidFile will read the appropriate file (/etc/subuid or /etc/subgid) -// and return all found ranges for a specified username. If the special value -// "ALL" is supplied for username, then all ranges in the file will be returned -func parseSubidFile(path, username string) (ranges, error) { - var rangeList ranges +// and return all found subIDRanges for a specified username. If the special value +// "ALL" is supplied for username, then all subIDRanges in the file will be returned +func parseSubidFile(path, username string) (subIDRanges, error) { + var rangeList subIDRanges subidFile, err := os.Open(path) if err != nil { diff --git a/vendor/github.com/docker/docker/pkg/idtools/usergroupadd_linux.go b/vendor/github.com/docker/docker/pkg/idtools/usergroupadd_linux.go index f0c075e20f9..7fd6c413d45 100644 --- a/vendor/github.com/docker/docker/pkg/idtools/usergroupadd_linux.go +++ b/vendor/github.com/docker/docker/pkg/idtools/usergroupadd_linux.go @@ -145,7 +145,7 @@ func findNextGIDRange() (int, error) { return findNextRangeStart(ranges) } -func findNextRangeStart(rangeList ranges) (int, error) { +func findNextRangeStart(rangeList subIDRanges) (int, error) { startID := defaultRangeStart for _, arange := range rangeList { if wouldOverlap(arange, startID) { diff --git a/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go b/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go index 8d2c8857fb0..037327b908c 100644 --- a/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go +++ b/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go @@ -7,7 +7,7 @@ import ( "strings" "time" - units "github.com/docker/go-units" + "github.com/docker/go-units" "github.com/moby/term" "github.com/morikuni/aec" ) diff --git a/vendor/github.com/docker/docker/pkg/stringid/stringid.go b/vendor/github.com/docker/docker/pkg/stringid/stringid.go index bffac8035e6..a79c96728ed 100644 --- a/vendor/github.com/docker/docker/pkg/stringid/stringid.go +++ b/vendor/github.com/docker/docker/pkg/stringid/stringid.go @@ -4,9 +4,6 @@ package stringid // import "github.com/docker/docker/pkg/stringid" import ( "crypto/rand" "encoding/hex" - "errors" - "regexp" - "strconv" "strings" ) @@ -15,22 +12,6 @@ const ( fullLen = 64 ) -var ( - validShortID = regexp.MustCompile("^[a-f0-9]{12}$") - validHex = regexp.MustCompile(`^[a-f0-9]{64}$`) -) - -// IsShortID determines if id has the correct format and length for a short ID. -// It checks the IDs length and if it consists of valid characters for IDs (a-f0-9). -// -// Deprecated: this function is no longer used, and will be removed in the next release. -func IsShortID(id string) bool { - if len(id) != shortLen { - return false - } - return validShortID.MatchString(id) -} - // TruncateID returns a shorthand version of a string identifier for convenience. // A collision with other shorthands is very unlikely, but possible. // In case of a collision a lookup with TruncIndex.Get() will fail, and the caller @@ -45,7 +26,10 @@ func TruncateID(id string) string { return id } -// GenerateRandomID returns a unique id. +// GenerateRandomID returns a unique, 64-character ID consisting of a-z, 0-9. +// It guarantees that the ID, when truncated ([TruncateID]) does not consist +// of numbers only, so that the truncated ID can be used as hostname for +// containers. func GenerateRandomID() string { b := make([]byte, 32) for { @@ -53,25 +37,27 @@ func GenerateRandomID() string { panic(err) // This shouldn't happen } id := hex.EncodeToString(b) - // if we try to parse the truncated for as an int and we don't have - // an error then the value is all numeric and causes issues when - // used as a hostname. ref #3869 - if _, err := strconv.ParseInt(TruncateID(id), 10, 64); err == nil { + + // make sure that the truncated ID does not consist of only numeric + // characters, as it's used as default hostname for containers. + // + // See: + // - https://github.com/moby/moby/issues/3869 + // - https://bugzilla.redhat.com/show_bug.cgi?id=1059122 + if allNum(id[:shortLen]) { + // all numbers; try again continue } return id } } -// ValidateID checks whether an ID string is a valid, full-length image ID. -// -// Deprecated: use [github.com/docker/docker/image/v1.ValidateID] instead. Will be removed in the next release. -func ValidateID(id string) error { - if len(id) != fullLen { - return errors.New("image ID '" + id + "' is invalid") - } - if !validHex.MatchString(id) { - return errors.New("image ID '" + id + "' is invalid") +// allNum checks whether id consists of only numbers (0-9). +func allNum(id string) bool { + for _, c := range []byte(id) { + if c > '9' || c < '0' { + return false + } } - return nil + return true } diff --git a/vendor/github.com/docker/docker/pkg/system/init_windows.go b/vendor/github.com/docker/docker/pkg/system/init_windows.go index 7603efbbd81..51e332c4b73 100644 --- a/vendor/github.com/docker/docker/pkg/system/init_windows.go +++ b/vendor/github.com/docker/docker/pkg/system/init_windows.go @@ -3,8 +3,8 @@ package system // import "github.com/docker/docker/pkg/system" // containerdRuntimeSupported determines if containerd should be the runtime. var containerdRuntimeSupported = false -// InitContainerdRuntime sets whether to use containerd for runtime on Windows. -func InitContainerdRuntime(cdPath string) { +// EnableContainerdRuntime sets whether to use containerd for runtime on Windows. +func EnableContainerdRuntime(cdPath string) { if len(cdPath) > 0 { containerdRuntimeSupported = true } diff --git a/vendor/github.com/docker/docker/pkg/system/lstat_unix.go b/vendor/github.com/docker/docker/pkg/system/lstat_unix.go index 5e29a6b3b8a..97f355d2e4d 100644 --- a/vendor/github.com/docker/docker/pkg/system/lstat_unix.go +++ b/vendor/github.com/docker/docker/pkg/system/lstat_unix.go @@ -10,7 +10,9 @@ import ( // Lstat takes a path to a file and returns // a system.StatT type pertaining to that file. // -// Throws an error if the file does not exist +// Throws an error if the file does not exist. +// +// Deprecated: this function is only used internally, and will be removed in the next release. func Lstat(path string) (*StatT, error) { s := &syscall.Stat_t{} if err := syscall.Lstat(path, s); err != nil { diff --git a/vendor/github.com/docker/docker/pkg/system/lstat_windows.go b/vendor/github.com/docker/docker/pkg/system/lstat_windows.go index 359c791d9b6..4180f3ac207 100644 --- a/vendor/github.com/docker/docker/pkg/system/lstat_windows.go +++ b/vendor/github.com/docker/docker/pkg/system/lstat_windows.go @@ -4,6 +4,8 @@ import "os" // Lstat calls os.Lstat to get a fileinfo interface back. // This is then copied into our own locally defined structure. +// +// Deprecated: this function is only used internally, and will be removed in the next release. func Lstat(path string) (*StatT, error) { fi, err := os.Lstat(path) if err != nil { diff --git a/vendor/github.com/docker/docker/pkg/system/mknod.go b/vendor/github.com/docker/docker/pkg/system/mknod.go index 2a62237a45c..e0cd22d7a78 100644 --- a/vendor/github.com/docker/docker/pkg/system/mknod.go +++ b/vendor/github.com/docker/docker/pkg/system/mknod.go @@ -11,6 +11,8 @@ import ( // Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes. // They are, from low to high: the lower 8 bits of the minor, then 12 bits of the major, // then the top 12 bits of the minor. +// +// Deprecated: this function is only used internally, and will be removed in the next release. func Mkdev(major int64, minor int64) uint32 { return uint32(unix.Mkdev(uint32(major), uint32(minor))) } diff --git a/vendor/github.com/docker/docker/pkg/system/mknod_freebsd.go b/vendor/github.com/docker/docker/pkg/system/mknod_freebsd.go index e218e742d49..4f66453d622 100644 --- a/vendor/github.com/docker/docker/pkg/system/mknod_freebsd.go +++ b/vendor/github.com/docker/docker/pkg/system/mknod_freebsd.go @@ -8,6 +8,8 @@ import ( // Mknod creates a filesystem node (file, device special file or named pipe) named path // with attributes specified by mode and dev. +// +// Deprecated: this function is only used internally, and will be removed in the next release. func Mknod(path string, mode uint32, dev int) error { return unix.Mknod(path, mode, uint64(dev)) } diff --git a/vendor/github.com/docker/docker/pkg/system/mknod_unix.go b/vendor/github.com/docker/docker/pkg/system/mknod_unix.go index 34df0b9236c..34c5532631a 100644 --- a/vendor/github.com/docker/docker/pkg/system/mknod_unix.go +++ b/vendor/github.com/docker/docker/pkg/system/mknod_unix.go @@ -8,6 +8,8 @@ import ( // Mknod creates a filesystem node (file, device special file or named pipe) named path // with attributes specified by mode and dev. +// +// Deprecated: this function is only used internally, and will be removed in the next release. func Mknod(path string, mode uint32, dev int) error { return unix.Mknod(path, mode, dev) } diff --git a/vendor/github.com/docker/docker/pkg/system/stat_linux.go b/vendor/github.com/docker/docker/pkg/system/stat_linux.go index 4309d42b9fd..0557235f987 100644 --- a/vendor/github.com/docker/docker/pkg/system/stat_linux.go +++ b/vendor/github.com/docker/docker/pkg/system/stat_linux.go @@ -17,6 +17,8 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) { // FromStatT converts a syscall.Stat_t type to a system.Stat_t type // This is exposed on Linux as pkg/archive/changes uses it. +// +// Deprecated: this function is only used internally, and will be removed in the next release. func FromStatT(s *syscall.Stat_t) (*StatT, error) { return fromStatT(s) } diff --git a/vendor/github.com/docker/docker/pkg/system/stat_unix.go b/vendor/github.com/docker/docker/pkg/system/stat_unix.go index 205e54677db..661b0bed201 100644 --- a/vendor/github.com/docker/docker/pkg/system/stat_unix.go +++ b/vendor/github.com/docker/docker/pkg/system/stat_unix.go @@ -9,6 +9,8 @@ import ( // StatT type contains status of a file. It contains metadata // like permission, owner, group, size, etc about a file. +// +// Deprecated: this type is only used internally, and will be removed in the next release. type StatT struct { mode uint32 uid uint32 @@ -56,7 +58,9 @@ func (s StatT) IsDir() bool { // Stat takes a path to a file and returns // a system.StatT type pertaining to that file. // -// Throws an error if the file does not exist +// Throws an error if the file does not exist. +// +// Deprecated: this function is only used internally, and will be removed in the next release. func Stat(path string) (*StatT, error) { s := &syscall.Stat_t{} if err := syscall.Stat(path, s); err != nil { diff --git a/vendor/github.com/docker/docker/pkg/system/stat_windows.go b/vendor/github.com/docker/docker/pkg/system/stat_windows.go index 10876cd73e2..e74a0f4fd70 100644 --- a/vendor/github.com/docker/docker/pkg/system/stat_windows.go +++ b/vendor/github.com/docker/docker/pkg/system/stat_windows.go @@ -7,6 +7,8 @@ import ( // StatT type contains status of a file. It contains metadata // like permission, size, etc about a file. +// +// Deprecated: this type is only used internally, and will be removed in the next release. type StatT struct { mode os.FileMode size int64 @@ -31,7 +33,9 @@ func (s StatT) Mtim() time.Time { // Stat takes a path to a file and returns // a system.StatT type pertaining to that file. // -// Throws an error if the file does not exist +// Throws an error if the file does not exist. +// +// Deprecated: this function is only used internally, and will be removed in the next release. func Stat(path string) (*StatT, error) { fi, err := os.Stat(path) if err != nil { diff --git a/vendor/github.com/docker/docker/registry/auth.go b/vendor/github.com/docker/docker/registry/auth.go index 905ccf5f512..8c62b83c075 100644 --- a/vendor/github.com/docker/docker/registry/auth.go +++ b/vendor/github.com/docker/docker/registry/auth.go @@ -66,23 +66,23 @@ func (scs staticCredentialStore) SetRefreshToken(*url.URL, string, string) { // loginV2 tries to login to the v2 registry server. The given registry // endpoint will be pinged to get authorization challenges. These challenges // will be used to authenticate against the registry to validate credentials. -func loginV2(authConfig *registry.AuthConfig, endpoint APIEndpoint, userAgent string) (string, string, error) { - var ( - endpointStr = strings.TrimRight(endpoint.URL.String(), "/") + "/v2/" - modifiers = Headers(userAgent, nil) - authTransport = transport.NewTransport(newTransport(endpoint.TLSConfig), modifiers...) - credentialAuthConfig = *authConfig - creds = loginCredentialStore{authConfig: &credentialAuthConfig} - ) - +func loginV2(authConfig *registry.AuthConfig, endpoint APIEndpoint, userAgent string) (status string, token string, _ error) { + endpointStr := strings.TrimRight(endpoint.URL.String(), "/") + "/v2/" log.G(context.TODO()).Debugf("attempting v2 login to registry endpoint %s", endpointStr) - loginClient, err := v2AuthHTTPClient(endpoint.URL, authTransport, modifiers, creds, nil) + req, err := http.NewRequest(http.MethodGet, endpointStr, nil) if err != nil { return "", "", err } - req, err := http.NewRequest(http.MethodGet, endpointStr, nil) + var ( + modifiers = Headers(userAgent, nil) + authTrans = transport.NewTransport(newTransport(endpoint.TLSConfig), modifiers...) + credentialAuthConfig = *authConfig + creds = loginCredentialStore{authConfig: &credentialAuthConfig} + ) + + loginClient, err := v2AuthHTTPClient(endpoint.URL, authTrans, modifiers, creds, nil) if err != nil { return "", "", err } @@ -133,12 +133,13 @@ func v2AuthHTTPClient(endpoint *url.URL, authTransport http.RoundTripper, modifi // files). func ConvertToHostname(url string) string { stripped := url - if strings.HasPrefix(url, "http://") { - stripped = strings.TrimPrefix(url, "http://") - } else if strings.HasPrefix(url, "https://") { - stripped = strings.TrimPrefix(url, "https://") + if strings.HasPrefix(stripped, "http://") { + stripped = strings.TrimPrefix(stripped, "http://") + } else if strings.HasPrefix(stripped, "https://") { + stripped = strings.TrimPrefix(stripped, "https://") } - return strings.SplitN(stripped, "/", 2)[0] + stripped, _, _ = strings.Cut(stripped, "/") + return stripped } // ResolveAuthConfig matches an auth configuration to a server address or a URL diff --git a/vendor/github.com/docker/docker/registry/config.go b/vendor/github.com/docker/docker/registry/config.go index e1b0a0ca14c..07fdea1b6ce 100644 --- a/vendor/github.com/docker/docker/registry/config.go +++ b/vendor/github.com/docker/docker/registry/config.go @@ -15,9 +15,10 @@ import ( // ServiceOptions holds command line options. type ServiceOptions struct { - AllowNondistributableArtifacts []string `json:"allow-nondistributable-artifacts,omitempty"` - Mirrors []string `json:"registry-mirrors,omitempty"` - InsecureRegistries []string `json:"insecure-registries,omitempty"` + AllowNondistributableArtifacts []string `json:"allow-nondistributable-artifacts,omitempty"` // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release. + + Mirrors []string `json:"registry-mirrors,omitempty"` + InsecureRegistries []string `json:"insecure-registries,omitempty"` } // serviceConfig holds daemon configuration for the registry service. @@ -58,9 +59,6 @@ var ( emptyServiceConfig, _ = newServiceConfig(ServiceOptions{}) validHostPortRegex = regexp.MustCompile(`^` + reference.DomainRegexp.String() + `$`) - // for mocking in unit tests - lookupIP = net.LookupIP - // certsDir is used to override defaultCertsDir. certsDir string ) @@ -83,9 +81,6 @@ func CertsDir() string { // newServiceConfig returns a new instance of ServiceConfig func newServiceConfig(options ServiceOptions) (*serviceConfig, error) { config := &serviceConfig{} - if err := config.loadAllowNondistributableArtifacts(options.AllowNondistributableArtifacts); err != nil { - return nil, err - } if err := config.loadMirrors(options.Mirrors); err != nil { return nil, err } @@ -103,51 +98,12 @@ func (config *serviceConfig) copy() *registry.ServiceConfig { ic[key] = value } return ®istry.ServiceConfig{ - AllowNondistributableArtifactsCIDRs: append([]*registry.NetIPNet(nil), config.AllowNondistributableArtifactsCIDRs...), - AllowNondistributableArtifactsHostnames: append([]string(nil), config.AllowNondistributableArtifactsHostnames...), - InsecureRegistryCIDRs: append([]*registry.NetIPNet(nil), config.InsecureRegistryCIDRs...), - IndexConfigs: ic, - Mirrors: append([]string(nil), config.Mirrors...), + InsecureRegistryCIDRs: append([]*registry.NetIPNet(nil), config.InsecureRegistryCIDRs...), + IndexConfigs: ic, + Mirrors: append([]string(nil), config.Mirrors...), } } -// loadAllowNondistributableArtifacts loads allow-nondistributable-artifacts registries into config. -func (config *serviceConfig) loadAllowNondistributableArtifacts(registries []string) error { - cidrs := map[string]*registry.NetIPNet{} - hostnames := map[string]bool{} - - for _, r := range registries { - if _, err := ValidateIndexName(r); err != nil { - return err - } - if hasScheme(r) { - return invalidParamf("allow-nondistributable-artifacts registry %s should not contain '://'", r) - } - - if _, ipnet, err := net.ParseCIDR(r); err == nil { - // Valid CIDR. - cidrs[ipnet.String()] = (*registry.NetIPNet)(ipnet) - } else if err = validateHostPort(r); err == nil { - // Must be `host:port` if not CIDR. - hostnames[r] = true - } else { - return invalidParamWrapf(err, "allow-nondistributable-artifacts registry %s is not valid", r) - } - } - - config.AllowNondistributableArtifactsCIDRs = make([]*registry.NetIPNet, 0, len(cidrs)) - for _, c := range cidrs { - config.AllowNondistributableArtifactsCIDRs = append(config.AllowNondistributableArtifactsCIDRs, c) - } - - config.AllowNondistributableArtifactsHostnames = make([]string, 0, len(hostnames)) - for h := range hostnames { - config.AllowNondistributableArtifactsHostnames = append(config.AllowNondistributableArtifactsHostnames, h) - } - - return nil -} - // loadMirrors loads mirrors to config, after removing duplicates. // Returns an error if mirrors contains an invalid mirror. func (config *serviceConfig) loadMirrors(mirrors []string) error { @@ -184,7 +140,7 @@ func (config *serviceConfig) loadMirrors(mirrors []string) error { func (config *serviceConfig) loadInsecureRegistries(registries []string) error { // Localhost is by default considered as an insecure registry. This is a // stop-gap for people who are running a private registry on localhost. - registries = append(registries, "127.0.0.0/8") + registries = append(registries, "::1/128", "127.0.0.0/8") var ( insecureRegistryCIDRs = make([]*registry.NetIPNet, 0) @@ -245,25 +201,6 @@ skip: return nil } -// allowNondistributableArtifacts returns true if the provided hostname is part of the list of registries -// that allow push of nondistributable artifacts. -// -// The list can contain elements with CIDR notation to specify a whole subnet. If the subnet contains an IP -// of the registry specified by hostname, true is returned. -// -// hostname should be a URL.Host (`host:port` or `host`) where the `host` part can be either a domain name -// or an IP address. If it is a domain name, then it will be resolved to IP addresses for matching. If -// resolution fails, CIDR matching is not performed. -func (config *serviceConfig) allowNondistributableArtifacts(hostname string) bool { - for _, h := range config.AllowNondistributableArtifactsHostnames { - if h == hostname { - return true - } - } - - return isCIDRMatch(config.AllowNondistributableArtifactsCIDRs, hostname) -} - // isSecureIndex returns false if the provided indexName is part of the list of insecure registries // Insecure registries accept HTTP and/or accept HTTPS with certificates from unknown CAs. // @@ -285,30 +222,37 @@ func (config *serviceConfig) isSecureIndex(indexName string) bool { return !isCIDRMatch(config.InsecureRegistryCIDRs, indexName) } +// for mocking in unit tests. +var lookupIP = net.LookupIP + // isCIDRMatch returns true if URLHost matches an element of cidrs. URLHost is a URL.Host (`host:port` or `host`) // where the `host` part can be either a domain name or an IP address. If it is a domain name, then it will be // resolved to IP addresses for matching. If resolution fails, false is returned. func isCIDRMatch(cidrs []*registry.NetIPNet, URLHost string) bool { + if len(cidrs) == 0 { + return false + } + host, _, err := net.SplitHostPort(URLHost) if err != nil { - // Assume URLHost is of the form `host` without the port and go on. + // Assume URLHost is a host without port and go on. host = URLHost } - addrs, err := lookupIP(host) - if err != nil { - ip := net.ParseIP(host) - if ip != nil { - addrs = []net.IP{ip} + var addresses []net.IP + if ip := net.ParseIP(host); ip != nil { + // Host is an IP-address. + addresses = append(addresses, ip) + } else { + // Try to resolve the host's IP-address. + addresses, err = lookupIP(host) + if err != nil { + // We failed to resolve the host; assume there's no match. + return false } - - // if ip == nil, then `host` is neither an IP nor it could be looked up, - // either because the index is unreachable, or because the index is behind an HTTP proxy. - // So, len(addrs) == 0 and we're not aborting. } - // Try CIDR notation only if addrs has any elements, i.e. if `host`'s IP could be determined. - for _, addr := range addrs { + for _, addr := range addresses { for _, ipnet := range cidrs { // check if the addr falls in the subnet if (*net.IPNet)(ipnet).Contains(addr) { diff --git a/vendor/github.com/docker/docker/registry/service.go b/vendor/github.com/docker/docker/registry/service.go index 6881c110576..4d66523c616 100644 --- a/vendor/github.com/docker/docker/registry/service.go +++ b/vendor/github.com/docker/docker/registry/service.go @@ -68,10 +68,11 @@ func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, use registryHostName = u.Host } - // Lookup endpoints for authentication using "LookupPushEndpoints", which - // excludes mirrors to prevent sending credentials of the upstream registry - // to a mirror. - endpoints, err := s.LookupPushEndpoints(registryHostName) + // Lookup endpoints for authentication but exclude mirrors to prevent + // sending credentials of the upstream registry to a mirror. + s.mu.RLock() + endpoints, err := s.lookupV2Endpoints(registryHostName, false) + s.mu.RUnlock() if err != nil { return "", "", invalidParam(err) } @@ -103,10 +104,9 @@ func (s *Service) ResolveRepository(name reference.Named) (*RepositoryInfo, erro type APIEndpoint struct { Mirror bool URL *url.URL - Version APIVersion // Deprecated: v1 registries are deprecated, and endpoints are always v2. - AllowNondistributableArtifacts bool + AllowNondistributableArtifacts bool // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release. Official bool - TrimHostname bool + TrimHostname bool // Deprecated: hostname is now trimmed unconditionally for remote names. This field will be removed in the next release. TLSConfig *tls.Config } @@ -116,7 +116,7 @@ func (s *Service) LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, s.mu.RLock() defer s.mu.RUnlock() - return s.lookupV2Endpoints(hostname) + return s.lookupV2Endpoints(hostname, true) } // LookupPushEndpoints creates a list of v2 endpoints to try to push to, in order of preference. @@ -125,15 +125,7 @@ func (s *Service) LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, s.mu.RLock() defer s.mu.RUnlock() - allEndpoints, err := s.lookupV2Endpoints(hostname) - if err == nil { - for _, endpoint := range allEndpoints { - if !endpoint.Mirror { - endpoints = append(endpoints, endpoint) - } - } - } - return endpoints, err + return s.lookupV2Endpoints(hostname, false) } // IsInsecureRegistry returns true if the registry at given host is configured as diff --git a/vendor/github.com/docker/docker/registry/service_v2.go b/vendor/github.com/docker/docker/registry/service_v2.go index 5d09e11c9c5..43754527a22 100644 --- a/vendor/github.com/docker/docker/registry/service_v2.go +++ b/vendor/github.com/docker/docker/registry/service_v2.go @@ -7,38 +7,33 @@ import ( "github.com/docker/go-connections/tlsconfig" ) -func (s *Service) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) { - ana := s.config.allowNondistributableArtifacts(hostname) - +func (s *Service) lookupV2Endpoints(hostname string, includeMirrors bool) ([]APIEndpoint, error) { + var endpoints []APIEndpoint if hostname == DefaultNamespace || hostname == IndexHostname { - for _, mirror := range s.config.Mirrors { - if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") { - mirror = "https://" + mirror - } - mirrorURL, err := url.Parse(mirror) - if err != nil { - return nil, invalidParam(err) - } - mirrorTLSConfig, err := newTLSConfig(mirrorURL.Host, s.config.isSecureIndex(mirrorURL.Host)) - if err != nil { - return nil, err + if includeMirrors { + for _, mirror := range s.config.Mirrors { + if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") { + mirror = "https://" + mirror + } + mirrorURL, err := url.Parse(mirror) + if err != nil { + return nil, invalidParam(err) + } + mirrorTLSConfig, err := newTLSConfig(mirrorURL.Host, s.config.isSecureIndex(mirrorURL.Host)) + if err != nil { + return nil, err + } + endpoints = append(endpoints, APIEndpoint{ + URL: mirrorURL, + Mirror: true, + TLSConfig: mirrorTLSConfig, + }) } - endpoints = append(endpoints, APIEndpoint{ - URL: mirrorURL, - Version: APIVersion2, //nolint:staticcheck // ignore SA1019 (Version is deprecated) to allow potential consumers to transition. - Mirror: true, - TrimHostname: true, - TLSConfig: mirrorTLSConfig, - }) } endpoints = append(endpoints, APIEndpoint{ - URL: DefaultV2Registry, - Version: APIVersion2, //nolint:staticcheck // ignore SA1019 (Version is deprecated) to allow potential consumers to transition. - Official: true, - TrimHostname: true, - TLSConfig: tlsconfig.ServerDefault(), - - AllowNondistributableArtifacts: ana, + URL: DefaultV2Registry, + Official: true, + TLSConfig: tlsconfig.ServerDefault(), }) return endpoints, nil @@ -55,10 +50,7 @@ func (s *Service) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, e Scheme: "https", Host: hostname, }, - Version: APIVersion2, //nolint:staticcheck // ignore SA1019 (Version is deprecated) to allow potential consumers to transition. - AllowNondistributableArtifacts: ana, - TrimHostname: true, - TLSConfig: tlsConfig, + TLSConfig: tlsConfig, }, } @@ -68,9 +60,6 @@ func (s *Service) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, e Scheme: "http", Host: hostname, }, - Version: APIVersion2, //nolint:staticcheck // ignore SA1019 (Version is deprecated) to allow potential consumers to transition. - AllowNondistributableArtifacts: ana, - TrimHostname: true, // used to check if supposed to be secure via InsecureSkipVerify TLSConfig: tlsConfig, }) diff --git a/vendor/github.com/docker/docker/registry/types.go b/vendor/github.com/docker/docker/registry/types.go index 4926580a6ce..02d7f4f383b 100644 --- a/vendor/github.com/docker/docker/registry/types.go +++ b/vendor/github.com/docker/docker/registry/types.go @@ -5,27 +5,6 @@ import ( "github.com/docker/docker/api/types/registry" ) -// APIVersion is an integral representation of an API version (presently -// either 1 or 2) -// -// Deprecated: v1 registries are deprecated, and endpoints are always v2. -type APIVersion int - -func (av APIVersion) String() string { - return apiVersions[av] -} - -// API Version identifiers. -const ( - APIVersion1 APIVersion = 1 // Deprecated: v1 registries are deprecated, and endpoints are always v2. - APIVersion2 APIVersion = 2 // Deprecated: v1 registries are deprecated, and endpoints are always v2. -) - -var apiVersions = map[APIVersion]string{ - APIVersion1: "v1", - APIVersion2: "v2", -} - // RepositoryInfo describes a repository type RepositoryInfo struct { Name reference.Named diff --git a/vendor/modules.txt b/vendor/modules.txt index ce75ea78200..ab94f35ff82 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -274,7 +274,7 @@ github.com/docker/distribution/registry/client/transport github.com/docker/distribution/registry/storage/cache github.com/docker/distribution/registry/storage/cache/memory github.com/docker/distribution/uuid -# github.com/docker/docker v27.4.0+incompatible +# github.com/docker/docker v27.4.0+incompatible => github.com/docker/docker v27.0.2-0.20241217103611-726b327b83bb+incompatible ## explicit github.com/docker/docker/api github.com/docker/docker/api/types @@ -287,6 +287,7 @@ github.com/docker/docker/api/types/image github.com/docker/docker/api/types/mount github.com/docker/docker/api/types/network github.com/docker/docker/api/types/registry +github.com/docker/docker/api/types/storage github.com/docker/docker/api/types/strslice github.com/docker/docker/api/types/swarm github.com/docker/docker/api/types/swarm/runtime @@ -1343,3 +1344,4 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.3.0 ## explicit; go 1.12 sigs.k8s.io/yaml +# github.com/docker/docker => github.com/docker/docker v27.0.2-0.20241217103611-726b327b83bb+incompatible From 2876a24292b2a73eb76718692946e7aeb5544be5 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 17 Dec 2024 12:11:24 +0100 Subject: [PATCH 2/3] vendor: docker/cli master Signed-off-by: Sebastiaan van Stijn --- go.mod | 2 + go.sum | 4 +- .../docker/cli/cli-plugins/manager/cobra.go | 3 +- .../docker/cli/cli-plugins/plugin/plugin.go | 22 +++++----- vendor/github.com/docker/cli/cli/cobra.go | 6 +-- .../github.com/docker/cli/cli/command/cli.go | 4 +- .../cli/cli/command/formatter/container.go | 20 +++++----- .../cli/cli/command/formatter/disk_usage.go | 34 ++++++++-------- .../docker/cli/cli/command/registry.go | 3 +- .../docker/cli/cli/command/utils.go | 2 +- .../docker/cli/cli/config/config.go | 2 +- .../cli/cli/config/credentials/file_store.go | 36 +++++++++++++---- vendor/github.com/docker/cli/cli/error.go | 30 ++++---------- .../github.com/docker/cli/cli/hints/hints.go | 4 +- .../cli/cli/registry/client/endpoint.go | 7 +--- vendor/github.com/docker/cli/cli/required.go | 40 ++++++++++--------- vendor/github.com/docker/cli/opts/network.go | 8 ++++ vendor/modules.txt | 3 +- 18 files changed, 123 insertions(+), 107 deletions(-) diff --git a/go.mod b/go.mod index dd529b3f82b..61c15d5eb05 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,8 @@ go 1.22.0 // FIXME(thaJeztah): testing moby master replace github.com/docker/docker => github.com/docker/docker v27.0.2-0.20241217103611-726b327b83bb+incompatible +replace github.com/docker/cli => github.com/docker/cli v27.0.2-0.20241216164627-8454e012cade+incompatible + require ( github.com/Masterminds/semver/v3 v3.2.1 github.com/Microsoft/go-winio v0.6.2 diff --git a/go.sum b/go.sum index d052442f33f..4eb54c4c86b 100644 --- a/go.sum +++ b/go.sum @@ -125,8 +125,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v27.4.0+incompatible h1:/nJzWkcI1MDMN+U+px/YXnQWJqnu4J+QKGTfD6ptiTc= -github.com/docker/cli v27.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.0.2-0.20241216164627-8454e012cade+incompatible h1:pyDQtU605ZHT0c7WXSG+QQPovGUhFmOmWiAr2/86FfU= +github.com/docker/cli v27.0.2-0.20241216164627-8454e012cade+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli-docs-tool v0.8.0 h1:YcDWl7rQJC3lJ7WVZRwSs3bc9nka97QLWfyJQli8yJU= github.com/docker/cli-docs-tool v0.8.0/go.mod h1:8TQQ3E7mOXoYUs811LiPdUnAhXrcVsBIrW21a5pUbdk= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= diff --git a/vendor/github.com/docker/cli/cli-plugins/manager/cobra.go b/vendor/github.com/docker/cli/cli-plugins/manager/cobra.go index feff8a8fd6f..4bfa06fa5c0 100644 --- a/vendor/github.com/docker/cli/cli-plugins/manager/cobra.go +++ b/vendor/github.com/docker/cli/cli-plugins/manager/cobra.go @@ -52,7 +52,6 @@ func AddPluginCommandStubs(dockerCli command.Cli, rootCmd *cobra.Command) (err e return } for _, p := range plugins { - p := p vendor := p.Vendor if vendor == "" { vendor = "unknown" @@ -82,7 +81,7 @@ func AddPluginCommandStubs(dockerCli command.Cli, rootCmd *cobra.Command) (err e cmd.HelpFunc()(rootCmd, args) return nil } - return fmt.Errorf("docker: '%s' is not a docker command.\nSee 'docker --help'", cmd.Name()) + return fmt.Errorf("docker: unknown command: docker %s\n\nRun 'docker --help' for more information", cmd.Name()) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { // Delegate completion to plugin diff --git a/vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go b/vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go index 8cce73d9acd..4ae85dbce4c 100644 --- a/vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go +++ b/vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go @@ -3,6 +3,7 @@ package plugin import ( "context" "encoding/json" + "errors" "fmt" "os" "sync" @@ -34,7 +35,7 @@ func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager var persistentPreRunOnce sync.Once PersistentPreRunE = func(cmd *cobra.Command, _ []string) error { - var err error + var retErr error persistentPreRunOnce.Do(func() { ctx, cancel := context.WithCancel(cmd.Context()) cmd.SetContext(ctx) @@ -46,7 +47,7 @@ func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager opts = append(opts, withPluginClientConn(plugin.Name())) } opts = append(opts, command.WithEnableGlobalMeterProvider(), command.WithEnableGlobalTracerProvider()) - err = tcmd.Initialize(opts...) + retErr = tcmd.Initialize(opts...) ogRunE := cmd.RunE if ogRunE == nil { ogRun := cmd.Run @@ -66,7 +67,7 @@ func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager return err } }) - return err + return retErr } cmd, args, err := tcmd.HandleGlobalFlags() @@ -92,18 +93,17 @@ func Run(makeCmd func(command.Cli) *cobra.Command, meta manager.Metadata) { plugin := makeCmd(dockerCli) if err := RunPlugin(dockerCli, plugin, meta); err != nil { - if sterr, ok := err.(cli.StatusError); ok { - if sterr.Status != "" { - fmt.Fprintln(dockerCli.Err(), sterr.Status) - } + var stErr cli.StatusError + if errors.As(err, &stErr) { // StatusError should only be used for errors, and all errors should // have a non-zero exit status, so never exit with 0 - if sterr.StatusCode == 0 { - os.Exit(1) + if stErr.StatusCode == 0 { // FIXME(thaJeztah): this should never be used with a zero status-code. Check if we do this anywhere. + stErr.StatusCode = 1 } - os.Exit(sterr.StatusCode) + _, _ = fmt.Fprintln(dockerCli.Err(), stErr) + os.Exit(stErr.StatusCode) } - fmt.Fprintln(dockerCli.Err(), err) + _, _ = fmt.Fprintln(dockerCli.Err(), err) os.Exit(1) } } diff --git a/vendor/github.com/docker/cli/cli/cobra.go b/vendor/github.com/docker/cli/cli/cobra.go index f6a69ae0701..feab2b4a91c 100644 --- a/vendor/github.com/docker/cli/cli/cobra.go +++ b/vendor/github.com/docker/cli/cli/cobra.go @@ -92,12 +92,8 @@ func FlagErrorFunc(cmd *cobra.Command, err error) error { return nil } - usage := "" - if cmd.HasSubCommands() { - usage = "\n\n" + cmd.UsageString() - } return StatusError{ - Status: fmt.Sprintf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage), + Status: fmt.Sprintf("%s\n\nUsage: %s\n\nRun '%s --help' for more information", err, cmd.UseLine(), cmd.CommandPath()), StatusCode: 125, } } diff --git a/vendor/github.com/docker/cli/cli/command/cli.go b/vendor/github.com/docker/cli/cli/command/cli.go index da0802d54bc..722901e0604 100644 --- a/vendor/github.com/docker/cli/cli/command/cli.go +++ b/vendor/github.com/docker/cli/cli/command/cli.go @@ -272,7 +272,7 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...CLIOption) debug.Enable() } if opts.Context != "" && len(opts.Hosts) > 0 { - return errors.New("conflicting options: either specify --host or --context, not both") + return errors.New("conflicting options: cannot specify both --host and --context") } cli.options = opts @@ -299,7 +299,7 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...CLIOption) // NewAPIClientFromFlags creates a new APIClient from command line flags func NewAPIClientFromFlags(opts *cliflags.ClientOptions, configFile *configfile.ConfigFile) (client.APIClient, error) { if opts.Context != "" && len(opts.Hosts) > 0 { - return nil, errors.New("conflicting options: either specify --host or --context, not both") + return nil, errors.New("conflicting options: cannot specify both --host and --context") } storeConfig := DefaultContextStoreConfig() diff --git a/vendor/github.com/docker/cli/cli/command/formatter/container.go b/vendor/github.com/docker/cli/cli/command/formatter/container.go index 10d4e4b4422..ba62efb2f47 100644 --- a/vendor/github.com/docker/cli/cli/command/formatter/container.go +++ b/vendor/github.com/docker/cli/cli/command/formatter/container.go @@ -12,7 +12,7 @@ import ( "time" "github.com/distribution/reference" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/stringid" "github.com/docker/go-units" ) @@ -67,10 +67,10 @@ ports: {{- pad .Ports 1 0}} } // ContainerWrite renders the context for a list of containers -func ContainerWrite(ctx Context, containers []types.Container) error { +func ContainerWrite(ctx Context, containers []container.Summary) error { render := func(format func(subContext SubContext) error) error { - for _, container := range containers { - err := format(&ContainerContext{trunc: ctx.Trunc, c: container}) + for _, ctr := range containers { + err := format(&ContainerContext{trunc: ctx.Trunc, c: ctr}) if err != nil { return err } @@ -84,7 +84,7 @@ func ContainerWrite(ctx Context, containers []types.Container) error { type ContainerContext struct { HeaderContext trunc bool - c types.Container + c container.Summary // FieldsUsed is used in the pre-processing step to detect which fields are // used in the template. It's currently only used to detect use of the .Size @@ -193,7 +193,9 @@ func (c *ContainerContext) Command() string { return strconv.Quote(command) } -// CreatedAt returns the "Created" date/time of the container as a unix timestamp. +// CreatedAt returns the formatted string representing the container's creation date/time. +// The format may include nanoseconds if present. +// e.g. "2006-01-02 15:04:05.999999999 -0700 MST" or "2006-01-02 15:04:05 -0700 MST" func (c *ContainerContext) CreatedAt() string { return time.Unix(c.c.Created, 0).String() } @@ -314,7 +316,7 @@ func (c *ContainerContext) Networks() string { // DisplayablePorts returns formatted string representing open ports of container // e.g. "0.0.0.0:80->9090/tcp, 9988/tcp" // it's used by command 'docker ps' -func DisplayablePorts(ports []types.Port) string { +func DisplayablePorts(ports []container.Port) string { type portGroup struct { first uint16 last uint16 @@ -375,12 +377,12 @@ func formGroup(key string, start, last uint16) string { group = fmt.Sprintf("%s-%d", group, last) } if ip != "" { - group = fmt.Sprintf("%s:%s->%s", ip, group, group) + group = fmt.Sprintf("%s->%s", net.JoinHostPort(ip, group), group) } return group + "/" + groupType } -func comparePorts(i, j types.Port) bool { +func comparePorts(i, j container.Port) bool { if i.PrivatePort != j.PrivatePort { return i.PrivatePort < j.PrivatePort } diff --git a/vendor/github.com/docker/cli/cli/command/formatter/disk_usage.go b/vendor/github.com/docker/cli/cli/command/formatter/disk_usage.go index d91df2fc55f..01edd2b042e 100644 --- a/vendor/github.com/docker/cli/cli/command/formatter/disk_usage.go +++ b/vendor/github.com/docker/cli/cli/command/formatter/disk_usage.go @@ -9,6 +9,7 @@ import ( "github.com/distribution/reference" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/volume" units "github.com/docker/go-units" @@ -36,7 +37,7 @@ type DiskUsageContext struct { Verbose bool LayersSize int64 Images []*image.Summary - Containers []*types.Container + Containers []*container.Summary Volumes []*volume.Volume BuildCache []*types.BuildCache BuilderSize int64 @@ -124,7 +125,7 @@ func (ctx *DiskUsageContext) Write() (err error) { return err } - diskUsageContainersCtx := diskUsageContainersContext{containers: []*types.Container{}} + diskUsageContainersCtx := diskUsageContainersContext{containers: []*container.Summary{}} diskUsageContainersCtx.Header = SubHeaderContext{ "Type": typeHeader, "TotalCount": totalHeader, @@ -313,7 +314,7 @@ func (c *diskUsageImagesContext) Reclaimable() string { type diskUsageContainersContext struct { HeaderContext - containers []*types.Container + containers []*container.Summary } func (c *diskUsageContainersContext) MarshalJSON() ([]byte, error) { @@ -328,16 +329,16 @@ func (c *diskUsageContainersContext) TotalCount() string { return strconv.Itoa(len(c.containers)) } -func (c *diskUsageContainersContext) isActive(container types.Container) bool { - return strings.Contains(container.State, "running") || - strings.Contains(container.State, "paused") || - strings.Contains(container.State, "restarting") +func (c *diskUsageContainersContext) isActive(ctr container.Summary) bool { + return strings.Contains(ctr.State, "running") || + strings.Contains(ctr.State, "paused") || + strings.Contains(ctr.State, "restarting") } func (c *diskUsageContainersContext) Active() string { used := 0 - for _, container := range c.containers { - if c.isActive(*container) { + for _, ctr := range c.containers { + if c.isActive(*ctr) { used++ } } @@ -348,22 +349,21 @@ func (c *diskUsageContainersContext) Active() string { func (c *diskUsageContainersContext) Size() string { var size int64 - for _, container := range c.containers { - size += container.SizeRw + for _, ctr := range c.containers { + size += ctr.SizeRw } return units.HumanSize(float64(size)) } func (c *diskUsageContainersContext) Reclaimable() string { - var reclaimable int64 - var totalSize int64 + var reclaimable, totalSize int64 - for _, container := range c.containers { - if !c.isActive(*container) { - reclaimable += container.SizeRw + for _, ctr := range c.containers { + if !c.isActive(*ctr) { + reclaimable += ctr.SizeRw } - totalSize += container.SizeRw + totalSize += ctr.SizeRw } if totalSize > 0 { diff --git a/vendor/github.com/docker/cli/cli/command/registry.go b/vendor/github.com/docker/cli/cli/command/registry.go index cb966be1a77..2d8dd99e708 100644 --- a/vendor/github.com/docker/cli/cli/command/registry.go +++ b/vendor/github.com/docker/cli/cli/command/registry.go @@ -13,7 +13,6 @@ import ( configtypes "github.com/docker/cli/cli/config/types" "github.com/docker/cli/cli/hints" "github.com/docker/cli/cli/streams" - "github.com/docker/docker/api/types" registrytypes "github.com/docker/docker/api/types/registry" "github.com/docker/docker/registry" "github.com/pkg/errors" @@ -29,7 +28,7 @@ const ( // RegistryAuthenticationPrivilegedFunc returns a RequestPrivilegeFunc from the specified registry index info // for the given command. -func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInfo, cmdName string) types.RequestPrivilegeFunc { +func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInfo, cmdName string) registrytypes.RequestAuthConfig { return func(ctx context.Context) (string, error) { _, _ = fmt.Fprintf(cli.Out(), "\nLogin prior to %s:\n", cmdName) indexServer := registry.GetAuthConfigKey(index) diff --git a/vendor/github.com/docker/cli/cli/command/utils.go b/vendor/github.com/docker/cli/cli/command/utils.go index 2b4a885ed9f..8a8368fbaa6 100644 --- a/vendor/github.com/docker/cli/cli/command/utils.go +++ b/vendor/github.com/docker/cli/cli/command/utils.go @@ -199,7 +199,7 @@ func PruneFilters(dockerCli Cli, pruneFilters filters.Args) filters.Args { // AddPlatformFlag adds `platform` to a set of flags for API version 1.32 and later. func AddPlatformFlag(flags *pflag.FlagSet, target *string) { flags.StringVar(target, "platform", os.Getenv("DOCKER_DEFAULT_PLATFORM"), "Set platform if server is multi-platform capable") - flags.SetAnnotation("platform", "version", []string{"1.32"}) + _ = flags.SetAnnotation("platform", "version", []string{"1.32"}) } // ValidateOutputPath validates the output paths of the `export` and `save` commands. diff --git a/vendor/github.com/docker/cli/cli/config/config.go b/vendor/github.com/docker/cli/cli/config/config.go index 5a518432601..910b3c0064a 100644 --- a/vendor/github.com/docker/cli/cli/config/config.go +++ b/vendor/github.com/docker/cli/cli/config/config.go @@ -143,7 +143,7 @@ func load(configDir string) (*configfile.ConfigFile, error) { defer file.Close() err = configFile.LoadFromReader(file) if err != nil { - err = errors.Wrapf(err, "loading config file: %s: ", filename) + err = errors.Wrapf(err, "parsing config file (%s)", filename) } return configFile, err } diff --git a/vendor/github.com/docker/cli/cli/config/credentials/file_store.go b/vendor/github.com/docker/cli/cli/config/credentials/file_store.go index 95406281501..c69312b0149 100644 --- a/vendor/github.com/docker/cli/cli/config/credentials/file_store.go +++ b/vendor/github.com/docker/cli/cli/config/credentials/file_store.go @@ -1,9 +1,12 @@ package credentials import ( + "fmt" "net" "net/url" + "os" "strings" + "sync/atomic" "github.com/docker/cli/cli/config/types" ) @@ -57,6 +60,21 @@ func (c *fileStore) GetAll() (map[string]types.AuthConfig, error) { return c.file.GetAuthConfigs(), nil } +// unencryptedWarning warns the user when using an insecure credential storage. +// After a deprecation period, user will get prompted if stdin and stderr are a terminal. +// Otherwise, we'll assume they want it (sadly), because people may have been scripting +// insecure logins and we don't want to break them. Maybe they'll see the warning in their +// logs and fix things. +const unencryptedWarning = ` +WARNING! Your credentials are stored unencrypted in '%s'. +Configure a credential helper to remove this warning. See +https://docs.docker.com/go/credential-store/ +` + +// alreadyPrinted ensures that we only print the unencryptedWarning once per +// CLI invocation (no need to warn the user multiple times per command). +var alreadyPrinted atomic.Bool + // Store saves the given credentials in the file store. This function is // idempotent and does not update the file if credentials did not change. func (c *fileStore) Store(authConfig types.AuthConfig) error { @@ -66,15 +84,19 @@ func (c *fileStore) Store(authConfig types.AuthConfig) error { return nil } authConfigs[authConfig.ServerAddress] = authConfig - return c.file.Save() -} + if err := c.file.Save(); err != nil { + return err + } -func (c *fileStore) GetFilename() string { - return c.file.GetFilename() -} + if !alreadyPrinted.Load() && authConfig.Password != "" { + // Display a warning if we're storing the users password (not a token). + // + // FIXME(thaJeztah): make output configurable instead of hardcoding to os.Stderr + _, _ = fmt.Fprintln(os.Stderr, fmt.Sprintf(unencryptedWarning, c.file.GetFilename())) + alreadyPrinted.Store(true) + } -func (c *fileStore) IsFileStore() bool { - return true + return nil } // ConvertToHostname converts a registry url which has http|https prepended diff --git a/vendor/github.com/docker/cli/cli/error.go b/vendor/github.com/docker/cli/cli/error.go index a821f9e5a8c..8c4a5f952bc 100644 --- a/vendor/github.com/docker/cli/cli/error.go +++ b/vendor/github.com/docker/cli/cli/error.go @@ -1,35 +1,21 @@ package cli import ( - "fmt" - "strings" + "strconv" ) -// Errors is a list of errors. -// Useful in a loop if you don't want to return the error right away and you want to display after the loop, -// all the errors that happened during the loop. -// -// Deprecated: use [errors.Join] instead; will be removed in the next release. -type Errors []error - -func (errList Errors) Error() string { - if len(errList) < 1 { - return "" - } - - out := make([]string, len(errList)) - for i := range errList { - out[i] = errList[i].Error() - } - return strings.Join(out, ", ") -} - // StatusError reports an unsuccessful exit by a command. type StatusError struct { Status string StatusCode int } +// Error formats the error for printing. If a custom Status is provided, +// it is returned as-is, otherwise it generates a generic error-message +// based on the StatusCode. func (e StatusError) Error() string { - return fmt.Sprintf("Status: %s, Code: %d", e.Status, e.StatusCode) + if e.Status == "" { + return "exit status " + strconv.Itoa(e.StatusCode) + } + return e.Status } diff --git a/vendor/github.com/docker/cli/cli/hints/hints.go b/vendor/github.com/docker/cli/cli/hints/hints.go index f99df8fda02..aed3577893f 100644 --- a/vendor/github.com/docker/cli/cli/hints/hints.go +++ b/vendor/github.com/docker/cli/cli/hints/hints.go @@ -5,7 +5,9 @@ import ( "strconv" ) -// Enabled returns whether cli hints are enabled or not +// Enabled returns whether cli hints are enabled or not. Hints are enabled by +// default, but can be disabled through the "DOCKER_CLI_HINTS" environment +// variable. func Enabled() bool { if v := os.Getenv("DOCKER_CLI_HINTS"); v != "" { enabled, err := strconv.ParseBool(v) diff --git a/vendor/github.com/docker/cli/cli/registry/client/endpoint.go b/vendor/github.com/docker/cli/cli/registry/client/endpoint.go index e06bfea50bc..2446da85a04 100644 --- a/vendor/github.com/docker/cli/cli/registry/client/endpoint.go +++ b/vendor/github.com/docker/cli/cli/registry/client/endpoint.go @@ -22,12 +22,7 @@ type repositoryEndpoint struct { // Name returns the repository name func (r repositoryEndpoint) Name() string { - repoName := r.info.Name.Name() - // If endpoint does not support CanonicalName, use the RemoteName instead - if r.endpoint.TrimHostname { - repoName = reference.Path(r.info.Name) - } - return repoName + return reference.Path(r.info.Name) } // BaseURL returns the endpoint url diff --git a/vendor/github.com/docker/cli/cli/required.go b/vendor/github.com/docker/cli/cli/required.go index e8edcaafac2..6455e8867e0 100644 --- a/vendor/github.com/docker/cli/cli/required.go +++ b/vendor/github.com/docker/cli/cli/required.go @@ -1,8 +1,6 @@ package cli import ( - "strings" - "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -14,15 +12,20 @@ func NoArgs(cmd *cobra.Command, args []string) error { } if cmd.HasSubCommands() { - return errors.New("\n" + strings.TrimRight(cmd.UsageString(), "\n")) + return errors.Errorf( + "%[1]s: unknown command: %[2]s %[3]s\n\nUsage: %[4]s\n\nRun '%[2]s --help' for more information", + binName(cmd), + cmd.CommandPath(), + args[0], + cmd.UseLine(), + ) } return errors.Errorf( - "%q accepts no arguments.\nSee '%s --help'.\n\nUsage: %s\n\n%s", - cmd.CommandPath(), + "%[1]s: '%[2]s' accepts no arguments\n\nUsage: %[3]s\n\nRun '%[2]s --help' for more information", + binName(cmd), cmd.CommandPath(), cmd.UseLine(), - cmd.Short, ) } @@ -33,13 +36,12 @@ func RequiresMinArgs(minArgs int) cobra.PositionalArgs { return nil } return errors.Errorf( - "%q requires at least %d %s.\nSee '%s --help'.\n\nUsage: %s\n\n%s", + "%[1]s: '%[2]s' requires at least %[3]d %[4]s\n\nUsage: %[5]s\n\nSee '%[2]s --help' for more information", + binName(cmd), cmd.CommandPath(), minArgs, pluralize("argument", minArgs), - cmd.CommandPath(), cmd.UseLine(), - cmd.Short, ) } } @@ -51,13 +53,12 @@ func RequiresMaxArgs(maxArgs int) cobra.PositionalArgs { return nil } return errors.Errorf( - "%q requires at most %d %s.\nSee '%s --help'.\n\nUsage: %s\n\n%s", + "%[1]s: '%[2]s' requires at most %[3]d %[4]s\n\nUsage: %[5]s\n\nSRun '%[2]s --help' for more information", + binName(cmd), cmd.CommandPath(), maxArgs, pluralize("argument", maxArgs), - cmd.CommandPath(), cmd.UseLine(), - cmd.Short, ) } } @@ -69,14 +70,13 @@ func RequiresRangeArgs(minArgs int, maxArgs int) cobra.PositionalArgs { return nil } return errors.Errorf( - "%q requires at least %d and at most %d %s.\nSee '%s --help'.\n\nUsage: %s\n\n%s", + "%[1]s: '%[2]s' requires at least %[3]d and at most %[4]d %[5]s\n\nUsage: %[6]s\n\nRun '%[2]s --help' for more information", + binName(cmd), cmd.CommandPath(), minArgs, maxArgs, pluralize("argument", maxArgs), - cmd.CommandPath(), cmd.UseLine(), - cmd.Short, ) } } @@ -88,17 +88,21 @@ func ExactArgs(number int) cobra.PositionalArgs { return nil } return errors.Errorf( - "%q requires exactly %d %s.\nSee '%s --help'.\n\nUsage: %s\n\n%s", + "%[1]s: '%[2]s' requires %[3]d %[4]s\n\nUsage: %[5]s\n\nRun '%[2]s --help' for more information", + binName(cmd), cmd.CommandPath(), number, pluralize("argument", number), - cmd.CommandPath(), cmd.UseLine(), - cmd.Short, ) } } +// binName returns the name of the binary / root command (usually 'docker'). +func binName(cmd *cobra.Command) string { + return cmd.Root().Name() +} + //nolint:unparam func pluralize(word string, number int) string { if number == 1 { diff --git a/vendor/github.com/docker/cli/opts/network.go b/vendor/github.com/docker/cli/opts/network.go index 413aec7b52e..2ce5dff1f81 100644 --- a/vendor/github.com/docker/cli/opts/network.go +++ b/vendor/github.com/docker/cli/opts/network.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "regexp" + "strconv" "strings" ) @@ -16,6 +17,7 @@ const ( networkOptMacAddress = "mac-address" networkOptLinkLocalIP = "link-local-ip" driverOpt = "driver-opt" + gwPriorityOpt = "gw-priority" ) // NetworkAttachmentOpts represents the network options for endpoint creation @@ -28,6 +30,7 @@ type NetworkAttachmentOpts struct { IPv6Address string LinkLocalIPs []string MacAddress string + GwPriority int } // NetworkOpt represents a network config in swarm mode. @@ -83,6 +86,11 @@ func (n *NetworkOpt) Set(value string) error { //nolint:gocyclo netOpt.DriverOpts = make(map[string]string) } netOpt.DriverOpts[key] = val + case gwPriorityOpt: + netOpt.GwPriority, err = strconv.Atoi(val) + if err != nil { + return fmt.Errorf("invalid gw-priority: %w", err) + } default: return errors.New("invalid field key " + key) } diff --git a/vendor/modules.txt b/vendor/modules.txt index ab94f35ff82..64a561fe31d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -221,7 +221,7 @@ github.com/davecgh/go-spew/spew # github.com/distribution/reference v0.6.0 ## explicit; go 1.20 github.com/distribution/reference -# github.com/docker/cli v27.4.0+incompatible +# github.com/docker/cli v27.4.0+incompatible => github.com/docker/cli v27.0.2-0.20241216164627-8454e012cade+incompatible ## explicit github.com/docker/cli/cli github.com/docker/cli/cli-plugins/hooks @@ -1345,3 +1345,4 @@ sigs.k8s.io/structured-merge-diff/v4/value ## explicit; go 1.12 sigs.k8s.io/yaml # github.com/docker/docker => github.com/docker/docker v27.0.2-0.20241217103611-726b327b83bb+incompatible +# github.com/docker/cli => github.com/docker/cli v27.0.2-0.20241216164627-8454e012cade+incompatible From 770d443937600c00abef71b90f06bdcdc15c5f47 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 17 Dec 2024 11:41:17 +0100 Subject: [PATCH 3/3] vendor: test moby pkg/system refactor Signed-off-by: Sebastiaan van Stijn --- go.mod | 4 +- go.sum | 4 +- .../docker/docker/pkg/archive/archive.go | 25 ++++--- .../docker/pkg/archive/archive_linux.go | 3 +- .../docker/docker/pkg/archive/archive_unix.go | 3 +- .../docker/docker/pkg/archive/changes.go | 10 +-- .../docker/pkg/archive/changes_linux.go | 9 +-- .../docker/pkg/archive/changes_other.go | 10 +-- .../docker/docker/pkg/archive/changes_unix.go | 20 +++--- .../docker/pkg/archive/changes_windows.go | 7 +- .../docker/docker/pkg/archive/copy.go | 3 +- .../docker/docker/pkg/archive/dev_freebsd.go | 7 ++ .../docker/docker/pkg/archive/dev_unix.go | 9 +++ .../docker/docker/pkg/archive/diff.go | 3 +- .../docker/docker/pkg/archive/time.go | 12 ++++ .../docker/docker/pkg/archive/time_linux.go | 16 ----- .../docker/pkg/archive/time_nonwindows.go | 40 +++++++++++ .../docker/pkg/archive/time_unsupported.go | 16 ----- .../docker/docker/pkg/archive/time_windows.go | 32 +++++++++ .../docker/pkg/archive/xattr_supported.go | 52 ++++++++++++++ .../pkg/archive/xattr_supported_linux.go | 5 ++ .../pkg/archive/xattr_supported_unix.go | 7 ++ .../docker/pkg/archive/xattr_unsupported.go | 13 ++++ .../docker/docker/pkg/system/lstat_unix.go | 22 ------ .../docker/docker/pkg/system/lstat_windows.go | 16 ----- .../docker/docker/pkg/system/mknod.go | 18 ----- .../docker/docker/pkg/system/mknod_freebsd.go | 15 ---- .../docker/docker/pkg/system/mknod_unix.go | 15 ---- .../docker/docker/pkg/system/stat_bsd.go | 17 ----- .../docker/docker/pkg/system/stat_darwin.go | 15 ---- .../docker/docker/pkg/system/stat_illumos.go | 15 ---- .../docker/docker/pkg/system/stat_linux.go | 24 ------- .../docker/docker/pkg/system/stat_openbsd.go | 15 ---- .../docker/docker/pkg/system/stat_unix.go | 70 ------------------- .../docker/docker/pkg/system/stat_windows.go | 54 -------------- vendor/modules.txt | 4 +- 36 files changed, 218 insertions(+), 392 deletions(-) create mode 100644 vendor/github.com/docker/docker/pkg/archive/dev_freebsd.go create mode 100644 vendor/github.com/docker/docker/pkg/archive/dev_unix.go create mode 100644 vendor/github.com/docker/docker/pkg/archive/time.go delete mode 100644 vendor/github.com/docker/docker/pkg/archive/time_linux.go create mode 100644 vendor/github.com/docker/docker/pkg/archive/time_nonwindows.go delete mode 100644 vendor/github.com/docker/docker/pkg/archive/time_unsupported.go create mode 100644 vendor/github.com/docker/docker/pkg/archive/time_windows.go create mode 100644 vendor/github.com/docker/docker/pkg/archive/xattr_supported.go create mode 100644 vendor/github.com/docker/docker/pkg/archive/xattr_supported_linux.go create mode 100644 vendor/github.com/docker/docker/pkg/archive/xattr_supported_unix.go create mode 100644 vendor/github.com/docker/docker/pkg/archive/xattr_unsupported.go delete mode 100644 vendor/github.com/docker/docker/pkg/system/lstat_unix.go delete mode 100644 vendor/github.com/docker/docker/pkg/system/lstat_windows.go delete mode 100644 vendor/github.com/docker/docker/pkg/system/mknod.go delete mode 100644 vendor/github.com/docker/docker/pkg/system/mknod_freebsd.go delete mode 100644 vendor/github.com/docker/docker/pkg/system/mknod_unix.go delete mode 100644 vendor/github.com/docker/docker/pkg/system/stat_bsd.go delete mode 100644 vendor/github.com/docker/docker/pkg/system/stat_darwin.go delete mode 100644 vendor/github.com/docker/docker/pkg/system/stat_illumos.go delete mode 100644 vendor/github.com/docker/docker/pkg/system/stat_linux.go delete mode 100644 vendor/github.com/docker/docker/pkg/system/stat_openbsd.go delete mode 100644 vendor/github.com/docker/docker/pkg/system/stat_unix.go delete mode 100644 vendor/github.com/docker/docker/pkg/system/stat_windows.go diff --git a/go.mod b/go.mod index 61c15d5eb05..9c917435b9c 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,8 @@ module github.com/docker/buildx go 1.22.0 -// FIXME(thaJeztah): testing moby master -replace github.com/docker/docker => github.com/docker/docker v27.0.2-0.20241217103611-726b327b83bb+incompatible +// FIXME(thaJeztah): testing https://github.com/moby/moby/pull/49072 +replace github.com/docker/docker => github.com/dmcgowan/docker v1.1.3-0.20241217181958-95a218fd37d3 replace github.com/docker/cli => github.com/docker/cli v27.0.2-0.20241216164627-8454e012cade+incompatible diff --git a/go.sum b/go.sum index 4eb54c4c86b..d9359311224 100644 --- a/go.sum +++ b/go.sum @@ -125,6 +125,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/dmcgowan/docker v1.1.3-0.20241217181958-95a218fd37d3 h1:yHhgVWAIVQerCChKHjPMN1qL/OCVu/vi7Huni3DMVlI= +github.com/dmcgowan/docker v1.1.3-0.20241217181958-95a218fd37d3/go.mod h1:AKi7Z6FzccBGsB9PP0AbY4O0g9QR4Y5RmrVhRbN4r3Q= github.com/docker/cli v27.0.2-0.20241216164627-8454e012cade+incompatible h1:pyDQtU605ZHT0c7WXSG+QQPovGUhFmOmWiAr2/86FfU= github.com/docker/cli v27.0.2-0.20241216164627-8454e012cade+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli-docs-tool v0.8.0 h1:YcDWl7rQJC3lJ7WVZRwSs3bc9nka97QLWfyJQli8yJU= @@ -132,8 +134,6 @@ github.com/docker/cli-docs-tool v0.8.0/go.mod h1:8TQQ3E7mOXoYUs811LiPdUnAhXrcVsB github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.0.2-0.20241217103611-726b327b83bb+incompatible h1:POWgeNKhbpPC5FMSP5ztYL+sr9ytSdoC+q72dawLR/0= -github.com/docker/docker v27.0.2-0.20241217103611-726b327b83bb+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= diff --git a/vendor/github.com/docker/docker/pkg/archive/archive.go b/vendor/github.com/docker/docker/pkg/archive/archive.go index 77868900eb9..01d4e12480b 100644 --- a/vendor/github.com/docker/docker/pkg/archive/archive.go +++ b/vendor/github.com/docker/docker/pkg/archive/archive.go @@ -26,7 +26,6 @@ import ( "github.com/containerd/log" "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/pools" - "github.com/docker/docker/pkg/system" "github.com/klauspost/compress/zstd" "github.com/moby/patternmatcher" "github.com/moby/sys/sequential" @@ -507,7 +506,7 @@ func ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error { vfsCapRevision2 = 2 vfsCapRevision3 = 3 ) - capability, _ := system.Lgetxattr(path, "security.capability") + capability, _ := lgetxattr(path, "security.capability") if capability != nil { if capability[versionOffset] == vfsCapRevision3 { // Convert VFS_CAP_REVISION_3 to VFS_CAP_REVISION_2 as root UID makes no @@ -799,7 +798,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, o if !ok { continue } - if err := system.Lsetxattr(path, xattr, []byte(value), 0); err != nil { + if err := lsetxattr(path, xattr, []byte(value), 0); err != nil { if bestEffortXattrs && errors.Is(err, syscall.ENOTSUP) || errors.Is(err, syscall.EPERM) { // EPERM occurs if modifying xattrs is not allowed. This can // happen when running in userns with restrictions (ChromeOS). @@ -822,26 +821,26 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, o return err } - aTime := hdr.AccessTime - if aTime.Before(hdr.ModTime) { + aTime := sanitizeTime(hdr.AccessTime) + mTime := sanitizeTime(hdr.ModTime) + if aTime.Before(mTime) { // Last access time should never be before last modified time. - aTime = hdr.ModTime + aTime = mTime } - // system.Chtimes doesn't support a NOFOLLOW flag atm + // chtimes doesn't support a NOFOLLOW flag atm if hdr.Typeflag == tar.TypeLink { if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) { - if err := system.Chtimes(path, aTime, hdr.ModTime); err != nil { + if err := chtimes(path, aTime, mTime); err != nil { return err } } } else if hdr.Typeflag != tar.TypeSymlink { - if err := system.Chtimes(path, aTime, hdr.ModTime); err != nil { + if err := chtimes(path, aTime, mTime); err != nil { return err } } else { - ts := []syscall.Timespec{timeToTimespec(aTime), timeToTimespec(hdr.ModTime)} - if err := system.LUtimesNano(path, ts); err != nil && err != system.ErrNotSupportedPlatform { + if err := lchtimes(path, aTime, mTime); err != nil { return err } } @@ -1201,7 +1200,7 @@ loop: // #nosec G305 -- The header was checked for path traversal before it was appended to the dirs slice. path := filepath.Join(dest, hdr.Name) - if err := system.Chtimes(path, hdr.AccessTime, hdr.ModTime); err != nil { + if err := chtimes(path, sanitizeTime(hdr.AccessTime), sanitizeTime(hdr.ModTime)); err != nil { return err } } @@ -1350,7 +1349,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) { dst = filepath.Join(dst, filepath.Base(src)) } // Create the holding directory if necessary - if err := system.MkdirAll(filepath.Dir(dst), 0o700); err != nil { + if err := os.MkdirAll(filepath.Dir(dst), 0o700); err != nil { return err } diff --git a/vendor/github.com/docker/docker/pkg/archive/archive_linux.go b/vendor/github.com/docker/docker/pkg/archive/archive_linux.go index 061564991c6..62814028e48 100644 --- a/vendor/github.com/docker/docker/pkg/archive/archive_linux.go +++ b/vendor/github.com/docker/docker/pkg/archive/archive_linux.go @@ -7,7 +7,6 @@ import ( "path/filepath" "strings" - "github.com/docker/docker/pkg/system" "github.com/moby/sys/userns" "golang.org/x/sys/unix" ) @@ -39,7 +38,7 @@ func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os } // convert opaque dirs to AUFS format by writing an empty file with the prefix - opaque, err := system.Lgetxattr(path, opaqueXattrName) + opaque, err := lgetxattr(path, opaqueXattrName) if err != nil { return nil, err } diff --git a/vendor/github.com/docker/docker/pkg/archive/archive_unix.go b/vendor/github.com/docker/docker/pkg/archive/archive_unix.go index f559a30565f..f67613b7ca3 100644 --- a/vendor/github.com/docker/docker/pkg/archive/archive_unix.go +++ b/vendor/github.com/docker/docker/pkg/archive/archive_unix.go @@ -12,7 +12,6 @@ import ( "syscall" "github.com/docker/docker/pkg/idtools" - "github.com/docker/docker/pkg/system" "golang.org/x/sys/unix" ) @@ -109,7 +108,7 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error { mode |= unix.S_IFIFO } - return system.Mknod(path, mode, int(system.Mkdev(hdr.Devmajor, hdr.Devminor))) + return mknod(path, mode, unix.Mkdev(uint32(hdr.Devmajor), uint32(hdr.Devminor))) } func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error { diff --git a/vendor/github.com/docker/docker/pkg/archive/changes.go b/vendor/github.com/docker/docker/pkg/archive/changes.go index 5f12ca4016a..6492834a3b8 100644 --- a/vendor/github.com/docker/docker/pkg/archive/changes.go +++ b/vendor/github.com/docker/docker/pkg/archive/changes.go @@ -6,17 +6,16 @@ import ( "context" "fmt" "io" + "io/fs" "os" "path/filepath" "sort" "strings" - "syscall" "time" "github.com/containerd/log" "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/pools" - "github.com/docker/docker/pkg/system" ) // ChangeType represents the change type. @@ -74,11 +73,6 @@ func sameFsTime(a, b time.Time) bool { (a.Nanosecond() == 0 || b.Nanosecond() == 0)) } -func sameFsTimeSpec(a, b syscall.Timespec) bool { - return a.Sec == b.Sec && - (a.Nsec == b.Nsec || a.Nsec == 0 || b.Nsec == 0) -} - // Changes walks the path rw and determines changes for the files in the path, // with respect to the parent layers func Changes(layers []string, rw string) ([]Change, error) { @@ -210,7 +204,7 @@ func changes(layers []string, rw string, dc deleteChange, sc skipChange) ([]Chan type FileInfo struct { parent *FileInfo name string - stat *system.StatT + stat fs.FileInfo children map[string]*FileInfo capability []byte added bool diff --git a/vendor/github.com/docker/docker/pkg/archive/changes_linux.go b/vendor/github.com/docker/docker/pkg/archive/changes_linux.go index 877ec785589..5205883214e 100644 --- a/vendor/github.com/docker/docker/pkg/archive/changes_linux.go +++ b/vendor/github.com/docker/docker/pkg/archive/changes_linux.go @@ -9,7 +9,6 @@ import ( "syscall" "unsafe" - "github.com/docker/docker/pkg/system" "golang.org/x/sys/unix" ) @@ -74,12 +73,8 @@ func walkchunk(path string, fi os.FileInfo, dir string, root *FileInfo) error { parent: parent, } cpath := filepath.Join(dir, path) - stat, err := system.FromStatT(fi.Sys().(*syscall.Stat_t)) - if err != nil { - return err - } - info.stat = stat - info.capability, _ = system.Lgetxattr(cpath, "security.capability") // lgetxattr(2): fs access + info.stat = fi + info.capability, _ = lgetxattr(cpath, "security.capability") // lgetxattr(2): fs access parent.children[info.name] = info return nil } diff --git a/vendor/github.com/docker/docker/pkg/archive/changes_other.go b/vendor/github.com/docker/docker/pkg/archive/changes_other.go index 28f741a25dd..db5aab8c7b3 100644 --- a/vendor/github.com/docker/docker/pkg/archive/changes_other.go +++ b/vendor/github.com/docker/docker/pkg/archive/changes_other.go @@ -8,8 +8,6 @@ import ( "path/filepath" "runtime" "strings" - - "github.com/docker/docker/pkg/system" ) func collectFileInfoForChanges(oldDir, newDir string) (*FileInfo, *FileInfo, error) { @@ -72,7 +70,7 @@ func collectFileInfo(sourceDir string) (*FileInfo, error) { return fmt.Errorf("collectFileInfo: Unexpectedly no parent for %s", relPath) } - s, err := system.Lstat(path) + s, err := os.Lstat(path) if err != nil { return err } @@ -84,11 +82,7 @@ func collectFileInfo(sourceDir string) (*FileInfo, error) { stat: s, } - // system.Lgetxattr is only implemented on Linux and produces an error - // on other platforms. This code is intentionally left commented-out - // as a reminder to include this code if this would ever be implemented - // on other platforms. - // info.capability, _ = system.Lgetxattr(path, "security.capability") + info.capability, _ = lgetxattr(path, "security.capability") parent.children[info.name] = info diff --git a/vendor/github.com/docker/docker/pkg/archive/changes_unix.go b/vendor/github.com/docker/docker/pkg/archive/changes_unix.go index 853c73ee8c0..776be78325c 100644 --- a/vendor/github.com/docker/docker/pkg/archive/changes_unix.go +++ b/vendor/github.com/docker/docker/pkg/archive/changes_unix.go @@ -3,19 +3,19 @@ package archive // import "github.com/docker/docker/pkg/archive" import ( + "io/fs" "os" "syscall" - - "github.com/docker/docker/pkg/system" - "golang.org/x/sys/unix" ) -func statDifferent(oldStat *system.StatT, newStat *system.StatT) bool { +func statDifferent(oldStat fs.FileInfo, newStat fs.FileInfo) bool { + oldSys := oldStat.Sys().(*syscall.Stat_t) + newSys := newStat.Sys().(*syscall.Stat_t) // Don't look at size for dirs, its not a good measure of change if oldStat.Mode() != newStat.Mode() || - oldStat.UID() != newStat.UID() || - oldStat.GID() != newStat.GID() || - oldStat.Rdev() != newStat.Rdev() || + oldSys.Uid != newSys.Uid || + oldSys.Gid != newSys.Gid || + oldSys.Rdev != newSys.Rdev || // Don't look at size or modification time for dirs, its not a good // measure of change. See https://github.com/moby/moby/issues/9874 // for a description of the issue with modification time, and @@ -23,15 +23,15 @@ func statDifferent(oldStat *system.StatT, newStat *system.StatT) bool { // (Note that in the Windows implementation of this function, // modification time IS taken as a change). See // https://github.com/moby/moby/pull/37982 for more information. - (oldStat.Mode()&unix.S_IFDIR != unix.S_IFDIR && - (!sameFsTimeSpec(oldStat.Mtim(), newStat.Mtim()) || (oldStat.Size() != newStat.Size()))) { + (!oldStat.Mode().IsDir() && + (!sameFsTime(oldStat.ModTime(), newStat.ModTime()) || (oldStat.Size() != newStat.Size()))) { return true } return false } func (info *FileInfo) isDir() bool { - return info.parent == nil || info.stat.Mode()&unix.S_IFDIR != 0 + return info.parent == nil || info.stat.Mode().IsDir() } func getIno(fi os.FileInfo) uint64 { diff --git a/vendor/github.com/docker/docker/pkg/archive/changes_windows.go b/vendor/github.com/docker/docker/pkg/archive/changes_windows.go index 9906685e4b0..9ab0e6350e2 100644 --- a/vendor/github.com/docker/docker/pkg/archive/changes_windows.go +++ b/vendor/github.com/docker/docker/pkg/archive/changes_windows.go @@ -1,19 +1,18 @@ package archive // import "github.com/docker/docker/pkg/archive" import ( + "io/fs" "os" - - "github.com/docker/docker/pkg/system" ) -func statDifferent(oldStat *system.StatT, newStat *system.StatT) bool { +func statDifferent(oldStat fs.FileInfo, newStat fs.FileInfo) bool { // Note there is slight difference between the Linux and Windows // implementations here. Due to https://github.com/moby/moby/issues/9874, // and the fix at https://github.com/moby/moby/pull/11422, Linux does not // consider a change to the directory time as a change. Windows on NTFS // does. See https://github.com/moby/moby/pull/37982 for more information. - if !sameFsTime(oldStat.Mtim(), newStat.Mtim()) || + if !sameFsTime(oldStat.ModTime(), newStat.ModTime()) || oldStat.Mode() != newStat.Mode() || oldStat.Size() != newStat.Size() && !oldStat.Mode().IsDir() { return true diff --git a/vendor/github.com/docker/docker/pkg/archive/copy.go b/vendor/github.com/docker/docker/pkg/archive/copy.go index 01eadc30d99..9918b5d60e2 100644 --- a/vendor/github.com/docker/docker/pkg/archive/copy.go +++ b/vendor/github.com/docker/docker/pkg/archive/copy.go @@ -10,7 +10,6 @@ import ( "strings" "github.com/containerd/log" - "github.com/docker/docker/pkg/system" ) // Errors used or returned by this file. @@ -203,7 +202,7 @@ func CopyInfoDestinationPath(path string) (info CopyInfo, err error) { return CopyInfo{}, err } - if !system.IsAbs(linkTarget) { + if !filepath.IsAbs(linkTarget) { // Join with the parent directory. dstParent, _ := SplitPathDirEntry(path) linkTarget = filepath.Join(dstParent, linkTarget) diff --git a/vendor/github.com/docker/docker/pkg/archive/dev_freebsd.go b/vendor/github.com/docker/docker/pkg/archive/dev_freebsd.go new file mode 100644 index 00000000000..aa8e29154a2 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/archive/dev_freebsd.go @@ -0,0 +1,7 @@ +//go:build freebsd + +package archive + +import "golang.org/x/sys/unix" + +var mknod = unix.Mknod diff --git a/vendor/github.com/docker/docker/pkg/archive/dev_unix.go b/vendor/github.com/docker/docker/pkg/archive/dev_unix.go new file mode 100644 index 00000000000..dffc596f93f --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/archive/dev_unix.go @@ -0,0 +1,9 @@ +//go:build !windows && !freebsd + +package archive + +import "golang.org/x/sys/unix" + +func mknod(path string, mode uint32, dev uint64) error { + return unix.Mknod(path, mode, int(dev)) +} diff --git a/vendor/github.com/docker/docker/pkg/archive/diff.go b/vendor/github.com/docker/docker/pkg/archive/diff.go index e080e310ac8..2a950b1cbf2 100644 --- a/vendor/github.com/docker/docker/pkg/archive/diff.go +++ b/vendor/github.com/docker/docker/pkg/archive/diff.go @@ -12,7 +12,6 @@ import ( "github.com/containerd/log" "github.com/docker/docker/pkg/pools" - "github.com/docker/docker/pkg/system" ) // UnpackLayer unpack `layer` to a `dest`. The stream `layer` can be @@ -200,7 +199,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, for _, hdr := range dirs { // #nosec G305 -- The header was checked for path traversal before it was appended to the dirs slice. path := filepath.Join(dest, hdr.Name) - if err := system.Chtimes(path, hdr.AccessTime, hdr.ModTime); err != nil { + if err := chtimes(path, hdr.AccessTime, hdr.ModTime); err != nil { return 0, err } } diff --git a/vendor/github.com/docker/docker/pkg/archive/time.go b/vendor/github.com/docker/docker/pkg/archive/time.go new file mode 100644 index 00000000000..bc31023a889 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/archive/time.go @@ -0,0 +1,12 @@ +package archive // import "github.com/docker/docker/pkg/archive" + +import "time" + +const maxSeconds = (1<<63 - 1) / int64(1e9) + +func sanitizeTime(t time.Time) time.Time { + if ut := t.Unix(); ut < 0 || ut > maxSeconds { + return time.Unix(0, 0) + } + return t +} diff --git a/vendor/github.com/docker/docker/pkg/archive/time_linux.go b/vendor/github.com/docker/docker/pkg/archive/time_linux.go deleted file mode 100644 index 797143ee84d..00000000000 --- a/vendor/github.com/docker/docker/pkg/archive/time_linux.go +++ /dev/null @@ -1,16 +0,0 @@ -package archive // import "github.com/docker/docker/pkg/archive" - -import ( - "syscall" - "time" -) - -func timeToTimespec(time time.Time) (ts syscall.Timespec) { - if time.IsZero() { - // Return UTIME_OMIT special value - ts.Sec = 0 - ts.Nsec = (1 << 30) - 2 - return - } - return syscall.NsecToTimespec(time.UnixNano()) -} diff --git a/vendor/github.com/docker/docker/pkg/archive/time_nonwindows.go b/vendor/github.com/docker/docker/pkg/archive/time_nonwindows.go new file mode 100644 index 00000000000..55aaef49758 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/archive/time_nonwindows.go @@ -0,0 +1,40 @@ +//go:build !windows + +package archive // import "github.com/docker/docker/pkg/archive" + +import ( + "os" + "time" + + "golang.org/x/sys/unix" +) + +// chtimes changes the access time and modified time of a file at the given path. +// If the modified time is prior to the Unix Epoch (unixMinTime), or after the +// end of Unix Time (unixEpochTime), os.Chtimes has undefined behavior. In this +// case, Chtimes defaults to Unix Epoch, just in case. +func chtimes(name string, atime time.Time, mtime time.Time) error { + return os.Chtimes(name, atime, mtime) +} + +func timeToTimespec(time time.Time) (ts unix.Timespec) { + if time.IsZero() { + // Return UTIME_OMIT special value + ts.Sec = 0 + ts.Nsec = (1 << 30) - 2 + return + } + return unix.NsecToTimespec(time.UnixNano()) +} + +func lchtimes(name string, atime time.Time, mtime time.Time) error { + utimes := [2]unix.Timespec{ + timeToTimespec(atime), + timeToTimespec(mtime), + } + err := unix.UtimesNanoAt(unix.AT_FDCWD, name, utimes[0:], unix.AT_SYMLINK_NOFOLLOW) + if err != nil && err != unix.ENOSYS { + return err + } + return err +} diff --git a/vendor/github.com/docker/docker/pkg/archive/time_unsupported.go b/vendor/github.com/docker/docker/pkg/archive/time_unsupported.go deleted file mode 100644 index 14c4ceb1d8b..00000000000 --- a/vendor/github.com/docker/docker/pkg/archive/time_unsupported.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build !linux - -package archive // import "github.com/docker/docker/pkg/archive" - -import ( - "syscall" - "time" -) - -func timeToTimespec(time time.Time) (ts syscall.Timespec) { - nsec := int64(0) - if !time.IsZero() { - nsec = time.UnixNano() - } - return syscall.NsecToTimespec(nsec) -} diff --git a/vendor/github.com/docker/docker/pkg/archive/time_windows.go b/vendor/github.com/docker/docker/pkg/archive/time_windows.go new file mode 100644 index 00000000000..1e7a5f7bd67 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/archive/time_windows.go @@ -0,0 +1,32 @@ +package archive // import "github.com/docker/docker/pkg/archive" + +import ( + "os" + "time" + + "golang.org/x/sys/windows" +) + +func chtimes(name string, atime time.Time, mtime time.Time) error { + if err := os.Chtimes(name, atime, mtime); err != nil { + return err + } + + pathp, err := windows.UTF16PtrFromString(name) + if err != nil { + return err + } + h, err := windows.CreateFile(pathp, + windows.FILE_WRITE_ATTRIBUTES, windows.FILE_SHARE_WRITE, nil, + windows.OPEN_EXISTING, windows.FILE_FLAG_BACKUP_SEMANTICS, 0) + if err != nil { + return err + } + defer windows.Close(h) + c := windows.NsecToFiletime(mtime.UnixNano()) + return windows.SetFileTime(h, &c, nil, nil) +} + +func lchtimes(name string, atime time.Time, mtime time.Time) error { + return nil +} diff --git a/vendor/github.com/docker/docker/pkg/archive/xattr_supported.go b/vendor/github.com/docker/docker/pkg/archive/xattr_supported.go new file mode 100644 index 00000000000..652a1f0f349 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/archive/xattr_supported.go @@ -0,0 +1,52 @@ +//go:build linux || darwin || freebsd || netbsd + +package archive + +import ( + "errors" + "fmt" + "io/fs" + + "golang.org/x/sys/unix" +) + +// lgetxattr retrieves the value of the extended attribute identified by attr +// and associated with the given path in the file system. +// It returns a nil slice and nil error if the xattr is not set. +func lgetxattr(path string, attr string) ([]byte, error) { + // Start with a 128 length byte array + dest := make([]byte, 128) + sz, err := unix.Lgetxattr(path, attr, dest) + + for errors.Is(err, unix.ERANGE) { + // Buffer too small, use zero-sized buffer to get the actual size + sz, err = unix.Lgetxattr(path, attr, []byte{}) + if err != nil { + return nil, wrapPathError("lgetxattr", path, attr, err) + } + dest = make([]byte, sz) + sz, err = unix.Lgetxattr(path, attr, dest) + } + + if err != nil { + if errors.Is(err, noattr) { + return nil, nil + } + return nil, wrapPathError("lgetxattr", path, attr, err) + } + + return dest[:sz], nil +} + +// lsetxattr sets the value of the extended attribute identified by attr +// and associated with the given path in the file system. +func lsetxattr(path string, attr string, data []byte, flags int) error { + return wrapPathError("lsetxattr", path, attr, unix.Lsetxattr(path, attr, data, flags)) +} + +func wrapPathError(op, path, attr string, err error) error { + if err == nil { + return nil + } + return &fs.PathError{Op: op, Path: path, Err: fmt.Errorf("xattr %q: %w", attr, err)} +} diff --git a/vendor/github.com/docker/docker/pkg/archive/xattr_supported_linux.go b/vendor/github.com/docker/docker/pkg/archive/xattr_supported_linux.go new file mode 100644 index 00000000000..f2e76465ae5 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/archive/xattr_supported_linux.go @@ -0,0 +1,5 @@ +package archive + +import "golang.org/x/sys/unix" + +var noattr = unix.ENODATA diff --git a/vendor/github.com/docker/docker/pkg/archive/xattr_supported_unix.go b/vendor/github.com/docker/docker/pkg/archive/xattr_supported_unix.go new file mode 100644 index 00000000000..4d8824158ea --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/archive/xattr_supported_unix.go @@ -0,0 +1,7 @@ +//go:build !linux && !windows + +package archive + +import "golang.org/x/sys/unix" + +var noattr = unix.ENOATTR diff --git a/vendor/github.com/docker/docker/pkg/archive/xattr_unsupported.go b/vendor/github.com/docker/docker/pkg/archive/xattr_unsupported.go new file mode 100644 index 00000000000..26095db19df --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/archive/xattr_unsupported.go @@ -0,0 +1,13 @@ +//go:build !linux && !darwin && !freebsd && !netbsd + +package archive + +// lgetxattr is not supported on Windows. +func lgetxattr(path string, attr string) ([]byte, error) { + return nil, nil +} + +// lsetxattr is not supported on Windows. +func lsetxattr(path string, attr string, data []byte, flags int) error { + return nil +} diff --git a/vendor/github.com/docker/docker/pkg/system/lstat_unix.go b/vendor/github.com/docker/docker/pkg/system/lstat_unix.go deleted file mode 100644 index 97f355d2e4d..00000000000 --- a/vendor/github.com/docker/docker/pkg/system/lstat_unix.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build !windows - -package system // import "github.com/docker/docker/pkg/system" - -import ( - "os" - "syscall" -) - -// Lstat takes a path to a file and returns -// a system.StatT type pertaining to that file. -// -// Throws an error if the file does not exist. -// -// Deprecated: this function is only used internally, and will be removed in the next release. -func Lstat(path string) (*StatT, error) { - s := &syscall.Stat_t{} - if err := syscall.Lstat(path, s); err != nil { - return nil, &os.PathError{Op: "Lstat", Path: path, Err: err} - } - return fromStatT(s) -} diff --git a/vendor/github.com/docker/docker/pkg/system/lstat_windows.go b/vendor/github.com/docker/docker/pkg/system/lstat_windows.go deleted file mode 100644 index 4180f3ac207..00000000000 --- a/vendor/github.com/docker/docker/pkg/system/lstat_windows.go +++ /dev/null @@ -1,16 +0,0 @@ -package system // import "github.com/docker/docker/pkg/system" - -import "os" - -// Lstat calls os.Lstat to get a fileinfo interface back. -// This is then copied into our own locally defined structure. -// -// Deprecated: this function is only used internally, and will be removed in the next release. -func Lstat(path string) (*StatT, error) { - fi, err := os.Lstat(path) - if err != nil { - return nil, err - } - - return fromStatT(&fi) -} diff --git a/vendor/github.com/docker/docker/pkg/system/mknod.go b/vendor/github.com/docker/docker/pkg/system/mknod.go deleted file mode 100644 index e0cd22d7a78..00000000000 --- a/vendor/github.com/docker/docker/pkg/system/mknod.go +++ /dev/null @@ -1,18 +0,0 @@ -//go:build !windows - -package system // import "github.com/docker/docker/pkg/system" - -import ( - "golang.org/x/sys/unix" -) - -// Mkdev is used to build the value of linux devices (in /dev/) which specifies major -// and minor number of the newly created device special file. -// Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes. -// They are, from low to high: the lower 8 bits of the minor, then 12 bits of the major, -// then the top 12 bits of the minor. -// -// Deprecated: this function is only used internally, and will be removed in the next release. -func Mkdev(major int64, minor int64) uint32 { - return uint32(unix.Mkdev(uint32(major), uint32(minor))) -} diff --git a/vendor/github.com/docker/docker/pkg/system/mknod_freebsd.go b/vendor/github.com/docker/docker/pkg/system/mknod_freebsd.go deleted file mode 100644 index 4f66453d622..00000000000 --- a/vendor/github.com/docker/docker/pkg/system/mknod_freebsd.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build freebsd - -package system // import "github.com/docker/docker/pkg/system" - -import ( - "golang.org/x/sys/unix" -) - -// Mknod creates a filesystem node (file, device special file or named pipe) named path -// with attributes specified by mode and dev. -// -// Deprecated: this function is only used internally, and will be removed in the next release. -func Mknod(path string, mode uint32, dev int) error { - return unix.Mknod(path, mode, uint64(dev)) -} diff --git a/vendor/github.com/docker/docker/pkg/system/mknod_unix.go b/vendor/github.com/docker/docker/pkg/system/mknod_unix.go deleted file mode 100644 index 34c5532631a..00000000000 --- a/vendor/github.com/docker/docker/pkg/system/mknod_unix.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !freebsd && !windows - -package system // import "github.com/docker/docker/pkg/system" - -import ( - "golang.org/x/sys/unix" -) - -// Mknod creates a filesystem node (file, device special file or named pipe) named path -// with attributes specified by mode and dev. -// -// Deprecated: this function is only used internally, and will be removed in the next release. -func Mknod(path string, mode uint32, dev int) error { - return unix.Mknod(path, mode, dev) -} diff --git a/vendor/github.com/docker/docker/pkg/system/stat_bsd.go b/vendor/github.com/docker/docker/pkg/system/stat_bsd.go deleted file mode 100644 index 435b776ee36..00000000000 --- a/vendor/github.com/docker/docker/pkg/system/stat_bsd.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build freebsd || netbsd - -package system // import "github.com/docker/docker/pkg/system" - -import "syscall" - -// fromStatT converts a syscall.Stat_t type to a system.Stat_t type -func fromStatT(s *syscall.Stat_t) (*StatT, error) { - return &StatT{ - size: s.Size, - mode: uint32(s.Mode), - uid: s.Uid, - gid: s.Gid, - rdev: uint64(s.Rdev), - mtim: s.Mtimespec, - }, nil -} diff --git a/vendor/github.com/docker/docker/pkg/system/stat_darwin.go b/vendor/github.com/docker/docker/pkg/system/stat_darwin.go deleted file mode 100644 index e0b629df0e2..00000000000 --- a/vendor/github.com/docker/docker/pkg/system/stat_darwin.go +++ /dev/null @@ -1,15 +0,0 @@ -package system // import "github.com/docker/docker/pkg/system" - -import "syscall" - -// fromStatT converts a syscall.Stat_t type to a system.Stat_t type -func fromStatT(s *syscall.Stat_t) (*StatT, error) { - return &StatT{ - size: s.Size, - mode: uint32(s.Mode), - uid: s.Uid, - gid: s.Gid, - rdev: uint64(s.Rdev), - mtim: s.Mtimespec, - }, nil -} diff --git a/vendor/github.com/docker/docker/pkg/system/stat_illumos.go b/vendor/github.com/docker/docker/pkg/system/stat_illumos.go deleted file mode 100644 index 851374e5d99..00000000000 --- a/vendor/github.com/docker/docker/pkg/system/stat_illumos.go +++ /dev/null @@ -1,15 +0,0 @@ -package system // import "github.com/docker/docker/pkg/system" - -import "syscall" - -// fromStatT converts a syscall.Stat_t type to a system.Stat_t type -func fromStatT(s *syscall.Stat_t) (*StatT, error) { - return &StatT{ - size: s.Size, - mode: uint32(s.Mode), - uid: s.Uid, - gid: s.Gid, - rdev: uint64(s.Rdev), - mtim: s.Mtim, - }, nil -} diff --git a/vendor/github.com/docker/docker/pkg/system/stat_linux.go b/vendor/github.com/docker/docker/pkg/system/stat_linux.go deleted file mode 100644 index 0557235f987..00000000000 --- a/vendor/github.com/docker/docker/pkg/system/stat_linux.go +++ /dev/null @@ -1,24 +0,0 @@ -package system // import "github.com/docker/docker/pkg/system" - -import "syscall" - -// fromStatT converts a syscall.Stat_t type to a system.Stat_t type -func fromStatT(s *syscall.Stat_t) (*StatT, error) { - return &StatT{ - size: s.Size, - mode: s.Mode, - uid: s.Uid, - gid: s.Gid, - // the type is 32bit on mips - rdev: uint64(s.Rdev), //nolint: unconvert - mtim: s.Mtim, - }, nil -} - -// FromStatT converts a syscall.Stat_t type to a system.Stat_t type -// This is exposed on Linux as pkg/archive/changes uses it. -// -// Deprecated: this function is only used internally, and will be removed in the next release. -func FromStatT(s *syscall.Stat_t) (*StatT, error) { - return fromStatT(s) -} diff --git a/vendor/github.com/docker/docker/pkg/system/stat_openbsd.go b/vendor/github.com/docker/docker/pkg/system/stat_openbsd.go deleted file mode 100644 index 851374e5d99..00000000000 --- a/vendor/github.com/docker/docker/pkg/system/stat_openbsd.go +++ /dev/null @@ -1,15 +0,0 @@ -package system // import "github.com/docker/docker/pkg/system" - -import "syscall" - -// fromStatT converts a syscall.Stat_t type to a system.Stat_t type -func fromStatT(s *syscall.Stat_t) (*StatT, error) { - return &StatT{ - size: s.Size, - mode: uint32(s.Mode), - uid: s.Uid, - gid: s.Gid, - rdev: uint64(s.Rdev), - mtim: s.Mtim, - }, nil -} diff --git a/vendor/github.com/docker/docker/pkg/system/stat_unix.go b/vendor/github.com/docker/docker/pkg/system/stat_unix.go deleted file mode 100644 index 661b0bed201..00000000000 --- a/vendor/github.com/docker/docker/pkg/system/stat_unix.go +++ /dev/null @@ -1,70 +0,0 @@ -//go:build !windows - -package system // import "github.com/docker/docker/pkg/system" - -import ( - "os" - "syscall" -) - -// StatT type contains status of a file. It contains metadata -// like permission, owner, group, size, etc about a file. -// -// Deprecated: this type is only used internally, and will be removed in the next release. -type StatT struct { - mode uint32 - uid uint32 - gid uint32 - rdev uint64 - size int64 - mtim syscall.Timespec -} - -// Mode returns file's permission mode. -func (s StatT) Mode() uint32 { - return s.mode -} - -// UID returns file's user id of owner. -func (s StatT) UID() uint32 { - return s.uid -} - -// GID returns file's group id of owner. -func (s StatT) GID() uint32 { - return s.gid -} - -// Rdev returns file's device ID (if it's special file). -func (s StatT) Rdev() uint64 { - return s.rdev -} - -// Size returns file's size. -func (s StatT) Size() int64 { - return s.size -} - -// Mtim returns file's last modification time. -func (s StatT) Mtim() syscall.Timespec { - return s.mtim -} - -// IsDir reports whether s describes a directory. -func (s StatT) IsDir() bool { - return s.mode&syscall.S_IFDIR != 0 -} - -// Stat takes a path to a file and returns -// a system.StatT type pertaining to that file. -// -// Throws an error if the file does not exist. -// -// Deprecated: this function is only used internally, and will be removed in the next release. -func Stat(path string) (*StatT, error) { - s := &syscall.Stat_t{} - if err := syscall.Stat(path, s); err != nil { - return nil, &os.PathError{Op: "Stat", Path: path, Err: err} - } - return fromStatT(s) -} diff --git a/vendor/github.com/docker/docker/pkg/system/stat_windows.go b/vendor/github.com/docker/docker/pkg/system/stat_windows.go deleted file mode 100644 index e74a0f4fd70..00000000000 --- a/vendor/github.com/docker/docker/pkg/system/stat_windows.go +++ /dev/null @@ -1,54 +0,0 @@ -package system // import "github.com/docker/docker/pkg/system" - -import ( - "os" - "time" -) - -// StatT type contains status of a file. It contains metadata -// like permission, size, etc about a file. -// -// Deprecated: this type is only used internally, and will be removed in the next release. -type StatT struct { - mode os.FileMode - size int64 - mtim time.Time -} - -// Size returns file's size. -func (s StatT) Size() int64 { - return s.size -} - -// Mode returns file's permission mode. -func (s StatT) Mode() os.FileMode { - return s.mode -} - -// Mtim returns file's last modification time. -func (s StatT) Mtim() time.Time { - return s.mtim -} - -// Stat takes a path to a file and returns -// a system.StatT type pertaining to that file. -// -// Throws an error if the file does not exist. -// -// Deprecated: this function is only used internally, and will be removed in the next release. -func Stat(path string) (*StatT, error) { - fi, err := os.Stat(path) - if err != nil { - return nil, err - } - return fromStatT(&fi) -} - -// fromStatT converts a os.FileInfo type to a system.StatT type -func fromStatT(fi *os.FileInfo) (*StatT, error) { - return &StatT{ - size: (*fi).Size(), - mode: (*fi).Mode(), - mtim: (*fi).ModTime(), - }, nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 64a561fe31d..65b729cced9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -274,7 +274,7 @@ github.com/docker/distribution/registry/client/transport github.com/docker/distribution/registry/storage/cache github.com/docker/distribution/registry/storage/cache/memory github.com/docker/distribution/uuid -# github.com/docker/docker v27.4.0+incompatible => github.com/docker/docker v27.0.2-0.20241217103611-726b327b83bb+incompatible +# github.com/docker/docker v27.4.0+incompatible => github.com/dmcgowan/docker v1.1.3-0.20241217181958-95a218fd37d3 ## explicit github.com/docker/docker/api github.com/docker/docker/api/types @@ -1344,5 +1344,5 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.3.0 ## explicit; go 1.12 sigs.k8s.io/yaml -# github.com/docker/docker => github.com/docker/docker v27.0.2-0.20241217103611-726b327b83bb+incompatible +# github.com/docker/docker => github.com/dmcgowan/docker v1.1.3-0.20241217181958-95a218fd37d3 # github.com/docker/cli => github.com/docker/cli v27.0.2-0.20241216164627-8454e012cade+incompatible