diff --git a/cli/command/container/opts_test.go b/cli/command/container/opts_test.go index c54f3107b6d5..a6e0cf43ff0a 100644 --- a/cli/command/container/opts_test.go +++ b/cli/command/container/opts_test.go @@ -1017,7 +1017,7 @@ func TestParseLabelfileVariables(t *testing.T) { func TestParseEntryPoint(t *testing.T) { config, _, _, err := parseRun([]string{"--entrypoint=anything", "cmd", "img"}) assert.NilError(t, err) - assert.Check(t, is.DeepEqual([]string(config.Entrypoint), []string{"anything"})) + assert.Check(t, is.DeepEqual(config.Entrypoint, []string{"anything"})) } func TestValidateDevice(t *testing.T) { diff --git a/opts/swarmopts/port_test.go b/opts/swarmopts/port_test.go index c13c6cd4d000..a9e2f4a293a9 100644 --- a/opts/swarmopts/port_test.go +++ b/opts/swarmopts/port_test.go @@ -309,7 +309,8 @@ func TestPortOptInvalidSimpleSyntax(t *testing.T) { }, { value: "", - expectedError: "no port specified: ", + expectedError: "invalid proto: ", + // expectedError: "no port specified: ", // FIXME(thaJeztah): re-enable once https://github.com/docker/go-connections/pull/143 is in a go-connections release. }, { value: "1.1.1.1:80:80", diff --git a/vendor.mod b/vendor.mod index b0744d0334e8..62fba7cdb260 100644 --- a/vendor.mod +++ b/vendor.mod @@ -6,6 +6,15 @@ module github.com/docker/cli go 1.23.0 +replace ( + // FIXME(thaJeztah): trying https://github.com/moby/moby/pull/50475 + github.com/docker/docker => github.com/thaJeztah/docker v24.0.0-rc.1.0.20250821102143-9382f0e13085+incompatible + + // FIXME(thaJeztah): temporarily need to pin on commits, otherwise go modules won't resolve until these are tagged. + github.com/moby/moby/api => github.com/moby/moby/api v1.52.0-alpha.1.0.20250820163354-c8c4996ebfdf // master + github.com/moby/moby/client => github.com/moby/moby/client v0.1.0-alpha.0.0.20250820163354-c8c4996ebfdf // master +) + require ( dario.cat/mergo v1.0.1 github.com/containerd/errdefs v1.0.0 @@ -18,7 +27,7 @@ require ( github.com/docker/distribution v2.8.3+incompatible github.com/docker/docker v28.3.3+incompatible github.com/docker/docker-credential-helpers v0.9.3 - github.com/docker/go-connections v0.5.0 + github.com/docker/go-connections v0.6.0 github.com/docker/go-units v0.5.0 github.com/fvbommel/sortorder v1.1.0 github.com/go-jose/go-jose/v4 v4.0.5 @@ -85,6 +94,8 @@ require ( github.com/klauspost/compress v1.18.0 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/moby/moby/api v1.52.0-alpha.1 // indirect + github.com/moby/moby/client v0.0.0-00010101000000-000000000000 // indirect github.com/moby/sys/user v0.4.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect diff --git a/vendor.sum b/vendor.sum index 5f58c88f589b..8c90c2fbcb77 100644 --- a/vendor.sum +++ b/vendor.sum @@ -57,15 +57,13 @@ github.com/docker/cli-docs-tool v0.10.0/go.mod h1:5EM5zPnT2E7yCLERZmrDA234Vwn09f 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 v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI= -github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= +github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= @@ -172,6 +170,10 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ= github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo= +github.com/moby/moby/api v1.52.0-alpha.1.0.20250820163354-c8c4996ebfdf h1:XeF0zzinsXSRWFFLt49coRV8xa5dUb920dewMNGGrtg= +github.com/moby/moby/api v1.52.0-alpha.1.0.20250820163354-c8c4996ebfdf/go.mod h1:8sBV0soUREiudtow4vqJGOxa4GyHI5vLQmvgKdHq5Ok= +github.com/moby/moby/client v0.1.0-alpha.0.0.20250820163354-c8c4996ebfdf h1:jAG3Ydt0zIp5USA9kHzQZNsVlBkaMLgam1/4OX+HERM= +github.com/moby/moby/client v0.1.0-alpha.0.0.20250820163354-c8c4996ebfdf/go.mod h1:7pOYrEHdG7I0dNZEC+yqk/p8ZOxGMR1KgoexzCEDe0w= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/swarmkit/v2 v2.0.0 h1:jkWQKQaJ4ltA61/mC9UdPe1McLma55RUcacTO+pPweY= @@ -275,6 +277,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/thaJeztah/docker v24.0.0-rc.1.0.20250821102143-9382f0e13085+incompatible h1:66ofuDf0ykLSlQ5ojCcB7ohwWN5nWBbke2ZRsClnG/E= +github.com/thaJeztah/docker v24.0.0-rc.1.0.20250821102143-9382f0e13085+incompatible/go.mod h1:eZ6Ef2GDr/8h8se23uenzFTrBHwc9jBEEnfrxqOb0Ss= github.com/theupdateframework/notary v0.7.1-0.20210315103452-bf96a202a09a h1:tlJ7tGUHvcvL1v3yR6NcCc9nOqh2L+CG6HWrYQtwzQ0= github.com/theupdateframework/notary v0.7.1-0.20210315103452-bf96a202a09a/go.mod h1:Y94A6rPp2OwNfP/7vmf8O2xx2IykP8pPXQ1DLouGnEw= github.com/tonistiigi/go-rosetta v0.0.0-20220804170347-3f4430f2d346 h1:TvtdmeYsYEij78hS4oxnwikoiLdIrgav3BA+CbhaDAI= @@ -416,5 +420,7 @@ gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= tags.cncf.io/container-device-interface v0.8.0 h1:8bCFo/g9WODjWx3m6EYl3GfUG31eKJbaggyBDxEldRc= tags.cncf.io/container-device-interface v0.8.0/go.mod h1:Apb7N4VdILW0EVdEMRYXIDVRZfNJZ+kmEUss2kRRQ6Y= diff --git a/vendor/github.com/docker/docker/api/swagger.yaml b/vendor/github.com/docker/docker/api/swagger.yaml index 3880635db128..08e4e66d3b22 100644 --- a/vendor/github.com/docker/docker/api/swagger.yaml +++ b/vendor/github.com/docker/docker/api/swagger.yaml @@ -4392,6 +4392,7 @@ definitions: A counter that triggers an update even if no relevant parameters have been changed. type: "integer" + format: "uint64" Runtime: description: | Runtime is the type of runtime specified for the task executor. diff --git a/vendor/github.com/docker/docker/api/types/aliases.go b/vendor/github.com/docker/docker/api/types/aliases.go new file mode 100644 index 000000000000..eb7c73e15193 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/aliases.go @@ -0,0 +1,135 @@ +package types + +import ( + "net" + + "github.com/moby/moby/api/types" + "github.com/moby/moby/api/types/common" + "github.com/moby/moby/api/types/plugin" + "github.com/moby/moby/api/types/system" + "github.com/moby/moby/client" +) + +// NewHijackedResponse initializes a [HijackedResponse] type. +func NewHijackedResponse(conn net.Conn, mediaType string) client.HijackedResponse { + return client.NewHijackedResponse(conn, mediaType) +} + +// HijackedResponse holds connection information for a hijacked request. +type HijackedResponse = client.HijackedResponse + +// CloseWriter is an interface that implements structs +// that close input streams to prevent from writing. +type CloseWriter = client.CloseWriter + +// PluginRemoveOptions holds parameters to remove plugins. +type PluginRemoveOptions = client.PluginRemoveOptions + +// PluginEnableOptions holds parameters to enable plugins. +type PluginEnableOptions = client.PluginEnableOptions + +// PluginDisableOptions holds parameters to disable plugins. +type PluginDisableOptions = client.PluginDisableOptions + +// PluginInstallOptions holds parameters to install a plugin. +type PluginInstallOptions = client.PluginInstallOptions + +// PluginCreateOptions hold all options to plugin create. +type PluginCreateOptions = client.PluginCreateOptions + +// ErrorResponse Represents an error. +type ErrorResponse = common.ErrorResponse + +// Plugin A plugin for the Engine API +type Plugin = plugin.Plugin + +// PluginConfig The config of a plugin. +type PluginConfig = plugin.Config + +// PluginConfigArgs plugin config args +type PluginConfigArgs = plugin.Args + +// PluginConfigInterface The interface between Docker and the plugin +type PluginConfigInterface = plugin.Interface + +// PluginConfigLinux plugin config linux +type PluginConfigLinux = plugin.LinuxConfig + +// PluginConfigNetwork plugin config network +type PluginConfigNetwork = plugin.NetworkConfig + +// PluginConfigRootfs plugin config rootfs +type PluginConfigRootfs = plugin.RootFS + +// PluginConfigUser plugin config user +type PluginConfigUser = plugin.User + +// PluginSettings Settings that can be modified by users. +type PluginSettings = plugin.Settings + +// PluginDevice plugin device +type PluginDevice = plugin.Device + +// PluginEnv plugin env +type PluginEnv = plugin.Env + +// PluginInterfaceType plugin interface type +type PluginInterfaceType = plugin.CapabilityID + +// PluginMount plugin mount +type PluginMount = plugin.Mount + +// PluginsListResponse contains the response for the Engine API +type PluginsListResponse = plugin.ListResponse + +// PluginPrivilege describes a permission the user has to accept +// upon installing a plugin. +type PluginPrivilege = plugin.Privilege + +// PluginPrivileges is a list of PluginPrivilege +type PluginPrivileges = plugin.Privileges + +const ( + // MediaTypeRawStream is vendor specific MIME-Type set for raw TTY streams + MediaTypeRawStream = types.MediaTypeRawStream + + // MediaTypeMultiplexedStream is vendor specific MIME-Type set for stdin/stdout/stderr multiplexed streams + MediaTypeMultiplexedStream = types.MediaTypeMultiplexedStream +) + +// Ping contains response of Engine API: +// GET "/_ping" +type Ping = types.Ping + +// ComponentVersion describes the version information for a specific component. +type ComponentVersion = types.ComponentVersion + +// Version contains response of Engine API: +// GET "/version" +type Version = types.Version + +// DiskUsageObject represents an object type used for disk usage query filtering. +type DiskUsageObject = system.DiskUsageObject + +const ( + // ContainerObject represents a container DiskUsageObject. + ContainerObject = system.ContainerObject + // ImageObject represents an image DiskUsageObject. + ImageObject = system.ImageObject + // VolumeObject represents a volume DiskUsageObject. + VolumeObject = system.VolumeObject + // BuildCacheObject represents a build-cache DiskUsageObject. + BuildCacheObject = system.BuildCacheObject +) + +// DiskUsageOptions holds parameters for system disk usage query. +type DiskUsageOptions = system.DiskUsageOptions + +// DiskUsage contains response of Engine API: +// GET "/system/df" +type DiskUsage = system.DiskUsage + +// PushResult contains the tag, manifest digest, and manifest size from the +// push. It's used to signal this information to the trust code in the client +// so it can sign the manifest if necessary. +type PushResult = types.PushResult diff --git a/vendor/github.com/docker/docker/api/types/auxprogress/aliases.go b/vendor/github.com/docker/docker/api/types/auxprogress/aliases.go new file mode 100644 index 000000000000..9068ae6c02a4 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/auxprogress/aliases.go @@ -0,0 +1,11 @@ +package auxprogress + +import "github.com/moby/moby/api/types/auxprogress" + +// ManifestPushedInsteadOfIndex is a note that is sent when a manifest is pushed +// instead of an index. It is sent when the pushed image is an multi-platform +// index, but the whole index couldn't be pushed. +type ManifestPushedInsteadOfIndex = auxprogress.ManifestPushedInsteadOfIndex + +// ContentMissing is a note that is sent when push fails because the content is missing. +type ContentMissing = auxprogress.ContentMissing diff --git a/vendor/github.com/docker/docker/api/types/blkiodev/aliases.go b/vendor/github.com/docker/docker/api/types/blkiodev/aliases.go new file mode 100644 index 000000000000..9f257e5f8d6a --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/blkiodev/aliases.go @@ -0,0 +1,9 @@ +package blkiodev + +import "github.com/moby/moby/api/types/blkiodev" + +// WeightDevice is a structure that holds device:weight pair +type WeightDevice = blkiodev.WeightDevice + +// ThrottleDevice is a structure that holds device:rate_per_second pair +type ThrottleDevice = blkiodev.ThrottleDevice diff --git a/vendor/github.com/docker/docker/api/types/build/aliases.go b/vendor/github.com/docker/docker/api/types/build/aliases.go new file mode 100644 index 000000000000..7ffbb08958db --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/build/aliases.go @@ -0,0 +1,38 @@ +package build + +import "github.com/moby/moby/api/types/build" + +// BuilderVersion sets the version of underlying builder to use +type BuilderVersion = build.BuilderVersion + +const ( + // BuilderV1 is the first generation builder in docker daemon + BuilderV1 = build.BuilderV1 + // BuilderBuildKit is builder based on moby/buildkit project + BuilderBuildKit = build.BuilderBuildKit +) + +// Result contains the image id of a successful build. +type Result = build.Result + +// ImageBuildOptions holds the information +// necessary to build images. +type ImageBuildOptions = build.ImageBuildOptions + +// ImageBuildOutput defines configuration for exporting a build result +type ImageBuildOutput = build.ImageBuildOutput + +// ImageBuildResponse holds information +// returned by a server after building +// an image. +type ImageBuildResponse = build.ImageBuildResponse + +// CacheRecord contains information about a build cache record. +type CacheRecord = build.CacheRecord + +// CachePruneOptions hold parameters to prune the build cache. +type CachePruneOptions = build.CachePruneOptions + +// CachePruneReport contains the response for Engine API: +// POST "/build/prune" +type CachePruneReport = build.CachePruneReport diff --git a/vendor/github.com/docker/docker/api/types/build/disk_usage.go b/vendor/github.com/docker/docker/api/types/build/disk_usage.go index e969b6d615f2..cfd7333272c4 100644 --- a/vendor/github.com/docker/docker/api/types/build/disk_usage.go +++ b/vendor/github.com/docker/docker/api/types/build/disk_usage.go @@ -1,6 +1,8 @@ package build // CacheDiskUsage contains disk usage for the build cache. +// +// Deprecated: this type is no longer used and will be removed in the next release. type CacheDiskUsage struct { TotalSize int64 Reclaimable int64 diff --git a/vendor/github.com/docker/docker/api/types/checkpoint/aliases.go b/vendor/github.com/docker/docker/api/types/checkpoint/aliases.go new file mode 100644 index 000000000000..ae9f8e27f3e9 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/checkpoint/aliases.go @@ -0,0 +1,15 @@ +package checkpoint + +import "github.com/moby/moby/api/types/checkpoint" + +// Summary represents the details of a checkpoint when listing endpoints. +type Summary = checkpoint.Summary + +// CreateOptions holds parameters to create a checkpoint from a container. +type CreateOptions = checkpoint.CreateOptions + +// ListOptions holds parameters to list checkpoints for a container. +type ListOptions = checkpoint.ListOptions + +// DeleteOptions holds parameters to delete a checkpoint from a container. +type DeleteOptions = checkpoint.DeleteOptions diff --git a/vendor/github.com/docker/docker/api/types/client.go b/vendor/github.com/docker/docker/api/types/client.go deleted file mode 100644 index 42fe03ecca89..000000000000 --- a/vendor/github.com/docker/docker/api/types/client.go +++ /dev/null @@ -1,85 +0,0 @@ -package types - -import ( - "bufio" - "context" - "net" -) - -// NewHijackedResponse initializes a [HijackedResponse] type. -func NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse { - return HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType} -} - -// HijackedResponse holds connection information for a hijacked request. -type HijackedResponse struct { - mediaType string - Conn net.Conn - Reader *bufio.Reader -} - -// Close closes the hijacked connection and reader. -func (h *HijackedResponse) Close() { - h.Conn.Close() -} - -// MediaType let client know if HijackedResponse hold a raw or multiplexed stream. -// returns false if HTTP Content-Type is not relevant, and container must be inspected -func (h *HijackedResponse) MediaType() (string, bool) { - if h.mediaType == "" { - return "", false - } - return h.mediaType, true -} - -// CloseWriter is an interface that implements structs -// that close input streams to prevent from writing. -type CloseWriter interface { - CloseWrite() error -} - -// CloseWrite closes a readWriter for writing. -func (h *HijackedResponse) CloseWrite() error { - if conn, ok := h.Conn.(CloseWriter); ok { - return conn.CloseWrite() - } - return nil -} - -// PluginRemoveOptions holds parameters to remove plugins. -type PluginRemoveOptions struct { - Force bool -} - -// PluginEnableOptions holds parameters to enable plugins. -type PluginEnableOptions struct { - Timeout int -} - -// PluginDisableOptions holds parameters to disable plugins. -type PluginDisableOptions struct { - Force bool -} - -// 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 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 -} - -// PluginCreateOptions hold all options to plugin create. -type PluginCreateOptions struct { - RepoName string -} diff --git a/vendor/github.com/docker/docker/api/types/container/aliases.go b/vendor/github.com/docker/docker/api/types/container/aliases.go new file mode 100644 index 000000000000..76469dd941c8 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/aliases.go @@ -0,0 +1,419 @@ +package container + +import ( + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" +) + +// ChangeType Kind of change +// +// Can be one of: +// +// - `0`: Modified ("C") +// - `1`: Added ("A") +// - `2`: Deleted ("D") +// +// swagger:model ChangeType +type ChangeType = container.ChangeType + +const ( + // ChangeModify represents the modify operation. + ChangeModify = container.ChangeModify + // ChangeAdd represents the add operation. + ChangeAdd = container.ChangeAdd + // ChangeDelete represents the delete operation. + ChangeDelete = container.ChangeDelete +) + +// CommitResponse response for the commit API call, containing the ID of the +// image that was produced. +type CommitResponse = container.CommitResponse + +// MinimumDuration puts a minimum on user configured duration. +// This is to prevent API error on time unit. For example, API may +// set 3 as healthcheck interval with intention of 3 seconds, but +// Docker interprets it as 3 nanoseconds. +const MinimumDuration = container.MinimumDuration + +// StopOptions holds the options to stop or restart a container. +type StopOptions = container.StopOptions + +// HealthConfig holds configuration settings for the HEALTHCHECK feature. +type HealthConfig = container.HealthConfig + +// Config contains the configuration data about a container. +// It should hold only portable information about the container. +// Here, "portable" means "independent from the host we are running on". +// Non-portable information *should* appear in HostConfig. +// All fields added to this struct must be marked `omitempty` to keep getting +// predictable hashes from the old `v1Compatibility` configuration. +type Config = container.Config + +// ContainerUpdateOKBody OK response to ContainerUpdate operation +// +// Deprecated: use [container.UpdateResponse]. This alias will be removed in the next release. +type ContainerUpdateOKBody = container.UpdateResponse + +// ContainerTopOKBody OK response to ContainerTop operation +// +// Deprecated: use [container.TopResponse]. This alias will be removed in the next release. +type ContainerTopOKBody = container.TopResponse + +// PruneReport contains the response for Engine API: +// POST "/containers/prune" +type PruneReport = container.PruneReport + +// PathStat is used to encode the header from +// GET "/containers/{name:.*}/archive" +// "Name" is the file or directory name. +type PathStat = container.PathStat + +// CopyToContainerOptions holds information +// about files to copy into a container +type CopyToContainerOptions = container.CopyToContainerOptions + +// StatsResponseReader wraps an io.ReadCloser to read (a stream of) stats +// for a container, as produced by the GET "/stats" endpoint. +// +// The OSType field is set to the server's platform to allow +// platform-specific handling of the response. +// +// TODO(thaJeztah): remove this wrapper, and make OSType part of [StatsResponse]. +type StatsResponseReader = client.StatsResponseReader + +// MountPoint represents a mount point configuration inside the container. +// This is used for reporting the mountpoints in use by a container. +type MountPoint = container.MountPoint + +// State stores container's running state +// it's part of ContainerJSONBase and returned by "inspect" command +type State = container.State + +// Summary contains response of Engine API: +// GET "/containers/json" +type Summary = container.Summary + +// 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 = container.ContainerJSONBase + +// InspectResponse is the response for the GET "/containers/{name:.*}/json" +// endpoint. +type InspectResponse = container.InspectResponse + +// CreateRequest is the request message sent to the server for container +// create calls. It is a config wrapper that holds the container [Config] +// (portable) and the corresponding [HostConfig] (non-portable) and +// [network.NetworkingConfig]. +type CreateRequest = container.CreateRequest + +// CreateResponse ContainerCreateResponse +// +// OK response to ContainerCreate operation +// swagger:model CreateResponse +type CreateResponse = container.CreateResponse + +// ExecCreateResponse is the response for a successful exec-create request. +// It holds the ID of the exec that was created. +// +// TODO(thaJeztah): make this a distinct type. +type ExecCreateResponse = container.ExecCreateResponse + +// ExecOptions is a small subset of the Config struct that holds the configuration +// for the exec feature of docker. +type ExecOptions = container.ExecOptions + +// ExecStartOptions is a temp struct used by execStart +// Config fields is part of ExecConfig in runconfig package +type ExecStartOptions = container.ExecStartOptions + +// ExecAttachOptions is a temp struct used by execAttach. +// +// TODO(thaJeztah): make this a separate type; ContainerExecAttach does not use the Detach option, and cannot run detached. +type ExecAttachOptions = container.ExecAttachOptions + +// ExecInspect holds information returned by exec inspect. +type ExecInspect = container.ExecInspect + +// FilesystemChange Change in the container's filesystem. +type FilesystemChange = container.FilesystemChange + +// HealthStatus is a string representation of the container's health. +// +// It currently is an alias for string, but may become a distinct type in future. +type HealthStatus = container.HealthStatus + +// Health states +const ( + NoHealthcheck = container.NoHealthcheck // Indicates there is no healthcheck + Starting = container.Starting // Starting indicates that the container is not yet ready + Healthy = container.Healthy // Healthy indicates that the container is running correctly + Unhealthy = container.Unhealthy // Unhealthy indicates that the container has a problem +) + +// Health stores information about the container's healthcheck results +type Health = container.Health + +// HealthcheckResult stores information about a single run of a healthcheck probe +type HealthcheckResult = container.HealthcheckResult + +// ValidateHealthStatus checks if the provided string is a valid +// container [container.HealthStatus]. +func ValidateHealthStatus(s container.HealthStatus) error { + return container.ValidateHealthStatus(s) +} + +// CgroupnsMode represents the cgroup namespace mode of the container +type CgroupnsMode = container.CgroupnsMode + +// cgroup namespace modes for containers +const ( + CgroupnsModeEmpty = container.CgroupnsModeEmpty + CgroupnsModePrivate = container.CgroupnsModePrivate + CgroupnsModeHost = container.CgroupnsModeHost +) + +// Isolation represents the isolation technology of a container. The supported +// values are platform specific +type Isolation = container.Isolation + +// Isolation modes for containers +const ( + IsolationEmpty = container.IsolationEmpty // IsolationEmpty is unspecified (same behavior as default) + IsolationDefault = container.IsolationDefault // IsolationDefault is the default isolation mode on current daemon + IsolationProcess = container.IsolationProcess // IsolationProcess is process isolation mode + IsolationHyperV = container.IsolationHyperV // IsolationHyperV is HyperV isolation mode +) + +// IpcMode represents the container ipc stack. +type IpcMode = container.IpcMode + +// IpcMode constants +const ( + IPCModeNone = container.IPCModeNone + IPCModeHost = container.IPCModeHost + IPCModeContainer = container.IPCModeContainer + IPCModePrivate = container.IPCModePrivate + IPCModeShareable = container.IPCModeShareable +) + +// NetworkMode represents the container network stack. +type NetworkMode = container.NetworkMode + +// UsernsMode represents userns mode in the container. +type UsernsMode = container.UsernsMode + +// CgroupSpec represents the cgroup to use for the container. +type CgroupSpec = container.CgroupSpec + +// UTSMode represents the UTS namespace of the container. +type UTSMode = container.UTSMode + +// PidMode represents the pid namespace of the container. +type PidMode = container.PidMode + +// DeviceRequest represents a request for devices from a device driver. +// Used by GPU device drivers. +type DeviceRequest = container.DeviceRequest + +// DeviceMapping represents the device mapping between the host and the container. +type DeviceMapping = container.DeviceMapping + +// RestartPolicy represents the restart policies of the container. +type RestartPolicy = container.RestartPolicy + +type RestartPolicyMode = container.RestartPolicyMode + +const ( + RestartPolicyDisabled = container.RestartPolicyDisabled + RestartPolicyAlways = container.RestartPolicyAlways + RestartPolicyOnFailure = container.RestartPolicyOnFailure + RestartPolicyUnlessStopped = container.RestartPolicyUnlessStopped +) + +// ValidateRestartPolicy validates the given RestartPolicy. +func ValidateRestartPolicy(policy container.RestartPolicy) error { + return container.ValidateRestartPolicy(policy) +} + +// LogMode is a type to define the available modes for logging +// These modes affect how logs are handled when log messages start piling up. +type LogMode = container.LogMode + +// Available logging modes +const ( + LogModeUnset = container.LogModeUnset + LogModeBlocking = container.LogModeBlocking + LogModeNonBlock = container.LogModeNonBlock +) + +// LogConfig represents the logging configuration of the container. +type LogConfig = container.LogConfig + +// Ulimit is an alias for [units.Ulimit], which may be moving to a different +// location or become a local type. This alias is to help transitioning. +// +// Users are recommended to use this alias instead of using [units.Ulimit] directly. +type Ulimit = container.Ulimit + +// Resources contains container's resources (cgroups config, ulimits...) +type Resources = container.Resources + +// UpdateConfig holds the mutable attributes of a Container. +// Those attributes can be updated at runtime. +type UpdateConfig = container.UpdateConfig + +// HostConfig the non-portable Config structure of a container. +// Here, "non-portable" means "dependent of the host we are running on". +// Portable information *should* appear in Config. +type HostConfig = container.HostConfig + +// NetworkSettings exposes the network settings in the api +type NetworkSettings = container.NetworkSettings + +// NetworkSettingsBase holds networking state for a container when inspecting it. +type NetworkSettingsBase = container.NetworkSettingsBase + +// DefaultNetworkSettings holds network information +// during the 2 release deprecation period. +// It will be removed in Docker 1.11. +type DefaultNetworkSettings = container.DefaultNetworkSettings + +// NetworkSettingsSummary provides a summary of container's networks +// in /containers/json +type NetworkSettingsSummary = container.NetworkSettingsSummary + +// ResizeOptions holds parameters to resize a TTY. +// It can be used to resize container TTYs and +// exec process TTYs too. +type ResizeOptions = container.ResizeOptions + +// AttachOptions holds parameters to attach to a container. +type AttachOptions = container.AttachOptions + +// CommitOptions holds parameters to commit changes into a container. +type CommitOptions = container.CommitOptions + +// RemoveOptions holds parameters to remove containers. +type RemoveOptions = container.RemoveOptions + +// StartOptions holds parameters to start containers. +type StartOptions = container.StartOptions + +// ListOptions holds parameters to list containers with. +type ListOptions = container.ListOptions + +// LogsOptions holds parameters to filter logs with. +type LogsOptions = container.LogsOptions + +// Port An open port on a container +type Port = container.PortSummary + +// ContainerState is a string representation of the container's current state. +// +// It currently is an alias for string, but may become a distinct type in the future. +type ContainerState = container.ContainerState + +const ( + StateCreated = container.StateCreated // StateCreated indicates the container is created, but not (yet) started. + StateRunning = container.StateRunning // StateRunning indicates that the container is running. + StatePaused = container.StatePaused // StatePaused indicates that the container's current state is paused. + StateRestarting = container.StateRestarting // StateRestarting indicates that the container is currently restarting. + StateRemoving = container.StateRemoving // StateRemoving indicates that the container is being removed. + StateExited = container.StateExited // StateExited indicates that the container exited. + StateDead = container.StateDead // StateDead indicates that the container failed to be deleted. Containers in this state are attempted to be cleaned up when the daemon restarts. +) + +// ValidateContainerState checks if the provided string is a valid +// container [container.ContainerState]. +func ValidateContainerState(s container.ContainerState) error { + return container.ValidateContainerState(s) +} + +// ThrottlingData stores CPU throttling stats of one running container. +// Not used on Windows. +type ThrottlingData = container.ThrottlingData + +// CPUUsage stores All CPU stats aggregated since container inception. +type CPUUsage = container.CPUUsage + +// CPUStats aggregates and wraps all CPU related info of container +type CPUStats = container.CPUStats + +// MemoryStats aggregates all memory stats since container inception on Linux. +// Windows returns stats for commit and private working set only. +type MemoryStats = container.MemoryStats + +// BlkioStatEntry is one small entity to store a piece of Blkio stats +// Not used on Windows. +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. +type BlkioStats = container.BlkioStats + +// StorageStats is the disk I/O stats for read/write on Windows. +type StorageStats = container.StorageStats + +// NetworkStats aggregates the network stats of one container +type NetworkStats = container.NetworkStats + +// PidsStats contains the stats of a container's pids +type PidsStats = container.PidsStats + +// Stats is Ultimate struct aggregating all types of stats of one container +// +// Deprecated: use [StatsResponse] instead. This type will be removed in the next release. +type Stats = StatsResponse + +// StatsResponse aggregates all types of stats of one container. +type StatsResponse = container.StatsResponse + +// TopResponse ContainerTopResponse +// +// Container "top" response. +type TopResponse = container.TopResponse + +// UpdateResponse ContainerUpdateResponse +// +// Response for a successful container-update. +type UpdateResponse = container.UpdateResponse + +// WaitExitError container waiting error, if any +type WaitExitError = container.WaitExitError + +// WaitResponse ContainerWaitResponse +// +// OK response to ContainerWait operation +// swagger:model WaitResponse +type WaitResponse = container.WaitResponse + +// WaitCondition is a type used to specify a container state for which +// to wait. +type WaitCondition = container.WaitCondition + +// Possible WaitCondition Values. +// +// WaitConditionNotRunning (default) is used to wait for any of the non-running +// states: "created", "exited", "dead", "removing", or "removed". +// +// WaitConditionNextExit is used to wait for the next time the state changes +// to a non-running state. If the state is currently "created" or "exited", +// this would cause Wait() to block until either the container runs and exits +// or is removed. +// +// WaitConditionRemoved is used to wait for the container to be removed. +const ( + WaitConditionNotRunning = container.WaitConditionNotRunning + WaitConditionNextExit = container.WaitConditionNextExit + WaitConditionRemoved = container.WaitConditionRemoved +) diff --git a/vendor/github.com/docker/docker/api/types/container/disk_usage.go b/vendor/github.com/docker/docker/api/types/container/disk_usage.go index 05b6cbe9c709..d77538c2ab55 100644 --- a/vendor/github.com/docker/docker/api/types/container/disk_usage.go +++ b/vendor/github.com/docker/docker/api/types/container/disk_usage.go @@ -1,6 +1,8 @@ package container // DiskUsage contains disk usage for containers. +// +// Deprecated: this type is no longer used and will be removed in the next release. type DiskUsage struct { TotalSize int64 Reclaimable int64 diff --git a/vendor/github.com/docker/docker/api/types/container/state.go b/vendor/github.com/docker/docker/api/types/container/state.go index 78d5c4fe85c7..e5b0ecb3f55a 100644 --- a/vendor/github.com/docker/docker/api/types/container/state.go +++ b/vendor/github.com/docker/docker/api/types/container/state.go @@ -1,40 +1,5 @@ package container -import ( - "fmt" - "strings" -) - -// ContainerState is a string representation of the container's current state. -// -// It currently is an alias for string, but may become a distinct type in the future. -type ContainerState = string - -const ( - StateCreated ContainerState = "created" // StateCreated indicates the container is created, but not (yet) started. - StateRunning ContainerState = "running" // StateRunning indicates that the container is running. - StatePaused ContainerState = "paused" // StatePaused indicates that the container's current state is paused. - StateRestarting ContainerState = "restarting" // StateRestarting indicates that the container is currently restarting. - StateRemoving ContainerState = "removing" // StateRemoving indicates that the container is being removed. - StateExited ContainerState = "exited" // StateExited indicates that the container exited. - StateDead ContainerState = "dead" // StateDead indicates that the container failed to be deleted. Containers in this state are attempted to be cleaned up when the daemon restarts. -) - -var validStates = []ContainerState{ - StateCreated, StateRunning, StatePaused, StateRestarting, StateRemoving, StateExited, StateDead, -} - -// ValidateContainerState checks if the provided string is a valid -// container [ContainerState]. -func ValidateContainerState(s ContainerState) error { - switch s { - case StateCreated, StateRunning, StatePaused, StateRestarting, StateRemoving, StateExited, StateDead: - return nil - default: - return errInvalidParameter{error: fmt.Errorf("invalid value for state (%s): must be one of %s", s, strings.Join(validStates, ", "))} - } -} - // StateStatus is used to return container wait results. // Implements exec.ExitCode interface. // This type is needed as State include a sync.Mutex field which make diff --git a/vendor/github.com/docker/docker/api/types/events/aliases.go b/vendor/github.com/docker/docker/api/types/events/aliases.go new file mode 100644 index 000000000000..c29c3ee69d80 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/events/aliases.go @@ -0,0 +1,114 @@ +package events + +import "github.com/moby/moby/api/types/events" + +// Type is used for event-types. +type Type = events.Type + +// List of known event types. +const ( + BuilderEventType = events.BuilderEventType // BuilderEventType is the event type that the builder generates. + ConfigEventType = events.ConfigEventType // ConfigEventType is the event type that configs generate. + ContainerEventType = events.ContainerEventType // ContainerEventType is the event type that containers generate. + DaemonEventType = events.DaemonEventType // DaemonEventType is the event type that daemon generate. + ImageEventType = events.ImageEventType // ImageEventType is the event type that images generate. + NetworkEventType = events.NetworkEventType // NetworkEventType is the event type that networks generate. + NodeEventType = events.NodeEventType // NodeEventType is the event type that nodes generate. + PluginEventType = events.PluginEventType // PluginEventType is the event type that plugins generate. + SecretEventType = events.SecretEventType // SecretEventType is the event type that secrets generate. + ServiceEventType = events.ServiceEventType // ServiceEventType is the event type that services generate. + VolumeEventType = events.VolumeEventType // VolumeEventType is the event type that volumes generate. +) + +// Action is used for event-actions. +type Action = events.Action + +const ( + ActionCreate = events.ActionCreate + ActionStart = events.ActionStart + ActionRestart = events.ActionRestart + ActionStop = events.ActionStop + ActionCheckpoint = events.ActionCheckpoint + ActionPause = events.ActionPause + ActionUnPause = events.ActionUnPause + ActionAttach = events.ActionAttach + ActionDetach = events.ActionDetach + ActionResize = events.ActionResize + ActionUpdate = events.ActionUpdate + ActionRename = events.ActionRename + ActionKill = events.ActionKill + ActionDie = events.ActionDie + ActionOOM = events.ActionOOM + ActionDestroy = events.ActionDestroy + ActionRemove = events.ActionRemove + ActionCommit = events.ActionCommit + ActionTop = events.ActionTop + ActionCopy = events.ActionCopy + ActionArchivePath = events.ActionArchivePath + ActionExtractToDir = events.ActionExtractToDir + ActionExport = events.ActionExport + ActionImport = events.ActionImport + ActionSave = events.ActionSave + ActionLoad = events.ActionLoad + ActionTag = events.ActionTag + ActionUnTag = events.ActionUnTag + ActionPush = events.ActionPush + ActionPull = events.ActionPull + ActionPrune = events.ActionPrune + ActionDelete = events.ActionDelete + ActionEnable = events.ActionEnable + ActionDisable = events.ActionDisable + ActionConnect = events.ActionConnect + ActionDisconnect = events.ActionDisconnect + ActionReload = events.ActionReload + ActionMount = events.ActionMount + ActionUnmount = events.ActionUnmount + + // ActionExecCreate is the prefix used for exec_create events. These + // event-actions are commonly followed by a colon and space (": "), + // and the command that's defined for the exec, for example: + // + // exec_create: /bin/sh -c 'echo hello' + // + // This is far from ideal; it's a compromise to allow filtering and + // to preserve backward-compatibility. + ActionExecCreate = events.ActionExecCreate + // ActionExecStart is the prefix used for exec_create events. These + // event-actions are commonly followed by a colon and space (": "), + // and the command that's defined for the exec, for example: + // + // exec_start: /bin/sh -c 'echo hello' + // + // This is far from ideal; it's a compromise to allow filtering and + // to preserve backward-compatibility. + ActionExecStart = events.ActionExecStart + ActionExecDie = events.ActionExecDie + ActionExecDetach = events.ActionExecDetach + + // ActionHealthStatus is the prefix to use for health_status events. + // + // Health-status events can either have a pre-defined status, in which + // case the "health_status" action is followed by a colon, or can be + // "free-form", in which case they're followed by the output of the + // health-check output. + // + // This is far form ideal, and a compromise to allow filtering, and + // to preserve backward-compatibility. + ActionHealthStatus = events.ActionHealthStatus + ActionHealthStatusRunning = events.ActionHealthStatusRunning + ActionHealthStatusHealthy = events.ActionHealthStatusHealthy + ActionHealthStatusUnhealthy = events.ActionHealthStatusUnhealthy +) + +// Actor describes something that generates events, +// like a container, or a network, or a volume. +// It has a defined name and a set of attributes. +// The container attributes are its labels, other actors +// can generate these attributes from other properties. +type Actor = events.Actor + +// Message represents the information an event contains +type Message = events.Message + +// ListOptions holds parameters to filter events with. +type ListOptions = events.ListOptions diff --git a/vendor/github.com/docker/docker/api/types/filters/aliases.go b/vendor/github.com/docker/docker/api/types/filters/aliases.go new file mode 100644 index 000000000000..81fc56463cea --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/filters/aliases.go @@ -0,0 +1,35 @@ +/* +Package filters provides tools for encoding a mapping of keys to a set of +multiple values. +*/ +package filters + +import ( + "github.com/moby/moby/api/types/filters" +) + +// Args stores a mapping of keys to a set of multiple values. +type Args = filters.Args + +// KeyValuePair are used to initialize a new Args +type KeyValuePair = filters.KeyValuePair + +// Arg creates a new KeyValuePair for initializing Args +func Arg(key, value string) filters.KeyValuePair { + return filters.Arg(key, value) +} + +// NewArgs returns a new Args populated with the initial args +func NewArgs(initialArgs ...filters.KeyValuePair) filters.Args { + return filters.NewArgs(initialArgs...) +} + +// ToJSON returns the Args as a JSON encoded string +func ToJSON(a Args) (string, error) { + return filters.ToJSON(a) +} + +// FromJSON decodes a JSON encoded string into Args +func FromJSON(p string) (filters.Args, error) { + return filters.FromJSON(p) +} diff --git a/vendor/github.com/docker/docker/api/types/filters/filters_deprecated.go b/vendor/github.com/docker/docker/api/types/filters/filters_deprecated.go new file mode 100644 index 000000000000..3e9646b1e28a --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/filters/filters_deprecated.go @@ -0,0 +1,32 @@ +package filters + +import ( + "encoding/json" + + "github.com/docker/docker/api/types/versions" + "github.com/moby/moby/api/types/filters" +) + +// ToParamWithVersion encodes Args as a JSON string. If version is less than 1.22 +// then the encoded format will use an older legacy format where the values are a +// list of strings, instead of a set. +// +// Deprecated: do not use in any new code; use ToJSON instead +func ToParamWithVersion(version string, a filters.Args) (string, error) { + if a.Len() == 0 { + return "", nil + } + if version != "" && versions.LessThan(version, "1.22") { + buf, err := json.Marshal(convertArgsToSlice(a)) + return string(buf), err + } + return ToJSON(a) +} + +func convertArgsToSlice(f filters.Args) map[string][]string { + m := map[string][]string{} + for _, key := range f.Keys() { + m[key] = f.Get(key) + } + return m +} diff --git a/vendor/github.com/docker/docker/api/types/image/aliases.go b/vendor/github.com/docker/docker/api/types/image/aliases.go new file mode 100644 index 000000000000..7470ef6b7add --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/image/aliases.go @@ -0,0 +1,95 @@ +package image + +import "github.com/moby/moby/api/types/image" + +// DeleteResponse delete response +type DeleteResponse = image.DeleteResponse + +// Metadata contains engine-local data about the image. +type Metadata = image.Metadata + +// PruneReport contains the response for Engine API: +// POST "/images/prune" +type PruneReport = image.PruneReport + +// LoadResponse returns information to the client about a load process. +// +// TODO(thaJeztah): remove this type, and just use an io.ReadCloser +// +// This type was added in https://github.com/moby/moby/pull/18878, related +// to https://github.com/moby/moby/issues/19177; +// +// Make docker load to output json when the response content type is json +// Swarm hijacks the response from docker load and returns JSON rather +// than plain text like the Engine does. This makes the API library to return +// information to figure that out. +// +// However the "load" endpoint unconditionally returns JSON; +// https://github.com/moby/moby/blob/7b9d2ef6e5518a3d3f3cc418459f8df786cfbbd1/api/server/router/image/image_routes.go#L248-L255 +// +// PR https://github.com/moby/moby/pull/21959 made the response-type depend +// on whether "quiet" was set, but this logic got changed in a follow-up +// https://github.com/moby/moby/pull/25557, which made the JSON response-type +// unconditionally, but the output produced depend on whether"quiet" was set. +// +// We should deprecated the "quiet" option, as it's really a client +// responsibility. +type LoadResponse = image.LoadResponse + +// HistoryResponseItem individual image layer information in response to ImageHistory operation +type HistoryResponseItem = image.HistoryResponseItem + +// RootFS returns Image's RootFS description including the layer IDs. +type RootFS = image.RootFS + +// InspectResponse contains response of Engine API: +// GET "/images/{name:.*}/json" +type InspectResponse = image.InspectResponse + +type ManifestKind = image.ManifestKind + +const ( + ManifestKindImage = image.ManifestKindImage + ManifestKindAttestation = image.ManifestKindAttestation + ManifestKindUnknown = image.ManifestKindUnknown +) + +type ManifestSummary = image.ManifestSummary + +type ImageProperties = image.ImageProperties + +type AttestationProperties = image.AttestationProperties + +// ImportSource holds source information for ImageImport +type ImportSource = image.ImportSource + +// ImportOptions holds information to import images from the client host. +type ImportOptions = image.ImportOptions + +// CreateOptions holds information to create images. +type CreateOptions = image.CreateOptions + +// PullOptions holds information to pull images. +type PullOptions = image.PullOptions + +// PushOptions holds information to push images. +type PushOptions = image.PushOptions + +// ListOptions holds parameters to list images with. +type ListOptions = image.ListOptions + +// RemoveOptions holds parameters to remove images. +type RemoveOptions = image.RemoveOptions + +// HistoryOptions holds parameters to get image history. +type HistoryOptions = image.HistoryOptions + +// LoadOptions holds parameters to load images. +type LoadOptions = image.LoadOptions + +type InspectOptions = image.InspectOptions + +// SaveOptions holds parameters to save images. +type SaveOptions = image.SaveOptions + +type Summary = image.Summary diff --git a/vendor/github.com/docker/docker/api/types/image/disk_usage.go b/vendor/github.com/docker/docker/api/types/image/disk_usage.go index b29d925cac48..e847386a8d13 100644 --- a/vendor/github.com/docker/docker/api/types/image/disk_usage.go +++ b/vendor/github.com/docker/docker/api/types/image/disk_usage.go @@ -1,6 +1,8 @@ package image // DiskUsage contains disk usage for images. +// +// Deprecated: this type is no longer used and will be removed in the next release. type DiskUsage struct { TotalSize int64 Reclaimable int64 diff --git a/vendor/github.com/docker/docker/api/types/mount/aliases.go b/vendor/github.com/docker/docker/api/types/mount/aliases.go new file mode 100644 index 000000000000..711709990696 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/mount/aliases.go @@ -0,0 +1,77 @@ +package mount + +import "github.com/moby/moby/api/types/mount" + +// Type represents the type of a mount. +type Type = mount.Type + +// Type constants +const ( + // TypeBind is the type for mounting host dir + TypeBind = mount.TypeBind + // TypeVolume is the type for remote storage volumes + TypeVolume = mount.TypeVolume + // TypeTmpfs is the type for mounting tmpfs + TypeTmpfs = mount.TypeTmpfs + // TypeNamedPipe is the type for mounting Windows named pipes + TypeNamedPipe = mount.TypeNamedPipe + // TypeCluster is the type for Swarm Cluster Volumes. + TypeCluster = mount.TypeCluster + // TypeImage is the type for mounting another image's filesystem + TypeImage = mount.TypeImage +) + +// Mount represents a mount (volume). +type Mount = mount.Mount + +// Propagation represents the propagation of a mount. +type Propagation = mount.Propagation + +const ( + // PropagationRPrivate RPRIVATE + PropagationRPrivate = mount.PropagationRPrivate + // PropagationPrivate PRIVATE + PropagationPrivate = mount.PropagationPrivate + // PropagationRShared RSHARED + PropagationRShared = mount.PropagationRShared + // PropagationShared SHARED + PropagationShared = mount.PropagationShared + // PropagationRSlave RSLAVE + PropagationRSlave = mount.PropagationRSlave + // PropagationSlave SLAVE + PropagationSlave = mount.PropagationSlave +) + +// Propagations is the list of all valid mount propagations +var Propagations = mount.Propagations + +// Consistency represents the consistency requirements of a mount. +type Consistency = mount.Consistency + +const ( + // ConsistencyFull guarantees bind mount-like consistency + ConsistencyFull = mount.ConsistencyFull + // ConsistencyCached mounts can cache read data and FS structure + ConsistencyCached = mount.ConsistencyCached + // ConsistencyDelegated mounts can cache read and written data and structure + ConsistencyDelegated = mount.ConsistencyDelegated + // ConsistencyDefault provides "consistent" behavior unless overridden + ConsistencyDefault = mount.ConsistencyDefault +) + +// BindOptions defines options specific to mounts of type "bind". +type BindOptions = mount.BindOptions + +// VolumeOptions represents the options for a mount of type volume. +type VolumeOptions = mount.VolumeOptions + +type ImageOptions = mount.ImageOptions + +// Driver represents a volume driver. +type Driver = mount.Driver + +// TmpfsOptions defines options specific to mounts of type "tmpfs". +type TmpfsOptions = mount.TmpfsOptions + +// ClusterOptions specifies options for a Cluster volume. +type ClusterOptions = mount.ClusterOptions diff --git a/vendor/github.com/docker/docker/api/types/network/aliases.go b/vendor/github.com/docker/docker/api/types/network/aliases.go new file mode 100644 index 000000000000..79666e99b1a3 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/network/aliases.go @@ -0,0 +1,106 @@ +package network + +import ( + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/network" +) + +// CreateResponse NetworkCreateResponse +// +// OK response to NetworkCreate operation +type CreateResponse = network.CreateResponse + +// EndpointSettings stores the network endpoint details +type EndpointSettings = network.EndpointSettings + +// EndpointIPAMConfig represents IPAM configurations for the endpoint +type EndpointIPAMConfig = network.EndpointIPAMConfig + +// NetworkSubnet describes a user-defined subnet for a specific network. It's only used to validate if an +// EndpointIPAMConfig is valid for a specific network. +type NetworkSubnet = network.NetworkSubnet + +// IPAM represents IP Address Management +type IPAM = network.IPAM + +// IPAMConfig represents IPAM configurations +type IPAMConfig = network.IPAMConfig + +// ValidateIPAM checks whether the network's IPAM passed as argument is valid. It returns a joinError of the list of +// errors found. +func ValidateIPAM(ipam *network.IPAM, enableIPv6 bool) error { + return network.ValidateIPAM(ipam, enableIPv6) +} + +const ( + // NetworkDefault is a platform-independent alias to choose the platform-specific default network stack. + NetworkDefault = network.NetworkDefault + // NetworkHost is the name of the predefined network used when the NetworkMode host is selected (only available on Linux) + NetworkHost = network.NetworkHost + // NetworkNone is the name of the predefined network used when the NetworkMode none is selected (available on both Linux and Windows) + NetworkNone = network.NetworkNone + // NetworkBridge is the name of the default network on Linux + NetworkBridge = network.NetworkBridge + // NetworkNat is the name of the default network on Windows + NetworkNat = network.NetworkNat +) + +// CreateRequest is the request message sent to the server for network create call. +type CreateRequest = network.CreateRequest + +// CreateOptions holds options to create a network. +type CreateOptions = network.CreateOptions + +// ListOptions holds parameters to filter the list of networks with. +type ListOptions = network.ListOptions + +// InspectOptions holds parameters to inspect network. +type InspectOptions = network.InspectOptions + +// ConnectOptions represents the data to be used to connect a container to the +// network. +type ConnectOptions = network.ConnectOptions + +// DisconnectOptions represents the data to be used to disconnect a container +// from the network. +type DisconnectOptions = network.DisconnectOptions + +// Inspect is the body of the "get network" http response message. +type Inspect = network.Inspect + +// Summary is used as response when listing networks. It currently is an alias +// for [Inspect], but may diverge in the future, as not all information may +// be included when listing networks. +type Summary = network.Summary + +// Address represents an IP address +type Address = network.Address + +// PeerInfo represents one peer of an overlay network +type PeerInfo = network.PeerInfo + +// Task carries the information about one backend task +type Task = network.Task + +// ServiceInfo represents service parameters with the list of service's tasks +type ServiceInfo = network.ServiceInfo + +// EndpointResource contains network resources allocated and used for a +// container in a network. +type EndpointResource = network.EndpointResource + +// NetworkingConfig represents the container's networking configuration for each of its interfaces +// Carries the networking configs specified in the `docker run` and `docker network connect` commands +type NetworkingConfig = network.NetworkingConfig + +// ConfigReference specifies the source which provides a network's configuration +type ConfigReference = network.ConfigReference + +// ValidateFilters validates the list of filter args with the available filters. +func ValidateFilters(filter filters.Args) error { + return network.ValidateFilters(filter) +} + +// PruneReport contains the response for Engine API: +// POST "/networks/prune" +type PruneReport = network.PruneReport diff --git a/vendor/github.com/docker/docker/api/types/plugin_interface_type.go b/vendor/github.com/docker/docker/api/types/plugin_interface_type.go deleted file mode 100644 index c82f204e8708..000000000000 --- a/vendor/github.com/docker/docker/api/types/plugin_interface_type.go +++ /dev/null @@ -1,21 +0,0 @@ -package types - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -// PluginInterfaceType plugin interface type -// swagger:model PluginInterfaceType -type PluginInterfaceType struct { - - // capability - // Required: true - Capability string `json:"Capability"` - - // prefix - // Required: true - Prefix string `json:"Prefix"` - - // version - // Required: true - Version string `json:"Version"` -} diff --git a/vendor/github.com/docker/docker/api/types/plugin_responses.go b/vendor/github.com/docker/docker/api/types/plugin_responses.go deleted file mode 100644 index 18f743fcde3a..000000000000 --- a/vendor/github.com/docker/docker/api/types/plugin_responses.go +++ /dev/null @@ -1,71 +0,0 @@ -package types - -import ( - "encoding/json" - "fmt" - "sort" -) - -// PluginsListResponse contains the response for the Engine API -type PluginsListResponse []*Plugin - -// UnmarshalJSON implements json.Unmarshaler for PluginInterfaceType -func (t *PluginInterfaceType) UnmarshalJSON(p []byte) error { - versionIndex := len(p) - prefixIndex := 0 - if len(p) < 2 || p[0] != '"' || p[len(p)-1] != '"' { - return fmt.Errorf("%q is not a plugin interface type", p) - } - p = p[1 : len(p)-1] -loop: - for i, b := range p { - switch b { - case '.': - prefixIndex = i - case '/': - versionIndex = i - break loop - } - } - t.Prefix = string(p[:prefixIndex]) - t.Capability = string(p[prefixIndex+1 : versionIndex]) - if versionIndex < len(p) { - t.Version = string(p[versionIndex+1:]) - } - return nil -} - -// MarshalJSON implements json.Marshaler for PluginInterfaceType -func (t *PluginInterfaceType) MarshalJSON() ([]byte, error) { - return json.Marshal(t.String()) -} - -// String implements fmt.Stringer for PluginInterfaceType -func (t PluginInterfaceType) String() string { - return fmt.Sprintf("%s.%s/%s", t.Prefix, t.Capability, t.Version) -} - -// PluginPrivilege describes a permission the user has to accept -// upon installing a plugin. -type PluginPrivilege struct { - Name string - Description string - Value []string -} - -// PluginPrivileges is a list of PluginPrivilege -type PluginPrivileges []PluginPrivilege - -func (s PluginPrivileges) Len() int { - return len(s) -} - -func (s PluginPrivileges) Less(i, j int) bool { - return s[i].Name < s[j].Name -} - -func (s PluginPrivileges) Swap(i, j int) { - sort.Strings(s[i].Value) - sort.Strings(s[j].Value) - s[i], s[j] = s[j], s[i] -} diff --git a/vendor/github.com/docker/docker/api/types/registry/aliases.go b/vendor/github.com/docker/docker/api/types/registry/aliases.go new file mode 100644 index 000000000000..f2eb1e8a5620 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/registry/aliases.go @@ -0,0 +1,111 @@ +// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: +//go:build go1.23 + +package registry + +import ( + "encoding/json" + "fmt" + "io" + + "github.com/moby/moby/api/types/registry" +) + +// AuthHeader is the name of the header used to send encoded registry +// authorization credentials for registry operations (push/pull). +const AuthHeader = registry.AuthHeader + +// 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 = registry.RequestAuthConfig + +// AuthConfig contains authorization information for connecting to a Registry. +type AuthConfig = registry.AuthConfig + +// EncodeAuthConfig serializes the auth configuration as a base64url encoded +// ([RFC4648, section 5]) JSON string for sending through the X-Registry-Auth header. +// +// [RFC4648, section 5]: https://tools.ietf.org/html/rfc4648#section-5 +func EncodeAuthConfig(authConfig registry.AuthConfig) (string, error) { + return registry.EncodeAuthConfig(authConfig) +} + +// DecodeAuthConfig decodes base64url encoded ([RFC4648, section 5]) JSON +// authentication information as sent through the X-Registry-Auth header. +// +// This function always returns an [AuthConfig], even if an error occurs. It is up +// to the caller to decide if authentication is required, and if the error can +// be ignored. +// +// [RFC4648, section 5]: https://tools.ietf.org/html/rfc4648#section-5 +func DecodeAuthConfig(authEncoded string) (*registry.AuthConfig, error) { + return registry.DecodeAuthConfig(authEncoded) +} + +// DecodeAuthConfigBody decodes authentication information as sent as JSON in the +// body of a request. This function is to provide backward compatibility with old +// clients and API versions. Current clients and API versions expect authentication +// to be provided through the X-Registry-Auth header. +// +// Like [DecodeAuthConfig], this function always returns an [AuthConfig], even if an +// error occurs. It is up to the caller to decide if authentication is required, +// and if the error can be ignored. +func DecodeAuthConfigBody(rdr io.ReadCloser) (*registry.AuthConfig, error) { + return decodeAuthConfigFromReader(rdr) +} + +func decodeAuthConfigFromReader(rdr io.Reader) (*registry.AuthConfig, error) { + authConfig := ®istry.AuthConfig{} + if err := json.NewDecoder(rdr).Decode(authConfig); err != nil { + // always return an (empty) AuthConfig to increase compatibility with + // the existing API. + return ®istry.AuthConfig{}, invalid(err) + } + return authConfig, nil +} + +func invalid(err error) error { + return errInvalidParameter{fmt.Errorf("invalid X-Registry-Auth header: %w", err)} +} + +type errInvalidParameter struct{ error } + +func (errInvalidParameter) InvalidParameter() {} + +func (e errInvalidParameter) Cause() error { return e.error } + +func (e errInvalidParameter) Unwrap() error { return e.error } + +// AuthenticateOKBody authenticate o k body +type AuthenticateOKBody = registry.AuthenticateOKBody + +// ServiceConfig stores daemon registry services configuration. +type ServiceConfig = registry.ServiceConfig + +// NetIPNet is the net.IPNet type, which can be marshalled and +// unmarshalled to JSON +type NetIPNet = registry.NetIPNet + +// IndexInfo contains information about a registry +type IndexInfo = registry.IndexInfo + +// DistributionInspect describes the result obtained from contacting the +// registry to retrieve image metadata +type DistributionInspect = registry.DistributionInspect + +// SearchOptions holds parameters to search images with. +type SearchOptions = registry.SearchOptions + +// SearchResult describes a search result returned from a registry +type SearchResult = registry.SearchResult + +// SearchResults lists a collection search results returned from a registry +type SearchResults = registry.SearchResults diff --git a/vendor/github.com/docker/docker/api/types/strslice/strslice.go b/vendor/github.com/docker/docker/api/types/strslice/strslice.go deleted file mode 100644 index bad493fb89fd..000000000000 --- a/vendor/github.com/docker/docker/api/types/strslice/strslice.go +++ /dev/null @@ -1,30 +0,0 @@ -package strslice - -import "encoding/json" - -// StrSlice represents a string or an array of strings. -// We need to override the json decoder to accept both options. -type StrSlice []string - -// UnmarshalJSON decodes the byte slice whether it's a string or an array of -// strings. This method is needed to implement json.Unmarshaler. -func (e *StrSlice) UnmarshalJSON(b []byte) error { - if len(b) == 0 { - // With no input, we preserve the existing value by returning nil and - // leaving the target alone. This allows defining default values for - // the type. - return nil - } - - p := make([]string, 0, 1) - if err := json.Unmarshal(b, &p); err != nil { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - p = append(p, s) - } - - *e = p - return nil -} diff --git a/vendor/github.com/docker/docker/api/types/swarm/aliases.go b/vendor/github.com/docker/docker/api/types/swarm/aliases.go new file mode 100644 index 000000000000..7cc558138494 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/swarm/aliases.go @@ -0,0 +1,576 @@ +package swarm + +import "github.com/moby/moby/api/types/swarm" + +// Version represents the internal object version. +type Version = swarm.Version + +// Meta is a base object inherited by most of the other once. +type Meta = swarm.Meta + +// Annotations represents how to describe an object. +type Annotations = swarm.Annotations + +// Driver represents a driver (network, logging, secrets backend). +type Driver = swarm.Driver + +// TLSInfo represents the TLS information about what CA certificate is trusted, +// and who the issuer for a TLS certificate is +type TLSInfo = swarm.TLSInfo + +// Config represents a config. +type Config = swarm.Config + +// ConfigSpec represents a config specification from a config in swarm +type ConfigSpec = swarm.ConfigSpec + +// ConfigReferenceFileTarget is a file target in a config reference +type ConfigReferenceFileTarget = swarm.ConfigReferenceFileTarget + +// ConfigReferenceRuntimeTarget is a target for a config specifying that it +// isn't mounted into the container but instead has some other purpose. +type ConfigReferenceRuntimeTarget = swarm.ConfigReferenceRuntimeTarget + +// ConfigReference is a reference to a config in swarm +type ConfigReference = swarm.ConfigReference + +// ConfigCreateResponse contains the information returned to a client +// on the creation of a new config. +type ConfigCreateResponse = swarm.ConfigCreateResponse + +// ConfigListOptions holds parameters to list configs +type ConfigListOptions = swarm.ConfigListOptions + +// DNSConfig specifies DNS related configurations in resolver configuration file (resolv.conf) +type DNSConfig = swarm.DNSConfig + +// SELinuxContext contains the SELinux labels of the container. +type SELinuxContext = swarm.SELinuxContext + +// SeccompMode is the type used for the enumeration of possible seccomp modes +// in SeccompOpts +type SeccompMode = swarm.SeccompMode + +const ( + SeccompModeDefault = swarm.SeccompModeDefault + SeccompModeUnconfined = swarm.SeccompModeUnconfined + SeccompModeCustom = swarm.SeccompModeCustom +) + +// SeccompOpts defines the options for configuring seccomp on a swarm-managed +// container. +type SeccompOpts = swarm.SeccompOpts + +// AppArmorMode is type used for the enumeration of possible AppArmor modes in +// AppArmorOpts +type AppArmorMode = swarm.AppArmorMode + +const ( + AppArmorModeDefault = swarm.AppArmorModeDefault + AppArmorModeDisabled = swarm.AppArmorModeDisabled +) + +// AppArmorOpts defines the options for configuring AppArmor on a swarm-managed +// container. Currently, custom AppArmor profiles are not supported. +type AppArmorOpts = swarm.AppArmorOpts + +// CredentialSpec for managed service account (Windows only) +type CredentialSpec = swarm.CredentialSpec + +// Privileges defines the security options for the container. +type Privileges = swarm.Privileges + +// ContainerSpec represents the spec of a container. +type ContainerSpec = swarm.ContainerSpec + +// Endpoint represents an endpoint. +type Endpoint = swarm.Endpoint + +// EndpointSpec represents the spec of an endpoint. +type EndpointSpec = swarm.EndpointSpec + +// ResolutionMode represents a resolution mode. +type ResolutionMode = swarm.ResolutionMode + +const ( + // ResolutionModeVIP VIP + ResolutionModeVIP = swarm.ResolutionModeVIP + // ResolutionModeDNSRR DNSRR + ResolutionModeDNSRR = swarm.ResolutionModeDNSRR +) + +// PortConfig represents the config of a port. +type PortConfig = swarm.PortConfig + +// PortConfigPublishMode represents the mode in which the port is to +// be published. +type PortConfigPublishMode = swarm.PortConfigPublishMode + +const ( + // PortConfigPublishModeIngress is used for ports published + // for ingress load balancing using routing mesh. + PortConfigPublishModeIngress = swarm.PortConfigPublishModeIngress + // PortConfigPublishModeHost is used for ports published + // for direct host level access on the host where the task is running. + PortConfigPublishModeHost = swarm.PortConfigPublishModeHost +) + +// PortConfigProtocol represents the protocol of a port. +type PortConfigProtocol = swarm.PortConfigProtocol + +const ( + // PortConfigProtocolTCP TCP + PortConfigProtocolTCP = swarm.PortConfigProtocolTCP + // PortConfigProtocolUDP UDP + PortConfigProtocolUDP = swarm.PortConfigProtocolUDP + // PortConfigProtocolSCTP SCTP + PortConfigProtocolSCTP = swarm.PortConfigProtocolSCTP +) + +// EndpointVirtualIP represents the virtual ip of a port. +type EndpointVirtualIP = swarm.EndpointVirtualIP + +// Network represents a network. +type Network = swarm.Network + +// NetworkSpec represents the spec of a network. +type NetworkSpec = swarm.NetworkSpec + +// NetworkAttachmentConfig represents the configuration of a network attachment. +type NetworkAttachmentConfig = swarm.NetworkAttachmentConfig + +// NetworkAttachment represents a network attachment. +type NetworkAttachment = swarm.NetworkAttachment + +// IPAMOptions represents ipam options. +type IPAMOptions = swarm.IPAMOptions + +// IPAMConfig represents ipam configuration. +type IPAMConfig = swarm.IPAMConfig + +// Node represents a node. +type Node = swarm.Node + +// NodeSpec represents the spec of a node. +type NodeSpec = swarm.NodeSpec + +// NodeRole represents the role of a node. +type NodeRole = swarm.NodeRole + +const ( + // NodeRoleWorker WORKER + NodeRoleWorker = swarm.NodeRoleWorker + // NodeRoleManager MANAGER + NodeRoleManager = swarm.NodeRoleManager +) + +// NodeAvailability represents the availability of a node. +type NodeAvailability = swarm.NodeAvailability + +const ( + // NodeAvailabilityActive ACTIVE + NodeAvailabilityActive = swarm.NodeAvailabilityActive + // NodeAvailabilityPause PAUSE + NodeAvailabilityPause = swarm.NodeAvailabilityPause + // NodeAvailabilityDrain DRAIN + NodeAvailabilityDrain = swarm.NodeAvailabilityDrain +) + +// NodeDescription represents the description of a node. +type NodeDescription = swarm.NodeDescription + +// Platform represents the platform (Arch/OS). +type Platform = swarm.Platform + +// EngineDescription represents the description of an engine. +type EngineDescription = swarm.EngineDescription + +// NodeCSIInfo represents information about a CSI plugin available on the node +type NodeCSIInfo = swarm.NodeCSIInfo + +// PluginDescription represents the description of an engine plugin. +type PluginDescription = swarm.PluginDescription + +// NodeStatus represents the status of a node. +type NodeStatus = swarm.NodeStatus + +// Reachability represents the reachability of a node. +type Reachability = swarm.Reachability + +const ( + // ReachabilityUnknown UNKNOWN + ReachabilityUnknown = swarm.ReachabilityUnknown + // ReachabilityUnreachable UNREACHABLE + ReachabilityUnreachable = swarm.ReachabilityUnreachable + // ReachabilityReachable REACHABLE + ReachabilityReachable = swarm.ReachabilityReachable +) + +// ManagerStatus represents the status of a manager. +type ManagerStatus = swarm.ManagerStatus + +// NodeState represents the state of a node. +type NodeState = swarm.NodeState + +const ( + // NodeStateUnknown UNKNOWN + NodeStateUnknown = swarm.NodeStateUnknown + // NodeStateDown DOWN + NodeStateDown = swarm.NodeStateDown + // NodeStateReady READY + NodeStateReady = swarm.NodeStateReady + // NodeStateDisconnected DISCONNECTED + NodeStateDisconnected = swarm.NodeStateDisconnected +) + +// Topology defines the CSI topology of this node. This type is a duplicate of +// github.com/docker/docker/api/types.Topology. Because the type definition +// is so simple and to avoid complicated structure or circular imports, we just +// duplicate it here. See that type for full documentation +type Topology = swarm.Topology + +// NodeListOptions holds parameters to list nodes with. +type NodeListOptions = swarm.NodeListOptions + +// NodeRemoveOptions holds parameters to remove nodes with. +type NodeRemoveOptions = swarm.NodeRemoveOptions + +// RuntimeType is the type of runtime used for the TaskSpec +type RuntimeType = swarm.RuntimeType + +// RuntimeURL is the proto type url +type RuntimeURL = swarm.RuntimeURL + +const ( + // RuntimeContainer is the container based runtime + RuntimeContainer = swarm.RuntimeContainer + // RuntimePlugin is the plugin based runtime + RuntimePlugin = swarm.RuntimePlugin + // RuntimeNetworkAttachment is the network attachment runtime + RuntimeNetworkAttachment = swarm.RuntimeNetworkAttachment + + // RuntimeURLContainer is the proto url for the container type + RuntimeURLContainer = swarm.RuntimeURLContainer + // RuntimeURLPlugin is the proto url for the plugin type + RuntimeURLPlugin = swarm.RuntimeURLPlugin +) + +// NetworkAttachmentSpec represents the runtime spec type for network +// attachment tasks +type NetworkAttachmentSpec = swarm.NetworkAttachmentSpec + +// Secret represents a secret. +type Secret = swarm.Secret + +// SecretSpec represents a secret specification from a secret in swarm +type SecretSpec = swarm.SecretSpec + +// SecretReferenceFileTarget is a file target in a secret reference +type SecretReferenceFileTarget = swarm.SecretReferenceFileTarget + +// SecretReference is a reference to a secret in swarm +type SecretReference = swarm.SecretReference + +// SecretCreateResponse contains the information returned to a client +// on the creation of a new secret. +type SecretCreateResponse = swarm.SecretCreateResponse + +// SecretListOptions holds parameters to list secrets +type SecretListOptions = swarm.SecretListOptions + +// Service represents a service. +type Service = swarm.Service + +// ServiceSpec represents the spec of a service. +type ServiceSpec = swarm.ServiceSpec + +// ServiceMode represents the mode of a service. +type ServiceMode = swarm.ServiceMode + +// UpdateState is the state of a service update. +type UpdateState = swarm.UpdateState + +const ( + // UpdateStateUpdating is the updating state. + UpdateStateUpdating = swarm.UpdateStateUpdating + // UpdateStatePaused is the paused state. + UpdateStatePaused = swarm.UpdateStatePaused + // UpdateStateCompleted is the completed state. + UpdateStateCompleted = swarm.UpdateStateCompleted + // UpdateStateRollbackStarted is the state with a rollback in progress. + UpdateStateRollbackStarted = swarm.UpdateStateRollbackStarted + // UpdateStateRollbackPaused is the state with a rollback in progress. + UpdateStateRollbackPaused = swarm.UpdateStateRollbackPaused + // UpdateStateRollbackCompleted is the state with a rollback in progress. + UpdateStateRollbackCompleted = swarm.UpdateStateRollbackCompleted +) + +// UpdateStatus reports the status of a service update. +type UpdateStatus = swarm.UpdateStatus + +// ReplicatedService is a kind of ServiceMode. +type ReplicatedService = swarm.ReplicatedService + +// GlobalService is a kind of ServiceMode. +type GlobalService = swarm.GlobalService + +// ReplicatedJob is the a type of Service which executes a defined Tasks +// in parallel until the specified number of Tasks have succeeded. +type ReplicatedJob = swarm.ReplicatedJob + +// GlobalJob is the type of a Service which executes a Task on every Node +// matching the Service's placement constraints. These tasks run to completion +// and then exit. +// +// This type is deliberately empty. +type GlobalJob = swarm.GlobalJob + +const ( + // UpdateFailureActionPause PAUSE + UpdateFailureActionPause = swarm.UpdateFailureActionPause + // UpdateFailureActionContinue CONTINUE + UpdateFailureActionContinue = swarm.UpdateFailureActionContinue + // UpdateFailureActionRollback ROLLBACK + UpdateFailureActionRollback = swarm.UpdateFailureActionRollback + + // UpdateOrderStopFirst STOP_FIRST + UpdateOrderStopFirst = swarm.UpdateOrderStopFirst + // UpdateOrderStartFirst START_FIRST + UpdateOrderStartFirst = swarm.UpdateOrderStartFirst +) + +// UpdateConfig represents the update configuration. +type UpdateConfig = swarm.UpdateConfig + +// ServiceStatus represents the number of running tasks in a service and the +// number of tasks desired to be running. +type ServiceStatus = swarm.ServiceStatus + +// JobStatus is the status of a job-type service. +type JobStatus = swarm.JobStatus + +// ServiceCreateOptions contains the options to use when creating a service. +type ServiceCreateOptions = swarm.ServiceCreateOptions + +// Values for RegistryAuthFrom in ServiceUpdateOptions +const ( + RegistryAuthFromSpec = swarm.RegistryAuthFromSpec + RegistryAuthFromPreviousSpec = swarm.RegistryAuthFromPreviousSpec +) + +// ServiceUpdateOptions contains the options to be used for updating services. +type ServiceUpdateOptions = swarm.ServiceUpdateOptions + +// ServiceListOptions holds parameters to list services with. +type ServiceListOptions = swarm.ServiceListOptions + +// ServiceInspectOptions holds parameters related to the "service inspect" +// operation. +type ServiceInspectOptions = swarm.ServiceInspectOptions + +// ServiceCreateResponse contains the information returned to a client on the +// creation of a new service. +type ServiceCreateResponse = swarm.ServiceCreateResponse + +// ServiceUpdateResponse service update response +type ServiceUpdateResponse = swarm.ServiceUpdateResponse + +// ClusterInfo represents info about the cluster for outputting in "info" +// it contains the same information as "Swarm", but without the JoinTokens +type ClusterInfo = swarm.ClusterInfo + +// Swarm represents a swarm. +type Swarm = swarm.Swarm + +// JoinTokens contains the tokens workers and managers need to join the swarm. +type JoinTokens = swarm.JoinTokens + +// Spec represents the spec of a swarm. +type Spec = swarm.Spec + +// OrchestrationConfig represents orchestration configuration. +type OrchestrationConfig = swarm.OrchestrationConfig + +// TaskDefaults parameterizes cluster-level task creation with default values. +type TaskDefaults = swarm.TaskDefaults + +// EncryptionConfig controls at-rest encryption of data and keys. +type EncryptionConfig = swarm.EncryptionConfig + +// RaftConfig represents raft configuration. +type RaftConfig = swarm.RaftConfig + +// DispatcherConfig represents dispatcher configuration. +type DispatcherConfig = swarm.DispatcherConfig + +// CAConfig represents CA configuration. +type CAConfig = swarm.CAConfig + +// ExternalCAProtocol represents type of external CA. +type ExternalCAProtocol = swarm.ExternalCAProtocol + +// ExternalCAProtocolCFSSL CFSSL +const ExternalCAProtocolCFSSL = swarm.ExternalCAProtocolCFSSL + +// ExternalCA defines external CA to be used by the cluster. +type ExternalCA = swarm.ExternalCA + +// InitRequest is the request used to init a swarm. +type InitRequest = swarm.InitRequest + +// JoinRequest is the request used to join a swarm. +type JoinRequest = swarm.JoinRequest + +// UnlockRequest is the request used to unlock a swarm. +type UnlockRequest = swarm.UnlockRequest + +// LocalNodeState represents the state of the local node. +type LocalNodeState = swarm.LocalNodeState + +const ( + // LocalNodeStateInactive INACTIVE + LocalNodeStateInactive = swarm.LocalNodeStateInactive + // LocalNodeStatePending PENDING + LocalNodeStatePending = swarm.LocalNodeStatePending + // LocalNodeStateActive ACTIVE + LocalNodeStateActive = swarm.LocalNodeStateActive + // LocalNodeStateError ERROR + LocalNodeStateError = swarm.LocalNodeStateError + // LocalNodeStateLocked LOCKED + LocalNodeStateLocked = swarm.LocalNodeStateLocked +) + +// Info represents generic information about swarm. +type Info = swarm.Info + +// Status provides information about the current swarm status and role, +// obtained from the "Swarm" header in the API response. +type Status = swarm.Status + +// Peer represents a peer. +type Peer = swarm.Peer + +// UpdateFlags contains flags for SwarmUpdate. +type UpdateFlags = swarm.UpdateFlags + +// UnlockKeyResponse contains the response for Engine API: +// GET /swarm/unlockkey +type UnlockKeyResponse = swarm.UnlockKeyResponse + +// TaskState represents the state of a task. +type TaskState = swarm.TaskState + +const ( + // TaskStateNew NEW + TaskStateNew = swarm.TaskStateNew + // TaskStateAllocated ALLOCATED + TaskStateAllocated = swarm.TaskStateAllocated + // TaskStatePending PENDING + TaskStatePending = swarm.TaskStatePending + // TaskStateAssigned ASSIGNED + TaskStateAssigned = swarm.TaskStateAssigned + // TaskStateAccepted ACCEPTED + TaskStateAccepted = swarm.TaskStateAccepted + // TaskStatePreparing PREPARING + TaskStatePreparing = swarm.TaskStatePreparing + // TaskStateReady READY + TaskStateReady = swarm.TaskStateReady + // TaskStateStarting STARTING + TaskStateStarting = swarm.TaskStateStarting + // TaskStateRunning RUNNING + TaskStateRunning = swarm.TaskStateRunning + // TaskStateComplete COMPLETE + TaskStateComplete = swarm.TaskStateComplete + // TaskStateShutdown SHUTDOWN + TaskStateShutdown = swarm.TaskStateShutdown + // TaskStateFailed FAILED + TaskStateFailed = swarm.TaskStateFailed + // TaskStateRejected REJECTED + TaskStateRejected = swarm.TaskStateRejected + // TaskStateRemove REMOVE + TaskStateRemove = swarm.TaskStateRemove + // TaskStateOrphaned ORPHANED + TaskStateOrphaned = swarm.TaskStateOrphaned +) + +// Task represents a task. +type Task = swarm.Task + +// TaskSpec represents the spec of a task. +type TaskSpec = swarm.TaskSpec + +// Resources represents resources (CPU/Memory) which can be advertised by a +// node and requested to be reserved for a task. +type Resources = swarm.Resources + +// Limit describes limits on resources which can be requested by a task. +type Limit = swarm.Limit + +// GenericResource represents a "user defined" resource which can +// be either an integer (e.g: SSD=3) or a string (e.g: SSD=sda1) +type GenericResource = swarm.GenericResource + +// NamedGenericResource represents a "user defined" resource which is defined +// as a string. +// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...) +// Value is used to identify the resource (GPU="UUID-1", FPGA="/dev/sdb5", ...) +type NamedGenericResource = swarm.NamedGenericResource + +// DiscreteGenericResource represents a "user defined" resource which is defined +// as an integer +// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...) +// Value is used to count the resource (SSD=5, HDD=3, ...) +type DiscreteGenericResource = swarm.DiscreteGenericResource + +// ResourceRequirements represents resources requirements. +type ResourceRequirements = swarm.ResourceRequirements + +// Placement represents orchestration parameters. +type Placement = swarm.Placement + +// PlacementPreference provides a way to make the scheduler aware of factors +// such as topology. +type PlacementPreference = swarm.PlacementPreference + +// SpreadOver is a scheduling preference that instructs the scheduler to spread +// tasks evenly over groups of nodes identified by labels. +type SpreadOver = swarm.SpreadOver + +// RestartPolicy represents the restart policy. +type RestartPolicy = swarm.RestartPolicy + +// RestartPolicyCondition represents when to restart. +type RestartPolicyCondition = swarm.RestartPolicyCondition + +const ( + // RestartPolicyConditionNone NONE + RestartPolicyConditionNone = swarm.RestartPolicyConditionNone + // RestartPolicyConditionOnFailure ON_FAILURE + RestartPolicyConditionOnFailure = swarm.RestartPolicyConditionOnFailure + // RestartPolicyConditionAny ANY + RestartPolicyConditionAny = swarm.RestartPolicyConditionAny +) + +// TaskStatus represents the status of a task. +type TaskStatus = swarm.TaskStatus + +// ContainerStatus represents the status of a container. +type ContainerStatus = swarm.ContainerStatus + +// PortStatus represents the port status of a task's host ports whose +// service has published host ports +type PortStatus = swarm.PortStatus + +// VolumeAttachment contains the associating a Volume to a Task. +type VolumeAttachment = swarm.VolumeAttachment + +// TaskListOptions holds parameters to list tasks with. +type TaskListOptions = swarm.TaskListOptions + +// --------------------------------------------------- +// New types, introduced in moby/moby/api +// --------------------------------------------------- + +type RuntimeSpec = swarm.RuntimeSpec + +type RuntimePrivilege = swarm.RuntimePrivilege diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime/gen.go b/vendor/github.com/docker/docker/api/types/swarm/runtime/gen.go deleted file mode 100644 index 90e572cf9c90..000000000000 --- a/vendor/github.com/docker/docker/api/types/swarm/runtime/gen.go +++ /dev/null @@ -1,3 +0,0 @@ -//go:generate protoc --gogofaster_out=import_path=github.com/docker/docker/api/types/swarm/runtime:. plugin.proto - -package runtime diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go deleted file mode 100644 index 32aaf0d51990..000000000000 --- a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go +++ /dev/null @@ -1,808 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: plugin.proto - -package runtime - -import ( - fmt "fmt" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// PluginSpec defines the base payload which clients can specify for creating -// a service with the plugin runtime. -type PluginSpec struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Remote string `protobuf:"bytes,2,opt,name=remote,proto3" json:"remote,omitempty"` - Privileges []*PluginPrivilege `protobuf:"bytes,3,rep,name=privileges,proto3" json:"privileges,omitempty"` - Disabled bool `protobuf:"varint,4,opt,name=disabled,proto3" json:"disabled,omitempty"` - Env []string `protobuf:"bytes,5,rep,name=env,proto3" json:"env,omitempty"` -} - -func (m *PluginSpec) Reset() { *m = PluginSpec{} } -func (m *PluginSpec) String() string { return proto.CompactTextString(m) } -func (*PluginSpec) ProtoMessage() {} -func (*PluginSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_22a625af4bc1cc87, []int{0} -} -func (m *PluginSpec) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PluginSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PluginSpec.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *PluginSpec) XXX_Merge(src proto.Message) { - xxx_messageInfo_PluginSpec.Merge(m, src) -} -func (m *PluginSpec) XXX_Size() int { - return m.Size() -} -func (m *PluginSpec) XXX_DiscardUnknown() { - xxx_messageInfo_PluginSpec.DiscardUnknown(m) -} - -var xxx_messageInfo_PluginSpec proto.InternalMessageInfo - -func (m *PluginSpec) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *PluginSpec) GetRemote() string { - if m != nil { - return m.Remote - } - return "" -} - -func (m *PluginSpec) GetPrivileges() []*PluginPrivilege { - if m != nil { - return m.Privileges - } - return nil -} - -func (m *PluginSpec) GetDisabled() bool { - if m != nil { - return m.Disabled - } - return false -} - -func (m *PluginSpec) GetEnv() []string { - if m != nil { - return m.Env - } - return nil -} - -// PluginPrivilege describes a permission the user has to accept -// upon installing a plugin. -type PluginPrivilege struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - Value []string `protobuf:"bytes,3,rep,name=value,proto3" json:"value,omitempty"` -} - -func (m *PluginPrivilege) Reset() { *m = PluginPrivilege{} } -func (m *PluginPrivilege) String() string { return proto.CompactTextString(m) } -func (*PluginPrivilege) ProtoMessage() {} -func (*PluginPrivilege) Descriptor() ([]byte, []int) { - return fileDescriptor_22a625af4bc1cc87, []int{1} -} -func (m *PluginPrivilege) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PluginPrivilege) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PluginPrivilege.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *PluginPrivilege) XXX_Merge(src proto.Message) { - xxx_messageInfo_PluginPrivilege.Merge(m, src) -} -func (m *PluginPrivilege) XXX_Size() int { - return m.Size() -} -func (m *PluginPrivilege) XXX_DiscardUnknown() { - xxx_messageInfo_PluginPrivilege.DiscardUnknown(m) -} - -var xxx_messageInfo_PluginPrivilege proto.InternalMessageInfo - -func (m *PluginPrivilege) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *PluginPrivilege) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *PluginPrivilege) GetValue() []string { - if m != nil { - return m.Value - } - return nil -} - -func init() { - proto.RegisterType((*PluginSpec)(nil), "PluginSpec") - proto.RegisterType((*PluginPrivilege)(nil), "PluginPrivilege") -} - -func init() { proto.RegisterFile("plugin.proto", fileDescriptor_22a625af4bc1cc87) } - -var fileDescriptor_22a625af4bc1cc87 = []byte{ - // 225 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0xc8, 0x29, 0x4d, - 0xcf, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x9a, 0xc1, 0xc8, 0xc5, 0x15, 0x00, 0x16, - 0x08, 0x2e, 0x48, 0x4d, 0x16, 0x12, 0xe2, 0x62, 0xc9, 0x4b, 0xcc, 0x4d, 0x95, 0x60, 0x54, 0x60, - 0xd4, 0xe0, 0x0c, 0x02, 0xb3, 0x85, 0xc4, 0xb8, 0xd8, 0x8a, 0x52, 0x73, 0xf3, 0x4b, 0x52, 0x25, - 0x98, 0xc0, 0xa2, 0x50, 0x9e, 0x90, 0x01, 0x17, 0x57, 0x41, 0x51, 0x66, 0x59, 0x66, 0x4e, 0x6a, - 0x7a, 0x6a, 0xb1, 0x04, 0xb3, 0x02, 0xb3, 0x06, 0xb7, 0x91, 0x80, 0x1e, 0xc4, 0xb0, 0x00, 0x98, - 0x44, 0x10, 0x92, 0x1a, 0x21, 0x29, 0x2e, 0x8e, 0x94, 0xcc, 0xe2, 0xc4, 0xa4, 0x9c, 0xd4, 0x14, - 0x09, 0x16, 0x05, 0x46, 0x0d, 0x8e, 0x20, 0x38, 0x5f, 0x48, 0x80, 0x8b, 0x39, 0x35, 0xaf, 0x4c, - 0x82, 0x55, 0x81, 0x59, 0x83, 0x33, 0x08, 0xc4, 0x54, 0x8a, 0xe5, 0xe2, 0x47, 0x33, 0x0c, 0xab, - 0xf3, 0x14, 0xb8, 0xb8, 0x53, 0x52, 0x8b, 0x93, 0x8b, 0x32, 0x0b, 0x4a, 0x32, 0xf3, 0xf3, 0xa0, - 0x6e, 0x44, 0x16, 0x12, 0x12, 0xe1, 0x62, 0x2d, 0x4b, 0xcc, 0x29, 0x4d, 0x05, 0xbb, 0x91, 0x33, - 0x08, 0xc2, 0x71, 0x92, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, - 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x24, 0x36, - 0x70, 0xd0, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x37, 0xea, 0xe2, 0xca, 0x2a, 0x01, 0x00, - 0x00, -} - -func (m *PluginSpec) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PluginSpec) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PluginSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Env) > 0 { - for iNdEx := len(m.Env) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Env[iNdEx]) - copy(dAtA[i:], m.Env[iNdEx]) - i = encodeVarintPlugin(dAtA, i, uint64(len(m.Env[iNdEx]))) - i-- - dAtA[i] = 0x2a - } - } - if m.Disabled { - i-- - if m.Disabled { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x20 - } - if len(m.Privileges) > 0 { - for iNdEx := len(m.Privileges) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Privileges[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintPlugin(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - } - if len(m.Remote) > 0 { - i -= len(m.Remote) - copy(dAtA[i:], m.Remote) - i = encodeVarintPlugin(dAtA, i, uint64(len(m.Remote))) - i-- - dAtA[i] = 0x12 - } - if len(m.Name) > 0 { - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintPlugin(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *PluginPrivilege) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PluginPrivilege) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PluginPrivilege) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Value) > 0 { - for iNdEx := len(m.Value) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Value[iNdEx]) - copy(dAtA[i:], m.Value[iNdEx]) - i = encodeVarintPlugin(dAtA, i, uint64(len(m.Value[iNdEx]))) - i-- - dAtA[i] = 0x1a - } - } - if len(m.Description) > 0 { - i -= len(m.Description) - copy(dAtA[i:], m.Description) - i = encodeVarintPlugin(dAtA, i, uint64(len(m.Description))) - i-- - dAtA[i] = 0x12 - } - if len(m.Name) > 0 { - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintPlugin(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintPlugin(dAtA []byte, offset int, v uint64) int { - offset -= sovPlugin(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *PluginSpec) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - if l > 0 { - n += 1 + l + sovPlugin(uint64(l)) - } - l = len(m.Remote) - if l > 0 { - n += 1 + l + sovPlugin(uint64(l)) - } - if len(m.Privileges) > 0 { - for _, e := range m.Privileges { - l = e.Size() - n += 1 + l + sovPlugin(uint64(l)) - } - } - if m.Disabled { - n += 2 - } - if len(m.Env) > 0 { - for _, s := range m.Env { - l = len(s) - n += 1 + l + sovPlugin(uint64(l)) - } - } - return n -} - -func (m *PluginPrivilege) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - if l > 0 { - n += 1 + l + sovPlugin(uint64(l)) - } - l = len(m.Description) - if l > 0 { - n += 1 + l + sovPlugin(uint64(l)) - } - if len(m.Value) > 0 { - for _, s := range m.Value { - l = len(s) - n += 1 + l + sovPlugin(uint64(l)) - } - } - return n -} - -func sovPlugin(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozPlugin(x uint64) (n int) { - return sovPlugin(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *PluginSpec) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlugin - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PluginSpec: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PluginSpec: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlugin - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPlugin - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPlugin - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Remote", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlugin - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPlugin - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPlugin - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Remote = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Privileges", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlugin - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthPlugin - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthPlugin - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Privileges = append(m.Privileges, &PluginPrivilege{}) - if err := m.Privileges[len(m.Privileges)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Disabled", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlugin - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Disabled = bool(v != 0) - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlugin - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPlugin - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPlugin - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Env = append(m.Env, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipPlugin(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthPlugin - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PluginPrivilege) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlugin - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PluginPrivilege: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PluginPrivilege: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlugin - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPlugin - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPlugin - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlugin - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPlugin - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPlugin - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Description = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlugin - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPlugin - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPlugin - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Value = append(m.Value, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipPlugin(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthPlugin - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipPlugin(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowPlugin - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowPlugin - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowPlugin - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthPlugin - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupPlugin - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthPlugin - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthPlugin = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowPlugin = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupPlugin = fmt.Errorf("proto: unexpected end of group") -) diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto deleted file mode 100644 index e311b36ba2cf..000000000000 --- a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; - -// PluginSpec defines the base payload which clients can specify for creating -// a service with the plugin runtime. -message PluginSpec { - string name = 1; - string remote = 2; - repeated PluginPrivilege privileges = 3; - bool disabled = 4; - repeated string env = 5; -} - -// PluginPrivilege describes a permission the user has to accept -// upon installing a plugin. -message PluginPrivilege { - string name = 1; - string description = 2; - repeated string value = 3; -} diff --git a/vendor/github.com/docker/docker/api/types/system/aliases.go b/vendor/github.com/docker/docker/api/types/system/aliases.go new file mode 100644 index 000000000000..7a5c28df89ca --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/system/aliases.go @@ -0,0 +1,52 @@ +package system + +import "github.com/moby/moby/api/types/system" + +// DiskUsage contains response of Engine API for API 1.49 and greater: +// GET "/system/df" +type DiskUsage = system.DiskUsage + +// Info contains response of Engine API: +// GET "/info" +type Info = system.Info + +// ContainerdInfo holds information about the containerd instance used by the daemon. +type ContainerdInfo = system.ContainerdInfo + +// ContainerdNamespaces reflects the containerd namespaces used by the daemon. +type ContainerdNamespaces = system.ContainerdNamespaces + +// PluginsInfo is a temp struct holding Plugins name +// registered with docker daemon. It is used by [Info] struct +type PluginsInfo = system.PluginsInfo + +// 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 = system.Commit + +// NetworkAddressPool is a temp struct used by [Info] struct. +type NetworkAddressPool = system.NetworkAddressPool + +// FirewallInfo describes the firewall backend. +type FirewallInfo = system.FirewallInfo + +// DeviceInfo represents a discoverable device from a device driver. +type DeviceInfo = system.DeviceInfo + +// Runtime describes an OCI runtime +type Runtime = system.Runtime + +// RuntimeWithStatus extends [Runtime] to hold [RuntimeStatus]. +type RuntimeWithStatus = system.RuntimeWithStatus + +// SecurityOpt contains the name and options of a security option +type SecurityOpt = system.SecurityOpt + +// DecodeSecurityOptions decodes a security options string slice to a +// type-safe [SecurityOpt]. +func DecodeSecurityOptions(opts []string) ([]system.SecurityOpt, error) { + return system.DecodeSecurityOptions(opts) +} + +// KeyValue holds a key/value pair. +type KeyValue = system.KeyValue diff --git a/vendor/github.com/docker/docker/api/types/system/disk_usage.go b/vendor/github.com/docker/docker/api/types/system/disk_usage.go deleted file mode 100644 index 99078cf196d0..000000000000 --- a/vendor/github.com/docker/docker/api/types/system/disk_usage.go +++ /dev/null @@ -1,17 +0,0 @@ -package system - -import ( - "github.com/docker/docker/api/types/build" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/image" - "github.com/docker/docker/api/types/volume" -) - -// DiskUsage contains response of Engine API for API 1.49 and greater: -// GET "/system/df" -type DiskUsage struct { - Images *image.DiskUsage - Containers *container.DiskUsage - Volumes *volume.DiskUsage - BuildCache *build.CacheDiskUsage -} 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 8456a45607e2..f851806a949f 100644 --- a/vendor/github.com/docker/docker/api/types/types_deprecated.go +++ b/vendor/github.com/docker/docker/api/types/types_deprecated.go @@ -3,12 +3,12 @@ package types import ( "context" - "github.com/docker/docker/api/types/build" - "github.com/docker/docker/api/types/common" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/image" - "github.com/docker/docker/api/types/storage" - "github.com/docker/docker/api/types/swarm" + "github.com/moby/moby/api/types/build" + "github.com/moby/moby/api/types/common" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/image" + "github.com/moby/moby/api/types/storage" + "github.com/moby/moby/api/types/swarm" ) // IDResponse Response to an API call that returns just an Id. @@ -88,8 +88,8 @@ type MountPoint = container.MountPoint // Port An open port on a container // -// Deprecated: use [container.Port]. -type Port = container.Port +// Deprecated: use [container.PortSummary]. +type Port = container.PortSummary // GraphDriverData Information about the storage driver used to store the container's and // image's filesystem. diff --git a/vendor/github.com/docker/docker/api/types/versions/aliases.go b/vendor/github.com/docker/docker/api/types/versions/aliases.go new file mode 100644 index 000000000000..6a03097186bb --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/versions/aliases.go @@ -0,0 +1,28 @@ +package versions + +import "github.com/moby/moby/api/types/versions" + +// LessThan checks if a version is less than another +func LessThan(v, other string) bool { + return versions.LessThan(v, other) +} + +// LessThanOrEqualTo checks if a version is less than or equal to another +func LessThanOrEqualTo(v, other string) bool { + return versions.LessThanOrEqualTo(v, other) +} + +// GreaterThan checks if a version is greater than another +func GreaterThan(v, other string) bool { + return versions.GreaterThan(v, other) +} + +// GreaterThanOrEqualTo checks if a version is greater than or equal to another +func GreaterThanOrEqualTo(v, other string) bool { + return versions.GreaterThanOrEqualTo(v, other) +} + +// Equal checks if a version is equal to another +func Equal(v, other string) bool { + return versions.Equal(v, other) +} diff --git a/vendor/github.com/docker/docker/api/types/volume/aliases.go b/vendor/github.com/docker/docker/api/types/volume/aliases.go new file mode 100644 index 000000000000..4112018a8840 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/volume/aliases.go @@ -0,0 +1,149 @@ +package volume + +import "github.com/moby/moby/api/types/volume" + +// ClusterVolume contains options and information specific to, and only present +// on, Swarm CSI cluster volumes. +type ClusterVolume = volume.ClusterVolume + +// ClusterVolumeSpec contains the spec used to create this volume. +type ClusterVolumeSpec = volume.ClusterVolumeSpec + +// Availability specifies the availability of the volume. +type Availability = volume.Availability + +const ( + // AvailabilityActive indicates that the volume is active and fully + // schedulable on the cluster. + AvailabilityActive = volume.AvailabilityActive + + // AvailabilityPause indicates that no new workloads should use the + // volume, but existing workloads can continue to use it. + AvailabilityPause = volume.AvailabilityPause + + // AvailabilityDrain indicates that all workloads using this volume + // should be rescheduled, and the volume unpublished from all nodes. + AvailabilityDrain = volume.AvailabilityDrain +) + +// AccessMode defines the access mode of a volume. +type AccessMode = volume.AccessMode + +// Scope defines the Scope of a Cluster Volume. This is how many nodes a +// Volume can be accessed simultaneously on. +type Scope = volume.Scope + +const ( + // ScopeSingleNode indicates the volume can be used on one node at a + // time. + ScopeSingleNode = volume.ScopeSingleNode + + // ScopeMultiNode indicates the volume can be used on many nodes at + // the same time. + ScopeMultiNode = volume.ScopeMultiNode +) + +// SharingMode defines the Sharing of a Cluster Volume. This is how Tasks using a +// Volume at the same time can use it. +type SharingMode = volume.SharingMode + +const ( + // SharingNone indicates that only one Task may use the Volume at a + // time. + SharingNone = volume.SharingNone + + // SharingReadOnly indicates that the Volume may be shared by any + // number of Tasks, but they must be read-only. + SharingReadOnly = volume.SharingReadOnly + + // SharingOneWriter indicates that the Volume may be shared by any + // number of Tasks, but all after the first must be read-only. + SharingOneWriter = volume.SharingOneWriter + + // SharingAll means that the Volume may be shared by any number of + // Tasks, as readers or writers. + SharingAll = volume.SharingAll +) + +// TypeBlock defines options for using a volume as a block-type volume. +// +// Intentionally empty. +type TypeBlock = volume.TypeBlock + +// TypeMount contains options for using a volume as a Mount-type +// volume. +type TypeMount = volume.TypeMount + +// TopologyRequirement expresses the user's requirements for a volume's +// accessible topology. +type TopologyRequirement = volume.TopologyRequirement + +// Topology is a map of topological domains to topological segments. +type Topology = volume.Topology + +// CapacityRange describes the minimum and maximum capacity a volume should be +// created with +type CapacityRange = volume.CapacityRange + +// Secret represents a Swarm Secret value that must be passed to the CSI +// storage plugin when operating on this Volume. It represents one key-value +// pair of possibly many. +type Secret = volume.Secret + +// PublishState represents the state of a Volume as it pertains to its +// use on a particular Node. +type PublishState = volume.PublishState + +const ( + // StatePending indicates that the volume should be published on + // this node, but the call to ControllerPublishVolume has not been + // successfully completed yet and the result recorded by swarmkit. + StatePending = volume.StatePending + + // StatePublished means the volume is published successfully to the node. + StatePublished = volume.StatePublished + // StatePendingNodeUnpublish indicates that the Volume should be + // unpublished on the Node, and we're waiting for confirmation that it has + // done so. After the Node has confirmed that the Volume has been + // unpublished, the state will move to StatePendingUnpublish. + StatePendingNodeUnpublish = volume.StatePendingNodeUnpublish + + // StatePendingUnpublish means the volume is still published to the node + // by the controller, awaiting the operation to unpublish it. + StatePendingUnpublish = volume.StatePendingUnpublish +) + +// PublishStatus represents the status of the volume as published to an +// individual node +type PublishStatus = volume.PublishStatus + +// Info contains information about the Volume as a whole as provided by +// the CSI storage plugin. +type Info = volume.Info + +// CreateOptions VolumeConfig +// +// Volume configuration +type CreateOptions = volume.CreateOptions + +// ListResponse VolumeListResponse +// +// Volume list response +type ListResponse = volume.ListResponse + +// ListOptions holds parameters to list volumes. +type ListOptions = volume.ListOptions + +// PruneReport contains the response for Engine API: +// POST "/volumes/prune" +type PruneReport = volume.PruneReport + +// Volume volume +type Volume = volume.Volume + +// UsageData Usage details about the volume. This information is used by the +// `GET /system/df` endpoint, and omitted in other endpoints. +type UsageData = volume.UsageData + +// UpdateOptions is configuration to update a Volume with. +type UpdateOptions = volume.UpdateOptions diff --git a/vendor/github.com/docker/docker/api/types/volume/disk_usage.go b/vendor/github.com/docker/docker/api/types/volume/disk_usage.go index 3d716c6e00d9..88974303a0b0 100644 --- a/vendor/github.com/docker/docker/api/types/volume/disk_usage.go +++ b/vendor/github.com/docker/docker/api/types/volume/disk_usage.go @@ -1,6 +1,8 @@ package volume // DiskUsage contains disk usage for volumes. +// +// Deprecated: this type is no longer used and will be removed in the next release. type DiskUsage struct { TotalSize int64 Reclaimable int64 diff --git a/vendor/github.com/docker/docker/client/container_stats.go b/vendor/github.com/docker/docker/client/container_stats.go index 2244e0f4b94a..076954f4c3e8 100644 --- a/vendor/github.com/docker/docker/client/container_stats.go +++ b/vendor/github.com/docker/docker/client/container_stats.go @@ -28,7 +28,7 @@ func (cli *Client) ContainerStats(ctx context.Context, containerID string, strea return container.StatsResponseReader{ Body: resp.Body, - OSType: getDockerOS(resp.Header.Get("Server")), + OSType: resp.Header.Get("Ostype"), }, nil } @@ -51,6 +51,6 @@ func (cli *Client) ContainerStatsOneShot(ctx context.Context, containerID string return container.StatsResponseReader{ Body: resp.Body, - OSType: getDockerOS(resp.Header.Get("Server")), + OSType: resp.Header.Get("Ostype"), }, nil } diff --git a/vendor/github.com/docker/docker/client/image_build.go b/vendor/github.com/docker/docker/client/image_build.go index 66ca75e4af28..1ed0878bfdb2 100644 --- a/vendor/github.com/docker/docker/client/image_build.go +++ b/vendor/github.com/docker/docker/client/image_build.go @@ -40,7 +40,7 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio return build.ImageBuildResponse{ Body: resp.Body, - OSType: getDockerOS(resp.Header.Get("Server")), + OSType: resp.Header.Get("Ostype"), }, nil } diff --git a/vendor/github.com/docker/docker/client/utils.go b/vendor/github.com/docker/docker/client/utils.go index 67e1e6934b59..7b82f185ac58 100644 --- a/vendor/github.com/docker/docker/client/utils.go +++ b/vendor/github.com/docker/docker/client/utils.go @@ -8,12 +8,9 @@ import ( cerrdefs "github.com/containerd/errdefs" "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/internal/lazyregexp" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) -var headerRegexp = lazyregexp.New(`\ADocker/.+\s\((.+)\)\z`) - type emptyIDError string func (e emptyIDError) InvalidParameter() {} @@ -31,16 +28,6 @@ func trimID(objType, id string) (string, error) { return id, nil } -// getDockerOS returns the operating system based on the server header from the daemon. -func getDockerOS(serverHeader string) string { - var osType string - matches := headerRegexp.FindStringSubmatch(serverHeader) - if len(matches) > 0 { - osType = matches[1] - } - return osType -} - // getFiltersQuery returns a url query with "filters" query term, based on the // filters provided. func getFiltersQuery(f filters.Args) (url.Values, error) { diff --git a/vendor/github.com/docker/docker/internal/lazyregexp/lazyregexp.go b/vendor/github.com/docker/docker/internal/lazyregexp/lazyregexp.go deleted file mode 100644 index 6334edb60dca..000000000000 --- a/vendor/github.com/docker/docker/internal/lazyregexp/lazyregexp.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code below was largely copied from golang.org/x/mod@v0.22; -// https://github.com/golang/mod/blob/v0.22.0/internal/lazyregexp/lazyre.go -// with some additional methods added. - -// Package lazyregexp is a thin wrapper over regexp, allowing the use of global -// regexp variables without forcing them to be compiled at init. -package lazyregexp - -import ( - "os" - "regexp" - "strings" - "sync" -) - -// Regexp is a wrapper around [regexp.Regexp], where the underlying regexp will be -// compiled the first time it is needed. -type Regexp struct { - str string - once sync.Once - rx *regexp.Regexp -} - -func (r *Regexp) re() *regexp.Regexp { - r.once.Do(r.build) - return r.rx -} - -func (r *Regexp) build() { - r.rx = regexp.MustCompile(r.str) - r.str = "" -} - -func (r *Regexp) FindSubmatch(s []byte) [][]byte { - return r.re().FindSubmatch(s) -} - -func (r *Regexp) FindAllStringSubmatch(s string, n int) [][]string { - return r.re().FindAllStringSubmatch(s, n) -} - -func (r *Regexp) FindStringSubmatch(s string) []string { - return r.re().FindStringSubmatch(s) -} - -func (r *Regexp) FindStringSubmatchIndex(s string) []int { - return r.re().FindStringSubmatchIndex(s) -} - -func (r *Regexp) ReplaceAllString(src, repl string) string { - return r.re().ReplaceAllString(src, repl) -} - -func (r *Regexp) FindString(s string) string { - return r.re().FindString(s) -} - -func (r *Regexp) FindAllString(s string, n int) []string { - return r.re().FindAllString(s, n) -} - -func (r *Regexp) MatchString(s string) bool { - return r.re().MatchString(s) -} - -func (r *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string { - return r.re().ReplaceAllStringFunc(src, repl) -} - -func (r *Regexp) SubexpNames() []string { - return r.re().SubexpNames() -} - -var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test") - -// New creates a new lazy regexp, delaying the compiling work until it is first -// needed. If the code is being run as part of tests, the regexp compiling will -// happen immediately. -func New(str string) *Regexp { - lr := &Regexp{str: str} - if inTest { - // In tests, always compile the regexps early. - lr.re() - } - return lr -} diff --git a/vendor/github.com/docker/docker/internal/multierror/multierror.go b/vendor/github.com/docker/docker/internal/multierror/multierror.go deleted file mode 100644 index e899f4de85c9..000000000000 --- a/vendor/github.com/docker/docker/internal/multierror/multierror.go +++ /dev/null @@ -1,46 +0,0 @@ -package multierror - -import ( - "strings" -) - -// Join is a drop-in replacement for errors.Join with better formatting. -func Join(errs ...error) error { - n := 0 - for _, err := range errs { - if err != nil { - n++ - } - } - if n == 0 { - return nil - } - e := &joinError{ - errs: make([]error, 0, n), - } - for _, err := range errs { - if err != nil { - e.errs = append(e.errs, err) - } - } - return e -} - -type joinError struct { - errs []error -} - -func (e *joinError) Error() string { - if len(e.errs) == 1 { - return strings.TrimSpace(e.errs[0].Error()) - } - stringErrs := make([]string, 0, len(e.errs)) - for _, subErr := range e.errs { - stringErrs = append(stringErrs, strings.ReplaceAll(subErr.Error(), "\n", "\n\t")) - } - return "* " + strings.Join(stringErrs, "\n* ") -} - -func (e *joinError) Unwrap() []error { - return e.errs -} diff --git a/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go b/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go index 3d072808f1de..a42b222e5c27 100644 --- a/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go +++ b/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go @@ -8,6 +8,7 @@ import ( "time" "github.com/docker/go-units" + "github.com/moby/moby/api/types/jsonstream" "github.com/moby/term" "github.com/morikuni/aec" ) @@ -18,14 +19,7 @@ const RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" // JSONError wraps a concrete Code and Message, Code is // an integer error code, Message is the error message. -type JSONError struct { - Code int `json:"code,omitempty"` - Message string `json:"message,omitempty"` -} - -func (e *JSONError) Error() string { - return e.Message -} +type JSONError = jsonstream.Error // JSONProgress describes a progress message in a JSON stream. type JSONProgress struct { @@ -149,12 +143,12 @@ type JSONMessage struct { // ProgressMessage is a pre-formatted presentation of [Progress]. // // Deprecated: this field is deprecated since docker v0.7.1 / API v1.8. Use the information in [Progress] instead. This field will be omitted in a future release. - ProgressMessage string `json:"progress,omitempty"` - ID string `json:"id,omitempty"` - From string `json:"from,omitempty"` - Time int64 `json:"time,omitempty"` - TimeNano int64 `json:"timeNano,omitempty"` - Error *JSONError `json:"errorDetail,omitempty"` + ProgressMessage string `json:"progress,omitempty"` + ID string `json:"id,omitempty"` + From string `json:"from,omitempty"` // Deprecated: this field is no longer set in stream responses and should not be used. + Time int64 `json:"time,omitempty"` // Deprecated: this field is no longer set in stream responses and should not be used. + TimeNano int64 `json:"timeNano,omitempty"` // Deprecated: this field is no longer set in stream responses and should not be used. + Error *jsonstream.Error `json:"errorDetail,omitempty"` // ErrorMessage contains errors encountered during the operation. // diff --git a/vendor/github.com/docker/docker/pkg/progress/progress.go b/vendor/github.com/docker/docker/pkg/progress/progress.go index 3f9887c5bbbd..528cd36f1440 100644 --- a/vendor/github.com/docker/docker/pkg/progress/progress.go +++ b/vendor/github.com/docker/docker/pkg/progress/progress.go @@ -2,92 +2,54 @@ package progress import ( "fmt" + + "github.com/moby/moby/api/pkg/progress" ) // Progress represents the progress of a transfer. -type Progress struct { - ID string - - // Progress contains a Message or... - Message string - - // ...progress of an action - Action string - Current int64 - Total int64 - - // If true, don't show xB/yB - HideCounts bool - // If not empty, use units instead of bytes for counts - Units string - - // Aux contains extra information not presented to the user, such as - // digests for push signing. - Aux interface{} - - LastUpdate bool -} +type Progress = progress.Progress // Output is an interface for writing progress information. It's // like a writer for progress, but we don't call it Writer because // that would be confusing next to ProgressReader (also, because it // doesn't implement the io.Writer interface). -type Output interface { - WriteProgress(Progress) error -} - -type chanOutput chan<- Progress - -func (out chanOutput) WriteProgress(p Progress) error { - // FIXME: workaround for panic in #37735 - defer func() { - recover() - }() - out <- p - return nil -} +type Output = progress.Output // ChanOutput returns an Output that writes progress updates to the // supplied channel. -func ChanOutput(progressChan chan<- Progress) Output { - return chanOutput(progressChan) -} - -type discardOutput struct{} - -func (discardOutput) WriteProgress(Progress) error { - return nil +func ChanOutput(progressChan chan<- progress.Progress) progress.Output { + return progress.ChanOutput(progressChan) } // DiscardOutput returns an Output that discards progress -func DiscardOutput() Output { - return discardOutput{} +func DiscardOutput() progress.Output { + return progress.DiscardOutput() } // Update is a convenience function to write a progress update to the channel. -func Update(out Output, id, action string) { - out.WriteProgress(Progress{ID: id, Action: action}) +func Update(out progress.Output, id, action string) { + out.WriteProgress(progress.Progress{ID: id, Action: action}) } // Updatef is a convenience function to write a printf-formatted progress update // to the channel. -func Updatef(out Output, id, format string, a ...interface{}) { +func Updatef(out progress.Output, id, format string, a ...interface{}) { Update(out, id, fmt.Sprintf(format, a...)) } // Message is a convenience function to write a progress message to the channel. -func Message(out Output, id, message string) { - out.WriteProgress(Progress{ID: id, Message: message}) +func Message(out progress.Output, id, message string) { + out.WriteProgress(progress.Progress{ID: id, Message: message}) } // Messagef is a convenience function to write a printf-formatted progress // message to the channel. -func Messagef(out Output, id, format string, a ...interface{}) { +func Messagef(out progress.Output, id, format string, a ...interface{}) { Message(out, id, fmt.Sprintf(format, a...)) } // Aux sends auxiliary information over a progress interface, which will not be // formatted for the UI. This is used for things such as push signing. -func Aux(out Output, a interface{}) { - out.WriteProgress(Progress{Aux: a}) +func Aux(out progress.Output, a interface{}) { + out.WriteProgress(progress.Progress{Aux: a}) } diff --git a/vendor/github.com/docker/docker/pkg/progress/progressreader.go b/vendor/github.com/docker/docker/pkg/progress/progressreader.go index 7a2954ec9920..7d792dee2f8e 100644 --- a/vendor/github.com/docker/docker/pkg/progress/progressreader.go +++ b/vendor/github.com/docker/docker/pkg/progress/progressreader.go @@ -2,65 +2,14 @@ package progress import ( "io" - "time" - "golang.org/x/time/rate" + "github.com/moby/moby/api/pkg/progress" ) // Reader is a Reader with progress bar. -type Reader struct { - in io.ReadCloser // Stream to read from - out Output // Where to send progress bar to - size int64 - current int64 - lastUpdate int64 - id string - action string - rateLimiter *rate.Limiter -} +type Reader = progress.Reader // NewProgressReader creates a new ProgressReader. -func NewProgressReader(in io.ReadCloser, out Output, size int64, id, action string) *Reader { - return &Reader{ - in: in, - out: out, - size: size, - id: id, - action: action, - rateLimiter: rate.NewLimiter(rate.Every(100*time.Millisecond), 1), - } -} - -func (p *Reader) Read(buf []byte) (int, error) { - read, err := p.in.Read(buf) - p.current += int64(read) - updateEvery := int64(1024 * 512) // 512kB - if p.size > 0 { - // Update progress for every 1% read if 1% < 512kB - if increment := int64(0.01 * float64(p.size)); increment < updateEvery { - updateEvery = increment - } - } - if p.current-p.lastUpdate > updateEvery || err != nil { - p.updateProgress(err != nil && read == 0) - p.lastUpdate = p.current - } - - return read, err -} - -// Close closes the progress reader and its underlying reader. -func (p *Reader) Close() error { - if p.current < p.size { - // print a full progress bar when closing prematurely - p.current = p.size - p.updateProgress(false) - } - return p.in.Close() -} - -func (p *Reader) updateProgress(last bool) { - if last || p.current == p.size || p.rateLimiter.Allow() { - p.out.WriteProgress(Progress{ID: p.id, Action: p.action, Current: p.current, Total: p.size, LastUpdate: last}) - } +func NewProgressReader(in io.ReadCloser, out progress.Output, size int64, id, action string) *progress.Reader { + return progress.NewProgressReader(in, out, size, id, action) } diff --git a/vendor/github.com/docker/docker/pkg/stdcopy/aliases.go b/vendor/github.com/docker/docker/pkg/stdcopy/aliases.go new file mode 100644 index 000000000000..34c33e93a492 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/stdcopy/aliases.go @@ -0,0 +1,30 @@ +package stdcopy + +import ( + "io" + + "github.com/moby/moby/api/pkg/stdcopy" +) + +// StdType is the type of standard stream +// a writer can multiplex to. +// +// Deprecated: use [stdcopy.StdType]. This alias will be removed in the next release. +type StdType = stdcopy.StdType + +const ( + Stdin = stdcopy.Stdin + Stdout = stdcopy.Stdout + Stderr = stdcopy.Stderr + Systemerr = stdcopy.Systemerr +) + +// NewStdWriter instantiates a new Writer. +func NewStdWriter(w io.Writer, t stdcopy.StdType) io.Writer { + return stdcopy.NewStdWriter(w, t) +} + +// StdCopy is a modified version of io.Copy. +func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, _ error) { + return stdcopy.StdCopy(dstout, dsterr, src) +} diff --git a/vendor/github.com/docker/docker/pkg/streamformatter/streamformatter.go b/vendor/github.com/docker/docker/pkg/streamformatter/streamformatter.go index 24e1b45f2704..5913b568a474 100644 --- a/vendor/github.com/docker/docker/pkg/streamformatter/streamformatter.go +++ b/vendor/github.com/docker/docker/pkg/streamformatter/streamformatter.go @@ -5,12 +5,34 @@ import ( "encoding/json" "fmt" "io" + "strings" "sync" + "time" - "github.com/docker/docker/pkg/jsonmessage" - "github.com/docker/docker/pkg/progress" + "github.com/docker/go-units" + "github.com/moby/moby/api/pkg/progress" + "github.com/moby/moby/api/types/jsonstream" ) +// jsonMessage defines a message struct. It describes +// the created time, where it from, status, ID of the +// message. It's used for docker events. +// +// It is a reduced set of [jsonmessage.JSONMessage]. +type jsonMessage struct { + Stream string `json:"stream,omitempty"` + Status string `json:"status,omitempty"` + Progress *jsonstream.Progress `json:"progressDetail,omitempty"` + ID string `json:"id,omitempty"` + Error *jsonstream.Error `json:"errorDetail,omitempty"` + Aux *json.RawMessage `json:"aux,omitempty"` // Aux contains out-of-band data, such as digests for push signing and image id after building. + + // ErrorMessage contains errors encountered during the operation. + // + // Deprecated: this field is deprecated since docker v0.6.0 / API v1.4. Use [Error.Message] instead. This field will be omitted in a future release. + ErrorMessage string `json:"error,omitempty"` // deprecated +} + const streamNewline = "\r\n" type jsonProgressFormatter struct{} @@ -22,7 +44,7 @@ func appendNewline(source []byte) []byte { // FormatStatus formats the specified objects according to the specified format (and id). func FormatStatus(id, format string, a ...interface{}) []byte { str := fmt.Sprintf(format, a...) - b, err := json.Marshal(&jsonmessage.JSONMessage{ID: id, Status: str}) + b, err := json.Marshal(&jsonMessage{ID: id, Status: str}) if err != nil { return FormatError(err) } @@ -31,11 +53,11 @@ func FormatStatus(id, format string, a ...interface{}) []byte { // FormatError formats the error as a JSON object func FormatError(err error) []byte { - jsonError, ok := err.(*jsonmessage.JSONError) + jsonError, ok := err.(*jsonstream.Error) if !ok { - jsonError = &jsonmessage.JSONError{Message: err.Error()} + jsonError = &jsonstream.Error{Message: err.Error()} } - if b, err := json.Marshal(&jsonmessage.JSONMessage{Error: jsonError, ErrorMessage: err.Error()}); err == nil { + if b, err := json.Marshal(&jsonMessage{Error: jsonError, ErrorMessage: err.Error()}); err == nil { return appendNewline(b) } return []byte(`{"error":"format error"}` + streamNewline) @@ -46,9 +68,9 @@ func (sf *jsonProgressFormatter) formatStatus(id, format string, a ...interface{ } // formatProgress formats the progress information for a specified action. -func (sf *jsonProgressFormatter) formatProgress(id, action string, progress *jsonmessage.JSONProgress, aux interface{}) []byte { +func (sf *jsonProgressFormatter) formatProgress(id, action string, progress *jsonstream.Progress, aux interface{}) []byte { if progress == nil { - progress = &jsonmessage.JSONProgress{} + progress = &jsonstream.Progress{} } var auxJSON *json.RawMessage if aux != nil { @@ -59,12 +81,11 @@ func (sf *jsonProgressFormatter) formatProgress(id, action string, progress *jso auxJSON = new(json.RawMessage) *auxJSON = auxJSONBytes } - b, err := json.Marshal(&jsonmessage.JSONMessage{ - Status: action, - ProgressMessage: progress.String(), - Progress: progress, - ID: id, - Aux: auxJSON, + b, err := json.Marshal(&jsonMessage{ + Status: action, + Progress: progress, + ID: id, + Aux: auxJSON, }) if err != nil { return nil @@ -78,15 +99,72 @@ func (sf *rawProgressFormatter) formatStatus(id, format string, a ...interface{} return []byte(fmt.Sprintf(format, a...) + streamNewline) } -func (sf *rawProgressFormatter) formatProgress(id, action string, progress *jsonmessage.JSONProgress, aux interface{}) []byte { +func rawProgressString(p *jsonstream.Progress) string { + if p == nil || (p.Current <= 0 && p.Total <= 0) { + return "" + } + if p.Total <= 0 { + switch p.Units { + case "": + return fmt.Sprintf("%8v", units.HumanSize(float64(p.Current))) + default: + return fmt.Sprintf("%d %s", p.Current, p.Units) + } + } + + percentage := int(float64(p.Current)/float64(p.Total)*100) / 2 + if percentage > 50 { + percentage = 50 + } + + numSpaces := 0 + if 50-percentage > 0 { + numSpaces = 50 - percentage + } + pbBox := fmt.Sprintf("[%s>%s] ", strings.Repeat("=", percentage), strings.Repeat(" ", numSpaces)) + + var numbersBox string + switch { + case p.HideCounts: + case p.Units == "": // no units, use bytes + current := units.HumanSize(float64(p.Current)) + total := units.HumanSize(float64(p.Total)) + + numbersBox = fmt.Sprintf("%8v/%v", current, total) + + if p.Current > p.Total { + // remove total display if the reported current is wonky. + numbersBox = fmt.Sprintf("%8v", current) + } + default: + numbersBox = fmt.Sprintf("%d/%d %s", p.Current, p.Total, p.Units) + + if p.Current > p.Total { + // remove total display if the reported current is wonky. + numbersBox = fmt.Sprintf("%d %s", p.Current, p.Units) + } + } + + var timeLeftBox string + if p.Current > 0 && p.Start > 0 && percentage < 50 { + fromStart := time.Since(time.Unix(p.Start, 0)) + perEntry := fromStart / time.Duration(p.Current) + left := time.Duration(p.Total-p.Current) * perEntry + timeLeftBox = " " + left.Round(time.Second).String() + } + return pbBox + numbersBox + timeLeftBox +} + +func (sf *rawProgressFormatter) formatProgress(id, action string, progress *jsonstream.Progress, aux interface{}) []byte { if progress == nil { - progress = &jsonmessage.JSONProgress{} + progress = &jsonstream.Progress{} } endl := "\r" - if progress.String() == "" { + out := rawProgressString(progress) + if out == "" { endl += "\n" } - return []byte(action + " " + progress.String() + endl) + return []byte(action + " " + out + endl) } // NewProgressOutput returns a progress.Output object that can be passed to @@ -103,7 +181,7 @@ func NewJSONProgressOutput(out io.Writer, newLines bool) progress.Output { type formatProgress interface { formatStatus(id, format string, a ...interface{}) []byte - formatProgress(id, action string, progress *jsonmessage.JSONProgress, aux interface{}) []byte + formatProgress(id, action string, progress *jsonstream.Progress, aux interface{}) []byte } type progressOutput struct { @@ -119,7 +197,12 @@ func (out *progressOutput) WriteProgress(prog progress.Progress) error { if prog.Message != "" { formatted = out.sf.formatStatus(prog.ID, prog.Message) } else { - jsonProgress := jsonmessage.JSONProgress{Current: prog.Current, Total: prog.Total, HideCounts: prog.HideCounts, Units: prog.Units} + jsonProgress := jsonstream.Progress{ + Current: prog.Current, + Total: prog.Total, + HideCounts: prog.HideCounts, + Units: prog.Units, + } formatted = out.sf.formatProgress(prog.ID, prog.Action, &jsonProgress, prog.Aux) } @@ -151,7 +234,7 @@ func (sf *AuxFormatter) Emit(id string, aux interface{}) error { } auxJSON := new(json.RawMessage) *auxJSON = auxJSONBytes - msgJSON, err := json.Marshal(&jsonmessage.JSONMessage{ID: id, Aux: auxJSON}) + msgJSON, err := json.Marshal(&jsonMessage{ID: id, Aux: auxJSON}) if err != nil { return err } diff --git a/vendor/github.com/docker/docker/pkg/streamformatter/streamwriter.go b/vendor/github.com/docker/docker/pkg/streamformatter/streamwriter.go index 141d12e20eee..a5f26d565c98 100644 --- a/vendor/github.com/docker/docker/pkg/streamformatter/streamwriter.go +++ b/vendor/github.com/docker/docker/pkg/streamformatter/streamwriter.go @@ -3,8 +3,6 @@ package streamformatter import ( "encoding/json" "io" - - "github.com/docker/docker/pkg/jsonmessage" ) type streamWriter struct { @@ -22,7 +20,7 @@ func (sw *streamWriter) Write(buf []byte) (int, error) { } func (sw *streamWriter) format(buf []byte) []byte { - msg := &jsonmessage.JSONMessage{Stream: sw.lineFormat(buf)} + msg := &jsonMessage{Stream: sw.lineFormat(buf)} b, err := json.Marshal(msg) if err != nil { return FormatError(err) diff --git a/vendor/github.com/docker/go-connections/nat/nat.go b/vendor/github.com/docker/go-connections/nat/nat.go index 4049d780c54a..1ffe0355dc15 100644 --- a/vendor/github.com/docker/go-connections/nat/nat.go +++ b/vendor/github.com/docker/go-connections/nat/nat.go @@ -2,6 +2,7 @@ package nat import ( + "errors" "fmt" "net" "strconv" @@ -43,19 +44,19 @@ func NewPort(proto, port string) (Port, error) { // ParsePort parses the port number string and returns an int func ParsePort(rawPort string) (int, error) { - if len(rawPort) == 0 { + if rawPort == "" { return 0, nil } port, err := strconv.ParseUint(rawPort, 10, 16) if err != nil { - return 0, err + return 0, fmt.Errorf("invalid port '%s': %w", rawPort, errors.Unwrap(err)) } return int(port), nil } // ParsePortRangeToInt parses the port range string and returns start/end ints func ParsePortRangeToInt(rawPort string) (int, int, error) { - if len(rawPort) == 0 { + if rawPort == "" { return 0, 0, nil } start, end, err := ParsePortRange(rawPort) @@ -91,29 +92,31 @@ func (p Port) Range() (int, int, error) { return ParsePortRangeToInt(p.Port()) } -// SplitProtoPort splits a port in the format of proto/port -func SplitProtoPort(rawPort string) (string, string) { - parts := strings.Split(rawPort, "/") - l := len(parts) - if len(rawPort) == 0 || l == 0 || len(parts[0]) == 0 { +// SplitProtoPort splits a port(range) and protocol, formatted as "/[]" +// "/[]". It returns an empty string for both if +// no port(range) is provided. If a port(range) is provided, but no protocol, +// the default ("tcp") protocol is returned. +// +// SplitProtoPort does not validate or normalize the returned values. +func SplitProtoPort(rawPort string) (proto string, port string) { + port, proto, _ = strings.Cut(rawPort, "/") + if port == "" { return "", "" } - if l == 1 { - return "tcp", rawPort + if proto == "" { + proto = "tcp" } - if len(parts[1]) == 0 { - return "tcp", parts[0] - } - return parts[1], parts[0] + return proto, port } -func validateProto(proto string) bool { - for _, availableProto := range []string{"tcp", "udp", "sctp"} { - if availableProto == proto { - return true - } +func validateProto(proto string) error { + switch proto { + case "tcp", "udp", "sctp": + // All good + return nil + default: + return errors.New("invalid proto: " + proto) } - return false } // ParsePortSpecs receives port specs in the format of ip:public:private/proto and parses @@ -123,22 +126,18 @@ func ParsePortSpecs(ports []string) (map[Port]struct{}, map[Port][]PortBinding, exposedPorts = make(map[Port]struct{}, len(ports)) bindings = make(map[Port][]PortBinding) ) - for _, rawPort := range ports { - portMappings, err := ParsePortSpec(rawPort) + for _, p := range ports { + portMappings, err := ParsePortSpec(p) if err != nil { return nil, nil, err } - for _, portMapping := range portMappings { - port := portMapping.Port - if _, exists := exposedPorts[port]; !exists { + for _, pm := range portMappings { + port := pm.Port + if _, ok := exposedPorts[port]; !ok { exposedPorts[port] = struct{}{} } - bslice, exists := bindings[port] - if !exists { - bslice = []PortBinding{} - } - bindings[port] = append(bslice, portMapping.Binding) + bindings[port] = append(bindings[port], pm.Binding) } } return exposedPorts, bindings, nil @@ -150,28 +149,34 @@ type PortMapping struct { Binding PortBinding } -func splitParts(rawport string) (string, string, string) { +func (p *PortMapping) String() string { + return net.JoinHostPort(p.Binding.HostIP, p.Binding.HostPort+":"+string(p.Port)) +} + +func splitParts(rawport string) (hostIP, hostPort, containerPort string) { parts := strings.Split(rawport, ":") - n := len(parts) - containerPort := parts[n-1] - switch n { + switch len(parts) { case 1: - return "", "", containerPort + return "", "", parts[0] case 2: - return "", parts[0], containerPort + return "", parts[0], parts[1] case 3: - return parts[0], parts[1], containerPort + return parts[0], parts[1], parts[2] default: - return strings.Join(parts[:n-2], ":"), parts[n-2], containerPort + n := len(parts) + return strings.Join(parts[:n-2], ":"), parts[n-2], parts[n-1] } } // ParsePortSpec parses a port specification string into a slice of PortMappings func ParsePortSpec(rawPort string) ([]PortMapping, error) { - var proto string ip, hostPort, containerPort := splitParts(rawPort) - proto, containerPort = SplitProtoPort(containerPort) + proto, containerPort := SplitProtoPort(containerPort) + proto = strings.ToLower(proto) + if err := validateProto(proto); err != nil { + return nil, err + } if ip != "" && ip[0] == '[' { // Strip [] from IPV6 addresses @@ -182,7 +187,7 @@ func ParsePortSpec(rawPort string) ([]PortMapping, error) { ip = rawIP } if ip != "" && net.ParseIP(ip) == nil { - return nil, fmt.Errorf("invalid IP address: %s", ip) + return nil, errors.New("invalid IP address: " + ip) } if containerPort == "" { return nil, fmt.Errorf("no port specified: %s", rawPort) @@ -190,51 +195,43 @@ func ParsePortSpec(rawPort string) ([]PortMapping, error) { startPort, endPort, err := ParsePortRange(containerPort) if err != nil { - return nil, fmt.Errorf("invalid containerPort: %s", containerPort) + return nil, errors.New("invalid containerPort: " + containerPort) } - var startHostPort, endHostPort uint64 = 0, 0 - if len(hostPort) > 0 { + var startHostPort, endHostPort uint64 + if hostPort != "" { startHostPort, endHostPort, err = ParsePortRange(hostPort) if err != nil { - return nil, fmt.Errorf("invalid hostPort: %s", hostPort) + return nil, errors.New("invalid hostPort: " + hostPort) } - } - - if hostPort != "" && (endPort-startPort) != (endHostPort-startHostPort) { - // Allow host port range iff containerPort is not a range. - // In this case, use the host port range as the dynamic - // host port range to allocate into. - if endPort != startPort { - return nil, fmt.Errorf("invalid ranges specified for container and host Ports: %s and %s", containerPort, hostPort) + if (endPort - startPort) != (endHostPort - startHostPort) { + // Allow host port range iff containerPort is not a range. + // In this case, use the host port range as the dynamic + // host port range to allocate into. + if endPort != startPort { + return nil, fmt.Errorf("invalid ranges specified for container and host Ports: %s and %s", containerPort, hostPort) + } } } - if !validateProto(strings.ToLower(proto)) { - return nil, fmt.Errorf("invalid proto: %s", proto) - } - - ports := []PortMapping{} - for i := uint64(0); i <= (endPort - startPort); i++ { - containerPort = strconv.FormatUint(startPort+i, 10) - if len(hostPort) > 0 { - hostPort = strconv.FormatUint(startHostPort+i, 10) - } - // Set hostPort to a range only if there is a single container port - // and a dynamic host port. - if startPort == endPort && startHostPort != endHostPort { - hostPort = fmt.Sprintf("%s-%s", hostPort, strconv.FormatUint(endHostPort, 10)) - } - port, err := NewPort(strings.ToLower(proto), containerPort) - if err != nil { - return nil, err - } + count := endPort - startPort + 1 + ports := make([]PortMapping, 0, count) - binding := PortBinding{ - HostIP: ip, - HostPort: hostPort, + for i := uint64(0); i < count; i++ { + cPort := Port(strconv.FormatUint(startPort+i, 10) + "/" + proto) + hPort := "" + if hostPort != "" { + hPort = strconv.FormatUint(startHostPort+i, 10) + // Set hostPort to a range only if there is a single container port + // and a dynamic host port. + if count == 1 && startHostPort != endHostPort { + hPort += "-" + strconv.FormatUint(endHostPort, 10) + } } - ports = append(ports, PortMapping{Port: port, Binding: binding}) + ports = append(ports, PortMapping{ + Port: cPort, + Binding: PortBinding{HostIP: ip, HostPort: hPort}, + }) } return ports, nil } diff --git a/vendor/github.com/docker/go-connections/nat/parse.go b/vendor/github.com/docker/go-connections/nat/parse.go index e4b53e8a3242..64affa2a904c 100644 --- a/vendor/github.com/docker/go-connections/nat/parse.go +++ b/vendor/github.com/docker/go-connections/nat/parse.go @@ -1,7 +1,7 @@ package nat import ( - "fmt" + "errors" "strconv" "strings" ) @@ -9,7 +9,7 @@ import ( // ParsePortRange parses and validates the specified string as a port-range (8000-9000) func ParsePortRange(ports string) (uint64, uint64, error) { if ports == "" { - return 0, 0, fmt.Errorf("empty string specified for ports") + return 0, 0, errors.New("empty string specified for ports") } if !strings.Contains(ports, "-") { start, err := strconv.ParseUint(ports, 10, 16) @@ -27,7 +27,7 @@ func ParsePortRange(ports string) (uint64, uint64, error) { return 0, 0, err } if end < start { - return 0, 0, fmt.Errorf("invalid range specified for port: %s", ports) + return 0, 0, errors.New("invalid range specified for port: " + ports) } return start, end, nil } diff --git a/vendor/github.com/docker/go-connections/sockets/README.md b/vendor/github.com/docker/go-connections/sockets/README.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/vendor/github.com/docker/go-connections/sockets/proxy.go b/vendor/github.com/docker/go-connections/sockets/proxy.go index c897cb02adea..f04980e40a5a 100644 --- a/vendor/github.com/docker/go-connections/sockets/proxy.go +++ b/vendor/github.com/docker/go-connections/sockets/proxy.go @@ -9,6 +9,8 @@ import ( // GetProxyEnv allows access to the uppercase and the lowercase forms of // proxy-related variables. See the Go specification for details on these // variables. https://golang.org/pkg/net/http/ +// +// Deprecated: this function was used as helper for [DialerFromEnvironment] and is no longer used. It will be removed in the next release. func GetProxyEnv(key string) string { proxyValue := os.Getenv(strings.ToUpper(key)) if proxyValue == "" { @@ -19,10 +21,11 @@ func GetProxyEnv(key string) string { // DialerFromEnvironment was previously used to configure a net.Dialer to route // connections through a SOCKS proxy. -// DEPRECATED: SOCKS proxies are now supported by configuring only +// +// Deprecated: SOCKS proxies are now supported by configuring only // http.Transport.Proxy, and no longer require changing http.Transport.Dial. -// Therefore, only sockets.ConfigureTransport() needs to be called, and any -// sockets.DialerFromEnvironment() calls can be dropped. +// Therefore, only [sockets.ConfigureTransport] needs to be called, and any +// [sockets.DialerFromEnvironment] calls can be dropped. func DialerFromEnvironment(direct *net.Dialer) (*net.Dialer, error) { return direct, nil } diff --git a/vendor/github.com/docker/go-connections/sockets/sockets.go b/vendor/github.com/docker/go-connections/sockets/sockets.go index b0eae239d2c5..6117297860db 100644 --- a/vendor/github.com/docker/go-connections/sockets/sockets.go +++ b/vendor/github.com/docker/go-connections/sockets/sockets.go @@ -2,13 +2,19 @@ package sockets import ( + "context" "errors" + "fmt" "net" "net/http" + "syscall" "time" ) -const defaultTimeout = 10 * time.Second +const ( + defaultTimeout = 10 * time.Second + maxUnixSocketPathSize = len(syscall.RawSockaddrUnix{}.Path) +) // ErrProtocolNotAvailable is returned when a given transport protocol is not provided by the operating system. var ErrProtocolNotAvailable = errors.New("protocol not available") @@ -35,3 +41,26 @@ func ConfigureTransport(tr *http.Transport, proto, addr string) error { } return nil } + +// DialPipe connects to a Windows named pipe. It is not supported on +// non-Windows platforms. +// +// Deprecated: use [github.com/Microsoft/go-winio.DialPipe] or [github.com/Microsoft/go-winio.DialPipeContext]. +func DialPipe(addr string, timeout time.Duration) (net.Conn, error) { + return dialPipe(addr, timeout) +} + +func configureUnixTransport(tr *http.Transport, proto, addr string) error { + if len(addr) > maxUnixSocketPathSize { + return fmt.Errorf("unix socket path %q is too long", addr) + } + // No need for compression in local communications. + tr.DisableCompression = true + dialer := &net.Dialer{ + Timeout: defaultTimeout, + } + tr.DialContext = func(ctx context.Context, _, _ string) (net.Conn, error) { + return dialer.DialContext(ctx, proto, addr) + } + return nil +} diff --git a/vendor/github.com/docker/go-connections/sockets/sockets_unix.go b/vendor/github.com/docker/go-connections/sockets/sockets_unix.go index 78a34a980d28..913d2f00dd2f 100644 --- a/vendor/github.com/docker/go-connections/sockets/sockets_unix.go +++ b/vendor/github.com/docker/go-connections/sockets/sockets_unix.go @@ -3,37 +3,16 @@ package sockets import ( - "context" - "fmt" "net" "net/http" "syscall" "time" ) -const maxUnixSocketPathSize = len(syscall.RawSockaddrUnix{}.Path) - -func configureUnixTransport(tr *http.Transport, proto, addr string) error { - if len(addr) > maxUnixSocketPathSize { - return fmt.Errorf("unix socket path %q is too long", addr) - } - // No need for compression in local communications. - tr.DisableCompression = true - dialer := &net.Dialer{ - Timeout: defaultTimeout, - } - tr.DialContext = func(ctx context.Context, _, _ string) (net.Conn, error) { - return dialer.DialContext(ctx, proto, addr) - } - return nil -} - func configureNpipeTransport(tr *http.Transport, proto, addr string) error { return ErrProtocolNotAvailable } -// DialPipe connects to a Windows named pipe. -// This is not supported on other OSes. -func DialPipe(_ string, _ time.Duration) (net.Conn, error) { +func dialPipe(_ string, _ time.Duration) (net.Conn, error) { return nil, syscall.EAFNOSUPPORT } diff --git a/vendor/github.com/docker/go-connections/sockets/sockets_windows.go b/vendor/github.com/docker/go-connections/sockets/sockets_windows.go index 7acafc5a2ad8..6d6beb3855c0 100644 --- a/vendor/github.com/docker/go-connections/sockets/sockets_windows.go +++ b/vendor/github.com/docker/go-connections/sockets/sockets_windows.go @@ -9,10 +9,6 @@ import ( "github.com/Microsoft/go-winio" ) -func configureUnixTransport(tr *http.Transport, proto, addr string) error { - return ErrProtocolNotAvailable -} - func configureNpipeTransport(tr *http.Transport, proto, addr string) error { // No need for compression in local communications. tr.DisableCompression = true @@ -22,7 +18,6 @@ func configureNpipeTransport(tr *http.Transport, proto, addr string) error { return nil } -// DialPipe connects to a Windows named pipe. -func DialPipe(addr string, timeout time.Duration) (net.Conn, error) { +func dialPipe(addr string, timeout time.Duration) (net.Conn, error) { return winio.DialPipe(addr, &timeout) } diff --git a/vendor/github.com/docker/go-connections/sockets/unix_socket.go b/vendor/github.com/docker/go-connections/sockets/unix_socket.go index b9233521e49a..e736f71d38b1 100644 --- a/vendor/github.com/docker/go-connections/sockets/unix_socket.go +++ b/vendor/github.com/docker/go-connections/sockets/unix_socket.go @@ -1,5 +1,3 @@ -//go:build !windows - /* Package sockets is a simple unix domain socket wrapper. @@ -57,26 +55,6 @@ import ( // SockOption sets up socket file's creating option type SockOption func(string) error -// WithChown modifies the socket file's uid and gid -func WithChown(uid, gid int) SockOption { - return func(path string) error { - if err := os.Chown(path, uid, gid); err != nil { - return err - } - return nil - } -} - -// WithChmod modifies socket file's access mode. -func WithChmod(mask os.FileMode) SockOption { - return func(path string) error { - if err := os.Chmod(path, mask); err != nil { - return err - } - return nil - } -} - // NewUnixSocketWithOpts creates a unix socket with the specified options. // By default, socket permissions are 0000 (i.e.: no access for anyone); pass // WithChmod() and WithChown() to set the desired ownership and permissions. @@ -90,22 +68,7 @@ func NewUnixSocketWithOpts(path string, opts ...SockOption) (net.Listener, error return nil, err } - // net.Listen does not allow for permissions to be set. As a result, when - // specifying custom permissions ("WithChmod()"), there is a short time - // between creating the socket and applying the permissions, during which - // the socket permissions are Less restrictive than desired. - // - // To work around this limitation of net.Listen(), we temporarily set the - // umask to 0777, which forces the socket to be created with 000 permissions - // (i.e.: no access for anyone). After that, WithChmod() must be used to set - // the desired permissions. - // - // We don't use "defer" here, to reset the umask to its original value as soon - // as possible. Ideally we'd be able to detect if WithChmod() was passed as - // an option, and skip changing umask if default permissions are used. - origUmask := syscall.Umask(0o777) - l, err := net.Listen("unix", path) - syscall.Umask(origUmask) + l, err := listenUnix(path) if err != nil { return nil, err } @@ -119,8 +82,3 @@ func NewUnixSocketWithOpts(path string, opts ...SockOption) (net.Listener, error return l, nil } - -// NewUnixSocket creates a unix socket with the specified path and group. -func NewUnixSocket(path string, gid int) (net.Listener, error) { - return NewUnixSocketWithOpts(path, WithChown(0, gid), WithChmod(0o660)) -} diff --git a/vendor/github.com/docker/go-connections/sockets/unix_socket_unix.go b/vendor/github.com/docker/go-connections/sockets/unix_socket_unix.go new file mode 100644 index 000000000000..a41a71654742 --- /dev/null +++ b/vendor/github.com/docker/go-connections/sockets/unix_socket_unix.go @@ -0,0 +1,54 @@ +//go:build !windows + +package sockets + +import ( + "net" + "os" + "syscall" +) + +// WithChown modifies the socket file's uid and gid +func WithChown(uid, gid int) SockOption { + return func(path string) error { + if err := os.Chown(path, uid, gid); err != nil { + return err + } + return nil + } +} + +// WithChmod modifies socket file's access mode. +func WithChmod(mask os.FileMode) SockOption { + return func(path string) error { + if err := os.Chmod(path, mask); err != nil { + return err + } + return nil + } +} + +// NewUnixSocket creates a unix socket with the specified path and group. +func NewUnixSocket(path string, gid int) (net.Listener, error) { + return NewUnixSocketWithOpts(path, WithChown(0, gid), WithChmod(0o660)) +} + +func listenUnix(path string) (net.Listener, error) { + // net.Listen does not allow for permissions to be set. As a result, when + // specifying custom permissions ("WithChmod()"), there is a short time + // between creating the socket and applying the permissions, during which + // the socket permissions are Less restrictive than desired. + // + // To work around this limitation of net.Listen(), we temporarily set the + // umask to 0777, which forces the socket to be created with 000 permissions + // (i.e.: no access for anyone). After that, WithChmod() must be used to set + // the desired permissions. + // + // We don't use "defer" here, to reset the umask to its original value as soon + // as possible. Ideally we'd be able to detect if WithChmod() was passed as + // an option, and skip changing umask if default permissions are used. + origUmask := syscall.Umask(0o777) + l, err := net.Listen("unix", path) + syscall.Umask(origUmask) + return l, err +} diff --git a/vendor/github.com/docker/go-connections/sockets/unix_socket_windows.go b/vendor/github.com/docker/go-connections/sockets/unix_socket_windows.go new file mode 100644 index 000000000000..5ec29e059e78 --- /dev/null +++ b/vendor/github.com/docker/go-connections/sockets/unix_socket_windows.go @@ -0,0 +1,7 @@ +package sockets + +import "net" + +func listenUnix(path string) (net.Listener, error) { + return net.Listen("unix", path) +} diff --git a/vendor/github.com/docker/go-connections/tlsconfig/config.go b/vendor/github.com/docker/go-connections/tlsconfig/config.go index 606c98a38b51..8b0264f68b75 100644 --- a/vendor/github.com/docker/go-connections/tlsconfig/config.go +++ b/vendor/github.com/docker/go-connections/tlsconfig/config.go @@ -34,51 +34,37 @@ type Options struct { // the system pool will be used. ExclusiveRootPools bool MinVersion uint16 - // If Passphrase is set, it will be used to decrypt a TLS private key - // if the key is encrypted. - // - // Deprecated: Use of encrypted TLS private keys has been deprecated, and - // will be removed in a future release. Golang has deprecated support for - // legacy PEM encryption (as specified in RFC 1423), as it is insecure by - // design (see https://go-review.googlesource.com/c/go/+/264159). - Passphrase string -} - -// Extra (server-side) accepted CBC cipher suites - will phase out in the future -var acceptedCBCCiphers = []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, } // DefaultServerAcceptedCiphers should be uses by code which already has a crypto/tls // options struct but wants to use a commonly accepted set of TLS cipher suites, with // known weak algorithms removed. -var DefaultServerAcceptedCiphers = append(clientCipherSuites, acceptedCBCCiphers...) +var DefaultServerAcceptedCiphers = defaultCipherSuites + +// defaultCipherSuites is shared by both client and server as the default set. +var defaultCipherSuites = []uint16{ + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, +} // ServerDefault returns a secure-enough TLS configuration for the server TLS configuration. func ServerDefault(ops ...func(*tls.Config)) *tls.Config { - tlsConfig := &tls.Config{ - // Avoid fallback by default to SSL protocols < TLS1.2 - MinVersion: tls.VersionTLS12, - PreferServerCipherSuites: true, - CipherSuites: DefaultServerAcceptedCiphers, - } - - for _, op := range ops { - op(tlsConfig) - } - - return tlsConfig + return defaultConfig(ops...) } // ClientDefault returns a secure-enough TLS configuration for the client TLS configuration. func ClientDefault(ops ...func(*tls.Config)) *tls.Config { + return defaultConfig(ops...) +} + +// defaultConfig is the default config used by both client and server TLS configuration. +func defaultConfig(ops ...func(*tls.Config)) *tls.Config { tlsConfig := &tls.Config{ - // Prefer TLS1.2 as the client minimum + // Avoid fallback by default to SSL protocols < TLS1.2 MinVersion: tls.VersionTLS12, - CipherSuites: clientCipherSuites, + CipherSuites: defaultCipherSuites, } for _, op := range ops { @@ -92,13 +78,13 @@ func ClientDefault(ops ...func(*tls.Config)) *tls.Config { func certPool(caFile string, exclusivePool bool) (*x509.CertPool, error) { // If we should verify the server, we need to load a trusted ca var ( - certPool *x509.CertPool - err error + pool *x509.CertPool + err error ) if exclusivePool { - certPool = x509.NewCertPool() + pool = x509.NewCertPool() } else { - certPool, err = SystemCertPool() + pool, err = SystemCertPool() if err != nil { return nil, fmt.Errorf("failed to read system certificates: %v", err) } @@ -107,10 +93,10 @@ func certPool(caFile string, exclusivePool bool) (*x509.CertPool, error) { if err != nil { return nil, fmt.Errorf("could not read CA certificate %q: %v", caFile, err) } - if !certPool.AppendCertsFromPEM(pemData) { + if !pool.AppendCertsFromPEM(pemData) { return nil, fmt.Errorf("failed to append certificates from PEM file: %q", caFile) } - return certPool, nil + return pool, nil } // allTLSVersions lists all the TLS versions and is used by the code that validates @@ -144,34 +130,32 @@ func adjustMinVersion(options Options, config *tls.Config) error { return nil } -// IsErrEncryptedKey returns true if the 'err' is an error of incorrect -// password when trying to decrypt a TLS private key. +// errEncryptedKeyDeprecated is produced when we encounter an encrypted +// (password-protected) key. From https://go-review.googlesource.com/c/go/+/264159; // -// Deprecated: Use of encrypted TLS private keys has been deprecated, and -// will be removed in a future release. Golang has deprecated support for -// legacy PEM encryption (as specified in RFC 1423), as it is insecure by -// design (see https://go-review.googlesource.com/c/go/+/264159). -func IsErrEncryptedKey(err error) bool { - return errors.Is(err, x509.IncorrectPasswordError) -} +// > Legacy PEM encryption as specified in RFC 1423 is insecure by design. Since +// > it does not authenticate the ciphertext, it is vulnerable to padding oracle +// > attacks that can let an attacker recover the plaintext +// > +// > It's unfortunate that we don't implement PKCS#8 encryption so we can't +// > recommend an alternative but PEM encryption is so broken that it's worth +// > deprecating outright. +// +// Also see https://docs.docker.com/go/deprecated/ +var errEncryptedKeyDeprecated = errors.New("private key is encrypted; encrypted private keys are obsolete, and not supported") // getPrivateKey returns the private key in 'keyBytes', in PEM-encoded format. -// If the private key is encrypted, 'passphrase' is used to decrypted the -// private key. -func getPrivateKey(keyBytes []byte, passphrase string) ([]byte, error) { +// It returns an error if the file could not be decoded or was protected by +// a passphrase. +func getPrivateKey(keyBytes []byte) ([]byte, error) { // this section makes some small changes to code from notary/tuf/utils/x509.go pemBlock, _ := pem.Decode(keyBytes) if pemBlock == nil { return nil, fmt.Errorf("no valid private key found") } - var err error if x509.IsEncryptedPEMBlock(pemBlock) { //nolint:staticcheck // Ignore SA1019 (IsEncryptedPEMBlock is deprecated) - keyBytes, err = x509.DecryptPEMBlock(pemBlock, []byte(passphrase)) //nolint:staticcheck // Ignore SA1019 (DecryptPEMBlock is deprecated) - if err != nil { - return nil, fmt.Errorf("private key is encrypted, but could not decrypt it: %w", err) - } - keyBytes = pem.EncodeToMemory(&pem.Block{Type: pemBlock.Type, Bytes: keyBytes}) + return nil, errEncryptedKeyDeprecated } return keyBytes, nil @@ -195,7 +179,7 @@ func getCert(options Options) ([]tls.Certificate, error) { return nil, err } - prKeyBytes, err = getPrivateKey(prKeyBytes, options.Passphrase) + prKeyBytes, err = getPrivateKey(prKeyBytes) if err != nil { return nil, err } @@ -210,7 +194,7 @@ func getCert(options Options) ([]tls.Certificate, error) { // Client returns a TLS configuration meant to be used by a client. func Client(options Options) (*tls.Config, error) { - tlsConfig := ClientDefault() + tlsConfig := defaultConfig() tlsConfig.InsecureSkipVerify = options.InsecureSkipVerify if !options.InsecureSkipVerify && options.CAFile != "" { CAs, err := certPool(options.CAFile, options.ExclusiveRootPools) @@ -235,7 +219,7 @@ func Client(options Options) (*tls.Config, error) { // Server returns a TLS configuration meant to be used by a server. func Server(options Options) (*tls.Config, error) { - tlsConfig := ServerDefault() + tlsConfig := defaultConfig() tlsConfig.ClientAuth = options.ClientAuth tlsCert, err := tls.LoadX509KeyPair(options.CertFile, options.KeyFile) if err != nil { diff --git a/vendor/github.com/docker/go-connections/tlsconfig/config_client_ciphers.go b/vendor/github.com/docker/go-connections/tlsconfig/config_client_ciphers.go deleted file mode 100644 index a82f9fa52e2e..000000000000 --- a/vendor/github.com/docker/go-connections/tlsconfig/config_client_ciphers.go +++ /dev/null @@ -1,14 +0,0 @@ -// Package tlsconfig provides primitives to retrieve secure-enough TLS configurations for both clients and servers. -package tlsconfig - -import ( - "crypto/tls" -) - -// Client TLS cipher suites (dropping CBC ciphers for client preferred suite set) -var clientCipherSuites = []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, -} diff --git a/vendor/github.com/moby/moby/api/LICENSE b/vendor/github.com/moby/moby/api/LICENSE new file mode 100644 index 000000000000..6d8d58fb676b --- /dev/null +++ b/vendor/github.com/moby/moby/api/LICENSE @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2013-2018 Docker, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/moby/moby/api/pkg/progress/progress.go b/vendor/github.com/moby/moby/api/pkg/progress/progress.go new file mode 100644 index 000000000000..7d2d59606009 --- /dev/null +++ b/vendor/github.com/moby/moby/api/pkg/progress/progress.go @@ -0,0 +1,93 @@ +package progress + +import ( + "fmt" +) + +// Progress represents the progress of a transfer. +type Progress struct { + ID string + + // Progress contains a Message or... + Message string + + // ...progress of an action + Action string + Current int64 + Total int64 + + // If true, don't show xB/yB + HideCounts bool + // If not empty, use units instead of bytes for counts + Units string + + // Aux contains extra information not presented to the user, such as + // digests for push signing. + Aux any + + LastUpdate bool +} + +// Output is an interface for writing progress information. It's +// like a writer for progress, but we don't call it Writer because +// that would be confusing next to ProgressReader (also, because it +// doesn't implement the io.Writer interface). +type Output interface { + WriteProgress(Progress) error +} + +type chanOutput chan<- Progress + +func (out chanOutput) WriteProgress(p Progress) error { + // FIXME: workaround for panic in #37735 + defer func() { + recover() + }() + out <- p + return nil +} + +// ChanOutput returns an Output that writes progress updates to the +// supplied channel. +func ChanOutput(progressChan chan<- Progress) Output { + return chanOutput(progressChan) +} + +type discardOutput struct{} + +func (discardOutput) WriteProgress(Progress) error { + return nil +} + +// DiscardOutput returns an Output that discards progress +func DiscardOutput() Output { + return discardOutput{} +} + +// Update is a convenience function to write a progress update to the channel. +func Update(out Output, id, action string) { + out.WriteProgress(Progress{ID: id, Action: action}) +} + +// Updatef is a convenience function to write a printf-formatted progress update +// to the channel. +func Updatef(out Output, id, format string, a ...any) { + Update(out, id, fmt.Sprintf(format, a...)) +} + +// Message is a convenience function to write a progress message to the channel. +func Message(out Output, id, message string) { + out.WriteProgress(Progress{ID: id, Message: message}) +} + +// Messagef is a convenience function to write a printf-formatted progress +// message to the channel. +func Messagef(out Output, id, format string, a ...any) { + Message(out, id, fmt.Sprintf(format, a...)) +} + +// Aux sends auxiliary information over a progress interface, which will not be +// formatted for the UI. This is used for things such as push signing. +func Aux(out Output, a any) { + out.WriteProgress(Progress{Aux: a}) +} diff --git a/vendor/github.com/moby/moby/api/pkg/progress/progressreader.go b/vendor/github.com/moby/moby/api/pkg/progress/progressreader.go new file mode 100644 index 000000000000..7a2954ec9920 --- /dev/null +++ b/vendor/github.com/moby/moby/api/pkg/progress/progressreader.go @@ -0,0 +1,66 @@ +package progress + +import ( + "io" + "time" + + "golang.org/x/time/rate" +) + +// Reader is a Reader with progress bar. +type Reader struct { + in io.ReadCloser // Stream to read from + out Output // Where to send progress bar to + size int64 + current int64 + lastUpdate int64 + id string + action string + rateLimiter *rate.Limiter +} + +// NewProgressReader creates a new ProgressReader. +func NewProgressReader(in io.ReadCloser, out Output, size int64, id, action string) *Reader { + return &Reader{ + in: in, + out: out, + size: size, + id: id, + action: action, + rateLimiter: rate.NewLimiter(rate.Every(100*time.Millisecond), 1), + } +} + +func (p *Reader) Read(buf []byte) (int, error) { + read, err := p.in.Read(buf) + p.current += int64(read) + updateEvery := int64(1024 * 512) // 512kB + if p.size > 0 { + // Update progress for every 1% read if 1% < 512kB + if increment := int64(0.01 * float64(p.size)); increment < updateEvery { + updateEvery = increment + } + } + if p.current-p.lastUpdate > updateEvery || err != nil { + p.updateProgress(err != nil && read == 0) + p.lastUpdate = p.current + } + + return read, err +} + +// Close closes the progress reader and its underlying reader. +func (p *Reader) Close() error { + if p.current < p.size { + // print a full progress bar when closing prematurely + p.current = p.size + p.updateProgress(false) + } + return p.in.Close() +} + +func (p *Reader) updateProgress(last bool) { + if last || p.current == p.size || p.rateLimiter.Allow() { + p.out.WriteProgress(Progress{ID: p.id, Action: p.action, Current: p.current, Total: p.size, LastUpdate: last}) + } +} diff --git a/vendor/github.com/docker/docker/pkg/stdcopy/stdcopy.go b/vendor/github.com/moby/moby/api/pkg/stdcopy/stdcopy.go similarity index 51% rename from vendor/github.com/docker/docker/pkg/stdcopy/stdcopy.go rename to vendor/github.com/moby/moby/api/pkg/stdcopy/stdcopy.go index 611432a6261f..3d52b1cdbb78 100644 --- a/vendor/github.com/docker/docker/pkg/stdcopy/stdcopy.go +++ b/vendor/github.com/moby/moby/api/pkg/stdcopy/stdcopy.go @@ -14,16 +14,13 @@ import ( type StdType byte const ( - // Stdin represents standard input stream type. - Stdin StdType = iota - // Stdout represents standard output stream type. - Stdout - // Stderr represents standard error steam type. - Stderr - // Systemerr represents errors originating from the system that make it - // into the multiplexed stream. - Systemerr + Stdin StdType = 0 // Stdin represents standard input stream. It is present for completeness and should NOT be used. When reading the stream with [StdCopy] it is output on [Stdout]. + Stdout StdType = 1 // Stdout represents standard output stream. + Stderr StdType = 2 // Stderr represents standard error steam. + Systemerr StdType = 3 // Systemerr represents errors originating from the system. When reading the stream with [StdCopy] it is returned as an error. +) +const ( stdWriterPrefixLen = 8 stdWriterFdIndex = 0 stdWriterSizeIndex = 4 @@ -31,7 +28,7 @@ const ( startingBufLen = 32*1024 + stdWriterPrefixLen + 1 ) -var bufPool = &sync.Pool{New: func() interface{} { return bytes.NewBuffer(nil) }} +var bufPool = &sync.Pool{New: func() any { return bytes.NewBuffer(nil) }} // stdWriter is wrapper of io.Writer with extra customized info. type stdWriter struct { @@ -39,10 +36,11 @@ type stdWriter struct { prefix byte } -// Write sends the buffer to the underneath writer. +// Write sends the buffer to the underlying writer. // It inserts the prefix header before the buffer, -// so stdcopy.StdCopy knows where to multiplex the output. -// It makes stdWriter to implement io.Writer. +// so [StdCopy] knows where to multiplex the output. +// +// It implements [io.Writer]. func (w *stdWriter) Write(p []byte) (int, error) { if w == nil || w.Writer == nil { return 0, errors.New("writer not instantiated") @@ -68,30 +66,55 @@ func (w *stdWriter) Write(p []byte) (int, error) { return n, err } -// NewStdWriter instantiates a new Writer. -// Everything written to it will be encapsulated using a custom format, -// and written to the underlying `w` stream. -// This allows multiple write streams (e.g. stdout and stderr) to be muxed into a single connection. -// `t` indicates the id of the stream to encapsulate. -// It can be stdcopy.Stdin, stdcopy.Stdout, stdcopy.Stderr. -func NewStdWriter(w io.Writer, t StdType) io.Writer { +// NewStdWriter instantiates a new writer using a custom format to multiplex +// multiple streams to a single writer. All messages written using this writer +// are encapsulated using a custom format, and written to the underlying +// stream "w". +// +// Writers created through NewStdWriter allow for multiple write streams +// (e.g., stdout ([Stdout]) and stderr ([Stderr]) to be multiplexed into a +// single connection. "streamType" indicates the type of stream to encapsulate, +// commonly, [Stdout] or [Stderr]. The [Systemerr] stream can be used to +// include server-side errors in the stream. Information on this stream +// is returned as an error by [StdCopy] and terminates processing the +// stream. +// +// The [Stdin] stream is present for completeness and should generally +// NOT be used. It is output on [Stdout] when reading the stream with +// [StdCopy]. +// +// All streams must share the same underlying [io.Writer] to ensure proper +// multiplexing. Each call to NewStdWriter wraps that shared writer with +// a header indicating the target stream. +func NewStdWriter(w io.Writer, streamType StdType) io.Writer { return &stdWriter{ Writer: w, - prefix: byte(t), + prefix: byte(streamType), } } -// StdCopy is a modified version of io.Copy. +// StdCopy is a modified version of [io.Copy] to de-multiplex messages +// from "multiplexedSource" and copy them to destination streams +// "destOut" and "destErr". +// +// StdCopy demultiplexes "multiplexedSource", assuming that it contains +// two streams, previously multiplexed using a writer created with +// [NewStdWriter]. // -// StdCopy will demultiplex `src`, assuming that it contains two streams, -// previously multiplexed together using a StdWriter instance. -// As it reads from `src`, StdCopy will write to `dstout` and `dsterr`. +// As it reads from "multiplexedSource", StdCopy writes [Stdout] messages +// to "destOut", and [Stderr] message to "destErr]. For backward-compatibility, +// [Stdin] messages are output to "destOut". The [Systemerr] stream provides +// errors produced by the daemon. It is returned as an error, and terminates +// processing the stream. // -// StdCopy will read until it hits EOF on `src`. It will then return a nil error. -// In other words: if `err` is non nil, it indicates a real underlying error. +// StdCopy it reads until it hits [io.EOF] on "multiplexedSource", after +// which it returns a nil error. In other words: any error returned indicates +// a real underlying error, which may be when an unknown [StdType] stream +// is received. // -// `written` will hold the total number of bytes written to `dstout` and `dsterr`. -func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, _ error) { +// The "written" return holds the total number of bytes written to "destOut" +// and "destErr" combined. +func StdCopy(destOut, destErr io.Writer, multiplexedSource io.Reader) (written int64, _ error) { var ( buf = make([]byte, startingBufLen) bufLen = len(buf) @@ -105,7 +128,7 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, _ error) { // Make sure we have at least a full header for nr < stdWriterPrefixLen { var nr2 int - nr2, err = src.Read(buf[nr:]) + nr2, err = multiplexedSource.Read(buf[nr:]) nr += nr2 if errors.Is(err, io.EOF) { if nr < stdWriterPrefixLen { @@ -118,24 +141,24 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, _ error) { } } - stream := StdType(buf[stdWriterFdIndex]) // Check the first byte to know where to write + stream := StdType(buf[stdWriterFdIndex]) switch stream { case Stdin: fallthrough case Stdout: // Write on stdout - out = dstout + out = destOut case Stderr: // Write on stderr - out = dsterr + out = destErr case Systemerr: // If we're on Systemerr, we won't write anywhere. // NB: if this code changes later, make sure you don't try to write // to outstream if Systemerr is the stream out = nil default: - return 0, fmt.Errorf("Unrecognized input header: %d", buf[stdWriterFdIndex]) + return 0, fmt.Errorf("unrecognized stream: %d", stream) } // Retrieve the size of the frame @@ -151,7 +174,7 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, _ error) { // While the amount of bytes read is less than the size of the frame + header, we keep reading for nr < frameSize+stdWriterPrefixLen { var nr2 int - nr2, err = src.Read(buf[nr:]) + nr2, err = multiplexedSource.Read(buf[nr:]) nr += nr2 if errors.Is(err, io.EOF) { if nr < frameSize+stdWriterPrefixLen { diff --git a/vendor/github.com/docker/docker/api/types/auxprogress/push.go b/vendor/github.com/moby/moby/api/types/auxprogress/push.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/auxprogress/push.go rename to vendor/github.com/moby/moby/api/types/auxprogress/push.go diff --git a/vendor/github.com/docker/docker/api/types/blkiodev/blkio.go b/vendor/github.com/moby/moby/api/types/blkiodev/blkio.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/blkiodev/blkio.go rename to vendor/github.com/moby/moby/api/types/blkiodev/blkio.go diff --git a/vendor/github.com/docker/docker/api/types/build/build.go b/vendor/github.com/moby/moby/api/types/build/build.go similarity index 96% rename from vendor/github.com/docker/docker/api/types/build/build.go rename to vendor/github.com/moby/moby/api/types/build/build.go index c43a0e21ea74..a798802357a7 100644 --- a/vendor/github.com/docker/docker/api/types/build/build.go +++ b/vendor/github.com/moby/moby/api/types/build/build.go @@ -3,8 +3,8 @@ package build import ( "io" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/registry" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/registry" ) // BuilderVersion sets the version of underlying builder to use diff --git a/vendor/github.com/docker/docker/api/types/build/cache.go b/vendor/github.com/moby/moby/api/types/build/cache.go similarity index 97% rename from vendor/github.com/docker/docker/api/types/build/cache.go rename to vendor/github.com/moby/moby/api/types/build/cache.go index 42c840457364..442bd903d939 100644 --- a/vendor/github.com/docker/docker/api/types/build/cache.go +++ b/vendor/github.com/moby/moby/api/types/build/cache.go @@ -3,7 +3,7 @@ package build import ( "time" - "github.com/docker/docker/api/types/filters" + "github.com/moby/moby/api/types/filters" ) // CacheRecord contains information about a build cache record. diff --git a/vendor/github.com/docker/docker/api/types/checkpoint/list.go b/vendor/github.com/moby/moby/api/types/checkpoint/list.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/checkpoint/list.go rename to vendor/github.com/moby/moby/api/types/checkpoint/list.go diff --git a/vendor/github.com/docker/docker/api/types/checkpoint/options.go b/vendor/github.com/moby/moby/api/types/checkpoint/options.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/checkpoint/options.go rename to vendor/github.com/moby/moby/api/types/checkpoint/options.go diff --git a/vendor/github.com/docker/docker/api/types/error_response.go b/vendor/github.com/moby/moby/api/types/common/error_response.go similarity index 73% rename from vendor/github.com/docker/docker/api/types/error_response.go rename to vendor/github.com/moby/moby/api/types/common/error_response.go index dc942d9d9efa..b49d3eea0a25 100644 --- a/vendor/github.com/docker/docker/api/types/error_response.go +++ b/vendor/github.com/moby/moby/api/types/common/error_response.go @@ -1,9 +1,13 @@ -package types +// Code generated by go-swagger; DO NOT EDIT. + +package common // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command // ErrorResponse Represents an error. +// Example: {"message":"Something went wrong."} +// // swagger:model ErrorResponse type ErrorResponse struct { diff --git a/vendor/github.com/docker/docker/api/types/error_response_ext.go b/vendor/github.com/moby/moby/api/types/common/error_response_ext.go similarity index 86% rename from vendor/github.com/docker/docker/api/types/error_response_ext.go rename to vendor/github.com/moby/moby/api/types/common/error_response_ext.go index f84f034cd545..c92dfe4b12ed 100644 --- a/vendor/github.com/docker/docker/api/types/error_response_ext.go +++ b/vendor/github.com/moby/moby/api/types/common/error_response_ext.go @@ -1,4 +1,4 @@ -package types +package common // Error returns the error message func (e ErrorResponse) Error() string { diff --git a/vendor/github.com/docker/docker/api/types/common/id_response.go b/vendor/github.com/moby/moby/api/types/common/id_response.go similarity index 87% rename from vendor/github.com/docker/docker/api/types/common/id_response.go rename to vendor/github.com/moby/moby/api/types/common/id_response.go index 22e8c60a48d3..7dfe4bf12b55 100644 --- a/vendor/github.com/docker/docker/api/types/common/id_response.go +++ b/vendor/github.com/moby/moby/api/types/common/id_response.go @@ -1,9 +1,12 @@ +// Code generated by go-swagger; DO NOT EDIT. + package common // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command // IDResponse Response to an API call that returns just an Id +// // swagger:model IDResponse type IDResponse struct { diff --git a/vendor/github.com/docker/docker/api/types/container/change_type.go b/vendor/github.com/moby/moby/api/types/container/change_type.go similarity index 87% rename from vendor/github.com/docker/docker/api/types/container/change_type.go rename to vendor/github.com/moby/moby/api/types/container/change_type.go index fe8d6d36966e..52fc99235b1e 100644 --- a/vendor/github.com/docker/docker/api/types/container/change_type.go +++ b/vendor/github.com/moby/moby/api/types/container/change_type.go @@ -1,3 +1,5 @@ +// Code generated by go-swagger; DO NOT EDIT. + package container // This file was generated by the swagger tool. diff --git a/vendor/github.com/docker/docker/api/types/container/change_types.go b/vendor/github.com/moby/moby/api/types/container/change_types.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/container/change_types.go rename to vendor/github.com/moby/moby/api/types/container/change_types.go diff --git a/vendor/github.com/docker/docker/api/types/container/commit.go b/vendor/github.com/moby/moby/api/types/container/commit.go similarity index 76% rename from vendor/github.com/docker/docker/api/types/container/commit.go rename to vendor/github.com/moby/moby/api/types/container/commit.go index 6fd1b0ead138..c5aab26ff4f0 100644 --- a/vendor/github.com/docker/docker/api/types/container/commit.go +++ b/vendor/github.com/moby/moby/api/types/container/commit.go @@ -1,6 +1,6 @@ package container -import "github.com/docker/docker/api/types/common" +import "github.com/moby/moby/api/types/common" // CommitResponse response for the commit API call, containing the ID of the // image that was produced. diff --git a/vendor/github.com/docker/docker/api/types/container/config.go b/vendor/github.com/moby/moby/api/types/container/config.go similarity index 91% rename from vendor/github.com/docker/docker/api/types/container/config.go rename to vendor/github.com/moby/moby/api/types/container/config.go index 0555416540bf..4c507cab93cd 100644 --- a/vendor/github.com/docker/docker/api/types/container/config.go +++ b/vendor/github.com/moby/moby/api/types/container/config.go @@ -3,8 +3,6 @@ package container import ( "time" - "github.com/docker/docker/api/types/strslice" - "github.com/docker/go-connections/nat" dockerspec "github.com/moby/docker-image-spec/specs-go/v1" ) @@ -48,18 +46,18 @@ type Config struct { AttachStdin bool // Attach the standard input, makes possible user interaction AttachStdout bool // Attach the standard output AttachStderr bool // Attach the standard error - ExposedPorts nat.PortSet `json:",omitempty"` // List of exposed ports + ExposedPorts PortSet `json:",omitempty"` // List of exposed ports Tty bool // Attach standard streams to a tty, including stdin if it is not closed. OpenStdin bool // Open stdin StdinOnce bool // If true, close stdin after the 1 attached client disconnects. Env []string // List of environment variable to set in the container - Cmd strslice.StrSlice // Command to run when starting the container + Cmd []string // Command to run when starting the container Healthcheck *HealthConfig `json:",omitempty"` // Healthcheck describes how to check the container is healthy ArgsEscaped bool `json:",omitempty"` // True if command is already escaped (meaning treat as a command line) (Windows specific). Image string // Name of the image as it was passed by the operator (e.g. could be symbolic) Volumes map[string]struct{} // List of volumes (mounts) used for the container WorkingDir string // Current directory (PWD) in the command will be launched - Entrypoint strslice.StrSlice // Entrypoint to run when starting the container + Entrypoint []string // Entrypoint to run when starting the container NetworkDisabled bool `json:",omitempty"` // Is network disabled // Mac Address of the container. // @@ -69,5 +67,5 @@ type Config struct { Labels map[string]string // List of labels set to this container StopSignal string `json:",omitempty"` // Signal to stop a container StopTimeout *int `json:",omitempty"` // Timeout (in seconds) to stop a container - Shell strslice.StrSlice `json:",omitempty"` // Shell for shell-form of RUN, CMD, ENTRYPOINT + Shell []string `json:",omitempty"` // Shell for shell-form of RUN, CMD, ENTRYPOINT } diff --git a/vendor/github.com/docker/docker/api/types/container/container.go b/vendor/github.com/moby/moby/api/types/container/container.go similarity index 83% rename from vendor/github.com/docker/docker/api/types/container/container.go rename to vendor/github.com/moby/moby/api/types/container/container.go index a191ca8bdb73..80d5ec9c97f5 100644 --- a/vendor/github.com/docker/docker/api/types/container/container.go +++ b/vendor/github.com/moby/moby/api/types/container/container.go @@ -1,25 +1,14 @@ package container import ( - "io" "os" "time" - "github.com/docker/docker/api/types/mount" - "github.com/docker/docker/api/types/storage" + "github.com/moby/moby/api/types/mount" + "github.com/moby/moby/api/types/storage" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) -// ContainerUpdateOKBody OK response to ContainerUpdate operation -// -// Deprecated: use [UpdateResponse]. This alias will be removed in the next release. -type ContainerUpdateOKBody = UpdateResponse - -// ContainerTopOKBody OK response to ContainerTop operation -// -// Deprecated: use [TopResponse]. This alias will be removed in the next release. -type ContainerTopOKBody = TopResponse - // PruneReport contains the response for Engine API: // POST "/containers/prune" type PruneReport struct { @@ -45,23 +34,10 @@ type CopyToContainerOptions struct { CopyUIDGID bool } -// StatsResponseReader wraps an io.ReadCloser to read (a stream of) stats -// for a container, as produced by the GET "/stats" endpoint. -// -// The OSType field is set to the server's platform to allow -// platform-specific handling of the response. -// -// TODO(thaJeztah): remove this wrapper, and make OSType part of [StatsResponse]. -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 is the type of mount, see [mount.Type] definitions for details. Type mount.Type `json:",omitempty"` // Name is the name reference to the underlying data defined by `Source` @@ -128,7 +104,7 @@ type Summary struct { ImageManifestDescriptor *ocispec.Descriptor `json:"ImageManifestDescriptor,omitempty"` Command string Created int64 - Ports []Port + Ports []PortSummary SizeRw int64 `json:",omitempty"` SizeRootFs int64 `json:",omitempty"` Labels map[string]string @@ -138,6 +114,7 @@ type Summary struct { NetworkMode string `json:",omitempty"` Annotations map[string]string `json:",omitempty"` } + Health *HealthSummary `json:",omitempty"` NetworkSettings *NetworkSettingsSummary Mounts []MountPoint } diff --git a/vendor/github.com/docker/docker/api/types/container/create_request.go b/vendor/github.com/moby/moby/api/types/container/create_request.go similarity index 89% rename from vendor/github.com/docker/docker/api/types/container/create_request.go rename to vendor/github.com/moby/moby/api/types/container/create_request.go index e98dd6ad449b..decb208af0e7 100644 --- a/vendor/github.com/docker/docker/api/types/container/create_request.go +++ b/vendor/github.com/moby/moby/api/types/container/create_request.go @@ -1,6 +1,6 @@ package container -import "github.com/docker/docker/api/types/network" +import "github.com/moby/moby/api/types/network" // CreateRequest is the request message sent to the server for container // create calls. It is a config wrapper that holds the container [Config] diff --git a/vendor/github.com/docker/docker/api/types/container/create_response.go b/vendor/github.com/moby/moby/api/types/container/create_response.go similarity index 70% rename from vendor/github.com/docker/docker/api/types/container/create_response.go rename to vendor/github.com/moby/moby/api/types/container/create_response.go index aa0e7f7d0789..39d761aa968c 100644 --- a/vendor/github.com/docker/docker/api/types/container/create_response.go +++ b/vendor/github.com/moby/moby/api/types/container/create_response.go @@ -1,3 +1,5 @@ +// Code generated by go-swagger; DO NOT EDIT. + package container // This file was generated by the swagger tool. @@ -5,15 +7,18 @@ package container // CreateResponse ContainerCreateResponse // -// OK response to ContainerCreate operation +// # OK response to ContainerCreate operation +// // swagger:model CreateResponse type CreateResponse struct { // The ID of the created container + // Example: ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743 // Required: true ID string `json:"Id"` // Warnings encountered when creating the container + // Example: [] // Required: true Warnings []string `json:"Warnings"` } diff --git a/vendor/github.com/docker/docker/api/types/container/errors.go b/vendor/github.com/moby/moby/api/types/container/errors.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/container/errors.go rename to vendor/github.com/moby/moby/api/types/container/errors.go diff --git a/vendor/github.com/docker/docker/api/types/container/exec.go b/vendor/github.com/moby/moby/api/types/container/exec.go similarity index 57% rename from vendor/github.com/docker/docker/api/types/container/exec.go rename to vendor/github.com/moby/moby/api/types/container/exec.go index e455cd27b278..d4ed9f8bd247 100644 --- a/vendor/github.com/docker/docker/api/types/container/exec.go +++ b/vendor/github.com/moby/moby/api/types/container/exec.go @@ -1,6 +1,6 @@ package container -import "github.com/docker/docker/api/types/common" +import "github.com/moby/moby/api/types/common" // ExecCreateResponse is the response for a successful exec-create request. // It holds the ID of the exec that was created. @@ -44,10 +44,42 @@ type ExecStartOptions struct { type ExecAttachOptions = ExecStartOptions // ExecInspect holds information returned by exec inspect. +// +// It is used by the client to unmarshal a [ExecInspectResponse], +// but currently only provides a subset of the information included +// in that type. +// +// TODO(thaJeztah): merge [ExecInspect] and [ExecInspectResponse], type ExecInspect struct { ExecID string `json:"ID"` - ContainerID string - Running bool - ExitCode int - Pid int + ContainerID string `json:"ContainerID"` + Running bool `json:"Running"` + ExitCode int `json:"ExitCode"` + Pid int `json:"Pid"` +} + +// ExecInspectResponse is the API response for the "GET /exec/{id}/json" +// endpoint and holds information about and exec. +type ExecInspectResponse struct { + ID string `json:"ID"` + Running bool `json:"Running"` + ExitCode *int `json:"ExitCode"` + ProcessConfig *ExecProcessConfig + OpenStdin bool `json:"OpenStdin"` + OpenStderr bool `json:"OpenStderr"` + OpenStdout bool `json:"OpenStdout"` + CanRemove bool `json:"CanRemove"` + ContainerID string `json:"ContainerID"` + DetachKeys []byte `json:"DetachKeys"` + Pid int `json:"Pid"` +} + +// ExecProcessConfig holds information about the exec process +// running on the host. +type ExecProcessConfig struct { + Tty bool `json:"tty"` + Entrypoint string `json:"entrypoint"` + Arguments []string `json:"arguments"` + Privileged *bool `json:"privileged,omitempty"` + User string `json:"user,omitempty"` } diff --git a/vendor/github.com/docker/docker/api/types/container/filesystem_change.go b/vendor/github.com/moby/moby/api/types/container/filesystem_change.go similarity index 90% rename from vendor/github.com/docker/docker/api/types/container/filesystem_change.go rename to vendor/github.com/moby/moby/api/types/container/filesystem_change.go index 9e9c2ad1d588..b9ec83e52190 100644 --- a/vendor/github.com/docker/docker/api/types/container/filesystem_change.go +++ b/vendor/github.com/moby/moby/api/types/container/filesystem_change.go @@ -1,3 +1,5 @@ +// Code generated by go-swagger; DO NOT EDIT. + package container // This file was generated by the swagger tool. diff --git a/vendor/github.com/docker/docker/api/types/container/health.go b/vendor/github.com/moby/moby/api/types/container/health.go similarity index 86% rename from vendor/github.com/docker/docker/api/types/container/health.go rename to vendor/github.com/moby/moby/api/types/container/health.go index 96e91cc8d8a8..b7fe592cc25b 100644 --- a/vendor/github.com/docker/docker/api/types/container/health.go +++ b/vendor/github.com/moby/moby/api/types/container/health.go @@ -26,6 +26,12 @@ type Health struct { Log []*HealthcheckResult // Log contains the last few results (oldest first) } +// HealthSummary stores a summary of the container's healthcheck results. +type HealthSummary struct { + Status HealthStatus // Status is one of [NoHealthcheck], [Starting], [Healthy] or [Unhealthy]. + FailingStreak int // FailingStreak is the number of consecutive failures +} + // HealthcheckResult stores information about a single run of a healthcheck probe type HealthcheckResult struct { Start time.Time // Start is the time this check started diff --git a/vendor/github.com/docker/docker/api/types/container/hostconfig.go b/vendor/github.com/moby/moby/api/types/container/hostconfig.go similarity index 97% rename from vendor/github.com/docker/docker/api/types/container/hostconfig.go rename to vendor/github.com/moby/moby/api/types/container/hostconfig.go index f63f049c7c25..0fb65e19218c 100644 --- a/vendor/github.com/docker/docker/api/types/container/hostconfig.go +++ b/vendor/github.com/moby/moby/api/types/container/hostconfig.go @@ -5,12 +5,10 @@ import ( "fmt" "strings" - "github.com/docker/docker/api/types/blkiodev" - "github.com/docker/docker/api/types/mount" - "github.com/docker/docker/api/types/network" - "github.com/docker/docker/api/types/strslice" - "github.com/docker/go-connections/nat" "github.com/docker/go-units" + "github.com/moby/moby/api/types/blkiodev" + "github.com/moby/moby/api/types/mount" + "github.com/moby/moby/api/types/network" ) // CgroupnsMode represents the cgroup namespace mode of the container @@ -427,7 +425,7 @@ type HostConfig struct { ContainerIDFile string // File (path) where the containerId is written LogConfig LogConfig // Configuration of the logs for this container NetworkMode NetworkMode // Network mode to use for the container - PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host + PortBindings PortMap // Port mapping between the exposed port (container) and the host RestartPolicy RestartPolicy // Restart policy to be used for the container AutoRemove bool // Automatically remove container when it exits VolumeDriver string // Name of the volume driver used to mount volumes @@ -436,8 +434,8 @@ type HostConfig struct { Annotations map[string]string `json:",omitempty"` // Arbitrary non-identifying metadata attached to container and provided to the runtime // Applicable to UNIX platforms - CapAdd strslice.StrSlice // List of kernel capabilities to add to the container - CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container + CapAdd []string // List of kernel capabilities to add to the container + CapDrop []string // List of kernel capabilities to remove from the container CgroupnsMode CgroupnsMode // Cgroup namespace mode to use for the container DNS []string `json:"Dns"` // List of DNS server to lookup DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for diff --git a/vendor/github.com/docker/docker/api/types/container/hostconfig_unix.go b/vendor/github.com/moby/moby/api/types/container/hostconfig_unix.go similarity index 95% rename from vendor/github.com/docker/docker/api/types/container/hostconfig_unix.go rename to vendor/github.com/moby/moby/api/types/container/hostconfig_unix.go index cd6a7a9be22b..326a5da7ebef 100644 --- a/vendor/github.com/docker/docker/api/types/container/hostconfig_unix.go +++ b/vendor/github.com/moby/moby/api/types/container/hostconfig_unix.go @@ -2,7 +2,7 @@ package container -import "github.com/docker/docker/api/types/network" +import "github.com/moby/moby/api/types/network" // IsValid indicates if an isolation technology is valid func (i Isolation) IsValid() bool { diff --git a/vendor/github.com/docker/docker/api/types/container/hostconfig_windows.go b/vendor/github.com/moby/moby/api/types/container/hostconfig_windows.go similarity index 95% rename from vendor/github.com/docker/docker/api/types/container/hostconfig_windows.go rename to vendor/github.com/moby/moby/api/types/container/hostconfig_windows.go index db63e190d199..977a3760237e 100644 --- a/vendor/github.com/docker/docker/api/types/container/hostconfig_windows.go +++ b/vendor/github.com/moby/moby/api/types/container/hostconfig_windows.go @@ -1,6 +1,6 @@ package container -import "github.com/docker/docker/api/types/network" +import "github.com/moby/moby/api/types/network" // IsValid indicates if an isolation technology is valid func (i Isolation) IsValid() bool { diff --git a/vendor/github.com/moby/moby/api/types/container/nat_aliases.go b/vendor/github.com/moby/moby/api/types/container/nat_aliases.go new file mode 100644 index 000000000000..470f15655cc3 --- /dev/null +++ b/vendor/github.com/moby/moby/api/types/container/nat_aliases.go @@ -0,0 +1,24 @@ +package container + +import "github.com/docker/go-connections/nat" + +// PortRangeProto is a string containing port number and protocol in the format "80/tcp", +// or a port range and protocol in the format "80-83/tcp". +// +// It is currently an alias for [nat.Port] but may become a concrete type in a future release. +type PortRangeProto = nat.Port + +// PortSet is a collection of structs indexed by [HostPort]. +// +// It is currently an alias for [nat.PortSet] but may become a concrete type in a future release. +type PortSet = nat.PortSet + +// PortBinding represents a binding between a Host IP address and a [HostPort]. +// +// It is currently an alias for [nat.PortBinding] but may become a concrete type in a future release. +type PortBinding = nat.PortBinding + +// PortMap is a collection of [PortBinding] indexed by [HostPort]. +// +// It is currently an alias for [nat.PortMap] but may become a concrete type in a future release. +type PortMap = nat.PortMap diff --git a/vendor/github.com/docker/docker/api/types/container/network_settings.go b/vendor/github.com/moby/moby/api/types/container/network_settings.go similarity index 83% rename from vendor/github.com/docker/docker/api/types/container/network_settings.go rename to vendor/github.com/moby/moby/api/types/container/network_settings.go index afec0e54323e..40d5cbd1de6d 100644 --- a/vendor/github.com/docker/docker/api/types/container/network_settings.go +++ b/vendor/github.com/moby/moby/api/types/container/network_settings.go @@ -1,8 +1,7 @@ package container import ( - "github.com/docker/docker/api/types/network" - "github.com/docker/go-connections/nat" + "github.com/moby/moby/api/types/network" ) // NetworkSettings exposes the network settings in the api @@ -14,10 +13,10 @@ type NetworkSettings struct { // 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 + 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 PortMap // Ports is a collection of PortBinding indexed by Port // HairpinMode specifies if hairpin NAT should be enabled on the virtual interface // diff --git a/vendor/github.com/docker/docker/api/types/container/options.go b/vendor/github.com/moby/moby/api/types/container/options.go similarity index 96% rename from vendor/github.com/docker/docker/api/types/container/options.go rename to vendor/github.com/moby/moby/api/types/container/options.go index 7a2300576923..b94152cb4767 100644 --- a/vendor/github.com/docker/docker/api/types/container/options.go +++ b/vendor/github.com/moby/moby/api/types/container/options.go @@ -1,6 +1,6 @@ package container -import "github.com/docker/docker/api/types/filters" +import "github.com/moby/moby/api/types/filters" // ResizeOptions holds parameters to resize a TTY. // It can be used to resize container TTYs and diff --git a/vendor/github.com/docker/docker/api/types/container/port.go b/vendor/github.com/moby/moby/api/types/container/port_summary.go similarity index 62% rename from vendor/github.com/docker/docker/api/types/container/port.go rename to vendor/github.com/moby/moby/api/types/container/port_summary.go index 895043cfe94f..3956224dcc6e 100644 --- a/vendor/github.com/docker/docker/api/types/container/port.go +++ b/vendor/github.com/moby/moby/api/types/container/port_summary.go @@ -1,11 +1,16 @@ +// Code generated by go-swagger; DO NOT EDIT. + package container // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command -// Port An open port on a container -// swagger:model Port -type Port struct { +// PortSummary Describes a port-mapping between the container and the host. +// +// Example: {"PrivatePort":8080,"PublicPort":80,"Type":"tcp"} +// +// swagger:model PortSummary +type PortSummary struct { // Host IP address that the container's port is mapped to IP string `json:"IP,omitempty"` @@ -19,5 +24,6 @@ type Port struct { // type // Required: true + // Enum: ["tcp","udp","sctp"] Type string `json:"Type"` } diff --git a/vendor/github.com/moby/moby/api/types/container/state.go b/vendor/github.com/moby/moby/api/types/container/state.go new file mode 100644 index 000000000000..6de2df66abb5 --- /dev/null +++ b/vendor/github.com/moby/moby/api/types/container/state.go @@ -0,0 +1,36 @@ +package container + +import ( + "fmt" + "strings" +) + +// ContainerState is a string representation of the container's current state. +// +// It currently is an alias for string, but may become a distinct type in the future. +type ContainerState = string + +const ( + StateCreated ContainerState = "created" // StateCreated indicates the container is created, but not (yet) started. + StateRunning ContainerState = "running" // StateRunning indicates that the container is running. + StatePaused ContainerState = "paused" // StatePaused indicates that the container's current state is paused. + StateRestarting ContainerState = "restarting" // StateRestarting indicates that the container is currently restarting. + StateRemoving ContainerState = "removing" // StateRemoving indicates that the container is being removed. + StateExited ContainerState = "exited" // StateExited indicates that the container exited. + StateDead ContainerState = "dead" // StateDead indicates that the container failed to be deleted. Containers in this state are attempted to be cleaned up when the daemon restarts. +) + +var validStates = []ContainerState{ + StateCreated, StateRunning, StatePaused, StateRestarting, StateRemoving, StateExited, StateDead, +} + +// ValidateContainerState checks if the provided string is a valid +// container [ContainerState]. +func ValidateContainerState(s ContainerState) error { + switch s { + case StateCreated, StateRunning, StatePaused, StateRestarting, StateRemoving, StateExited, StateDead: + return nil + default: + return errInvalidParameter{error: fmt.Errorf("invalid value for state (%s): must be one of %s", s, strings.Join(validStates, ", "))} + } +} diff --git a/vendor/github.com/docker/docker/api/types/container/stats.go b/vendor/github.com/moby/moby/api/types/container/stats.go similarity index 97% rename from vendor/github.com/docker/docker/api/types/container/stats.go rename to vendor/github.com/moby/moby/api/types/container/stats.go index 3bfeb4849f91..133bc35ecf9a 100644 --- a/vendor/github.com/docker/docker/api/types/container/stats.go +++ b/vendor/github.com/moby/moby/api/types/container/stats.go @@ -147,11 +147,6 @@ type PidsStats struct { Limit uint64 `json:"limit,omitempty"` } -// Stats is Ultimate struct aggregating all types of stats of one container -// -// Deprecated: use [StatsResponse] instead. This type will be removed in the next release. -type Stats = StatsResponse - // StatsResponse aggregates all types of stats of one container. type StatsResponse struct { Name string `json:"name,omitempty"` diff --git a/vendor/github.com/docker/docker/api/types/container/top_response.go b/vendor/github.com/moby/moby/api/types/container/top_response.go similarity index 63% rename from vendor/github.com/docker/docker/api/types/container/top_response.go rename to vendor/github.com/moby/moby/api/types/container/top_response.go index b4bae5ef036b..966603617f11 100644 --- a/vendor/github.com/docker/docker/api/types/container/top_response.go +++ b/vendor/github.com/moby/moby/api/types/container/top_response.go @@ -1,3 +1,5 @@ +// Code generated by go-swagger; DO NOT EDIT. + package container // This file was generated by the swagger tool. @@ -6,13 +8,16 @@ package container // TopResponse ContainerTopResponse // // Container "top" response. +// // swagger:model TopResponse type TopResponse struct { // Each process running in the container, where each process // is an array of values corresponding to the titles. + // Example: {"Processes":[["root","13642","882","0","17:03","pts/0","00:00:00","/bin/bash"],["root","13735","13642","0","17:06","pts/0","00:00:00","sleep 10"]]} Processes [][]string `json:"Processes"` // The ps column titles + // Example: {"Titles":["UID","PID","PPID","C","STIME","TTY","TIME","CMD"]} Titles []string `json:"Titles"` } diff --git a/vendor/github.com/docker/docker/api/types/container/update_response.go b/vendor/github.com/moby/moby/api/types/container/update_response.go similarity index 76% rename from vendor/github.com/docker/docker/api/types/container/update_response.go rename to vendor/github.com/moby/moby/api/types/container/update_response.go index e2b5bf5ac0e4..2f7263b14119 100644 --- a/vendor/github.com/docker/docker/api/types/container/update_response.go +++ b/vendor/github.com/moby/moby/api/types/container/update_response.go @@ -1,3 +1,5 @@ +// Code generated by go-swagger; DO NOT EDIT. + package container // This file was generated by the swagger tool. @@ -6,9 +8,11 @@ package container // UpdateResponse ContainerUpdateResponse // // Response for a successful container-update. +// // swagger:model UpdateResponse type UpdateResponse struct { // Warnings encountered when updating the container. + // Example: ["Published ports are discarded when using host network mode"] Warnings []string `json:"Warnings"` } diff --git a/vendor/github.com/docker/docker/api/types/container/wait_exit_error.go b/vendor/github.com/moby/moby/api/types/container/wait_exit_error.go similarity index 86% rename from vendor/github.com/docker/docker/api/types/container/wait_exit_error.go rename to vendor/github.com/moby/moby/api/types/container/wait_exit_error.go index ab56d4eed8e1..96a7770c34a7 100644 --- a/vendor/github.com/docker/docker/api/types/container/wait_exit_error.go +++ b/vendor/github.com/moby/moby/api/types/container/wait_exit_error.go @@ -1,9 +1,12 @@ +// Code generated by go-swagger; DO NOT EDIT. + package container // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command // WaitExitError container waiting error, if any +// // swagger:model WaitExitError type WaitExitError struct { diff --git a/vendor/github.com/docker/docker/api/types/container/wait_response.go b/vendor/github.com/moby/moby/api/types/container/wait_response.go similarity index 80% rename from vendor/github.com/docker/docker/api/types/container/wait_response.go rename to vendor/github.com/moby/moby/api/types/container/wait_response.go index 84fc6afddc60..68d3c3872421 100644 --- a/vendor/github.com/docker/docker/api/types/container/wait_response.go +++ b/vendor/github.com/moby/moby/api/types/container/wait_response.go @@ -1,3 +1,5 @@ +// Code generated by go-swagger; DO NOT EDIT. + package container // This file was generated by the swagger tool. @@ -5,7 +7,8 @@ package container // WaitResponse ContainerWaitResponse // -// OK response to ContainerWait operation +// # OK response to ContainerWait operation +// // swagger:model WaitResponse type WaitResponse struct { diff --git a/vendor/github.com/docker/docker/api/types/container/waitcondition.go b/vendor/github.com/moby/moby/api/types/container/waitcondition.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/container/waitcondition.go rename to vendor/github.com/moby/moby/api/types/container/waitcondition.go diff --git a/vendor/github.com/docker/docker/api/types/events/events.go b/vendor/github.com/moby/moby/api/types/events/events.go similarity index 99% rename from vendor/github.com/docker/docker/api/types/events/events.go rename to vendor/github.com/moby/moby/api/types/events/events.go index 952c0ff2429c..d5bf3059d6f1 100644 --- a/vendor/github.com/docker/docker/api/types/events/events.go +++ b/vendor/github.com/moby/moby/api/types/events/events.go @@ -1,6 +1,6 @@ package events -import "github.com/docker/docker/api/types/filters" +import "github.com/moby/moby/api/types/filters" // Type is used for event-types. type Type string diff --git a/vendor/github.com/docker/docker/api/types/filters/errors.go b/vendor/github.com/moby/moby/api/types/filters/errors.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/filters/errors.go rename to vendor/github.com/moby/moby/api/types/filters/errors.go diff --git a/vendor/github.com/docker/docker/api/types/filters/parse.go b/vendor/github.com/moby/moby/api/types/filters/parse.go similarity index 89% rename from vendor/github.com/docker/docker/api/types/filters/parse.go rename to vendor/github.com/moby/moby/api/types/filters/parse.go index 86f4bdb28e17..396657bb1921 100644 --- a/vendor/github.com/docker/docker/api/types/filters/parse.go +++ b/vendor/github.com/moby/moby/api/types/filters/parse.go @@ -8,8 +8,6 @@ import ( "encoding/json" "regexp" "strings" - - "github.com/docker/docker/api/types/versions" ) // Args stores a mapping of keys to a set of multiple values. @@ -63,24 +61,6 @@ func ToJSON(a Args) (string, error) { return string(buf), err } -// ToParamWithVersion encodes Args as a JSON string. If version is less than 1.22 -// then the encoded format will use an older legacy format where the values are a -// list of strings, instead of a set. -// -// Deprecated: do not use in any new code; use ToJSON instead -func ToParamWithVersion(version string, a Args) (string, error) { - if a.Len() == 0 { - return "", nil - } - - if version != "" && versions.LessThan(version, "1.22") { - buf, err := json.Marshal(convertArgsToSlice(a.fields)) - return string(buf), err - } - - return ToJSON(a) -} - // FromJSON decodes a JSON encoded string into Args func FromJSON(p string) (Args, error) { args := NewArgs() @@ -320,17 +300,3 @@ func deprecatedArgs(d map[string][]string) map[string]map[string]bool { } return m } - -func convertArgsToSlice(f map[string]map[string]bool) map[string][]string { - m := map[string][]string{} - for k, v := range f { - values := []string{} - for kk := range v { - if v[kk] { - values = append(values, kk) - } - } - m[k] = values - } - return m -} diff --git a/vendor/github.com/docker/docker/api/types/image/delete_response.go b/vendor/github.com/moby/moby/api/types/image/delete_response.go similarity index 89% rename from vendor/github.com/docker/docker/api/types/image/delete_response.go rename to vendor/github.com/moby/moby/api/types/image/delete_response.go index 998620dc6a25..b19119a381e6 100644 --- a/vendor/github.com/docker/docker/api/types/image/delete_response.go +++ b/vendor/github.com/moby/moby/api/types/image/delete_response.go @@ -1,9 +1,12 @@ +// Code generated by go-swagger; DO NOT EDIT. + package image // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command // DeleteResponse delete response +// // swagger:model DeleteResponse type DeleteResponse struct { diff --git a/vendor/github.com/docker/docker/api/types/image/image.go b/vendor/github.com/moby/moby/api/types/image/image.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/image/image.go rename to vendor/github.com/moby/moby/api/types/image/image.go diff --git a/vendor/github.com/docker/docker/api/types/image/image_history.go b/vendor/github.com/moby/moby/api/types/image/image_history.go similarity index 99% rename from vendor/github.com/docker/docker/api/types/image/image_history.go rename to vendor/github.com/moby/moby/api/types/image/image_history.go index a6cdab84d8a9..40aa9625856f 100644 --- a/vendor/github.com/docker/docker/api/types/image/image_history.go +++ b/vendor/github.com/moby/moby/api/types/image/image_history.go @@ -7,6 +7,7 @@ package image // ---------------------------------------------------------------------------- // HistoryResponseItem individual image layer information in response to ImageHistory operation +// // swagger:model HistoryResponseItem type HistoryResponseItem struct { diff --git a/vendor/github.com/docker/docker/api/types/image/image_inspect.go b/vendor/github.com/moby/moby/api/types/image/image_inspect.go similarity index 98% rename from vendor/github.com/docker/docker/api/types/image/image_inspect.go rename to vendor/github.com/moby/moby/api/types/image/image_inspect.go index 3bdb474287c0..4335f733d507 100644 --- a/vendor/github.com/docker/docker/api/types/image/image_inspect.go +++ b/vendor/github.com/moby/moby/api/types/image/image_inspect.go @@ -1,9 +1,9 @@ package image import ( - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/storage" dockerspec "github.com/moby/docker-image-spec/specs-go/v1" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/storage" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) diff --git a/vendor/github.com/docker/docker/api/types/image/manifest.go b/vendor/github.com/moby/moby/api/types/image/manifest.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/image/manifest.go rename to vendor/github.com/moby/moby/api/types/image/manifest.go diff --git a/vendor/github.com/docker/docker/api/types/image/opts.go b/vendor/github.com/moby/moby/api/types/image/opts.go similarity index 94% rename from vendor/github.com/docker/docker/api/types/image/opts.go rename to vendor/github.com/moby/moby/api/types/image/opts.go index 9e33a42fa63b..789037a59d4b 100644 --- a/vendor/github.com/docker/docker/api/types/image/opts.go +++ b/vendor/github.com/moby/moby/api/types/image/opts.go @@ -4,7 +4,7 @@ import ( "context" "io" - "github.com/docker/docker/api/types/filters" + "github.com/moby/moby/api/types/filters" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -38,7 +38,7 @@ type PullOptions struct { // 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]. + // For details, refer to [github.com/moby/moby/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. // - // For details, refer to [github.com/docker/docker/api/types/registry.RequestAuthConfig]. + // For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig]. PrivilegeFunc func(context.Context) (string, error) // Platform is an optional field that selects a specific platform to push diff --git a/vendor/github.com/docker/docker/api/types/image/summary.go b/vendor/github.com/moby/moby/api/types/image/summary.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/image/summary.go rename to vendor/github.com/moby/moby/api/types/image/summary.go diff --git a/vendor/github.com/moby/moby/api/types/jsonstream/json_error.go b/vendor/github.com/moby/moby/api/types/jsonstream/json_error.go new file mode 100644 index 000000000000..632b25fdf49a --- /dev/null +++ b/vendor/github.com/moby/moby/api/types/jsonstream/json_error.go @@ -0,0 +1,12 @@ +package jsonstream + +// Error wraps a concrete Code and Message, Code is +// an integer error code, Message is the error message. +type Error struct { + Code int `json:"code,omitempty"` + Message string `json:"message,omitempty"` +} + +func (e *Error) Error() string { + return e.Message +} diff --git a/vendor/github.com/moby/moby/api/types/jsonstream/progress.go b/vendor/github.com/moby/moby/api/types/jsonstream/progress.go new file mode 100644 index 000000000000..5c38b3b5efc2 --- /dev/null +++ b/vendor/github.com/moby/moby/api/types/jsonstream/progress.go @@ -0,0 +1,10 @@ +package jsonstream + +// Progress describes a progress message in a JSON stream. +type Progress struct { + Current int64 `json:"current,omitempty"` // Current is the current status and value of the progress made towards Total. + Total int64 `json:"total,omitempty"` // Total is the end value describing when we made 100% progress for an operation. + Start int64 `json:"start,omitempty"` // Start is the initial value for the operation. + HideCounts bool `json:"hidecounts,omitempty"` // HideCounts. if true, hides the progress count indicator (xB/yB). + Units string `json:"units,omitempty"` // Units is the unit to print for progress. It defaults to "bytes" if empty. +} diff --git a/vendor/github.com/docker/docker/api/types/mount/mount.go b/vendor/github.com/moby/moby/api/types/mount/mount.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/mount/mount.go rename to vendor/github.com/moby/moby/api/types/mount/mount.go diff --git a/vendor/github.com/docker/docker/api/types/network/create_response.go b/vendor/github.com/moby/moby/api/types/network/create_response.go similarity index 71% rename from vendor/github.com/docker/docker/api/types/network/create_response.go rename to vendor/github.com/moby/moby/api/types/network/create_response.go index c32b35bff522..199705991297 100644 --- a/vendor/github.com/docker/docker/api/types/network/create_response.go +++ b/vendor/github.com/moby/moby/api/types/network/create_response.go @@ -1,3 +1,5 @@ +// Code generated by go-swagger; DO NOT EDIT. + package network // This file was generated by the swagger tool. @@ -5,11 +7,13 @@ package network // CreateResponse NetworkCreateResponse // -// OK response to NetworkCreate operation +// # OK response to NetworkCreate operation +// // swagger:model CreateResponse type CreateResponse struct { // The ID of the created network. + // Example: b5c4fc71e8022147cd25de22b22173de4e3b170134117172eb595cb91b4e7e5d // Required: true ID string `json:"Id"` diff --git a/vendor/github.com/docker/docker/api/types/network/endpoint.go b/vendor/github.com/moby/moby/api/types/network/endpoint.go similarity index 85% rename from vendor/github.com/docker/docker/api/types/network/endpoint.go rename to vendor/github.com/moby/moby/api/types/network/endpoint.go index 167ac70ab56a..39b732e0e7e2 100644 --- a/vendor/github.com/docker/docker/api/types/network/endpoint.go +++ b/vendor/github.com/moby/moby/api/types/network/endpoint.go @@ -3,9 +3,9 @@ package network import ( "errors" "fmt" + "maps" "net" - - "github.com/docker/docker/internal/multierror" + "slices" ) // EndpointSettings stores the network endpoint details @@ -41,25 +41,16 @@ type EndpointSettings struct { // Copy makes a deep copy of `EndpointSettings` func (es *EndpointSettings) Copy() *EndpointSettings { - epCopy := *es - if es.IPAMConfig != nil { - epCopy.IPAMConfig = es.IPAMConfig.Copy() - } - - if es.Links != nil { - links := make([]string, 0, len(es.Links)) - epCopy.Links = append(links, es.Links...) - } - - if es.Aliases != nil { - aliases := make([]string, 0, len(es.Aliases)) - epCopy.Aliases = append(aliases, es.Aliases...) + if es == nil { + return nil } - if len(es.DNSNames) > 0 { - epCopy.DNSNames = make([]string, len(es.DNSNames)) - copy(epCopy.DNSNames, es.DNSNames) - } + epCopy := *es + epCopy.IPAMConfig = es.IPAMConfig.Copy() + epCopy.Links = slices.Clone(es.Links) + epCopy.Aliases = slices.Clone(es.Aliases) + epCopy.DNSNames = slices.Clone(es.DNSNames) + epCopy.DriverOpts = maps.Clone(es.DriverOpts) return &epCopy } @@ -73,9 +64,11 @@ type EndpointIPAMConfig struct { // Copy makes a copy of the endpoint ipam config func (cfg *EndpointIPAMConfig) Copy() *EndpointIPAMConfig { + if cfg == nil { + return nil + } cfgCopy := *cfg - cfgCopy.LinkLocalIPs = make([]string, 0, len(cfg.LinkLocalIPs)) - cfgCopy.LinkLocalIPs = append(cfgCopy.LinkLocalIPs, cfg.LinkLocalIPs...) + cfgCopy.LinkLocalIPs = slices.Clone(cfg.LinkLocalIPs) return &cfgCopy } @@ -99,7 +92,7 @@ func (cfg *EndpointIPAMConfig) IsInRange(v4Subnets []NetworkSubnet, v6Subnets [] errs = append(errs, err) } - return multierror.Join(errs...) + return errJoin(errs...) } func validateEndpointIPAddress(epAddr string, ipamSubnets []NetworkSubnet) error { @@ -149,5 +142,5 @@ func (cfg *EndpointIPAMConfig) Validate() error { } } - return multierror.Join(errs...) + return errJoin(errs...) } diff --git a/vendor/github.com/docker/docker/api/types/network/ipam.go b/vendor/github.com/moby/moby/api/types/network/ipam.go similarity index 81% rename from vendor/github.com/docker/docker/api/types/network/ipam.go rename to vendor/github.com/moby/moby/api/types/network/ipam.go index f319e1402b08..f9a9ff9b358f 100644 --- a/vendor/github.com/docker/docker/api/types/network/ipam.go +++ b/vendor/github.com/moby/moby/api/types/network/ipam.go @@ -4,8 +4,7 @@ import ( "errors" "fmt" "net/netip" - - "github.com/docker/docker/internal/multierror" + "strings" ) // IPAM represents IP Address Management @@ -72,7 +71,7 @@ func ValidateIPAM(ipam *IPAM, enableIPv6 bool) error { } } - if err := multierror.Join(errs...); err != nil { + if err := errJoin(errs...); err != nil { return fmt.Errorf("invalid network config:\n%w", err) } @@ -132,3 +131,43 @@ func validateAddress(address string, subnet netip.Prefix, subnetFamily ipFamily) return nil } + +func errJoin(errs ...error) error { + n := 0 + for _, err := range errs { + if err != nil { + n++ + } + } + if n == 0 { + return nil + } + e := &joinError{ + errs: make([]error, 0, n), + } + for _, err := range errs { + if err != nil { + e.errs = append(e.errs, err) + } + } + return e +} + +type joinError struct { + errs []error +} + +func (e *joinError) Error() string { + if len(e.errs) == 1 { + return strings.TrimSpace(e.errs[0].Error()) + } + stringErrs := make([]string, 0, len(e.errs)) + for _, subErr := range e.errs { + stringErrs = append(stringErrs, strings.ReplaceAll(subErr.Error(), "\n", "\n\t")) + } + return "* " + strings.Join(stringErrs, "\n* ") +} + +func (e *joinError) Unwrap() []error { + return e.errs +} diff --git a/vendor/github.com/docker/docker/api/types/network/network.go b/vendor/github.com/moby/moby/api/types/network/network.go similarity index 99% rename from vendor/github.com/docker/docker/api/types/network/network.go rename to vendor/github.com/moby/moby/api/types/network/network.go index 4a0cb479848d..f9a206f1890d 100644 --- a/vendor/github.com/docker/docker/api/types/network/network.go +++ b/vendor/github.com/moby/moby/api/types/network/network.go @@ -3,7 +3,7 @@ package network import ( "time" - "github.com/docker/docker/api/types/filters" + "github.com/moby/moby/api/types/filters" ) const ( diff --git a/vendor/github.com/moby/moby/api/types/plugin/.gitignore b/vendor/github.com/moby/moby/api/types/plugin/.gitignore new file mode 100644 index 000000000000..5cea8434d772 --- /dev/null +++ b/vendor/github.com/moby/moby/api/types/plugin/.gitignore @@ -0,0 +1 @@ +testdata/rapid/** diff --git a/vendor/github.com/moby/moby/api/types/plugin/capability.go b/vendor/github.com/moby/moby/api/types/plugin/capability.go new file mode 100644 index 000000000000..d53f77a1f11a --- /dev/null +++ b/vendor/github.com/moby/moby/api/types/plugin/capability.go @@ -0,0 +1,55 @@ +package plugin + +import ( + "bytes" + "encoding" + "fmt" + "strings" +) + +type CapabilityID struct { + Capability string + Prefix string + Version string +} + +var ( + _ fmt.Stringer = CapabilityID{} + _ encoding.TextUnmarshaler = (*CapabilityID)(nil) + _ encoding.TextMarshaler = CapabilityID{} +) + +// String implements [fmt.Stringer] for CapabilityID +func (t CapabilityID) String() string { + return fmt.Sprintf("%s.%s/%s", t.Prefix, t.Capability, t.Version) +} + +// UnmarshalText implements [encoding.TextUnmarshaler] for CapabilityID +func (t *CapabilityID) UnmarshalText(p []byte) error { + fqcap, version, _ := bytes.Cut(p, []byte{'/'}) + idx := bytes.LastIndexByte(fqcap, '.') + if idx < 0 { + t.Prefix = "" + t.Capability = string(fqcap) + } else { + t.Prefix = string(fqcap[:idx]) + t.Capability = string(fqcap[idx+1:]) + } + t.Version = string(version) + return nil +} + +// MarshalText implements [encoding.TextMarshaler] for CapabilityID +func (t CapabilityID) MarshalText() ([]byte, error) { + // Assert that the value can be round-tripped successfully. + if strings.Contains(t.Capability, ".") { + return nil, fmt.Errorf("capability %q cannot contain a dot", t.Capability) + } + if strings.Contains(t.Prefix, "/") { + return nil, fmt.Errorf("prefix %q cannot contain a slash", t.Prefix) + } + if strings.Contains(t.Capability, "/") { + return nil, fmt.Errorf("capability %q cannot contain a slash", t.Capability) + } + return []byte(t.String()), nil +} diff --git a/vendor/github.com/docker/docker/api/types/plugin_device.go b/vendor/github.com/moby/moby/api/types/plugin/device.go similarity index 72% rename from vendor/github.com/docker/docker/api/types/plugin_device.go rename to vendor/github.com/moby/moby/api/types/plugin/device.go index 569901067559..ae961770474e 100644 --- a/vendor/github.com/docker/docker/api/types/plugin_device.go +++ b/vendor/github.com/moby/moby/api/types/plugin/device.go @@ -1,11 +1,14 @@ -package types +// Code generated by go-swagger; DO NOT EDIT. + +package plugin // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command -// PluginDevice plugin device -// swagger:model PluginDevice -type PluginDevice struct { +// Device device +// +// swagger:model Device +type Device struct { // description // Required: true @@ -16,6 +19,7 @@ type PluginDevice struct { Name string `json:"Name"` // path + // Example: /dev/fuse // Required: true Path *string `json:"Path"` diff --git a/vendor/github.com/docker/docker/api/types/plugin_env.go b/vendor/github.com/moby/moby/api/types/plugin/env.go similarity index 77% rename from vendor/github.com/docker/docker/api/types/plugin_env.go rename to vendor/github.com/moby/moby/api/types/plugin/env.go index 32962dc2ebea..dcbe0b762d79 100644 --- a/vendor/github.com/docker/docker/api/types/plugin_env.go +++ b/vendor/github.com/moby/moby/api/types/plugin/env.go @@ -1,11 +1,14 @@ -package types +// Code generated by go-swagger; DO NOT EDIT. + +package plugin // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command -// PluginEnv plugin env -// swagger:model PluginEnv -type PluginEnv struct { +// Env env +// +// swagger:model Env +type Env struct { // description // Required: true diff --git a/vendor/github.com/docker/docker/api/types/plugin_mount.go b/vendor/github.com/moby/moby/api/types/plugin/mount.go similarity index 65% rename from vendor/github.com/docker/docker/api/types/plugin_mount.go rename to vendor/github.com/moby/moby/api/types/plugin/mount.go index 5c031cf8b5cc..7970306cc85b 100644 --- a/vendor/github.com/docker/docker/api/types/plugin_mount.go +++ b/vendor/github.com/moby/moby/api/types/plugin/mount.go @@ -1,25 +1,32 @@ -package types +// Code generated by go-swagger; DO NOT EDIT. + +package plugin // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command -// PluginMount plugin mount -// swagger:model PluginMount -type PluginMount struct { +// Mount mount +// +// swagger:model Mount +type Mount struct { // description + // Example: This is a mount that's used by the plugin. // Required: true Description string `json:"Description"` // destination + // Example: /mnt/state // Required: true Destination string `json:"Destination"` // name + // Example: some-mount // Required: true Name string `json:"Name"` // options + // Example: ["rbind","rw"] // Required: true Options []string `json:"Options"` @@ -28,10 +35,12 @@ type PluginMount struct { Settable []string `json:"Settable"` // source + // Example: /var/lib/docker/plugins/ // Required: true Source *string `json:"Source"` // type + // Example: bind // Required: true Type string `json:"Type"` } diff --git a/vendor/github.com/docker/docker/api/types/plugin.go b/vendor/github.com/moby/moby/api/types/plugin/plugin.go similarity index 52% rename from vendor/github.com/docker/docker/api/types/plugin.go rename to vendor/github.com/moby/moby/api/types/plugin/plugin.go index abae48b9ab01..b7c768d7fc66 100644 --- a/vendor/github.com/docker/docker/api/types/plugin.go +++ b/vendor/github.com/moby/moby/api/types/plugin/plugin.go @@ -1,110 +1,130 @@ -package types +// Code generated by go-swagger; DO NOT EDIT. + +package plugin // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command // Plugin A plugin for the Engine API +// // swagger:model Plugin type Plugin struct { // config // Required: true - Config PluginConfig `json:"Config"` + Config Config `json:"Config"` // True if the plugin is running. False if the plugin is not running, only installed. + // Example: true // Required: true Enabled bool `json:"Enabled"` // Id + // Example: 5724e2c8652da337ab2eedd19fc6fc0ec908e4bd907c7421bf6a8dfc70c4c078 ID string `json:"Id,omitempty"` // name + // Example: tiborvass/sample-volume-plugin // Required: true Name string `json:"Name"` // plugin remote reference used to push/pull the plugin + // Example: localhost:5000/tiborvass/sample-volume-plugin:latest PluginReference string `json:"PluginReference,omitempty"` // settings // Required: true - Settings PluginSettings `json:"Settings"` + Settings Settings `json:"Settings"` } -// PluginConfig The config of a plugin. -// swagger:model PluginConfig -type PluginConfig struct { +// Config The config of a plugin. +// +// swagger:model Config +type Config struct { // args // Required: true - Args PluginConfigArgs `json:"Args"` + Args Args `json:"Args"` // description + // Example: A sample volume plugin for Docker // Required: true Description string `json:"Description"` // Docker Version used to create the plugin + // Example: 17.06.0-ce DockerVersion string `json:"DockerVersion,omitempty"` // documentation + // Example: https://docs.docker.com/engine/extend/plugins/ // Required: true Documentation string `json:"Documentation"` // entrypoint + // Example: ["/usr/bin/sample-volume-plugin","/data"] // Required: true Entrypoint []string `json:"Entrypoint"` // env + // Example: [{"Description":"If set, prints debug messages","Name":"DEBUG","Settable":null,"Value":"0"}] // Required: true - Env []PluginEnv `json:"Env"` + Env []Env `json:"Env"` // interface // Required: true - Interface PluginConfigInterface `json:"Interface"` + Interface Interface `json:"Interface"` // ipc host + // Example: false // Required: true IpcHost bool `json:"IpcHost"` // linux // Required: true - Linux PluginConfigLinux `json:"Linux"` + Linux LinuxConfig `json:"Linux"` // mounts // Required: true - Mounts []PluginMount `json:"Mounts"` + Mounts []Mount `json:"Mounts"` // network // Required: true - Network PluginConfigNetwork `json:"Network"` + Network NetworkConfig `json:"Network"` // pid host + // Example: false // Required: true PidHost bool `json:"PidHost"` // propagated mount + // Example: /mnt/volumes // Required: true PropagatedMount string `json:"PropagatedMount"` // user - User PluginConfigUser `json:"User,omitempty"` + User User `json:"User,omitempty"` // work dir + // Example: /bin/ // Required: true WorkDir string `json:"WorkDir"` // rootfs - Rootfs *PluginConfigRootfs `json:"rootfs,omitempty"` + Rootfs *RootFS `json:"rootfs,omitempty"` } -// PluginConfigArgs plugin config args -// swagger:model PluginConfigArgs -type PluginConfigArgs struct { +// Args args +// +// swagger:model Args +type Args struct { // description + // Example: command line arguments // Required: true Description string `json:"Description"` // name + // Example: args // Required: true Name string `json:"Name"` @@ -117,73 +137,90 @@ type PluginConfigArgs struct { Value []string `json:"Value"` } -// PluginConfigInterface The interface between Docker and the plugin -// swagger:model PluginConfigInterface -type PluginConfigInterface struct { +// Interface The interface between Docker and the plugin +// +// swagger:model Interface +type Interface struct { // Protocol to use for clients connecting to the plugin. + // Example: some.protocol/v1.0 + // Enum: ["","moby.plugins.http/v1"] ProtocolScheme string `json:"ProtocolScheme,omitempty"` // socket + // Example: plugins.sock // Required: true Socket string `json:"Socket"` // types + // Example: ["docker.volumedriver/1.0"] // Required: true - Types []PluginInterfaceType `json:"Types"` + Types []CapabilityID `json:"Types"` } -// PluginConfigLinux plugin config linux -// swagger:model PluginConfigLinux -type PluginConfigLinux struct { +// LinuxConfig linux config +// +// swagger:model LinuxConfig +type LinuxConfig struct { // allow all devices + // Example: false // Required: true AllowAllDevices bool `json:"AllowAllDevices"` // capabilities + // Example: ["CAP_SYS_ADMIN","CAP_SYSLOG"] // Required: true Capabilities []string `json:"Capabilities"` // devices // Required: true - Devices []PluginDevice `json:"Devices"` + Devices []Device `json:"Devices"` } -// PluginConfigNetwork plugin config network -// swagger:model PluginConfigNetwork -type PluginConfigNetwork struct { +// NetworkConfig network config +// +// swagger:model NetworkConfig +type NetworkConfig struct { // type + // Example: host // Required: true Type string `json:"Type"` } -// PluginConfigRootfs plugin config rootfs -// swagger:model PluginConfigRootfs -type PluginConfigRootfs struct { +// RootFS root f s +// +// swagger:model RootFS +type RootFS struct { // diff ids + // Example: ["sha256:675532206fbf3030b8458f88d6e26d4eb1577688a25efec97154c94e8b6b4887","sha256:e216a057b1cb1efc11f8a268f37ef62083e70b1b38323ba252e25ac88904a7e8"] DiffIds []string `json:"diff_ids"` // type + // Example: layers Type string `json:"type,omitempty"` } -// PluginConfigUser plugin config user -// swagger:model PluginConfigUser -type PluginConfigUser struct { +// User user +// +// swagger:model User +type User struct { // g ID + // Example: 1000 GID uint32 `json:"GID,omitempty"` // UID + // Example: 1000 UID uint32 `json:"UID,omitempty"` } -// PluginSettings Settings that can be modified by users. -// swagger:model PluginSettings -type PluginSettings struct { +// Settings user-configurable settings for the plugin. +// +// swagger:model Settings +type Settings struct { // args // Required: true @@ -191,13 +228,14 @@ type PluginSettings struct { // devices // Required: true - Devices []PluginDevice `json:"Devices"` + Devices []Device `json:"Devices"` // env + // Example: ["DEBUG=0"] // Required: true Env []string `json:"Env"` // mounts // Required: true - Mounts []PluginMount `json:"Mounts"` + Mounts []Mount `json:"Mounts"` } diff --git a/vendor/github.com/moby/moby/api/types/plugin/plugin_responses.go b/vendor/github.com/moby/moby/api/types/plugin/plugin_responses.go new file mode 100644 index 000000000000..939e4f59fb26 --- /dev/null +++ b/vendor/github.com/moby/moby/api/types/plugin/plugin_responses.go @@ -0,0 +1,33 @@ +package plugin + +import ( + "sort" +) + +// ListResponse contains the response for the Engine API +type ListResponse []*Plugin + +// Privilege describes a permission the user has to accept +// upon installing a plugin. +type Privilege struct { + Name string + Description string + Value []string +} + +// Privileges is a list of Privilege +type Privileges []Privilege + +func (s Privileges) Len() int { + return len(s) +} + +func (s Privileges) Less(i, j int) bool { + return s[i].Name < s[j].Name +} + +func (s Privileges) Swap(i, j int) { + sort.Strings(s[i].Value) + sort.Strings(s[j].Value) + s[i], s[j] = s[j], s[i] +} diff --git a/vendor/github.com/docker/docker/api/types/registry/authconfig.go b/vendor/github.com/moby/moby/api/types/registry/authconfig.go similarity index 84% rename from vendor/github.com/docker/docker/api/types/registry/authconfig.go rename to vendor/github.com/moby/moby/api/types/registry/authconfig.go index fa9037bdadfd..56703705a26e 100644 --- a/vendor/github.com/docker/docker/api/types/registry/authconfig.go +++ b/vendor/github.com/moby/moby/api/types/registry/authconfig.go @@ -1,12 +1,13 @@ package registry import ( + "bytes" "context" "encoding/base64" "encoding/json" + "errors" "fmt" "io" - "strings" ) // AuthHeader is the name of the header used to send encoded registry @@ -51,6 +52,11 @@ type AuthConfig struct { // // [RFC4648, section 5]: https://tools.ietf.org/html/rfc4648#section-5 func EncodeAuthConfig(authConfig AuthConfig) (string, error) { + // Older daemons (or registries) may not handle an empty string, + // which resulted in an "io.EOF" when unmarshaling or decoding. + // + // FIXME(thaJeztah): find exactly what code-paths are impacted by this. + // if authConfig == (AuthConfig{}) { return "", nil } buf, err := json.Marshal(authConfig) if err != nil { return "", errInvalidParameter{err} @@ -71,8 +77,20 @@ func DecodeAuthConfig(authEncoded string) (*AuthConfig, error) { return &AuthConfig{}, nil } - authJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded)) - return decodeAuthConfigFromReader(authJSON) + decoded, err := base64.URLEncoding.DecodeString(authEncoded) + if err != nil { + var e base64.CorruptInputError + if errors.As(err, &e) { + return &AuthConfig{}, invalid(errors.New("must be a valid base64url-encoded string")) + } + return &AuthConfig{}, invalid(err) + } + + if bytes.Equal(decoded, []byte("{}")) { + return &AuthConfig{}, nil + } + + return decodeAuthConfigFromReader(bytes.NewReader(decoded)) } // DecodeAuthConfigBody decodes authentication information as sent as JSON in the @@ -94,7 +112,7 @@ func decodeAuthConfigFromReader(rdr io.Reader) (*AuthConfig, error) { if err := json.NewDecoder(rdr).Decode(authConfig); err != nil { // always return an (empty) AuthConfig to increase compatibility with // the existing API. - return &AuthConfig{}, invalid(err) + return &AuthConfig{}, invalid(fmt.Errorf("invalid JSON: %w", err)) } return authConfig, nil } diff --git a/vendor/github.com/docker/docker/api/types/registry/authenticate.go b/vendor/github.com/moby/moby/api/types/registry/authenticate.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/registry/authenticate.go rename to vendor/github.com/moby/moby/api/types/registry/authenticate.go diff --git a/vendor/github.com/docker/docker/api/types/registry/registry.go b/vendor/github.com/moby/moby/api/types/registry/registry.go similarity index 83% rename from vendor/github.com/docker/docker/api/types/registry/registry.go rename to vendor/github.com/moby/moby/api/types/registry/registry.go index 9319c964cdbd..5924da377d8e 100644 --- a/vendor/github.com/docker/docker/api/types/registry/registry.go +++ b/vendor/github.com/moby/moby/api/types/registry/registry.go @@ -1,6 +1,3 @@ -// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: -//go:build go1.23 - package registry import ( @@ -12,9 +9,6 @@ import ( // ServiceConfig stores daemon registry services configuration. type ServiceConfig struct { - 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 diff --git a/vendor/github.com/docker/docker/api/types/registry/search.go b/vendor/github.com/moby/moby/api/types/registry/search.go similarity index 92% rename from vendor/github.com/docker/docker/api/types/registry/search.go rename to vendor/github.com/moby/moby/api/types/registry/search.go index 994ca4c6f96f..17d77f212270 100644 --- a/vendor/github.com/docker/docker/api/types/registry/search.go +++ b/vendor/github.com/moby/moby/api/types/registry/search.go @@ -3,7 +3,7 @@ package registry import ( "context" - "github.com/docker/docker/api/types/filters" + "github.com/moby/moby/api/types/filters" ) // SearchOptions holds parameters to search images with. @@ -15,7 +15,7 @@ type SearchOptions struct { // 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]. + // For details, refer to [github.com/moby/moby/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/storage/driver_data.go b/vendor/github.com/moby/moby/api/types/storage/driver_data.go similarity index 61% rename from vendor/github.com/docker/docker/api/types/storage/driver_data.go rename to vendor/github.com/moby/moby/api/types/storage/driver_data.go index 009e21309507..65d5b4c20ea0 100644 --- a/vendor/github.com/docker/docker/api/types/storage/driver_data.go +++ b/vendor/github.com/moby/moby/api/types/storage/driver_data.go @@ -1,3 +1,5 @@ +// Code generated by go-swagger; DO NOT EDIT. + package storage // This file was generated by the swagger tool. @@ -14,10 +16,12 @@ type DriverData struct { // This information is driver-specific, and depends on the storage-driver // in use, and should be used for informational purposes only. // + // Example: {"MergedDir":"/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/merged","UpperDir":"/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/diff","WorkDir":"/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/work"} // Required: true Data map[string]string `json:"Data"` // Name of the storage driver. + // Example: overlay2 // Required: true Name string `json:"Name"` } diff --git a/vendor/github.com/docker/docker/api/types/swarm/common.go b/vendor/github.com/moby/moby/api/types/swarm/common.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/swarm/common.go rename to vendor/github.com/moby/moby/api/types/swarm/common.go diff --git a/vendor/github.com/docker/docker/api/types/swarm/config.go b/vendor/github.com/moby/moby/api/types/swarm/config.go similarity index 97% rename from vendor/github.com/docker/docker/api/types/swarm/config.go rename to vendor/github.com/moby/moby/api/types/swarm/config.go index 80a6ffdb9aaf..f8e7f4a6f9c8 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/config.go +++ b/vendor/github.com/moby/moby/api/types/swarm/config.go @@ -3,7 +3,7 @@ package swarm import ( "os" - "github.com/docker/docker/api/types/filters" + "github.com/moby/moby/api/types/filters" ) // Config represents a config. diff --git a/vendor/github.com/docker/docker/api/types/swarm/container.go b/vendor/github.com/moby/moby/api/types/swarm/container.go similarity index 97% rename from vendor/github.com/docker/docker/api/types/swarm/container.go rename to vendor/github.com/moby/moby/api/types/swarm/container.go index f9416bacca6b..bc8690d8cbb5 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/container.go +++ b/vendor/github.com/moby/moby/api/types/swarm/container.go @@ -3,8 +3,8 @@ package swarm import ( "time" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/mount" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/mount" ) // DNSConfig specifies DNS related configurations in resolver configuration file (resolv.conf) diff --git a/vendor/github.com/docker/docker/api/types/swarm/network.go b/vendor/github.com/moby/moby/api/types/swarm/network.go similarity index 98% rename from vendor/github.com/docker/docker/api/types/swarm/network.go rename to vendor/github.com/moby/moby/api/types/swarm/network.go index 4b8807233993..95a5fb385a51 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/network.go +++ b/vendor/github.com/moby/moby/api/types/swarm/network.go @@ -1,7 +1,7 @@ package swarm import ( - "github.com/docker/docker/api/types/network" + "github.com/moby/moby/api/types/network" ) // Endpoint represents an endpoint. diff --git a/vendor/github.com/docker/docker/api/types/swarm/node.go b/vendor/github.com/moby/moby/api/types/swarm/node.go similarity index 97% rename from vendor/github.com/docker/docker/api/types/swarm/node.go rename to vendor/github.com/moby/moby/api/types/swarm/node.go index 2018a031bbf7..3e503ef24b2b 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/node.go +++ b/vendor/github.com/moby/moby/api/types/swarm/node.go @@ -1,6 +1,6 @@ package swarm -import "github.com/docker/docker/api/types/filters" +import "github.com/moby/moby/api/types/filters" // Node represents a node. type Node struct { @@ -133,7 +133,7 @@ const ( ) // Topology defines the CSI topology of this node. This type is a duplicate of -// github.com/docker/docker/api/types.Topology. Because the type definition +// [github.com/moby/moby/api/types/volume.Topology]. Because the type definition // is so simple and to avoid complicated structure or circular imports, we just // duplicate it here. See that type for full documentation type Topology struct { diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime.go b/vendor/github.com/moby/moby/api/types/swarm/runtime.go similarity index 55% rename from vendor/github.com/docker/docker/api/types/swarm/runtime.go rename to vendor/github.com/moby/moby/api/types/swarm/runtime.go index 8a28320f7b85..23ea712c4770 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/runtime.go +++ b/vendor/github.com/moby/moby/api/types/swarm/runtime.go @@ -25,3 +25,21 @@ const ( type NetworkAttachmentSpec struct { ContainerID string } + +// RuntimeSpec defines the base payload which clients can specify for creating +// a service with the plugin runtime. +type RuntimeSpec struct { + Name string `json:"name,omitempty"` + Remote string `json:"remote,omitempty"` + Privileges []*RuntimePrivilege `json:"privileges,omitempty"` + Disabled bool `json:"disabled,omitempty"` + Env []string `json:"env,omitempty"` +} + +// RuntimePrivilege describes a permission the user has to accept +// upon installing a plugin. +type RuntimePrivilege struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Value []string `json:"value,omitempty"` +} diff --git a/vendor/github.com/docker/docker/api/types/swarm/secret.go b/vendor/github.com/moby/moby/api/types/swarm/secret.go similarity index 93% rename from vendor/github.com/docker/docker/api/types/swarm/secret.go rename to vendor/github.com/moby/moby/api/types/swarm/secret.go index d9482ab56d17..6fea600b42ed 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/secret.go +++ b/vendor/github.com/moby/moby/api/types/swarm/secret.go @@ -3,7 +3,7 @@ package swarm import ( "os" - "github.com/docker/docker/api/types/filters" + "github.com/moby/moby/api/types/filters" ) // Secret represents a secret. @@ -25,7 +25,7 @@ type SecretSpec struct { // This field is only used to create the secret, and is not returned // by other endpoints. // - // [MaxSecretSize]: https://pkg.go.dev/github.com/moby/swarmkit/v2@v2.0.0-20250103191802-8c1959736554/api/validation#MaxSecretSize + // [MaxSecretSize]: https://pkg.go.dev/github.com/moby/swarmkit/v2@v2.0.0/api/validation#MaxSecretSize Data []byte `json:",omitempty"` // Driver is the name of the secrets driver used to fetch the secret's diff --git a/vendor/github.com/docker/docker/api/types/swarm/service.go b/vendor/github.com/moby/moby/api/types/swarm/service.go similarity index 99% rename from vendor/github.com/docker/docker/api/types/swarm/service.go rename to vendor/github.com/moby/moby/api/types/swarm/service.go index 56c660c1f0c4..58749aa3550a 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/service.go +++ b/vendor/github.com/moby/moby/api/types/swarm/service.go @@ -3,7 +3,7 @@ package swarm import ( "time" - "github.com/docker/docker/api/types/filters" + "github.com/moby/moby/api/types/filters" ) // Service represents a service. diff --git a/vendor/github.com/docker/docker/api/types/swarm/service_create_response.go b/vendor/github.com/moby/moby/api/types/swarm/service_create_response.go similarity index 73% rename from vendor/github.com/docker/docker/api/types/swarm/service_create_response.go rename to vendor/github.com/moby/moby/api/types/swarm/service_create_response.go index 9a268ff1b93a..ebbc097d90db 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/service_create_response.go +++ b/vendor/github.com/moby/moby/api/types/swarm/service_create_response.go @@ -1,3 +1,5 @@ +// Code generated by go-swagger; DO NOT EDIT. + package swarm // This file was generated by the swagger tool. @@ -10,11 +12,13 @@ package swarm type ServiceCreateResponse struct { // The ID of the created service. + // Example: ak7w3gjqoa3kuz8xcpnyy0pvl ID string `json:"ID,omitempty"` // Optional warning message. // // FIXME(thaJeztah): this should have "omitempty" in the generated type. // + // Example: ["unable to pin image doesnotexist:latest to digest: image library/doesnotexist:latest not found"] Warnings []string `json:"Warnings"` } diff --git a/vendor/github.com/docker/docker/api/types/swarm/service_update_response.go b/vendor/github.com/moby/moby/api/types/swarm/service_update_response.go similarity index 66% rename from vendor/github.com/docker/docker/api/types/swarm/service_update_response.go rename to vendor/github.com/moby/moby/api/types/swarm/service_update_response.go index 0417467dae39..b7649096a07a 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/service_update_response.go +++ b/vendor/github.com/moby/moby/api/types/swarm/service_update_response.go @@ -1,9 +1,13 @@ +// Code generated by go-swagger; DO NOT EDIT. + package swarm // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command // ServiceUpdateResponse service update response +// Example: {"Warnings":["unable to pin image doesnotexist:latest to digest: image library/doesnotexist:latest not found"]} +// // swagger:model ServiceUpdateResponse type ServiceUpdateResponse struct { diff --git a/vendor/github.com/docker/docker/api/types/swarm/swarm.go b/vendor/github.com/moby/moby/api/types/swarm/swarm.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/swarm/swarm.go rename to vendor/github.com/moby/moby/api/types/swarm/swarm.go diff --git a/vendor/github.com/docker/docker/api/types/swarm/task.go b/vendor/github.com/moby/moby/api/types/swarm/task.go similarity index 98% rename from vendor/github.com/docker/docker/api/types/swarm/task.go rename to vendor/github.com/moby/moby/api/types/swarm/task.go index 4dc95e8b1dde..180676d5f0a0 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/task.go +++ b/vendor/github.com/moby/moby/api/types/swarm/task.go @@ -3,8 +3,7 @@ package swarm import ( "time" - "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/api/types/swarm/runtime" + "github.com/moby/moby/api/types/filters" ) // TaskState represents the state of a task. @@ -77,7 +76,7 @@ type TaskSpec struct { // NetworkAttachmentSpec is used if the `Runtime` field is set to // `attachment`. ContainerSpec *ContainerSpec `json:",omitempty"` - PluginSpec *runtime.PluginSpec `json:",omitempty"` + PluginSpec *RuntimeSpec `json:",omitempty"` NetworkAttachmentSpec *NetworkAttachmentSpec `json:",omitempty"` Resources *ResourceRequirements `json:",omitempty"` diff --git a/vendor/github.com/moby/moby/api/types/system/disk_usage.go b/vendor/github.com/moby/moby/api/types/system/disk_usage.go new file mode 100644 index 000000000000..0f8308c9b9a2 --- /dev/null +++ b/vendor/github.com/moby/moby/api/types/system/disk_usage.go @@ -0,0 +1,40 @@ +package system + +import ( + "github.com/moby/moby/api/types/build" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/image" + "github.com/moby/moby/api/types/volume" +) + +// DiskUsageObject represents an object type used for disk usage query filtering. +type DiskUsageObject string + +const ( + // ContainerObject represents a container DiskUsageObject. + ContainerObject DiskUsageObject = "container" + // ImageObject represents an image DiskUsageObject. + ImageObject DiskUsageObject = "image" + // VolumeObject represents a volume DiskUsageObject. + VolumeObject DiskUsageObject = "volume" + // BuildCacheObject represents a build-cache DiskUsageObject. + BuildCacheObject DiskUsageObject = "build-cache" +) + +// DiskUsageOptions holds parameters for system disk usage query. +type DiskUsageOptions struct { + // Types specifies what object types to include in the response. If empty, + // all object types are returned. + Types []DiskUsageObject +} + +// DiskUsage contains response of Engine API: +// GET "/system/df" +type DiskUsage struct { + LayersSize int64 + Images []*image.Summary + Containers []*container.Summary + Volumes []*volume.Volume + BuildCache []*build.CacheRecord + 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/system/info.go b/vendor/github.com/moby/moby/api/types/system/info.go similarity index 97% rename from vendor/github.com/docker/docker/api/types/system/info.go rename to vendor/github.com/moby/moby/api/types/system/info.go index 047639ed91e2..e9a4aa7c7f73 100644 --- a/vendor/github.com/docker/docker/api/types/system/info.go +++ b/vendor/github.com/moby/moby/api/types/system/info.go @@ -1,9 +1,9 @@ package system import ( - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/registry" - "github.com/docker/docker/api/types/swarm" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/registry" + "github.com/moby/moby/api/types/swarm" ) // Info contains response of Engine API: diff --git a/vendor/github.com/docker/docker/api/types/system/runtime.go b/vendor/github.com/moby/moby/api/types/system/runtime.go similarity index 79% rename from vendor/github.com/docker/docker/api/types/system/runtime.go rename to vendor/github.com/moby/moby/api/types/system/runtime.go index d077295a0d31..33cad367469b 100644 --- a/vendor/github.com/docker/docker/api/types/system/runtime.go +++ b/vendor/github.com/moby/moby/api/types/system/runtime.go @@ -9,8 +9,8 @@ type Runtime struct { // Shimv2 runtime configuration. Mutually exclusive with the legacy config above. - Type string `json:"runtimeType,omitempty"` - Options map[string]interface{} `json:"options,omitempty"` + Type string `json:"runtimeType,omitempty"` + Options map[string]any `json:"options,omitempty"` } // RuntimeWithStatus extends [Runtime] to hold [RuntimeStatus]. diff --git a/vendor/github.com/docker/docker/api/types/system/security_opts.go b/vendor/github.com/moby/moby/api/types/system/security_opts.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/system/security_opts.go rename to vendor/github.com/moby/moby/api/types/system/security_opts.go diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/moby/moby/api/types/types.go similarity index 60% rename from vendor/github.com/docker/docker/api/types/types.go rename to vendor/github.com/moby/moby/api/types/types.go index 8bbadeb208e3..3d00f354b6fe 100644 --- a/vendor/github.com/docker/docker/api/types/types.go +++ b/vendor/github.com/moby/moby/api/types/types.go @@ -1,11 +1,8 @@ package types import ( - "github.com/docker/docker/api/types/build" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/image" - "github.com/docker/docker/api/types/swarm" - "github.com/docker/docker/api/types/volume" + "github.com/moby/moby/api/types/build" + "github.com/moby/moby/api/types/swarm" ) const ( @@ -61,38 +58,6 @@ type Version struct { BuildTime string `json:",omitempty"` } -// DiskUsageObject represents an object type used for disk usage query filtering. -type DiskUsageObject string - -const ( - // ContainerObject represents a container DiskUsageObject. - ContainerObject DiskUsageObject = "container" - // ImageObject represents an image DiskUsageObject. - ImageObject DiskUsageObject = "image" - // VolumeObject represents a volume DiskUsageObject. - VolumeObject DiskUsageObject = "volume" - // BuildCacheObject represents a build-cache DiskUsageObject. - BuildCacheObject DiskUsageObject = "build-cache" -) - -// DiskUsageOptions holds parameters for system disk usage query. -type DiskUsageOptions struct { - // Types specifies what object types to include in the response. If empty, - // all object types are returned. - Types []DiskUsageObject -} - -// DiskUsage contains response of Engine API: -// GET "/system/df" -type DiskUsage struct { - LayersSize int64 - Images []*image.Summary - Containers []*container.Summary - Volumes []*volume.Volume - BuildCache []*build.CacheRecord - BuilderSize int64 `json:",omitempty"` // Deprecated: deprecated in API 1.38, and no longer used since API 1.40. -} - // PushResult contains the tag, manifest digest, and manifest size from the // push. It's used to signal this information to the trust code in the client // so it can sign the manifest if necessary. diff --git a/vendor/github.com/docker/docker/api/types/versions/compare.go b/vendor/github.com/moby/moby/api/types/versions/compare.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/versions/compare.go rename to vendor/github.com/moby/moby/api/types/versions/compare.go diff --git a/vendor/github.com/docker/docker/api/types/volume/cluster_volume.go b/vendor/github.com/moby/moby/api/types/volume/cluster_volume.go similarity index 99% rename from vendor/github.com/docker/docker/api/types/volume/cluster_volume.go rename to vendor/github.com/moby/moby/api/types/volume/cluster_volume.go index 618a4816209a..07b75d12a01f 100644 --- a/vendor/github.com/docker/docker/api/types/volume/cluster_volume.go +++ b/vendor/github.com/moby/moby/api/types/volume/cluster_volume.go @@ -1,7 +1,7 @@ package volume import ( - "github.com/docker/docker/api/types/swarm" + "github.com/moby/moby/api/types/swarm" ) // ClusterVolume contains options and information specific to, and only present diff --git a/vendor/github.com/docker/docker/api/types/volume/create_options.go b/vendor/github.com/moby/moby/api/types/volume/create_options.go similarity index 73% rename from vendor/github.com/docker/docker/api/types/volume/create_options.go rename to vendor/github.com/moby/moby/api/types/volume/create_options.go index 37c41a609690..c7b18a6d48ee 100644 --- a/vendor/github.com/docker/docker/api/types/volume/create_options.go +++ b/vendor/github.com/moby/moby/api/types/volume/create_options.go @@ -1,3 +1,5 @@ +// Code generated by go-swagger; DO NOT EDIT. + package volume // This file was generated by the swagger tool. @@ -5,7 +7,8 @@ package volume // CreateOptions VolumeConfig // -// Volume configuration +// # Volume configuration +// // swagger:model CreateOptions type CreateOptions struct { @@ -13,17 +16,21 @@ type CreateOptions struct { ClusterVolumeSpec *ClusterVolumeSpec `json:"ClusterVolumeSpec,omitempty"` // Name of the volume driver to use. + // Example: custom Driver string `json:"Driver,omitempty"` // A mapping of driver options and values. These options are // passed directly to the driver and are driver specific. // + // Example: {"device":"tmpfs","o":"size=100m,uid=1000","type":"tmpfs"} DriverOpts map[string]string `json:"DriverOpts,omitempty"` // User-defined key/value metadata. + // Example: {"com.example.some-label":"some-value","com.example.some-other-label":"some-other-value"} Labels map[string]string `json:"Labels,omitempty"` // The new volume's name. If not specified, Docker generates a name. // + // Example: tardis Name string `json:"Name,omitempty"` } diff --git a/vendor/github.com/docker/docker/api/types/volume/list_response.go b/vendor/github.com/moby/moby/api/types/volume/list_response.go similarity index 81% rename from vendor/github.com/docker/docker/api/types/volume/list_response.go rename to vendor/github.com/moby/moby/api/types/volume/list_response.go index ca5192a2a91e..b725b6f12128 100644 --- a/vendor/github.com/docker/docker/api/types/volume/list_response.go +++ b/vendor/github.com/moby/moby/api/types/volume/list_response.go @@ -1,3 +1,5 @@ +// Code generated by go-swagger; DO NOT EDIT. + package volume // This file was generated by the swagger tool. @@ -5,7 +7,8 @@ package volume // ListResponse VolumeListResponse // -// Volume list response +// # Volume list response +// // swagger:model ListResponse type ListResponse struct { @@ -14,5 +17,6 @@ type ListResponse struct { // Warnings that occurred when fetching the list of volumes. // + // Example: [] Warnings []string `json:"Warnings"` } diff --git a/vendor/github.com/docker/docker/api/types/volume/options.go b/vendor/github.com/moby/moby/api/types/volume/options.go similarity index 83% rename from vendor/github.com/docker/docker/api/types/volume/options.go rename to vendor/github.com/moby/moby/api/types/volume/options.go index 875524fbc2d4..7237f2db8d08 100644 --- a/vendor/github.com/docker/docker/api/types/volume/options.go +++ b/vendor/github.com/moby/moby/api/types/volume/options.go @@ -1,6 +1,6 @@ package volume -import "github.com/docker/docker/api/types/filters" +import "github.com/moby/moby/api/types/filters" // ListOptions holds parameters to list volumes. type ListOptions struct { diff --git a/vendor/github.com/docker/docker/api/types/volume/volume.go b/vendor/github.com/moby/moby/api/types/volume/volume.go similarity index 83% rename from vendor/github.com/docker/docker/api/types/volume/volume.go rename to vendor/github.com/moby/moby/api/types/volume/volume.go index ea7d555e5b49..7c199ed1e7b3 100644 --- a/vendor/github.com/docker/docker/api/types/volume/volume.go +++ b/vendor/github.com/moby/moby/api/types/volume/volume.go @@ -1,9 +1,12 @@ +// Code generated by go-swagger; DO NOT EDIT. + package volume // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command // Volume volume +// // swagger:model Volume type Volume struct { @@ -11,33 +14,41 @@ type Volume struct { ClusterVolume *ClusterVolume `json:"ClusterVolume,omitempty"` // Date/Time the volume was created. + // Example: 2016-06-07T20:31:11.853781916Z CreatedAt string `json:"CreatedAt,omitempty"` // Name of the volume driver used by the volume. + // Example: custom // Required: true Driver string `json:"Driver"` // User-defined key/value metadata. + // Example: {"com.example.some-label":"some-value","com.example.some-other-label":"some-other-value"} // Required: true Labels map[string]string `json:"Labels"` // Mount path of the volume on the host. + // Example: /var/lib/docker/volumes/tardis // Required: true Mountpoint string `json:"Mountpoint"` // Name of the volume. + // Example: tardis // Required: true Name string `json:"Name"` // The driver specific options used when creating the volume. // + // Example: {"device":"tmpfs","o":"size=100m,uid=1000","type":"tmpfs"} // Required: true Options map[string]string `json:"Options"` // The level at which the volume exists. Either `global` for cluster-wide, // or `local` for machine level. // + // Example: local // Required: true + // Enum: ["local","global"] Scope string `json:"Scope"` // Low-level details about the volume, provided by the volume driver. @@ -47,6 +58,7 @@ type Volume struct { // The `Status` field is optional, and is omitted if the volume driver // does not support this feature. // + // Example: {"hello":"world"} Status map[string]interface{} `json:"Status,omitempty"` // usage data diff --git a/vendor/github.com/docker/docker/api/types/volume/volume_update.go b/vendor/github.com/moby/moby/api/types/volume/volume_update.go similarity index 100% rename from vendor/github.com/docker/docker/api/types/volume/volume_update.go rename to vendor/github.com/moby/moby/api/types/volume/volume_update.go diff --git a/vendor/github.com/moby/moby/client/LICENSE b/vendor/github.com/moby/moby/client/LICENSE new file mode 100644 index 000000000000..6d8d58fb676b --- /dev/null +++ b/vendor/github.com/moby/moby/client/LICENSE @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2013-2018 Docker, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/moby/moby/client/README.md b/vendor/github.com/moby/moby/client/README.md new file mode 100644 index 000000000000..05d9e284e863 --- /dev/null +++ b/vendor/github.com/moby/moby/client/README.md @@ -0,0 +1,44 @@ +# Go client for the Docker Engine API + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/moby/moby/client)](https://pkg.go.dev/github.com/moby/moby/client) +![GitHub License](https://img.shields.io/github/license/moby/moby) +[![Go Report Card](https://goreportcard.com/badge/github.com/moby/moby/client)](https://goreportcard.com/report/github.com/moby/moby/client) +[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/moby/moby/badge)](https://scorecard.dev/viewer/?uri=github.com/moby/moby) +[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/10989/badge)](https://www.bestpractices.dev/projects/10989) + +The `docker` command uses this package to communicate with the daemon. It can +also be used by your own Go applications to do anything the command-line +interface does; running containers, pulling or pushing images, etc. + +For example, to list all containers (the equivalent of `docker ps --all`): + +```go +package main + +import ( + "context" + "fmt" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" +) + +func main() { + apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + panic(err) + } + defer apiClient.Close() + + containers, err := apiClient.ContainerList(context.Background(), container.ListOptions{All: true}) + if err != nil { + panic(err) + } + + for _, ctr := range containers { + fmt.Printf("%s %s (status: %s)\n", ctr.ID, ctr.Image, ctr.Status) + } +} +``` + +[Full documentation is available on pkg.go.dev.](https://pkg.go.dev/github.com/moby/moby/client) diff --git a/vendor/github.com/moby/moby/client/auth.go b/vendor/github.com/moby/moby/client/auth.go new file mode 100644 index 000000000000..8baf39d2cfa0 --- /dev/null +++ b/vendor/github.com/moby/moby/client/auth.go @@ -0,0 +1,14 @@ +package client + +import ( + "context" + + "github.com/moby/moby/api/types/registry" +) + +// staticAuth creates a privilegeFn from the given registryAuth. +func staticAuth(registryAuth string) registry.RequestAuthConfig { + return func(ctx context.Context) (string, error) { + return registryAuth, nil + } +} diff --git a/vendor/github.com/moby/moby/client/build_cancel.go b/vendor/github.com/moby/moby/client/build_cancel.go new file mode 100644 index 000000000000..f39b8761611f --- /dev/null +++ b/vendor/github.com/moby/moby/client/build_cancel.go @@ -0,0 +1,17 @@ +package client + +import ( + "context" + "net/url" +) + +// BuildCancel requests the daemon to cancel the ongoing build request +// with the given id. +func (cli *Client) BuildCancel(ctx context.Context, id string) error { + query := url.Values{} + query.Set("id", id) + + resp, err := cli.post(ctx, "/build/cancel", query, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/build_prune.go b/vendor/github.com/moby/moby/client/build_prune.go new file mode 100644 index 000000000000..c82cea06effe --- /dev/null +++ b/vendor/github.com/moby/moby/client/build_prune.go @@ -0,0 +1,56 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + "net/url" + "strconv" + + "github.com/moby/moby/api/types/build" + "github.com/moby/moby/api/types/filters" +) + +// BuildCachePrune requests the daemon to delete unused cache data. +func (cli *Client) BuildCachePrune(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error) { + if err := cli.NewVersionError(ctx, "1.31", "build prune"); err != nil { + return nil, err + } + + query := url.Values{} + if opts.All { + query.Set("all", "1") + } + + if opts.KeepStorage != 0 { + query.Set("keep-storage", strconv.Itoa(int(opts.KeepStorage))) + } + if opts.ReservedSpace != 0 { + query.Set("reserved-space", strconv.Itoa(int(opts.ReservedSpace))) + } + if opts.MaxUsedSpace != 0 { + query.Set("max-used-space", strconv.Itoa(int(opts.MaxUsedSpace))) + } + if opts.MinFreeSpace != 0 { + query.Set("min-free-space", strconv.Itoa(int(opts.MinFreeSpace))) + } + f, err := filters.ToJSON(opts.Filters) + if err != nil { + return nil, fmt.Errorf("prune could not marshal filters option: %w", err) + } + query.Set("filters", f) + + resp, err := cli.post(ctx, "/build/prune", query, nil, nil) + defer ensureReaderClosed(resp) + + if err != nil { + return nil, err + } + + report := build.CachePruneReport{} + if err := json.NewDecoder(resp.Body).Decode(&report); err != nil { + return nil, fmt.Errorf("error retrieving disk usage: %w", err) + } + + return &report, nil +} diff --git a/vendor/github.com/moby/moby/client/checkpoint.go b/vendor/github.com/moby/moby/client/checkpoint.go new file mode 100644 index 000000000000..af942c412c3e --- /dev/null +++ b/vendor/github.com/moby/moby/client/checkpoint.go @@ -0,0 +1,18 @@ +package client + +import ( + "context" + + "github.com/moby/moby/api/types/checkpoint" +) + +// CheckpointAPIClient defines API client methods for the checkpoints. +// +// Experimental: checkpoint and restore is still an experimental feature, +// and only available if the daemon is running with experimental features +// enabled. +type CheckpointAPIClient interface { + CheckpointCreate(ctx context.Context, container string, options checkpoint.CreateOptions) error + CheckpointDelete(ctx context.Context, container string, options checkpoint.DeleteOptions) error + CheckpointList(ctx context.Context, container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) +} diff --git a/vendor/github.com/moby/moby/client/checkpoint_create.go b/vendor/github.com/moby/moby/client/checkpoint_create.go new file mode 100644 index 000000000000..ef325a82dd6a --- /dev/null +++ b/vendor/github.com/moby/moby/client/checkpoint_create.go @@ -0,0 +1,19 @@ +package client + +import ( + "context" + + "github.com/moby/moby/api/types/checkpoint" +) + +// CheckpointCreate creates a checkpoint from the given container. +func (cli *Client) CheckpointCreate(ctx context.Context, containerID string, options checkpoint.CreateOptions) error { + containerID, err := trimID("container", containerID) + if err != nil { + return err + } + + resp, err := cli.post(ctx, "/containers/"+containerID+"/checkpoints", nil, options, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/checkpoint_delete.go b/vendor/github.com/moby/moby/client/checkpoint_delete.go new file mode 100644 index 000000000000..87f3f88218c0 --- /dev/null +++ b/vendor/github.com/moby/moby/client/checkpoint_delete.go @@ -0,0 +1,25 @@ +package client + +import ( + "context" + "net/url" + + "github.com/moby/moby/api/types/checkpoint" +) + +// CheckpointDelete deletes the checkpoint with the given name from the given container. +func (cli *Client) CheckpointDelete(ctx context.Context, containerID string, options checkpoint.DeleteOptions) error { + containerID, err := trimID("container", containerID) + if err != nil { + return err + } + + query := url.Values{} + if options.CheckpointDir != "" { + query.Set("dir", options.CheckpointDir) + } + + resp, err := cli.delete(ctx, "/containers/"+containerID+"/checkpoints/"+options.CheckpointID, query, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/checkpoint_list.go b/vendor/github.com/moby/moby/client/checkpoint_list.go new file mode 100644 index 000000000000..96833505fbad --- /dev/null +++ b/vendor/github.com/moby/moby/client/checkpoint_list.go @@ -0,0 +1,28 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/checkpoint" +) + +// CheckpointList returns the checkpoints of the given container in the docker host. +func (cli *Client) CheckpointList(ctx context.Context, container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) { + var checkpoints []checkpoint.Summary + + query := url.Values{} + if options.CheckpointDir != "" { + query.Set("dir", options.CheckpointDir) + } + + resp, err := cli.get(ctx, "/containers/"+container+"/checkpoints", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return checkpoints, err + } + + err = json.NewDecoder(resp.Body).Decode(&checkpoints) + return checkpoints, err +} diff --git a/vendor/github.com/moby/moby/client/client.go b/vendor/github.com/moby/moby/client/client.go new file mode 100644 index 000000000000..81139d19ce18 --- /dev/null +++ b/vendor/github.com/moby/moby/client/client.go @@ -0,0 +1,486 @@ +/* +Package client is a Go client for the Docker Engine API. + +For more information about the Engine API, see the documentation: +https://docs.docker.com/reference/api/engine/ + +# Usage + +You use the library by constructing a client object using [NewClientWithOpts] +and calling methods on it. The client can be configured from environment +variables by passing the [FromEnv] option, or configured manually by passing any +of the other available [Opts]. + +For example, to list running containers (the equivalent of "docker ps"): + + package main + + import ( + "context" + "fmt" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" + ) + + func main() { + cli, err := client.NewClientWithOpts(client.FromEnv) + if err != nil { + panic(err) + } + + containers, err := cli.ContainerList(context.Background(), container.ListOptions{}) + if err != nil { + panic(err) + } + + for _, ctr := range containers { + fmt.Printf("%s %s\n", ctr.ID, ctr.Image) + } + } +*/ +package client + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "net" + "net/http" + "net/url" + "path" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/docker/go-connections/sockets" + "github.com/moby/moby/api/types" + "github.com/moby/moby/api/types/versions" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +) + +// DummyHost is a hostname used for local communication. +// +// It acts as a valid formatted hostname for local connections (such as "unix://" +// or "npipe://") which do not require a hostname. It should never be resolved, +// but uses the special-purpose ".localhost" TLD (as defined in [RFC 2606, Section 2] +// and [RFC 6761, Section 6.3]). +// +// [RFC 7230, Section 5.4] defines that an empty header must be used for such +// cases: +// +// If the authority component is missing or undefined for the target URI, +// then a client MUST send a Host header field with an empty field-value. +// +// However, [Go stdlib] enforces the semantics of HTTP(S) over TCP, does not +// allow an empty header to be used, and requires req.URL.Scheme to be either +// "http" or "https". +// +// For further details, refer to: +// +// - https://github.com/docker/engine-api/issues/189 +// - https://github.com/golang/go/issues/13624 +// - https://github.com/golang/go/issues/61076 +// - https://github.com/moby/moby/issues/45935 +// +// [RFC 2606, Section 2]: https://www.rfc-editor.org/rfc/rfc2606.html#section-2 +// [RFC 6761, Section 6.3]: https://www.rfc-editor.org/rfc/rfc6761#section-6.3 +// [RFC 7230, Section 5.4]: https://datatracker.ietf.org/doc/html/rfc7230#section-5.4 +// [Go stdlib]: https://github.com/golang/go/blob/6244b1946bc2101b01955468f1be502dbadd6807/src/net/http/transport.go#L558-L569 +const DummyHost = "api.moby.localhost" + +// DefaultAPIVersion is the highest REST API version supported by the client. +// If API-version negotiation is enabled (see [WithAPIVersionNegotiation], +// [Client.NegotiateAPIVersion]), the client may downgrade its API version. +// Similarly, the [WithVersion] and [WithVersionFromEnv] allow overriding +// the version. +// +// This version may be lower than the [api.DefaultVersion], which is the default +// (and highest supported) version of the api library module used. +const DefaultAPIVersion = "1.52" + +// fallbackAPIVersion is the version to fallback to if API-version negotiation +// fails. This version is the highest version of the API before API-version +// negotiation was introduced. If negotiation fails (or no API version was +// included in the API response), we assume the API server uses the most +// recent version before negotiation was introduced. +const fallbackAPIVersion = "1.24" + +// Ensure that Client always implements APIClient. +var _ APIClient = &Client{} + +// Client is the API client that performs all operations +// against a docker server. +type Client struct { + // scheme sets the scheme for the client + scheme string + // host holds the server address to connect to + host string + // proto holds the client protocol i.e. unix. + proto string + // addr holds the client address. + addr string + // basePath holds the path to prepend to the requests. + basePath string + // client used to send and receive http requests. + client *http.Client + // version of the server to talk to. + version string + // userAgent is the User-Agent header to use for HTTP requests. It takes + // precedence over User-Agent headers set in customHTTPHeaders, and other + // header variables. When set to an empty string, the User-Agent header + // is removed, and no header is sent. + userAgent *string + // custom HTTP headers configured by users. + customHTTPHeaders map[string]string + // manualOverride is set to true when the version was set by users. + manualOverride bool + + // negotiateVersion indicates if the client should automatically negotiate + // the API version to use when making requests. API version negotiation is + // performed on the first request, after which negotiated is set to "true" + // so that subsequent requests do not re-negotiate. + negotiateVersion bool + + // negotiated indicates that API version negotiation took place + negotiated atomic.Bool + + // negotiateLock is used to single-flight the version negotiation process + negotiateLock sync.Mutex + + traceOpts []otelhttp.Option + + // When the client transport is an *http.Transport (default) we need to do some extra things (like closing idle connections). + // Store the original transport as the http.Client transport will be wrapped with tracing libs. + baseTransport *http.Transport +} + +// ErrRedirect is the error returned by checkRedirect when the request is non-GET. +var ErrRedirect = errors.New("unexpected redirect in response") + +// CheckRedirect specifies the policy for dealing with redirect responses. It +// can be set on [http.Client.CheckRedirect] to prevent HTTP redirects for +// non-GET requests. It returns an [ErrRedirect] for non-GET request, otherwise +// returns a [http.ErrUseLastResponse], which is special-cased by http.Client +// to use the last response. +// +// Go 1.8 changed behavior for HTTP redirects (specifically 301, 307, and 308) +// in the client. The client (and by extension API client) can be made to send +// a request like "POST /containers//start" where what would normally be in the +// name section of the URL is empty. This triggers an HTTP 301 from the daemon. +// +// In go 1.8 this 301 is converted to a GET request, and ends up getting +// a 404 from the daemon. This behavior change manifests in the client in that +// before, the 301 was not followed and the client did not generate an error, +// but now results in a message like "Error response from daemon: page not found". +func CheckRedirect(_ *http.Request, via []*http.Request) error { + if via[0].Method == http.MethodGet { + return http.ErrUseLastResponse + } + return ErrRedirect +} + +// NewClientWithOpts initializes a new API client with a default HTTPClient, and +// default API host and version. It also initializes the custom HTTP headers to +// add to each request. +// +// It takes an optional list of [Opt] functional arguments, which are applied in +// the order they're provided, which allows modifying the defaults when creating +// the client. For example, the following initializes a client that configures +// itself with values from environment variables ([FromEnv]), and has automatic +// API version negotiation enabled ([WithAPIVersionNegotiation]). +// +// cli, err := client.NewClientWithOpts( +// client.FromEnv, +// client.WithAPIVersionNegotiation(), +// ) +func NewClientWithOpts(ops ...Opt) (*Client, error) { + hostURL, err := ParseHostURL(DefaultDockerHost) + if err != nil { + return nil, err + } + + client, err := defaultHTTPClient(hostURL) + if err != nil { + return nil, err + } + c := &Client{ + host: DefaultDockerHost, + version: DefaultAPIVersion, + client: client, + proto: hostURL.Scheme, + addr: hostURL.Host, + + traceOpts: []otelhttp.Option{ + otelhttp.WithSpanNameFormatter(func(_ string, req *http.Request) string { + return req.Method + " " + req.URL.Path + }), + }, + } + + for _, op := range ops { + if err := op(c); err != nil { + return nil, err + } + } + + if tr, ok := c.client.Transport.(*http.Transport); ok { + // Store the base transport before we wrap it in tracing libs below + // This is used, as an example, to close idle connections when the client is closed + c.baseTransport = tr + } + + if c.scheme == "" { + // TODO(stevvooe): This isn't really the right way to write clients in Go. + // `NewClient` should probably only take an `*http.Client` and work from there. + // Unfortunately, the model of having a host-ish/url-thingy as the connection + // string has us confusing protocol and transport layers. We continue doing + // this to avoid breaking existing clients but this should be addressed. + if c.tlsConfig() != nil { + c.scheme = "https" + } else { + c.scheme = "http" + } + } + + c.client.Transport = otelhttp.NewTransport(c.client.Transport, c.traceOpts...) + + return c, nil +} + +func (cli *Client) tlsConfig() *tls.Config { + if cli.baseTransport == nil { + return nil + } + return cli.baseTransport.TLSClientConfig +} + +func defaultHTTPClient(hostURL *url.URL) (*http.Client, error) { + transport := &http.Transport{} + // Necessary to prevent long-lived processes using the + // client from leaking connections due to idle connections + // not being released. + // TODO: see if we can also address this from the server side, + // or in go-connections. + // see: https://github.com/moby/moby/issues/45539 + transport.MaxIdleConns = 6 + transport.IdleConnTimeout = 30 * time.Second + err := sockets.ConfigureTransport(transport, hostURL.Scheme, hostURL.Host) + if err != nil { + return nil, err + } + return &http.Client{ + Transport: transport, + CheckRedirect: CheckRedirect, + }, nil +} + +// Close the transport used by the client +func (cli *Client) Close() error { + if cli.baseTransport != nil { + cli.baseTransport.CloseIdleConnections() + return nil + } + return nil +} + +// checkVersion manually triggers API version negotiation (if configured). +// This allows for version-dependent code to use the same version as will +// be negotiated when making the actual requests, and for which cases +// we cannot do the negotiation lazily. +func (cli *Client) checkVersion(ctx context.Context) error { + if !cli.manualOverride && cli.negotiateVersion && !cli.negotiated.Load() { + // Ensure exclusive write access to version and negotiated fields + cli.negotiateLock.Lock() + defer cli.negotiateLock.Unlock() + + // May have been set during last execution of critical zone + if cli.negotiated.Load() { + return nil + } + + ping, err := cli.Ping(ctx) + if err != nil { + return err + } + cli.negotiateAPIVersionPing(ping) + } + return nil +} + +// getAPIPath returns the versioned request path to call the API. +// It appends the query parameters to the path if they are not empty. +func (cli *Client) getAPIPath(ctx context.Context, p string, query url.Values) string { + var apiPath string + _ = cli.checkVersion(ctx) + if cli.version != "" { + apiPath = path.Join(cli.basePath, "/v"+strings.TrimPrefix(cli.version, "v"), p) + } else { + apiPath = path.Join(cli.basePath, p) + } + return (&url.URL{Path: apiPath, RawQuery: query.Encode()}).String() +} + +// ClientVersion returns the API version used by this client. +func (cli *Client) ClientVersion() string { + return cli.version +} + +// NegotiateAPIVersion queries the API and updates the version to match the API +// version. NegotiateAPIVersion downgrades the client's API version to match the +// APIVersion if the ping version is lower than the default version. If the API +// version reported by the server is higher than the maximum version supported +// by the client, it uses the client's maximum version. +// +// If a manual override is in place, either through the "DOCKER_API_VERSION" +// ([EnvOverrideAPIVersion]) environment variable, or if the client is initialized +// with a fixed version ([WithVersion]), no negotiation is performed. +// +// If the API server's ping response does not contain an API version, or if the +// client did not get a successful ping response, it assumes it is connected with +// an old daemon that does not support API version negotiation, in which case it +// downgrades to the latest version of the API before version negotiation was +// added (1.24). +func (cli *Client) NegotiateAPIVersion(ctx context.Context) { + if !cli.manualOverride { + // Avoid concurrent modification of version-related fields + cli.negotiateLock.Lock() + defer cli.negotiateLock.Unlock() + + ping, err := cli.Ping(ctx) + if err != nil { + // FIXME(thaJeztah): Ping returns an error when failing to connect to the API; we should not swallow the error here, and instead returning it. + return + } + cli.negotiateAPIVersionPing(ping) + } +} + +// NegotiateAPIVersionPing downgrades the client's API version to match the +// APIVersion in the ping response. If the API version in pingResponse is higher +// than the maximum version supported by the client, it uses the client's maximum +// version. +// +// If a manual override is in place, either through the "DOCKER_API_VERSION" +// ([EnvOverrideAPIVersion]) environment variable, or if the client is initialized +// with a fixed version ([WithVersion]), no negotiation is performed. +// +// If the API server's ping response does not contain an API version, we assume +// we are connected with an old daemon without API version negotiation support, +// and downgrade to the latest version of the API before version negotiation was +// added (1.24). +func (cli *Client) NegotiateAPIVersionPing(pingResponse types.Ping) { + if !cli.manualOverride { + // Avoid concurrent modification of version-related fields + cli.negotiateLock.Lock() + defer cli.negotiateLock.Unlock() + + cli.negotiateAPIVersionPing(pingResponse) + } +} + +// negotiateAPIVersionPing queries the API and updates the version to match the +// API version from the ping response. +func (cli *Client) negotiateAPIVersionPing(pingResponse types.Ping) { + // default to the latest version before versioning headers existed + if pingResponse.APIVersion == "" { + pingResponse.APIVersion = fallbackAPIVersion + } + + // if the client is not initialized with a version, start with the latest supported version + if cli.version == "" { + cli.version = DefaultAPIVersion + } + + // if server version is lower than the client version, downgrade + if versions.LessThan(pingResponse.APIVersion, cli.version) { + cli.version = pingResponse.APIVersion + } + + // Store the results, so that automatic API version negotiation (if enabled) + // won't be performed on the next request. + if cli.negotiateVersion { + cli.negotiated.Store(true) + } +} + +// DaemonHost returns the host address used by the client +func (cli *Client) DaemonHost() string { + return cli.host +} + +// HTTPClient returns a copy of the HTTP client bound to the server +func (cli *Client) HTTPClient() *http.Client { + c := *cli.client + return &c +} + +// ParseHostURL parses a url string, validates the string is a host url, and +// returns the parsed URL +func ParseHostURL(host string) (*url.URL, error) { + proto, addr, ok := strings.Cut(host, "://") + if !ok || addr == "" { + return nil, fmt.Errorf("unable to parse docker host `%s`", host) + } + + var basePath string + if proto == "tcp" { + parsed, err := url.Parse("tcp://" + addr) + if err != nil { + return nil, err + } + addr = parsed.Host + basePath = parsed.Path + } + return &url.URL{ + Scheme: proto, + Host: addr, + Path: basePath, + }, nil +} + +func (cli *Client) dialerFromTransport() func(context.Context, string, string) (net.Conn, error) { + if cli.baseTransport == nil || cli.baseTransport.DialContext == nil { + return nil + } + + if cli.baseTransport.TLSClientConfig != nil { + // When using a tls config we don't use the configured dialer but instead a fallback dialer... + // Note: It seems like this should use the normal dialer and wrap the returned net.Conn in a tls.Conn + // I honestly don't know why it doesn't do that, but it doesn't and such a change is entirely unrelated to the change in this commit. + return nil + } + return cli.baseTransport.DialContext +} + +// Dialer returns a dialer for a raw stream connection, with an HTTP/1.1 header, +// that can be used for proxying the daemon connection. It is used by +// ["docker dial-stdio"]. +// +// ["docker dial-stdio"]: https://github.com/docker/cli/pull/1014 +func (cli *Client) Dialer() func(context.Context) (net.Conn, error) { + return cli.dialer() +} + +func (cli *Client) dialer() func(context.Context) (net.Conn, error) { + return func(ctx context.Context) (net.Conn, error) { + if dialFn := cli.dialerFromTransport(); dialFn != nil { + return dialFn(ctx, cli.proto, cli.addr) + } + switch cli.proto { + case "unix": + return net.Dial(cli.proto, cli.addr) + case "npipe": + ctx, cancel := context.WithTimeout(ctx, 32*time.Second) + defer cancel() + return dialPipeContext(ctx, cli.addr) + default: + if tlsConfig := cli.tlsConfig(); tlsConfig != nil { + return tls.Dial(cli.proto, cli.addr, tlsConfig) + } + return net.Dial(cli.proto, cli.addr) + } + } +} diff --git a/vendor/github.com/moby/moby/client/client_interfaces.go b/vendor/github.com/moby/moby/client/client_interfaces.go new file mode 100644 index 000000000000..a8b786274853 --- /dev/null +++ b/vendor/github.com/moby/moby/client/client_interfaces.go @@ -0,0 +1,223 @@ +package client + +import ( + "context" + "io" + "net" + "net/http" + + "github.com/moby/moby/api/types" + "github.com/moby/moby/api/types/build" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/events" + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/image" + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/api/types/plugin" + "github.com/moby/moby/api/types/registry" + "github.com/moby/moby/api/types/swarm" + "github.com/moby/moby/api/types/system" + "github.com/moby/moby/api/types/volume" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +// APIClient is an interface that clients that talk with a docker server must implement. +type APIClient interface { + stableAPIClient + CheckpointAPIClient // CheckpointAPIClient is still experimental. +} + +type stableAPIClient interface { + ConfigAPIClient + ContainerAPIClient + DistributionAPIClient + ImageAPIClient + NetworkAPIClient + PluginAPIClient + SystemAPIClient + VolumeAPIClient + ClientVersion() string + DaemonHost() string + HTTPClient() *http.Client + ServerVersion(ctx context.Context) (types.Version, error) + NegotiateAPIVersion(ctx context.Context) + NegotiateAPIVersionPing(types.Ping) + HijackDialer + Dialer() func(context.Context) (net.Conn, error) + Close() error + SwarmManagementAPIClient +} + +// SwarmManagementAPIClient defines all methods for managing Swarm-specific +// objects. +type SwarmManagementAPIClient interface { + SwarmAPIClient + NodeAPIClient + ServiceAPIClient + SecretAPIClient + ConfigAPIClient +} + +// HijackDialer defines methods for a hijack dialer. +type HijackDialer interface { + DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error) +} + +// ContainerAPIClient defines API client methods for the containers +type ContainerAPIClient interface { + ContainerAttach(ctx context.Context, container string, options container.AttachOptions) (HijackedResponse, error) + ContainerCommit(ctx context.Context, container string, options container.CommitOptions) (container.CommitResponse, error) + ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) + ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error) + ContainerExecAttach(ctx context.Context, execID string, options container.ExecAttachOptions) (HijackedResponse, error) + ContainerExecCreate(ctx context.Context, container string, options container.ExecOptions) (container.ExecCreateResponse, error) + ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error) + 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) (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) ([]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 + ContainerRename(ctx context.Context, container, newContainerName string) error + ContainerResize(ctx context.Context, container string, options container.ResizeOptions) error + ContainerRestart(ctx context.Context, container string, options container.StopOptions) error + ContainerStatPath(ctx context.Context, container, path string) (container.PathStat, error) + ContainerStats(ctx context.Context, container string, stream bool) (StatsResponseReader, error) + ContainerStatsOneShot(ctx context.Context, container string) (StatsResponseReader, error) + ContainerStart(ctx context.Context, container string, options container.StartOptions) error + ContainerStop(ctx context.Context, container string, options container.StopOptions) error + ContainerTop(ctx context.Context, container string, arguments []string) (container.TopResponse, error) + ContainerUnpause(ctx context.Context, container string) error + ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) (container.UpdateResponse, error) + ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) + CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error) + CopyToContainer(ctx context.Context, container, path string, content io.Reader, options container.CopyToContainerOptions) error + ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) +} + +// DistributionAPIClient defines API client methods for the registry +type DistributionAPIClient interface { + DistributionInspect(ctx context.Context, image, encodedRegistryAuth string) (registry.DistributionInspect, error) +} + +// ImageAPIClient defines API client methods for the images +type ImageAPIClient interface { + ImageBuild(ctx context.Context, context io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error) + BuildCachePrune(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error) + BuildCancel(ctx context.Context, id string) error + ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error) + ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) + + ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, 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) + ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error) + ImageTag(ctx context.Context, image, ref string) error + ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error) + + ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (image.InspectResponse, error) + ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) ([]image.HistoryResponseItem, error) + ImageLoad(ctx context.Context, input io.Reader, _ ...ImageLoadOption) (image.LoadResponse, error) + ImageSave(ctx context.Context, images []string, _ ...ImageSaveOption) (io.ReadCloser, error) +} + +// NetworkAPIClient defines API client methods for the networks +type NetworkAPIClient interface { + NetworkConnect(ctx context.Context, network, container string, config *network.EndpointSettings) error + NetworkCreate(ctx context.Context, name string, options network.CreateOptions) (network.CreateResponse, error) + NetworkDisconnect(ctx context.Context, network, container string, force bool) error + NetworkInspect(ctx context.Context, network string, options network.InspectOptions) (network.Inspect, error) + NetworkInspectWithRaw(ctx context.Context, network string, options network.InspectOptions) (network.Inspect, []byte, error) + NetworkList(ctx context.Context, options network.ListOptions) ([]network.Summary, error) + NetworkRemove(ctx context.Context, network string) error + NetworksPrune(ctx context.Context, pruneFilter filters.Args) (network.PruneReport, error) +} + +// NodeAPIClient defines API client methods for the nodes +type NodeAPIClient interface { + NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) + NodeList(ctx context.Context, options swarm.NodeListOptions) ([]swarm.Node, error) + NodeRemove(ctx context.Context, nodeID string, options swarm.NodeRemoveOptions) error + NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error +} + +// PluginAPIClient defines API client methods for the plugins +type PluginAPIClient interface { + PluginList(ctx context.Context, filter filters.Args) (plugin.ListResponse, error) + PluginRemove(ctx context.Context, name string, options PluginRemoveOptions) error + PluginEnable(ctx context.Context, name string, options PluginEnableOptions) error + PluginDisable(ctx context.Context, name string, options PluginDisableOptions) error + PluginInstall(ctx context.Context, name string, options PluginInstallOptions) (io.ReadCloser, error) + PluginUpgrade(ctx context.Context, name string, options PluginInstallOptions) (io.ReadCloser, error) + PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) + PluginSet(ctx context.Context, name string, args []string) error + PluginInspectWithRaw(ctx context.Context, name string) (*plugin.Plugin, []byte, error) + PluginCreate(ctx context.Context, createContext io.Reader, options PluginCreateOptions) error +} + +// ServiceAPIClient defines API client methods for the services +type ServiceAPIClient interface { + ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options swarm.ServiceCreateOptions) (swarm.ServiceCreateResponse, error) + ServiceInspectWithRaw(ctx context.Context, serviceID string, options swarm.ServiceInspectOptions) (swarm.Service, []byte, error) + ServiceList(ctx context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error) + ServiceRemove(ctx context.Context, serviceID string) error + ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) + ServiceLogs(ctx context.Context, serviceID string, options container.LogsOptions) (io.ReadCloser, error) + TaskLogs(ctx context.Context, taskID string, options container.LogsOptions) (io.ReadCloser, error) + TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) + TaskList(ctx context.Context, options swarm.TaskListOptions) ([]swarm.Task, error) +} + +// SwarmAPIClient defines API client methods for the swarm +type SwarmAPIClient interface { + SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) + SwarmJoin(ctx context.Context, req swarm.JoinRequest) error + SwarmGetUnlockKey(ctx context.Context) (swarm.UnlockKeyResponse, error) + SwarmUnlock(ctx context.Context, req swarm.UnlockRequest) error + SwarmLeave(ctx context.Context, force bool) error + SwarmInspect(ctx context.Context) (swarm.Swarm, error) + SwarmUpdate(ctx context.Context, version swarm.Version, swarm swarm.Spec, flags swarm.UpdateFlags) error +} + +// SystemAPIClient defines API client methods for the system +type SystemAPIClient interface { + Events(ctx context.Context, options events.ListOptions) (<-chan events.Message, <-chan error) + Info(ctx context.Context) (system.Info, error) + RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error) + DiskUsage(ctx context.Context, options system.DiskUsageOptions) (system.DiskUsage, error) + Ping(ctx context.Context) (types.Ping, error) +} + +// VolumeAPIClient defines API client methods for the volumes +type VolumeAPIClient interface { + VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error) + VolumeInspect(ctx context.Context, volumeID string) (volume.Volume, error) + VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error) + VolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error) + VolumeRemove(ctx context.Context, volumeID string, force bool) error + VolumesPrune(ctx context.Context, pruneFilter filters.Args) (volume.PruneReport, error) + VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error +} + +// SecretAPIClient defines API client methods for secrets +type SecretAPIClient interface { + SecretList(ctx context.Context, options swarm.SecretListOptions) ([]swarm.Secret, error) + SecretCreate(ctx context.Context, secret swarm.SecretSpec) (swarm.SecretCreateResponse, error) + SecretRemove(ctx context.Context, id string) error + SecretInspectWithRaw(ctx context.Context, name string) (swarm.Secret, []byte, error) + SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error +} + +// ConfigAPIClient defines API client methods for configs +type ConfigAPIClient interface { + ConfigList(ctx context.Context, options swarm.ConfigListOptions) ([]swarm.Config, error) + ConfigCreate(ctx context.Context, config swarm.ConfigSpec) (swarm.ConfigCreateResponse, error) + ConfigRemove(ctx context.Context, id string) error + ConfigInspectWithRaw(ctx context.Context, name string) (swarm.Config, []byte, error) + ConfigUpdate(ctx context.Context, id string, version swarm.Version, config swarm.ConfigSpec) error +} diff --git a/vendor/github.com/moby/moby/client/client_unix.go b/vendor/github.com/moby/moby/client/client_unix.go new file mode 100644 index 000000000000..1fb9fbfb9e55 --- /dev/null +++ b/vendor/github.com/moby/moby/client/client_unix.go @@ -0,0 +1,18 @@ +//go:build !windows + +package client + +import ( + "context" + "net" + "syscall" +) + +// DefaultDockerHost defines OS-specific default host if the DOCKER_HOST +// (EnvOverrideHost) environment variable is unset or empty. +const DefaultDockerHost = "unix:///var/run/docker.sock" + +// dialPipeContext connects to a Windows named pipe. It is not supported on non-Windows. +func dialPipeContext(_ context.Context, _ string) (net.Conn, error) { + return nil, syscall.EAFNOSUPPORT +} diff --git a/vendor/github.com/moby/moby/client/client_windows.go b/vendor/github.com/moby/moby/client/client_windows.go new file mode 100644 index 000000000000..b471c0612403 --- /dev/null +++ b/vendor/github.com/moby/moby/client/client_windows.go @@ -0,0 +1,17 @@ +package client + +import ( + "context" + "net" + + "github.com/Microsoft/go-winio" +) + +// DefaultDockerHost defines OS-specific default host if the DOCKER_HOST +// (EnvOverrideHost) environment variable is unset or empty. +const DefaultDockerHost = "npipe:////./pipe/docker_engine" + +// dialPipeContext connects to a Windows named pipe. It is not supported on non-Windows. +func dialPipeContext(ctx context.Context, addr string) (net.Conn, error) { + return winio.DialPipeContext(ctx, addr) +} diff --git a/vendor/github.com/moby/moby/client/config_create.go b/vendor/github.com/moby/moby/client/config_create.go new file mode 100644 index 000000000000..bb1cf9a5b13e --- /dev/null +++ b/vendor/github.com/moby/moby/client/config_create.go @@ -0,0 +1,24 @@ +package client + +import ( + "context" + "encoding/json" + + "github.com/moby/moby/api/types/swarm" +) + +// ConfigCreate creates a new config. +func (cli *Client) ConfigCreate(ctx context.Context, config swarm.ConfigSpec) (swarm.ConfigCreateResponse, error) { + var response swarm.ConfigCreateResponse + if err := cli.NewVersionError(ctx, "1.30", "config create"); err != nil { + return response, err + } + resp, err := cli.post(ctx, "/configs/create", nil, config, nil) + defer ensureReaderClosed(resp) + if err != nil { + return response, err + } + + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} diff --git a/vendor/github.com/moby/moby/client/config_inspect.go b/vendor/github.com/moby/moby/client/config_inspect.go new file mode 100644 index 000000000000..d43182e85e2c --- /dev/null +++ b/vendor/github.com/moby/moby/client/config_inspect.go @@ -0,0 +1,37 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "io" + + "github.com/moby/moby/api/types/swarm" +) + +// ConfigInspectWithRaw returns the config information with raw data +func (cli *Client) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.Config, []byte, error) { + id, err := trimID("contig", id) + if err != nil { + return swarm.Config{}, nil, err + } + if err := cli.NewVersionError(ctx, "1.30", "config inspect"); err != nil { + return swarm.Config{}, nil, err + } + resp, err := cli.get(ctx, "/configs/"+id, nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return swarm.Config{}, nil, err + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return swarm.Config{}, nil, err + } + + var config swarm.Config + rdr := bytes.NewReader(body) + err = json.NewDecoder(rdr).Decode(&config) + + return config, body, err +} diff --git a/vendor/github.com/moby/moby/client/config_list.go b/vendor/github.com/moby/moby/client/config_list.go new file mode 100644 index 000000000000..aae9c0d4e32f --- /dev/null +++ b/vendor/github.com/moby/moby/client/config_list.go @@ -0,0 +1,37 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/swarm" +) + +// ConfigList returns the list of configs. +func (cli *Client) ConfigList(ctx context.Context, options swarm.ConfigListOptions) ([]swarm.Config, error) { + if err := cli.NewVersionError(ctx, "1.30", "config list"); err != nil { + return nil, err + } + query := url.Values{} + + if options.Filters.Len() > 0 { + filterJSON, err := filters.ToJSON(options.Filters) + if err != nil { + return nil, err + } + + query.Set("filters", filterJSON) + } + + resp, err := cli.get(ctx, "/configs", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return nil, err + } + + var configs []swarm.Config + err = json.NewDecoder(resp.Body).Decode(&configs) + return configs, err +} diff --git a/vendor/github.com/moby/moby/client/config_remove.go b/vendor/github.com/moby/moby/client/config_remove.go new file mode 100644 index 000000000000..99d33b1ce2ba --- /dev/null +++ b/vendor/github.com/moby/moby/client/config_remove.go @@ -0,0 +1,17 @@ +package client + +import "context" + +// ConfigRemove removes a config. +func (cli *Client) ConfigRemove(ctx context.Context, id string) error { + id, err := trimID("config", id) + if err != nil { + return err + } + if err := cli.NewVersionError(ctx, "1.30", "config remove"); err != nil { + return err + } + resp, err := cli.delete(ctx, "/configs/"+id, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/config_update.go b/vendor/github.com/moby/moby/client/config_update.go new file mode 100644 index 000000000000..93037479471d --- /dev/null +++ b/vendor/github.com/moby/moby/client/config_update.go @@ -0,0 +1,24 @@ +package client + +import ( + "context" + "net/url" + + "github.com/moby/moby/api/types/swarm" +) + +// ConfigUpdate attempts to update a config +func (cli *Client) ConfigUpdate(ctx context.Context, id string, version swarm.Version, config swarm.ConfigSpec) error { + id, err := trimID("config", id) + if err != nil { + return err + } + if err := cli.NewVersionError(ctx, "1.30", "config update"); err != nil { + return err + } + query := url.Values{} + query.Set("version", version.String()) + resp, err := cli.post(ctx, "/configs/"+id+"/update", query, config, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/container_attach.go b/vendor/github.com/moby/moby/client/container_attach.go new file mode 100644 index 000000000000..cd1e1aa78a21 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_attach.go @@ -0,0 +1,68 @@ +package client + +import ( + "context" + "net/http" + "net/url" + + "github.com/moby/moby/api/types/container" +) + +// ContainerAttach attaches a connection to a container in the server. +// It returns a [HijackedResponse] with the hijacked connection +// and a reader to get output. It's up to the called to close +// the hijacked connection by calling [HijackedResponse.Close]. +// +// The stream format on the response uses one of two formats: +// +// - If the container is using a TTY, there is only a single stream (stdout) +// and data is copied directly from the container output stream, no extra +// multiplexing or headers. +// - If the container is *not* using a TTY, streams for stdout and stderr are +// multiplexed. +// +// The format of the multiplexed stream is defined in the [stdcopy] package, +// and as follows: +// +// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT} +// +// STREAM_TYPE can be 1 for [Stdout] and 2 for [Stderr]. Refer to [stdcopy.StdType] +// for details. SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded +// as big endian, this is the size of OUTPUT. You can use [stdcopy.StdCopy] +// to demultiplex this stream. +// +// [stdcopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy +// [stdcopy.StdCopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdCopy +// [stdcopy.StdType]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdType +// [Stdout]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#Stdout +// [Stderr]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#Stderr +func (cli *Client) ContainerAttach(ctx context.Context, containerID string, options container.AttachOptions) (HijackedResponse, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return HijackedResponse{}, err + } + + query := url.Values{} + if options.Stream { + query.Set("stream", "1") + } + if options.Stdin { + query.Set("stdin", "1") + } + if options.Stdout { + query.Set("stdout", "1") + } + if options.Stderr { + query.Set("stderr", "1") + } + if options.DetachKeys != "" { + query.Set("detachKeys", options.DetachKeys) + } + if options.Logs { + query.Set("logs", "1") + } + + return cli.postHijacked(ctx, "/containers/"+containerID+"/attach", query, nil, http.Header{ + "Content-Type": {"text/plain"}, + }) +} diff --git a/vendor/github.com/moby/moby/client/container_commit.go b/vendor/github.com/moby/moby/client/container_commit.go new file mode 100644 index 000000000000..fcdb115afe3b --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_commit.go @@ -0,0 +1,60 @@ +package client + +import ( + "context" + "encoding/json" + "errors" + "net/url" + + "github.com/distribution/reference" + "github.com/moby/moby/api/types/container" +) + +// ContainerCommit applies changes to a container and creates a new tagged image. +func (cli *Client) ContainerCommit(ctx context.Context, containerID string, options container.CommitOptions) (container.CommitResponse, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return container.CommitResponse{}, err + } + + var repository, tag string + if options.Reference != "" { + ref, err := reference.ParseNormalizedNamed(options.Reference) + if err != nil { + return container.CommitResponse{}, err + } + + if _, isCanonical := ref.(reference.Canonical); isCanonical { + return container.CommitResponse{}, errors.New("refusing to create a tag with a digest reference") + } + ref = reference.TagNameOnly(ref) + + if tagged, ok := ref.(reference.Tagged); ok { + tag = tagged.Tag() + } + repository = ref.Name() + } + + query := url.Values{} + query.Set("container", containerID) + query.Set("repo", repository) + query.Set("tag", tag) + query.Set("comment", options.Comment) + query.Set("author", options.Author) + for _, change := range options.Changes { + query.Add("changes", change) + } + if !options.Pause { + query.Set("pause", "0") + } + + var response container.CommitResponse + resp, err := cli.post(ctx, "/commit", query, options.Config, nil) + defer ensureReaderClosed(resp) + if err != nil { + return response, err + } + + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} diff --git a/vendor/github.com/moby/moby/client/container_copy.go b/vendor/github.com/moby/moby/client/container_copy.go new file mode 100644 index 000000000000..082ff56c3b50 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_copy.go @@ -0,0 +1,104 @@ +package client + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "path/filepath" + "strings" + + "github.com/moby/moby/api/types/container" +) + +// ContainerStatPath returns stat information about a path inside the container filesystem. +func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path string) (container.PathStat, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return container.PathStat{}, err + } + + query := url.Values{} + query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API. + + resp, err := cli.head(ctx, "/containers/"+containerID+"/archive", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return container.PathStat{}, err + } + return getContainerPathStatFromHeader(resp.Header) +} + +// CopyToContainer copies content into the container filesystem. +// Note that `content` must be a Reader for a TAR archive +func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options container.CopyToContainerOptions) error { + containerID, err := trimID("container", containerID) + if err != nil { + return err + } + + query := url.Values{} + query.Set("path", filepath.ToSlash(dstPath)) // Normalize the paths used in the API. + // Do not allow for an existing directory to be overwritten by a non-directory and vice versa. + if !options.AllowOverwriteDirWithFile { + query.Set("noOverwriteDirNonDir", "true") + } + + if options.CopyUIDGID { + query.Set("copyUIDGID", "true") + } + + response, err := cli.putRaw(ctx, "/containers/"+containerID+"/archive", query, content, nil) + defer ensureReaderClosed(response) + if err != nil { + return err + } + + return nil +} + +// CopyFromContainer gets the content from the container and returns it as a Reader +// for a TAR archive to manipulate it in the host. It's up to the caller to close the reader. +func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, container.PathStat, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return nil, container.PathStat{}, err + } + + query := make(url.Values, 1) + query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API. + + resp, err := cli.get(ctx, "/containers/"+containerID+"/archive", query, nil) + if err != nil { + return nil, container.PathStat{}, err + } + + // In order to get the copy behavior right, we need to know information + // about both the source and the destination. The response headers include + // stat info about the source that we can use in deciding exactly how to + // copy it locally. Along with the stat info about the local destination, + // we have everything we need to handle the multiple possibilities there + // can be when copying a file/dir from one location to another file/dir. + stat, err := getContainerPathStatFromHeader(resp.Header) + if err != nil { + return nil, stat, fmt.Errorf("unable to get resource stat from response: %s", err) + } + return resp.Body, stat, err +} + +func getContainerPathStatFromHeader(header http.Header) (container.PathStat, error) { + var stat container.PathStat + + encodedStat := header.Get("X-Docker-Container-Path-Stat") + statDecoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(encodedStat)) + + err := json.NewDecoder(statDecoder).Decode(&stat) + if err != nil { + err = fmt.Errorf("unable to decode container path stat header: %s", err) + } + + return stat, err +} diff --git a/vendor/github.com/moby/moby/client/container_create.go b/vendor/github.com/moby/moby/client/container_create.go new file mode 100644 index 000000000000..e39c3ca937aa --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_create.go @@ -0,0 +1,174 @@ +package client + +import ( + "context" + "encoding/json" + "errors" + "net/url" + "path" + "sort" + "strings" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/api/types/versions" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +// 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) { + var response container.CreateResponse + + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + return response, err + } + + if err := cli.NewVersionError(ctx, "1.25", "stop timeout"); config != nil && config.StopTimeout != nil && err != nil { + return response, err + } + if err := cli.NewVersionError(ctx, "1.41", "specify container image platform"); platform != nil && err != nil { + return response, err + } + if err := cli.NewVersionError(ctx, "1.44", "specify health-check start interval"); config != nil && config.Healthcheck != nil && config.Healthcheck.StartInterval != 0 && err != nil { + return response, err + } + if err := cli.NewVersionError(ctx, "1.44", "specify mac-address per network"); hasEndpointSpecificMacAddress(networkingConfig) && err != nil { + return response, err + } + + if hostConfig != nil { + if versions.LessThan(cli.ClientVersion(), "1.25") { + // When using API 1.24 and under, the client is responsible for removing the container + hostConfig.AutoRemove = false + } + if versions.GreaterThanOrEqualTo(cli.ClientVersion(), "1.42") || versions.LessThan(cli.ClientVersion(), "1.40") { + // KernelMemory was added in API 1.40, and deprecated in API 1.42 + hostConfig.KernelMemory = 0 + } + if platform != nil && platform.OS == "linux" && versions.LessThan(cli.ClientVersion(), "1.42") { + // When using API under 1.42, the Linux daemon doesn't respect the ConsoleSize + hostConfig.ConsoleSize = [2]uint{0, 0} + } + if versions.LessThan(cli.ClientVersion(), "1.44") { + for _, m := range hostConfig.Mounts { + if m.BindOptions != nil { + // ReadOnlyNonRecursive can be safely ignored when API < 1.44 + if m.BindOptions.ReadOnlyForceRecursive { + return response, errors.New("bind-recursive=readonly requires API v1.44 or later") + } + if m.BindOptions.NonRecursive && versions.LessThan(cli.ClientVersion(), "1.40") { + return response, errors.New("bind-recursive=disabled requires API v1.40 or later") + } + } + } + } + + hostConfig.CapAdd = normalizeCapabilities(hostConfig.CapAdd) + hostConfig.CapDrop = normalizeCapabilities(hostConfig.CapDrop) + } + + // Since API 1.44, the container-wide MacAddress is deprecated and triggers a WARNING if it's specified. + if versions.GreaterThanOrEqualTo(cli.ClientVersion(), "1.44") { + config.MacAddress = "" //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44. + } + + query := url.Values{} + if platform != nil { + if p := formatPlatform(*platform); p != "unknown" { + query.Set("platform", p) + } + } + + if containerName != "" { + query.Set("name", containerName) + } + + body := container.CreateRequest{ + Config: config, + HostConfig: hostConfig, + NetworkingConfig: networkingConfig, + } + + resp, err := cli.post(ctx, "/containers/create", query, body, nil) + defer ensureReaderClosed(resp) + if err != nil { + return response, err + } + + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} + +// formatPlatform returns a formatted string representing platform (e.g., "linux/arm/v7"). +// +// It is a fork of [platforms.Format], and does not yet support "os.version", +// as [[platforms.FormatAll] does. +// +// [platforms.Format]: https://github.com/containerd/platforms/blob/v1.0.0-rc.1/platforms.go#L309-L316 +// [platforms.FormatAll]: https://github.com/containerd/platforms/blob/v1.0.0-rc.1/platforms.go#L318-L330 +func formatPlatform(platform ocispec.Platform) string { + if platform.OS == "" { + return "unknown" + } + return path.Join(platform.OS, platform.Architecture, platform.Variant) +} + +// hasEndpointSpecificMacAddress checks whether one of the endpoint in networkingConfig has a MacAddress defined. +func hasEndpointSpecificMacAddress(networkingConfig *network.NetworkingConfig) bool { + if networkingConfig == nil { + return false + } + for _, endpoint := range networkingConfig.EndpointsConfig { + if endpoint.MacAddress != "" { + return true + } + } + 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 [caps.NormalizeLegacyCapabilities], +// but performs no validation based on supported capabilities. +// +// [caps.NormalizeLegacyCapabilities]: https://github.com/moby/moby/blob/v28.3.2/oci/caps/utils.go#L56 +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(capability string) string { + capability = strings.ToUpper(capability) + if capability == allCapabilities { + return capability + } + if !strings.HasPrefix(capability, "CAP_") { + capability = "CAP_" + capability + } + return capability +} diff --git a/vendor/github.com/moby/moby/client/container_diff.go b/vendor/github.com/moby/moby/client/container_diff.go new file mode 100644 index 000000000000..c87c6e4be9fc --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_diff.go @@ -0,0 +1,30 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/container" +) + +// ContainerDiff shows differences in a container filesystem since it was started. +func (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]container.FilesystemChange, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return nil, err + } + + resp, err := cli.get(ctx, "/containers/"+containerID+"/changes", url.Values{}, nil) + defer ensureReaderClosed(resp) + if err != nil { + return nil, err + } + + var changes []container.FilesystemChange + err = json.NewDecoder(resp.Body).Decode(&changes) + if err != nil { + return nil, err + } + return changes, err +} diff --git a/vendor/github.com/moby/moby/client/container_exec.go b/vendor/github.com/moby/moby/client/container_exec.go new file mode 100644 index 000000000000..8739c2967b76 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_exec.go @@ -0,0 +1,103 @@ +package client + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/versions" +) + +// ContainerExecCreate creates a new exec configuration to run an exec process. +func (cli *Client) ContainerExecCreate(ctx context.Context, containerID string, options container.ExecOptions) (container.ExecCreateResponse, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return container.ExecCreateResponse{}, err + } + + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + return container.ExecCreateResponse{}, err + } + + if err := cli.NewVersionError(ctx, "1.25", "env"); len(options.Env) != 0 && err != nil { + return container.ExecCreateResponse{}, err + } + if versions.LessThan(cli.ClientVersion(), "1.42") { + options.ConsoleSize = nil + } + + resp, err := cli.post(ctx, "/containers/"+containerID+"/exec", nil, options, nil) + defer ensureReaderClosed(resp) + if err != nil { + return container.ExecCreateResponse{}, err + } + + var response container.ExecCreateResponse + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} + +// ContainerExecStart starts an exec process already created in the docker host. +func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config container.ExecStartOptions) error { + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + return err + } + + if versions.LessThan(cli.ClientVersion(), "1.42") { + config.ConsoleSize = nil + } + resp, err := cli.post(ctx, "/exec/"+execID+"/start", nil, config, nil) + defer ensureReaderClosed(resp) + return err +} + +// ContainerExecAttach attaches a connection to an exec process in the server. +// +// It returns a [HijackedResponse] with the hijacked connection +// and a reader to get output. It's up to the called to close +// the hijacked connection by calling [HijackedResponse.Close]. +// +// The stream format on the response uses one of two formats: +// +// - If the container is using a TTY, there is only a single stream (stdout) +// and data is copied directly from the container output stream, no extra +// multiplexing or headers. +// - If the container is *not* using a TTY, streams for stdout and stderr are +// multiplexed. +// +// You can use [stdcopy.StdCopy] to demultiplex this stream. Refer to +// [Client.ContainerAttach] for details about the multiplexed stream. +// +// [stdcopy.StdCopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdCopy +func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config container.ExecAttachOptions) (HijackedResponse, error) { + if versions.LessThan(cli.ClientVersion(), "1.42") { + config.ConsoleSize = nil + } + return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, http.Header{ + "Content-Type": {"application/json"}, + }) +} + +// ContainerExecInspect returns information about a specific exec process on the docker host. +func (cli *Client) ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error) { + resp, err := cli.get(ctx, "/exec/"+execID+"/json", nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return container.ExecInspect{}, err + } + + var response container.ExecInspect + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} diff --git a/vendor/github.com/moby/moby/client/container_export.go b/vendor/github.com/moby/moby/client/container_export.go new file mode 100644 index 000000000000..211d92ed7516 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_export.go @@ -0,0 +1,24 @@ +package client + +import ( + "context" + "io" + "net/url" +) + +// ContainerExport retrieves the raw contents of a container +// and returns them as an [io.ReadCloser]. It's up to the caller +// to close the stream. +func (cli *Client) ContainerExport(ctx context.Context, containerID string) (io.ReadCloser, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return nil, err + } + + resp, err := cli.get(ctx, "/containers/"+containerID+"/export", url.Values{}, nil) + if err != nil { + return nil, err + } + + return resp.Body, nil +} diff --git a/vendor/github.com/moby/moby/client/container_inspect.go b/vendor/github.com/moby/moby/client/container_inspect.go new file mode 100644 index 000000000000..077d753d912e --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_inspect.go @@ -0,0 +1,57 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "io" + "net/url" + + "github.com/moby/moby/api/types/container" +) + +// ContainerInspect returns the container information. +func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (container.InspectResponse, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return container.InspectResponse{}, err + } + + resp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return container.InspectResponse{}, err + } + + var response container.InspectResponse + err = json.NewDecoder(resp.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) (container.InspectResponse, []byte, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return container.InspectResponse{}, nil, err + } + + query := url.Values{} + if getSize { + query.Set("size", "1") + } + resp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return container.InspectResponse{}, nil, err + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return container.InspectResponse{}, nil, err + } + + var response container.InspectResponse + rdr := bytes.NewReader(body) + err = json.NewDecoder(rdr).Decode(&response) + return response, body, err +} diff --git a/vendor/github.com/moby/moby/client/container_kill.go b/vendor/github.com/moby/moby/client/container_kill.go new file mode 100644 index 000000000000..d198337fd91d --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_kill.go @@ -0,0 +1,23 @@ +package client + +import ( + "context" + "net/url" +) + +// ContainerKill terminates the container process but does not remove the container from the docker host. +func (cli *Client) ContainerKill(ctx context.Context, containerID, signal string) error { + containerID, err := trimID("container", containerID) + if err != nil { + return err + } + + query := url.Values{} + if signal != "" { + query.Set("signal", signal) + } + + resp, err := cli.post(ctx, "/containers/"+containerID+"/kill", query, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/container_list.go b/vendor/github.com/moby/moby/client/container_list.go new file mode 100644 index 000000000000..5ebae2057ca8 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_list.go @@ -0,0 +1,72 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + "strconv" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/versions" +) + +// ContainerList returns the list of containers in the docker host. +func (cli *Client) ContainerList(ctx context.Context, options container.ListOptions) ([]container.Summary, error) { + query := url.Values{} + + if options.All { + query.Set("all", "1") + } + + if options.Limit > 0 { + query.Set("limit", strconv.Itoa(options.Limit)) + } + + if options.Since != "" { + query.Set("since", options.Since) + } + + if options.Before != "" { + query.Set("before", options.Before) + } + + if options.Size { + query.Set("size", "1") + } + + if options.Filters.Len() > 0 { + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + return nil, err + } + + filterJSON, err := filters.ToJSON(options.Filters) + if err != nil { + return nil, err + } + if cli.version != "" && versions.LessThan(cli.version, "1.22") { + legacyFormat, err := encodeLegacyFilters(filterJSON) + if err != nil { + return nil, err + } + filterJSON = legacyFormat + } + + query.Set("filters", filterJSON) + } + + resp, err := cli.get(ctx, "/containers/json", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return nil, err + } + + var containers []container.Summary + err = json.NewDecoder(resp.Body).Decode(&containers) + return containers, err +} diff --git a/vendor/github.com/moby/moby/client/container_logs.go b/vendor/github.com/moby/moby/client/container_logs.go new file mode 100644 index 000000000000..d98f625123c2 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_logs.go @@ -0,0 +1,89 @@ +package client + +import ( + "context" + "fmt" + "io" + "net/url" + "time" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client/internal/timestamp" +) + +// ContainerLogs returns the logs generated by a container in an [io.ReadCloser]. +// It's up to the caller to close the stream. +// +// The stream format on the response uses one of two formats: +// +// - If the container is using a TTY, there is only a single stream (stdout) +// and data is copied directly from the container output stream, no extra +// multiplexing or headers. +// - If the container is *not* using a TTY, streams for stdout and stderr are +// multiplexed. +// +// The format of the multiplexed stream is defined in the [stdcopy] package, +// and as follows: +// +// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT} +// +// STREAM_TYPE can be 1 for [Stdout] and 2 for [Stderr]. Refer to [stdcopy.StdType] +// for details. SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded +// as big endian, this is the size of OUTPUT. You can use [stdcopy.StdCopy] +// to demultiplex this stream. +// +// [stdcopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy +// [stdcopy.StdCopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdCopy +// [stdcopy.StdType]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdType +// [Stdout]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#Stdout +// [Stderr]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#Stderr +func (cli *Client) ContainerLogs(ctx context.Context, containerID string, options container.LogsOptions) (io.ReadCloser, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return nil, err + } + + query := url.Values{} + if options.ShowStdout { + query.Set("stdout", "1") + } + + if options.ShowStderr { + query.Set("stderr", "1") + } + + if options.Since != "" { + ts, err := timestamp.GetTimestamp(options.Since, time.Now()) + if err != nil { + return nil, fmt.Errorf(`invalid value for "since": %w`, err) + } + query.Set("since", ts) + } + + if options.Until != "" { + ts, err := timestamp.GetTimestamp(options.Until, time.Now()) + if err != nil { + return nil, fmt.Errorf(`invalid value for "until": %w`, err) + } + query.Set("until", ts) + } + + if options.Timestamps { + query.Set("timestamps", "1") + } + + if options.Details { + query.Set("details", "1") + } + + if options.Follow { + query.Set("follow", "1") + } + query.Set("tail", options.Tail) + + resp, err := cli.get(ctx, "/containers/"+containerID+"/logs", query, nil) + if err != nil { + return nil, err + } + return resp.Body, nil +} diff --git a/vendor/github.com/moby/moby/client/container_pause.go b/vendor/github.com/moby/moby/client/container_pause.go new file mode 100644 index 000000000000..c3488b9723f6 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_pause.go @@ -0,0 +1,15 @@ +package client + +import "context" + +// ContainerPause pauses the main process of a given container without terminating it. +func (cli *Client) ContainerPause(ctx context.Context, containerID string) error { + containerID, err := trimID("container", containerID) + if err != nil { + return err + } + + resp, err := cli.post(ctx, "/containers/"+containerID+"/pause", nil, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/container_prune.go b/vendor/github.com/moby/moby/client/container_prune.go new file mode 100644 index 000000000000..49a59893396e --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_prune.go @@ -0,0 +1,35 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/filters" +) + +// ContainersPrune requests the daemon to delete unused data +func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) { + if err := cli.NewVersionError(ctx, "1.25", "container prune"); err != nil { + return container.PruneReport{}, err + } + + query, err := getFiltersQuery(pruneFilters) + if err != nil { + return container.PruneReport{}, err + } + + resp, err := cli.post(ctx, "/containers/prune", query, nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return container.PruneReport{}, err + } + + var report container.PruneReport + if err := json.NewDecoder(resp.Body).Decode(&report); err != nil { + return container.PruneReport{}, fmt.Errorf("Error retrieving disk usage: %v", err) + } + + return report, nil +} diff --git a/vendor/github.com/moby/moby/client/container_remove.go b/vendor/github.com/moby/moby/client/container_remove.go new file mode 100644 index 000000000000..5d4b020e5ef1 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_remove.go @@ -0,0 +1,32 @@ +package client + +import ( + "context" + "net/url" + + "github.com/moby/moby/api/types/container" +) + +// ContainerRemove kills and removes a container from the docker host. +func (cli *Client) ContainerRemove(ctx context.Context, containerID string, options container.RemoveOptions) error { + containerID, err := trimID("container", containerID) + if err != nil { + return err + } + + query := url.Values{} + if options.RemoveVolumes { + query.Set("v", "1") + } + if options.RemoveLinks { + query.Set("link", "1") + } + + if options.Force { + query.Set("force", "1") + } + + resp, err := cli.delete(ctx, "/containers/"+containerID, query, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/container_rename.go b/vendor/github.com/moby/moby/client/container_rename.go new file mode 100644 index 000000000000..9eba310d5aa5 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_rename.go @@ -0,0 +1,20 @@ +package client + +import ( + "context" + "net/url" +) + +// ContainerRename changes the name of a given container. +func (cli *Client) ContainerRename(ctx context.Context, containerID, newContainerName string) error { + containerID, err := trimID("container", containerID) + if err != nil { + return err + } + + query := url.Values{} + query.Set("name", newContainerName) + resp, err := cli.post(ctx, "/containers/"+containerID+"/rename", query, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/container_resize.go b/vendor/github.com/moby/moby/client/container_resize.go new file mode 100644 index 000000000000..44449df27a0e --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_resize.go @@ -0,0 +1,38 @@ +package client + +import ( + "context" + "net/url" + "strconv" + + "github.com/moby/moby/api/types/container" +) + +// ContainerResize changes the size of the pseudo-TTY for a container. +func (cli *Client) ContainerResize(ctx context.Context, containerID string, options container.ResizeOptions) error { + containerID, err := trimID("container", containerID) + if err != nil { + return err + } + return cli.resize(ctx, "/containers/"+containerID, options.Height, options.Width) +} + +// ContainerExecResize changes the size of the tty for an exec process running inside a container. +func (cli *Client) ContainerExecResize(ctx context.Context, execID string, options container.ResizeOptions) error { + execID, err := trimID("exec", execID) + if err != nil { + return err + } + return cli.resize(ctx, "/exec/"+execID, options.Height, options.Width) +} + +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.FormatUint(uint64(height), 10)) + query.Set("w", strconv.FormatUint(uint64(width), 10)) + + resp, err := cli.post(ctx, basePath+"/resize", query, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/container_restart.go b/vendor/github.com/moby/moby/client/container_restart.go new file mode 100644 index 000000000000..ba4a76a85bf2 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_restart.go @@ -0,0 +1,41 @@ +package client + +import ( + "context" + "net/url" + "strconv" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/versions" +) + +// ContainerRestart stops, and starts a container again. +// It makes the daemon wait for the container to be up again for +// a specific amount of time, given the timeout. +func (cli *Client) ContainerRestart(ctx context.Context, containerID string, options container.StopOptions) error { + containerID, err := trimID("container", containerID) + if err != nil { + return err + } + + query := url.Values{} + if options.Timeout != nil { + query.Set("t", strconv.Itoa(*options.Timeout)) + } + if options.Signal != "" { + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + return err + } + if versions.GreaterThanOrEqualTo(cli.version, "1.42") { + query.Set("signal", options.Signal) + } + } + resp, err := cli.post(ctx, "/containers/"+containerID+"/restart", query, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/container_start.go b/vendor/github.com/moby/moby/client/container_start.go new file mode 100644 index 000000000000..37ef68cb4752 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_start.go @@ -0,0 +1,28 @@ +package client + +import ( + "context" + "net/url" + + "github.com/moby/moby/api/types/container" +) + +// ContainerStart sends a request to the docker daemon to start a container. +func (cli *Client) ContainerStart(ctx context.Context, containerID string, options container.StartOptions) error { + containerID, err := trimID("container", containerID) + if err != nil { + return err + } + + query := url.Values{} + if options.CheckpointID != "" { + query.Set("checkpoint", options.CheckpointID) + } + if options.CheckpointDir != "" { + query.Set("checkpoint-dir", options.CheckpointDir) + } + + resp, err := cli.post(ctx, "/containers/"+containerID+"/start", query, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/container_stats.go b/vendor/github.com/moby/moby/client/container_stats.go new file mode 100644 index 000000000000..d2493ed730a8 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_stats.go @@ -0,0 +1,67 @@ +package client + +import ( + "context" + "io" + "net/url" +) + +// StatsResponseReader wraps an [io.ReadCloser] to read (a stream of) stats +// for a container, as produced by the GET "/stats" endpoint. +// +// The OSType field is set to the server's platform to allow +// platform-specific handling of the response. +// +// TODO(thaJeztah): remove this wrapper, and make OSType part of [github.com/moby/moby/api/types/container.StatsResponse]. +type StatsResponseReader struct { + Body io.ReadCloser `json:"body"` + OSType string `json:"ostype"` +} + +// ContainerStats returns near realtime stats for a given container. +// It's up to the caller to close the [io.ReadCloser] returned. +func (cli *Client) ContainerStats(ctx context.Context, containerID string, stream bool) (StatsResponseReader, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return StatsResponseReader{}, err + } + + query := url.Values{} + query.Set("stream", "0") + if stream { + query.Set("stream", "1") + } + + resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil) + if err != nil { + return StatsResponseReader{}, err + } + + return StatsResponseReader{ + Body: resp.Body, + OSType: resp.Header.Get("Ostype"), + }, nil +} + +// ContainerStatsOneShot gets a single stat entry from a container. +// It differs from `ContainerStats` in that the API should not wait to prime the stats +func (cli *Client) ContainerStatsOneShot(ctx context.Context, containerID string) (StatsResponseReader, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return StatsResponseReader{}, err + } + + query := url.Values{} + query.Set("stream", "0") + query.Set("one-shot", "1") + + resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil) + if err != nil { + return StatsResponseReader{}, err + } + + return StatsResponseReader{ + Body: resp.Body, + OSType: resp.Header.Get("Ostype"), + }, nil +} diff --git a/vendor/github.com/moby/moby/client/container_stop.go b/vendor/github.com/moby/moby/client/container_stop.go new file mode 100644 index 000000000000..361464eea4e1 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_stop.go @@ -0,0 +1,45 @@ +package client + +import ( + "context" + "net/url" + "strconv" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/versions" +) + +// ContainerStop stops a container. In case the container fails to stop +// gracefully within a time frame specified by the timeout argument, +// it is forcefully terminated (killed). +// +// If the timeout is nil, the container's StopTimeout value is used, if set, +// otherwise the engine default. A negative timeout value can be specified, +// meaning no timeout, i.e. no forceful termination is performed. +func (cli *Client) ContainerStop(ctx context.Context, containerID string, options container.StopOptions) error { + containerID, err := trimID("container", containerID) + if err != nil { + return err + } + + query := url.Values{} + if options.Timeout != nil { + query.Set("t", strconv.Itoa(*options.Timeout)) + } + if options.Signal != "" { + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + return err + } + if versions.GreaterThanOrEqualTo(cli.version, "1.42") { + query.Set("signal", options.Signal) + } + } + resp, err := cli.post(ctx, "/containers/"+containerID+"/stop", query, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/container_top.go b/vendor/github.com/moby/moby/client/container_top.go new file mode 100644 index 000000000000..96b7e87f3dfe --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_top.go @@ -0,0 +1,33 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + "strings" + + "github.com/moby/moby/api/types/container" +) + +// ContainerTop shows process information from within a container. +func (cli *Client) ContainerTop(ctx context.Context, containerID string, arguments []string) (container.TopResponse, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return container.TopResponse{}, err + } + + query := url.Values{} + if len(arguments) > 0 { + query.Set("ps_args", strings.Join(arguments, " ")) + } + + resp, err := cli.get(ctx, "/containers/"+containerID+"/top", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return container.TopResponse{}, err + } + + var response container.TopResponse + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} diff --git a/vendor/github.com/moby/moby/client/container_unpause.go b/vendor/github.com/moby/moby/client/container_unpause.go new file mode 100644 index 000000000000..edaf236c1f43 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_unpause.go @@ -0,0 +1,15 @@ +package client + +import "context" + +// ContainerUnpause resumes the process execution within a container. +func (cli *Client) ContainerUnpause(ctx context.Context, containerID string) error { + containerID, err := trimID("container", containerID) + if err != nil { + return err + } + + resp, err := cli.post(ctx, "/containers/"+containerID+"/unpause", nil, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/container_update.go b/vendor/github.com/moby/moby/client/container_update.go new file mode 100644 index 000000000000..fc524b1c91d9 --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_update.go @@ -0,0 +1,26 @@ +package client + +import ( + "context" + "encoding/json" + + "github.com/moby/moby/api/types/container" +) + +// ContainerUpdate updates the resources of a container. +func (cli *Client) ContainerUpdate(ctx context.Context, containerID string, updateConfig container.UpdateConfig) (container.UpdateResponse, error) { + containerID, err := trimID("container", containerID) + if err != nil { + return container.UpdateResponse{}, err + } + + resp, err := cli.post(ctx, "/containers/"+containerID+"/update", nil, updateConfig, nil) + defer ensureReaderClosed(resp) + if err != nil { + return container.UpdateResponse{}, err + } + + var response container.UpdateResponse + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} diff --git a/vendor/github.com/moby/moby/client/container_wait.go b/vendor/github.com/moby/moby/client/container_wait.go new file mode 100644 index 000000000000..c38a159a653d --- /dev/null +++ b/vendor/github.com/moby/moby/client/container_wait.go @@ -0,0 +1,124 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "io" + "net/url" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/versions" +) + +const containerWaitErrorMsgLimit = 2 * 1024 /* Max: 2KiB */ + +// ContainerWait waits until the specified container is in a certain state +// indicated by the given condition, either "not-running" ([container.WaitConditionNotRunning]) +// (default), "next-exit" ([container.WaitConditionNextExit]), or "removed". +// ([container.WaitConditionRemoved]). +// +// If this client's API version is before 1.30, "condition" is ignored and +// ContainerWait returns immediately with the two channels, as the server +// waits as if the condition were "not-running". +// +// If this client's API version is at least 1.30, ContainerWait blocks until +// the request has been acknowledged by the server (with a response header), +// then returns two channels on which the caller can wait for the exit status +// of the container or an error if there was a problem either beginning the +// wait request or in getting the response. This allows the caller to +// synchronize ContainerWait with other calls, such as specifying a +// "next-exit" condition ([container.WaitConditionNextExit]) before +// issuing a [Client.ContainerStart] request. +func (cli *Client) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) { + resultC := make(chan container.WaitResponse) + errC := make(chan error, 1) + + containerID, err := trimID("container", containerID) + if err != nil { + errC <- err + return resultC, errC + } + + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + errC <- err + return resultC, errC + } + if versions.LessThan(cli.ClientVersion(), "1.30") { + return cli.legacyContainerWait(ctx, containerID) + } + + query := url.Values{} + if condition != "" { + query.Set("condition", string(condition)) + } + + resp, err := cli.post(ctx, "/containers/"+containerID+"/wait", query, nil, nil) + if err != nil { + defer ensureReaderClosed(resp) + errC <- err + return resultC, errC + } + + go func() { + defer ensureReaderClosed(resp) + + responseText := bytes.NewBuffer(nil) + stream := io.TeeReader(resp.Body, responseText) + + var res container.WaitResponse + if err := json.NewDecoder(stream).Decode(&res); err != nil { + // NOTE(nicks): The /wait API does not work well with HTTP proxies. + // At any time, the proxy could cut off the response stream. + // + // But because the HTTP status has already been written, the proxy's + // only option is to write a plaintext error message. + // + // If there's a JSON parsing error, read the real error message + // off the body and send it to the client. + if errors.As(err, new(*json.SyntaxError)) { + _, _ = io.ReadAll(io.LimitReader(stream, containerWaitErrorMsgLimit)) + errC <- errors.New(responseText.String()) + } else { + errC <- err + } + return + } + + resultC <- res + }() + + return resultC, errC +} + +// legacyContainerWait returns immediately and doesn't have an option to wait +// until the container is removed. +func (cli *Client) legacyContainerWait(ctx context.Context, containerID string) (<-chan container.WaitResponse, <-chan error) { + resultC := make(chan container.WaitResponse) + errC := make(chan error) + + go func() { + resp, err := cli.post(ctx, "/containers/"+containerID+"/wait", nil, nil, nil) + if err != nil { + errC <- err + return + } + defer ensureReaderClosed(resp) + + var res container.WaitResponse + if err := json.NewDecoder(resp.Body).Decode(&res); err != nil { + errC <- err + return + } + + resultC <- res + }() + + return resultC, errC +} diff --git a/vendor/github.com/moby/moby/client/distribution_inspect.go b/vendor/github.com/moby/moby/client/distribution_inspect.go new file mode 100644 index 000000000000..334c6d6bcf5f --- /dev/null +++ b/vendor/github.com/moby/moby/client/distribution_inspect.go @@ -0,0 +1,39 @@ +package client + +import ( + "context" + "encoding/json" + "net/http" + "net/url" + + "github.com/moby/moby/api/types/registry" +) + +// DistributionInspect returns the image digest with the full manifest. +func (cli *Client) DistributionInspect(ctx context.Context, imageRef, encodedRegistryAuth string) (registry.DistributionInspect, error) { + if imageRef == "" { + return registry.DistributionInspect{}, objectNotFoundError{object: "distribution", id: imageRef} + } + + if err := cli.NewVersionError(ctx, "1.30", "distribution inspect"); err != nil { + return registry.DistributionInspect{}, err + } + + var headers http.Header + if encodedRegistryAuth != "" { + headers = http.Header{ + registry.AuthHeader: {encodedRegistryAuth}, + } + } + + // Contact the registry to retrieve digest and platform information + resp, err := cli.get(ctx, "/distribution/"+imageRef+"/json", url.Values{}, headers) + defer ensureReaderClosed(resp) + if err != nil { + return registry.DistributionInspect{}, err + } + + var distributionInspect registry.DistributionInspect + err = json.NewDecoder(resp.Body).Decode(&distributionInspect) + return distributionInspect, err +} diff --git a/vendor/github.com/moby/moby/client/envvars.go b/vendor/github.com/moby/moby/client/envvars.go new file mode 100644 index 000000000000..2b0e3f6b5a4b --- /dev/null +++ b/vendor/github.com/moby/moby/client/envvars.go @@ -0,0 +1,95 @@ +package client + +const ( + // EnvOverrideHost is the name of the environment variable that can be used + // to override the default host to connect to (DefaultDockerHost). + // + // This env-var is read by [FromEnv] and [WithHostFromEnv] and when set to a + // non-empty value, takes precedence over the default host (which is platform + // specific), or any host already set. + EnvOverrideHost = "DOCKER_HOST" + + // EnvOverrideAPIVersion is the name of the environment variable that can + // be used to override the API version to use. Value must be + // formatted as MAJOR.MINOR, for example, "1.19". + // + // This env-var is read by [FromEnv] and [WithVersionFromEnv] and when set to a + // non-empty value, takes precedence over API version negotiation. + // + // This environment variable should be used for debugging purposes only, as + // it can set the client to use an incompatible (or invalid) API version. + EnvOverrideAPIVersion = "DOCKER_API_VERSION" + + // EnvOverrideCertPath is the name of the environment variable that can be + // used to specify the directory from which to load the TLS certificates + // (ca.pem, cert.pem, key.pem) from. These certificates are used to configure + // the [Client] for a TCP connection protected by TLS client authentication. + // + // TLS certificate verification is enabled by default if the Client is configured + // to use a TLS connection. Refer to [EnvTLSVerify] below to learn how to + // disable verification for testing purposes. + // + // WARNING: Access to the remote API is equivalent to root access to the + // host where the daemon runs. Do not expose the API without protection, + // and only if needed. Make sure you are familiar with the ["daemon attack surface"]. + // + // For local access to the API, it is recommended to connect with the daemon + // using the default local socket connection (on Linux), or the named pipe + // (on Windows). + // + // If you need to access the API of a remote daemon, consider using an SSH + // (ssh://) connection, which is easier to set up, and requires no additional + // configuration if the host is accessible using ssh. + // + // If you cannot use the alternatives above, and you must expose the API over + // a TCP connection. Refer to [Protect the Docker daemon socket] + // to learn how to configure the daemon and client to use a TCP connection + // with TLS client authentication. Make sure you know the differences between + // a regular TLS connection and a TLS connection protected by TLS client + // authentication, and verify that the API cannot be accessed by other clients. + // + // ["daemon attack surface"]: https://docs.docker.com/go/attack-surface/ + // [Protect the Docker daemon socket]: https://docs.docker.com/engine/security/protect-access/ + EnvOverrideCertPath = "DOCKER_CERT_PATH" + + // EnvTLSVerify is the name of the environment variable that can be used to + // enable or disable TLS certificate verification. When set to a non-empty + // value, TLS certificate verification is enabled, and the client is configured + // to use a TLS connection, using certificates from the default directories + // (within `~/.docker`); refer to EnvOverrideCertPath above for additional + // details. + // + // WARNING: Access to the remote API is equivalent to root access to the + // host where the daemon runs. Do not expose the API without protection, + // and only if needed. Make sure you are familiar with the ["daemon attack surface"]. + // + // Before setting up your client and daemon to use a TCP connection with TLS + // client authentication, consider using one of the alternatives mentioned + // in [EnvOverrideCertPath]. + // + // Disabling TLS certificate verification (for testing purposes) + // + // TLS certificate verification is enabled by default if the Client is configured + // to use a TLS connection, and it is highly recommended to keep verification + // enabled to prevent machine-in-the-middle attacks. Refer to [Protect the Docker daemon socket] + // in the documentation and pages linked from that page to learn how to + // configure the daemon and client to use a TCP connection with TLS client + // authentication enabled. + // + // Set the "DOCKER_TLS_VERIFY" environment to an empty string ("") to + // disable TLS certificate verification. Disabling verification is insecure, + // so should only be done for testing purposes. + // + // From the[crypto/tls.Config] documentation: + // + // InsecureSkipVerify controls whether a client verifies the server's + // certificate chain and host name. If InsecureSkipVerify is true, crypto/tls + // accepts any certificate presented by the server and any host name in that + // certificate. In this mode, TLS is susceptible to machine-in-the-middle + // attacks unless custom verification is used. This should be used only for + // testing or in combination with VerifyConnection or VerifyPeerCertificate. + // + // ["daemon attack surface"]: https://docs.docker.com/go/attack-surface/ + // [Protect the Docker daemon socket]: https://docs.docker.com/engine/security/protect-access/ + EnvTLSVerify = "DOCKER_TLS_VERIFY" +) diff --git a/vendor/github.com/moby/moby/client/errors.go b/vendor/github.com/moby/moby/client/errors.go new file mode 100644 index 000000000000..81a9f4eb1452 --- /dev/null +++ b/vendor/github.com/moby/moby/client/errors.go @@ -0,0 +1,114 @@ +package client + +import ( + "context" + "errors" + "fmt" + "net/http" + + cerrdefs "github.com/containerd/errdefs" + "github.com/containerd/errdefs/pkg/errhttp" + "github.com/moby/moby/api/types/versions" +) + +// errConnectionFailed implements an error returned when connection failed. +type errConnectionFailed struct { + error +} + +// Error returns a string representation of an errConnectionFailed +func (e errConnectionFailed) Error() string { + return e.error.Error() +} + +func (e errConnectionFailed) Unwrap() error { + return e.error +} + +// IsErrConnectionFailed returns true if the error is caused by connection failed. +func IsErrConnectionFailed(err error) bool { + return errors.As(err, &errConnectionFailed{}) +} + +// connectionFailed returns an error with host in the error message when connection +// to docker daemon failed. +func connectionFailed(host string) error { + var err error + if host == "" { + err = errors.New("Cannot connect to the Docker daemon. Is the docker daemon running on this host?") + } else { + err = fmt.Errorf("Cannot connect to the Docker daemon at %s. Is the docker daemon running?", host) + } + return errConnectionFailed{error: err} +} + +type objectNotFoundError struct { + object string + id string +} + +func (e objectNotFoundError) NotFound() {} + +func (e objectNotFoundError) Error() string { + return fmt.Sprintf("Error: No such %s: %s", e.object, e.id) +} + +// NewVersionError returns an error if the APIVersion required is less than the +// current supported version. +// +// It performs API-version negotiation if the Client is configured with this +// option, otherwise it assumes the latest API version is used. +func (cli *Client) NewVersionError(ctx context.Context, APIrequired, feature string) error { + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + return err + } + if cli.version != "" && versions.LessThan(cli.version, APIrequired) { + return fmt.Errorf("%q requires API version %s, but the Docker daemon API version is %s", feature, APIrequired, cli.version) + } + return nil +} + +type httpError struct { + err error + errdef error +} + +func (e *httpError) Error() string { + return e.err.Error() +} + +func (e *httpError) Unwrap() error { + return e.err +} + +func (e *httpError) Is(target error) bool { + return errors.Is(e.errdef, target) +} + +// httpErrorFromStatusCode creates an errdef error, based on the provided HTTP status-code +func httpErrorFromStatusCode(err error, statusCode int) error { + if err == nil { + return nil + } + base := errhttp.ToNative(statusCode) + if base != nil { + return &httpError{err: err, errdef: base} + } + + switch { + case statusCode >= http.StatusOK && statusCode < http.StatusBadRequest: + // it's a client error + return err + case statusCode >= http.StatusBadRequest && statusCode < http.StatusInternalServerError: + return &httpError{err: err, errdef: cerrdefs.ErrInvalidArgument} + case statusCode >= http.StatusInternalServerError && statusCode < 600: + return &httpError{err: err, errdef: cerrdefs.ErrInternal} + default: + return &httpError{err: err, errdef: cerrdefs.ErrUnknown} + } +} diff --git a/vendor/github.com/moby/moby/client/hijack.go b/vendor/github.com/moby/moby/client/hijack.go new file mode 100644 index 000000000000..f06f53a32312 --- /dev/null +++ b/vendor/github.com/moby/moby/client/hijack.go @@ -0,0 +1,178 @@ +package client + +import ( + "bufio" + "context" + "fmt" + "net" + "net/http" + "net/url" + "time" + + "github.com/moby/moby/api/types/versions" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +) + +// postHijacked sends a POST request and hijacks the connection. +func (cli *Client) postHijacked(ctx context.Context, path string, query url.Values, body any, headers map[string][]string) (HijackedResponse, error) { + jsonBody, err := jsonEncode(body) + if err != nil { + return HijackedResponse{}, err + } + req, err := cli.buildRequest(ctx, http.MethodPost, cli.getAPIPath(ctx, path, query), jsonBody, headers) + if err != nil { + return HijackedResponse{}, err + } + conn, mediaType, err := setupHijackConn(cli.dialer(), req, "tcp") + if err != nil { + return HijackedResponse{}, err + } + + if versions.LessThan(cli.ClientVersion(), "1.42") { + // Prior to 1.42, Content-Type is always set to raw-stream and not relevant + mediaType = "" + } + + return NewHijackedResponse(conn, mediaType), nil +} + +// DialHijack returns a hijacked connection with negotiated protocol proto. +func (cli *Client) DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, http.NoBody) + if err != nil { + return nil, err + } + req = cli.addHeaders(req, meta) + + conn, _, err := setupHijackConn(cli.Dialer(), req, proto) + return conn, err +} + +func setupHijackConn(dialer func(context.Context) (net.Conn, error), req *http.Request, proto string) (_ net.Conn, _ string, retErr error) { + ctx := req.Context() + req.Header.Set("Connection", "Upgrade") + req.Header.Set("Upgrade", proto) + + conn, err := dialer(ctx) + if err != nil { + return nil, "", fmt.Errorf("cannot connect to the Docker daemon. Is 'docker daemon' running on this host?: %w", err) + } + defer func() { + if retErr != nil { + _ = conn.Close() + } + }() + + // When we set up a TCP connection for hijack, there could be long periods + // of inactivity (a long running command with no output) that in certain + // network setups may cause ECONNTIMEOUT, leaving the client in an unknown + // state. Setting TCP KeepAlive on the socket connection prohibits + // ECONNTIMEOUT unless the socket connection truly is broken + if tcpConn, ok := conn.(*net.TCPConn); ok { + _ = tcpConn.SetKeepAlive(true) + _ = tcpConn.SetKeepAlivePeriod(30 * time.Second) + } + + hc := &hijackedConn{conn, bufio.NewReader(conn)} + + // Server hijacks the connection, error 'connection closed' expected + resp, err := otelhttp.NewTransport(hc).RoundTrip(req) + if err != nil { + return nil, "", err + } + if resp.StatusCode != http.StatusSwitchingProtocols { + _ = resp.Body.Close() + return nil, "", fmt.Errorf("unable to upgrade to %s, received %d", proto, resp.StatusCode) + } + + if hc.r.Buffered() > 0 { + // If there is buffered content, wrap the connection. We return an + // object that implements CloseWrite if the underlying connection + // implements it. + if _, ok := hc.Conn.(CloseWriter); ok { + conn = &hijackedConnCloseWriter{hc} + } else { + conn = hc + } + } else { + hc.r.Reset(nil) + } + + return conn, resp.Header.Get("Content-Type"), nil +} + +// hijackedConn wraps a net.Conn and is returned by setupHijackConn in the case +// that a) there was already buffered data in the http layer when Hijack() was +// called, and b) the underlying net.Conn does *not* implement CloseWrite(). +// hijackedConn does not implement CloseWrite() either. +type hijackedConn struct { + net.Conn + r *bufio.Reader +} + +func (c *hijackedConn) RoundTrip(req *http.Request) (*http.Response, error) { + if err := req.Write(c.Conn); err != nil { + return nil, err + } + return http.ReadResponse(c.r, req) +} + +func (c *hijackedConn) Read(b []byte) (int, error) { + return c.r.Read(b) +} + +// hijackedConnCloseWriter is a hijackedConn which additionally implements +// CloseWrite(). It is returned by setupHijackConn in the case that a) there +// was already buffered data in the http layer when Hijack() was called, and b) +// the underlying net.Conn *does* implement CloseWrite(). +type hijackedConnCloseWriter struct { + *hijackedConn +} + +var _ CloseWriter = &hijackedConnCloseWriter{} + +func (c *hijackedConnCloseWriter) CloseWrite() error { + conn := c.Conn.(CloseWriter) + return conn.CloseWrite() +} + +// NewHijackedResponse initializes a [HijackedResponse] type. +func NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse { + return HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType} +} + +// HijackedResponse holds connection information for a hijacked request. +type HijackedResponse struct { + mediaType string + Conn net.Conn + Reader *bufio.Reader +} + +// Close closes the hijacked connection and reader. +func (h *HijackedResponse) Close() { + h.Conn.Close() +} + +// MediaType let client know if HijackedResponse hold a raw or multiplexed stream. +// returns false if HTTP Content-Type is not relevant, and the container must be +// inspected. +func (h *HijackedResponse) MediaType() (string, bool) { + if h.mediaType == "" { + return "", false + } + return h.mediaType, true +} + +// CloseWriter is an interface that implements structs +// that close input streams to prevent from writing. +type CloseWriter interface { + CloseWrite() error +} + +// CloseWrite closes a readWriter for writing. +func (h *HijackedResponse) CloseWrite() error { + if conn, ok := h.Conn.(CloseWriter); ok { + return conn.CloseWrite() + } + return nil +} diff --git a/vendor/github.com/moby/moby/client/image_build.go b/vendor/github.com/moby/moby/client/image_build.go new file mode 100644 index 000000000000..94ec6c3a42d1 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_build.go @@ -0,0 +1,182 @@ +package client + +import ( + "context" + "encoding/base64" + "encoding/json" + "io" + "net/http" + "net/url" + "strconv" + "strings" + + "github.com/moby/moby/api/types/build" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" +) + +// ImageBuild sends a request to the daemon to build images. +// The Body in the response implements an [io.ReadCloser] and it's up to the caller to +// close it. +func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error) { + query, err := cli.imageBuildOptionsToQuery(ctx, options) + if err != nil { + return build.ImageBuildResponse{}, err + } + + buf, err := json.Marshal(options.AuthConfigs) + if err != nil { + return build.ImageBuildResponse{}, err + } + + headers := http.Header{} + headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf)) + headers.Set("Content-Type", "application/x-tar") + + resp, err := cli.postRaw(ctx, "/build", query, buildContext, headers) + if err != nil { + return build.ImageBuildResponse{}, err + } + + return build.ImageBuildResponse{ + Body: resp.Body, + OSType: resp.Header.Get("Ostype"), + }, nil +} + +func (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options build.ImageBuildOptions) (url.Values, error) { + 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") + } + if options.RemoteContext != "" { + query.Set("remote", options.RemoteContext) + } + if options.NoCache { + query.Set("nocache", "1") + } + 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") + } + + if options.ForceRemove { + query.Set("forcerm", "1") + } + + if options.PullParent { + query.Set("pull", "1") + } + + if options.Squash { + if err := cli.NewVersionError(ctx, "1.25", "squash"); err != nil { + return query, err + } + query.Set("squash", "1") + } + + if !container.Isolation.IsDefault(options.Isolation) { + query.Set("isolation", string(options.Isolation)) + } + + if options.CPUSetCPUs != "" { + query.Set("cpusetcpus", options.CPUSetCPUs) + } + if options.NetworkMode != "" && options.NetworkMode != network.NetworkDefault { + query.Set("networkmode", options.NetworkMode) + } + if options.CPUSetMems != "" { + query.Set("cpusetmems", options.CPUSetMems) + } + 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)) + } + if options.SessionID != "" { + query.Set("session", options.SessionID) + } + if options.Platform != "" { + if err := cli.NewVersionError(ctx, "1.32", "platform"); err != nil { + return query, err + } + query.Set("platform", strings.ToLower(options.Platform)) + } + if options.BuildID != "" { + query.Set("buildid", options.BuildID) + } + if options.Version != "" { + query.Set("version", string(options.Version)) + } + + if options.Outputs != nil { + outputsJSON, err := json.Marshal(options.Outputs) + if err != nil { + return query, err + } + query.Set("outputs", string(outputsJSON)) + } + return query, nil +} diff --git a/vendor/github.com/moby/moby/client/image_create.go b/vendor/github.com/moby/moby/client/image_create.go new file mode 100644 index 000000000000..4282158d21e8 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_create.go @@ -0,0 +1,48 @@ +package client + +import ( + "context" + "io" + "net/http" + "net/url" + "strings" + + "github.com/distribution/reference" + "github.com/moby/moby/api/types/image" + "github.com/moby/moby/api/types/registry" +) + +// ImageCreate creates a new image based on the parent options. +// It returns the JSON content in the response body. +func (cli *Client) ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error) { + ref, err := reference.ParseNormalizedNamed(parentReference) + if err != nil { + return nil, err + } + + query := url.Values{} + query.Set("fromImage", ref.Name()) + query.Set("tag", getAPITagFromNamedRef(ref)) + if options.Platform != "" { + query.Set("platform", strings.ToLower(options.Platform)) + } + resp, err := cli.tryImageCreate(ctx, query, staticAuth(options.RegistryAuth)) + if err != nil { + return nil, err + } + return resp.Body, nil +} + +func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, resolveAuth registry.RequestAuthConfig) (*http.Response, error) { + hdr := http.Header{} + if resolveAuth != nil { + registryAuth, err := resolveAuth(ctx) + if err != nil { + return nil, err + } + if registryAuth != "" { + hdr.Set(registry.AuthHeader, registryAuth) + } + } + return cli.post(ctx, "/images/create", query, nil, hdr) +} diff --git a/vendor/github.com/moby/moby/client/image_history.go b/vendor/github.com/moby/moby/client/image_history.go new file mode 100644 index 000000000000..42c2b134bdd8 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_history.go @@ -0,0 +1,56 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + "net/url" + + "github.com/moby/moby/api/types/image" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +// ImageHistoryWithPlatform sets the platform for the image history operation. +func ImageHistoryWithPlatform(platform ocispec.Platform) ImageHistoryOption { + return imageHistoryOptionFunc(func(opt *imageHistoryOpts) error { + if opt.apiOptions.Platform != nil { + return fmt.Errorf("platform already set to %s", *opt.apiOptions.Platform) + } + opt.apiOptions.Platform = &platform + return nil + }) +} + +// ImageHistory returns the changes in an image in history format. +func (cli *Client) ImageHistory(ctx context.Context, imageID string, historyOpts ...ImageHistoryOption) ([]image.HistoryResponseItem, error) { + query := url.Values{} + + var opts imageHistoryOpts + for _, o := range historyOpts { + if err := o.Apply(&opts); err != nil { + return nil, err + } + } + + if opts.apiOptions.Platform != nil { + if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil { + return nil, err + } + + p, err := encodePlatform(opts.apiOptions.Platform) + if err != nil { + return nil, err + } + query.Set("platform", p) + } + + resp, err := cli.get(ctx, "/images/"+imageID+"/history", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return nil, err + } + + var history []image.HistoryResponseItem + err = json.NewDecoder(resp.Body).Decode(&history) + return history, err +} diff --git a/vendor/github.com/moby/moby/client/image_history_opts.go b/vendor/github.com/moby/moby/client/image_history_opts.go new file mode 100644 index 000000000000..9641219f3f03 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_history_opts.go @@ -0,0 +1,19 @@ +package client + +import ( + "github.com/moby/moby/api/types/image" +) + +// ImageHistoryOption is a type representing functional options for the image history operation. +type ImageHistoryOption interface { + Apply(*imageHistoryOpts) error +} +type imageHistoryOptionFunc func(opt *imageHistoryOpts) error + +func (f imageHistoryOptionFunc) Apply(o *imageHistoryOpts) error { + return f(o) +} + +type imageHistoryOpts struct { + apiOptions image.HistoryOptions +} diff --git a/vendor/github.com/moby/moby/client/image_import.go b/vendor/github.com/moby/moby/client/image_import.go new file mode 100644 index 000000000000..b95438fbe82d --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_import.go @@ -0,0 +1,48 @@ +package client + +import ( + "context" + "io" + "net/url" + "strings" + + "github.com/distribution/reference" + "github.com/moby/moby/api/types/image" +) + +// ImageImport creates a new image based on the source options. +// It returns the JSON content in the response body. +func (cli *Client) ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) { + if ref != "" { + // Check if the given image name can be resolved + if _, err := reference.ParseNormalizedNamed(ref); err != nil { + return nil, err + } + } + + query := url.Values{} + 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)) + } + for _, change := range options.Changes { + query.Add("changes", change) + } + + resp, err := cli.postRaw(ctx, "/images/create", query, source.Source, nil) + if err != nil { + return nil, err + } + return resp.Body, nil +} diff --git a/vendor/github.com/moby/moby/client/image_inspect.go b/vendor/github.com/moby/moby/client/image_inspect.go new file mode 100644 index 000000000000..30579ddbe2c8 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_inspect.go @@ -0,0 +1,64 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/url" + + "github.com/moby/moby/api/types/image" +) + +// ImageInspect returns the image information. +func (cli *Client) ImageInspect(ctx context.Context, imageID string, inspectOpts ...ImageInspectOption) (image.InspectResponse, error) { + if imageID == "" { + return image.InspectResponse{}, objectNotFoundError{object: "image", id: imageID} + } + + var opts imageInspectOpts + for _, opt := range inspectOpts { + if err := opt.Apply(&opts); err != nil { + return image.InspectResponse{}, fmt.Errorf("error applying image inspect option: %w", err) + } + } + + query := url.Values{} + if opts.apiOptions.Manifests { + if err := cli.NewVersionError(ctx, "1.48", "manifests"); err != nil { + return image.InspectResponse{}, err + } + query.Set("manifests", "1") + } + + if opts.apiOptions.Platform != nil { + if err := cli.NewVersionError(ctx, "1.49", "platform"); err != nil { + return image.InspectResponse{}, err + } + platform, err := encodePlatform(opts.apiOptions.Platform) + if err != nil { + return image.InspectResponse{}, err + } + query.Set("platform", platform) + } + + resp, err := cli.get(ctx, "/images/"+imageID+"/json", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return image.InspectResponse{}, err + } + + buf := opts.raw + if buf == nil { + buf = &bytes.Buffer{} + } + + if _, err := io.Copy(buf, resp.Body); err != nil { + return image.InspectResponse{}, err + } + + var response image.InspectResponse + err = json.Unmarshal(buf.Bytes(), &response) + return response, err +} diff --git a/vendor/github.com/moby/moby/client/image_inspect_opts.go b/vendor/github.com/moby/moby/client/image_inspect_opts.go new file mode 100644 index 000000000000..8b67519e7556 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_inspect_opts.go @@ -0,0 +1,63 @@ +package client + +import ( + "bytes" + + "github.com/moby/moby/api/types/image" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +// ImageInspectOption is a type representing functional options for the image inspect operation. +type ImageInspectOption interface { + Apply(*imageInspectOpts) error +} +type imageInspectOptionFunc func(opt *imageInspectOpts) error + +func (f imageInspectOptionFunc) Apply(o *imageInspectOpts) error { + return f(o) +} + +// ImageInspectWithRawResponse instructs the client to additionally store the +// raw inspect response in the provided buffer. +func ImageInspectWithRawResponse(raw *bytes.Buffer) ImageInspectOption { + return imageInspectOptionFunc(func(opts *imageInspectOpts) error { + opts.raw = raw + return nil + }) +} + +// ImageInspectWithManifests sets manifests API option for the image inspect operation. +// This option is only available for API version 1.48 and up. +// With this option set, the image inspect operation response includes +// the [image.InspectResponse.Manifests] field if the server is multi-platform +// capable. +func ImageInspectWithManifests(manifests bool) ImageInspectOption { + return imageInspectOptionFunc(func(clientOpts *imageInspectOpts) error { + clientOpts.apiOptions.Manifests = manifests + return nil + }) +} + +// ImageInspectWithPlatform sets platform API option for the image inspect operation. +// This option is only available for API version 1.49 and up. +// With this option set, the image inspect operation returns information for the +// specified platform variant of the multi-platform image. +func ImageInspectWithPlatform(platform *ocispec.Platform) ImageInspectOption { + return imageInspectOptionFunc(func(clientOpts *imageInspectOpts) error { + clientOpts.apiOptions.Platform = platform + return nil + }) +} + +// ImageInspectWithAPIOpts sets the API options for the image inspect operation. +func ImageInspectWithAPIOpts(opts image.InspectOptions) ImageInspectOption { + return imageInspectOptionFunc(func(clientOpts *imageInspectOpts) error { + clientOpts.apiOptions = opts + return nil + }) +} + +type imageInspectOpts struct { + raw *bytes.Buffer + apiOptions image.InspectOptions +} diff --git a/vendor/github.com/moby/moby/client/image_list.go b/vendor/github.com/moby/moby/client/image_list.go new file mode 100644 index 000000000000..d29a7300edc8 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_list.go @@ -0,0 +1,73 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/image" + "github.com/moby/moby/api/types/versions" +) + +// ImageList returns a list of images in the docker host. +// +// Experimental: Set the [image.ListOptions.Manifest] option +// to include [image.Summary.Manifests] with information about image manifests. +// This is experimental and might change in the future without any backward +// compatibility. +func (cli *Client) ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error) { + var images []image.Summary + + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + return images, err + } + + query := url.Values{} + + optionFilters := options.Filters + referenceFilters := optionFilters.Get("reference") + if versions.LessThan(cli.version, "1.25") && len(referenceFilters) > 0 { + query.Set("filter", referenceFilters[0]) + for _, filterValue := range referenceFilters { + optionFilters.Del("reference", filterValue) + } + } + if optionFilters.Len() > 0 { + filterJSON, err := filters.ToJSON(optionFilters) + if err != nil { + return images, err + } + if cli.version != "" && versions.LessThan(cli.version, "1.22") { + legacyFormat, err := encodeLegacyFilters(filterJSON) + if err != nil { + return nil, err + } + filterJSON = legacyFormat + } + query.Set("filters", filterJSON) + } + if options.All { + query.Set("all", "1") + } + if options.SharedSize && versions.GreaterThanOrEqualTo(cli.version, "1.42") { + query.Set("shared-size", "1") + } + if options.Manifests && versions.GreaterThanOrEqualTo(cli.version, "1.47") { + query.Set("manifests", "1") + } + + resp, err := cli.get(ctx, "/images/json", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return images, err + } + + err = json.NewDecoder(resp.Body).Decode(&images) + return images, err +} diff --git a/vendor/github.com/moby/moby/client/image_load.go b/vendor/github.com/moby/moby/client/image_load.go new file mode 100644 index 000000000000..76642b828b5d --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_load.go @@ -0,0 +1,54 @@ +package client + +import ( + "context" + "io" + "net/http" + "net/url" + + "github.com/moby/moby/api/types/image" +) + +// 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 +// [image.LoadResponse] returned by this function. +// +// Platform is an optional parameter that specifies the platform to load from +// the provided multi-platform image. Passing a platform only has an effect +// if the input image is a multi-platform image. +func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...ImageLoadOption) (image.LoadResponse, error) { + var opts imageLoadOpts + for _, opt := range loadOpts { + if err := opt.Apply(&opts); err != nil { + return image.LoadResponse{}, err + } + } + + query := url.Values{} + query.Set("quiet", "0") + if opts.apiOptions.Quiet { + query.Set("quiet", "1") + } + if len(opts.apiOptions.Platforms) > 0 { + if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil { + return image.LoadResponse{}, err + } + + p, err := encodePlatforms(opts.apiOptions.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 { + return image.LoadResponse{}, err + } + return image.LoadResponse{ + Body: resp.Body, + JSON: resp.Header.Get("Content-Type") == "application/json", + }, nil +} diff --git a/vendor/github.com/moby/moby/client/image_load_opts.go b/vendor/github.com/moby/moby/client/image_load_opts.go new file mode 100644 index 000000000000..6681a63dddb2 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_load_opts.go @@ -0,0 +1,41 @@ +package client + +import ( + "fmt" + + "github.com/moby/moby/api/types/image" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +// ImageLoadOption is a type representing functional options for the image load operation. +type ImageLoadOption interface { + Apply(*imageLoadOpts) error +} +type imageLoadOptionFunc func(opt *imageLoadOpts) error + +func (f imageLoadOptionFunc) Apply(o *imageLoadOpts) error { + return f(o) +} + +type imageLoadOpts struct { + apiOptions image.LoadOptions +} + +// ImageLoadWithQuiet sets the quiet option for the image load operation. +func ImageLoadWithQuiet(quiet bool) ImageLoadOption { + return imageLoadOptionFunc(func(opt *imageLoadOpts) error { + opt.apiOptions.Quiet = quiet + return nil + }) +} + +// ImageLoadWithPlatforms sets the platforms to be loaded from the image. +func ImageLoadWithPlatforms(platforms ...ocispec.Platform) ImageLoadOption { + return imageLoadOptionFunc(func(opt *imageLoadOpts) error { + if opt.apiOptions.Platforms != nil { + return fmt.Errorf("platforms already set to %v", opt.apiOptions.Platforms) + } + opt.apiOptions.Platforms = platforms + return nil + }) +} diff --git a/vendor/github.com/moby/moby/client/image_prune.go b/vendor/github.com/moby/moby/client/image_prune.go new file mode 100644 index 000000000000..3909c16c09e0 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_prune.go @@ -0,0 +1,35 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/image" +) + +// ImagesPrune requests the daemon to delete unused data +func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (image.PruneReport, error) { + if err := cli.NewVersionError(ctx, "1.25", "image prune"); err != nil { + return image.PruneReport{}, err + } + + query, err := getFiltersQuery(pruneFilters) + if err != nil { + return image.PruneReport{}, err + } + + resp, err := cli.post(ctx, "/images/prune", query, nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return image.PruneReport{}, err + } + + var report image.PruneReport + if err := json.NewDecoder(resp.Body).Decode(&report); err != nil { + return image.PruneReport{}, fmt.Errorf("Error retrieving disk usage: %v", err) + } + + return report, nil +} diff --git a/vendor/github.com/moby/moby/client/image_pull.go b/vendor/github.com/moby/moby/client/image_pull.go new file mode 100644 index 000000000000..2a9613db9a06 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_pull.go @@ -0,0 +1,62 @@ +package client + +import ( + "context" + "io" + "net/url" + "strings" + + cerrdefs "github.com/containerd/errdefs" + "github.com/distribution/reference" + "github.com/moby/moby/api/types/image" +) + +// ImagePull requests the docker host to pull an image from a remote registry. +// It executes the privileged function if the operation is unauthorized +// and it tries one more time. +// It's up to the caller to handle the [io.ReadCloser] and close it. +func (cli *Client) ImagePull(ctx context.Context, refStr string, options image.PullOptions) (io.ReadCloser, error) { + // FIXME(vdemeester): there is currently used in a few way in docker/docker + // - if not in trusted content, ref is used to pass the whole reference, and tag is empty + // - if in trusted content, ref is used to pass the reference name, and tag for the digest + // + // ref; https://github.com/docker-archive-public/docker.engine-api/pull/162 + + ref, err := reference.ParseNormalizedNamed(refStr) + if err != nil { + return nil, err + } + + query := url.Values{} + query.Set("fromImage", ref.Name()) + if !options.All { + query.Set("tag", getAPITagFromNamedRef(ref)) + } + if options.Platform != "" { + query.Set("platform", strings.ToLower(options.Platform)) + } + + resp, err := cli.tryImageCreate(ctx, query, staticAuth(options.RegistryAuth)) + if cerrdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { + resp, err = cli.tryImageCreate(ctx, query, options.PrivilegeFunc) + } + if err != nil { + return nil, err + } + return resp.Body, nil +} + +// getAPITagFromNamedRef returns a tag from the specified reference. +// This function is necessary as long as the docker "server" api expects +// digests to be sent as tags and makes a distinction between the name +// and tag/digest part of a reference. +func getAPITagFromNamedRef(ref reference.Named) string { + if digested, ok := ref.(reference.Digested); ok { + return digested.Digest().String() + } + ref = reference.TagNameOnly(ref) + if tagged, ok := ref.(reference.Tagged); ok { + return tagged.Tag() + } + return "" +} diff --git a/vendor/github.com/moby/moby/client/image_push.go b/vendor/github.com/moby/moby/client/image_push.go new file mode 100644 index 000000000000..1ac5f43f5579 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_push.go @@ -0,0 +1,86 @@ +package client + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + + cerrdefs "github.com/containerd/errdefs" + "github.com/distribution/reference" + "github.com/moby/moby/api/types/image" + "github.com/moby/moby/api/types/registry" +) + +// ImagePush requests the docker host to push an image to a remote registry. +// It executes the privileged function if the operation is unauthorized +// and it tries one more time. +// It's up to the caller to handle the [io.ReadCloser] and close it. +func (cli *Client) ImagePush(ctx context.Context, image string, options image.PushOptions) (io.ReadCloser, error) { + ref, err := reference.ParseNormalizedNamed(image) + if err != nil { + return nil, err + } + + if _, isCanonical := ref.(reference.Canonical); isCanonical { + return nil, errors.New("cannot push a digest reference") + } + + query := url.Values{} + if !options.All { + ref = reference.TagNameOnly(ref) + if tagged, ok := ref.(reference.Tagged); ok { + query.Set("tag", tagged.Tag()) + } + } + + if options.Platform != nil { + if err := cli.NewVersionError(ctx, "1.46", "platform"); err != nil { + return nil, err + } + + p := *options.Platform + pJson, err := json.Marshal(p) + if err != nil { + return nil, fmt.Errorf("invalid platform: %v", err) + } + + query.Set("platform", string(pJson)) + } + + resp, err := cli.tryImagePush(ctx, ref.Name(), query, staticAuth(options.RegistryAuth)) + if cerrdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { + resp, err = cli.tryImagePush(ctx, ref.Name(), query, options.PrivilegeFunc) + } + if err != nil { + return nil, err + } + return resp.Body, nil +} + +func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, resolveAuth registry.RequestAuthConfig) (*http.Response, error) { + hdr := http.Header{} + if resolveAuth != nil { + registryAuth, err := resolveAuth(ctx) + if err != nil { + return nil, err + } + if registryAuth != "" { + hdr.Set(registry.AuthHeader, registryAuth) + } + } + + // Always send a body (which may be an empty JSON document ("{}")) to prevent + // EOF errors on older daemons which had faulty fallback code for handling + // authentication in the body when no auth-header was set, resulting in; + // + // Error response from daemon: bad parameters and missing X-Registry-Auth: invalid X-Registry-Auth header: EOF + // + // We use [http.NoBody], which gets marshaled to an empty JSON document. + // + // see: https://github.com/moby/moby/commit/ea29dffaa541289591aa44fa85d2a596ce860e16 + return cli.post(ctx, "/images/"+imageID+"/push", query, http.NoBody, hdr) +} diff --git a/vendor/github.com/moby/moby/client/image_remove.go b/vendor/github.com/moby/moby/client/image_remove.go new file mode 100644 index 000000000000..fb3175e6ab2c --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_remove.go @@ -0,0 +1,39 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/image" +) + +// ImageRemove removes an image from the docker host. +func (cli *Client) ImageRemove(ctx context.Context, imageID string, options image.RemoveOptions) ([]image.DeleteResponse, error) { + query := url.Values{} + + if options.Force { + query.Set("force", "1") + } + if !options.PruneChildren { + query.Set("noprune", "1") + } + + if len(options.Platforms) > 0 { + p, err := encodePlatforms(options.Platforms...) + if err != nil { + return nil, err + } + query["platforms"] = p + } + + resp, err := cli.delete(ctx, "/images/"+imageID, query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return nil, err + } + + var dels []image.DeleteResponse + err = json.NewDecoder(resp.Body).Decode(&dels) + return dels, err +} diff --git a/vendor/github.com/moby/moby/client/image_save.go b/vendor/github.com/moby/moby/client/image_save.go new file mode 100644 index 000000000000..ad32b0d65c79 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_save.go @@ -0,0 +1,43 @@ +package client + +import ( + "context" + "io" + "net/url" +) + +// ImageSave retrieves one or more images from the docker host as an +// [io.ReadCloser]. +// +// Platforms is an optional parameter that specifies the platforms to save +// from the image. Passing a platform only has an effect if the input image +// is a multi-platform image. +func (cli *Client) ImageSave(ctx context.Context, imageIDs []string, saveOpts ...ImageSaveOption) (io.ReadCloser, error) { + var opts imageSaveOpts + for _, opt := range saveOpts { + if err := opt.Apply(&opts); err != nil { + return nil, err + } + } + + query := url.Values{ + "names": imageIDs, + } + + if len(opts.apiOptions.Platforms) > 0 { + if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil { + return nil, err + } + p, err := encodePlatforms(opts.apiOptions.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 + } + return resp.Body, nil +} diff --git a/vendor/github.com/moby/moby/client/image_save_opts.go b/vendor/github.com/moby/moby/client/image_save_opts.go new file mode 100644 index 000000000000..787e78bda9c0 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_save_opts.go @@ -0,0 +1,33 @@ +package client + +import ( + "fmt" + + "github.com/moby/moby/api/types/image" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +type ImageSaveOption interface { + Apply(*imageSaveOpts) error +} + +type imageSaveOptionFunc func(opt *imageSaveOpts) error + +func (f imageSaveOptionFunc) Apply(o *imageSaveOpts) error { + return f(o) +} + +// ImageSaveWithPlatforms sets the platforms to be saved from the image. +func ImageSaveWithPlatforms(platforms ...ocispec.Platform) ImageSaveOption { + return imageSaveOptionFunc(func(opt *imageSaveOpts) error { + if opt.apiOptions.Platforms != nil { + return fmt.Errorf("platforms already set to %v", opt.apiOptions.Platforms) + } + opt.apiOptions.Platforms = platforms + return nil + }) +} + +type imageSaveOpts struct { + apiOptions image.SaveOptions +} diff --git a/vendor/github.com/moby/moby/client/image_search.go b/vendor/github.com/moby/moby/client/image_search.go new file mode 100644 index 000000000000..807fb69316cb --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_search.go @@ -0,0 +1,54 @@ +package client + +import ( + "context" + "encoding/json" + "net/http" + "net/url" + "strconv" + + cerrdefs "github.com/containerd/errdefs" + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/registry" +) + +// ImageSearch makes the docker host search by a term in a remote registry. +// The list of results is not sorted in any fashion. +func (cli *Client) ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error) { + var results []registry.SearchResult + query := url.Values{} + query.Set("term", term) + if options.Limit > 0 { + query.Set("limit", strconv.Itoa(options.Limit)) + } + + if options.Filters.Len() > 0 { + filterJSON, err := filters.ToJSON(options.Filters) + if err != nil { + return results, err + } + query.Set("filters", filterJSON) + } + + resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth) + defer ensureReaderClosed(resp) + if cerrdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { + newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx) + if privilegeErr != nil { + return results, privilegeErr + } + resp, err = cli.tryImageSearch(ctx, query, newAuthHeader) + } + if err != nil { + return results, err + } + + err = json.NewDecoder(resp.Body).Decode(&results) + return results, err +} + +func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (*http.Response, error) { + return cli.get(ctx, "/images/search", query, http.Header{ + registry.AuthHeader: {registryAuth}, + }) +} diff --git a/vendor/github.com/moby/moby/client/image_tag.go b/vendor/github.com/moby/moby/client/image_tag.go new file mode 100644 index 000000000000..a07f230b8b9a --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_tag.go @@ -0,0 +1,38 @@ +package client + +import ( + "context" + "errors" + "fmt" + "net/url" + + "github.com/distribution/reference" +) + +// ImageTag tags an image in the docker host +func (cli *Client) ImageTag(ctx context.Context, source, target string) error { + if _, err := reference.ParseAnyReference(source); err != nil { + return fmt.Errorf("error parsing reference: %q is not a valid repository/tag: %w", source, err) + } + + ref, err := reference.ParseNormalizedNamed(target) + if err != nil { + return fmt.Errorf("error parsing reference: %q is not a valid repository/tag: %w", target, err) + } + + if _, isCanonical := ref.(reference.Canonical); isCanonical { + return errors.New("refusing to create a tag with a digest reference") + } + + ref = reference.TagNameOnly(ref) + + query := url.Values{} + query.Set("repo", ref.Name()) + if tagged, ok := ref.(reference.Tagged); ok { + query.Set("tag", tagged.Tag()) + } + + resp, err := cli.post(ctx, "/images/"+source+"/tag", query, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/internal/timestamp/timestamp.go b/vendor/github.com/moby/moby/client/internal/timestamp/timestamp.go new file mode 100644 index 000000000000..7b175f0c93b4 --- /dev/null +++ b/vendor/github.com/moby/moby/client/internal/timestamp/timestamp.go @@ -0,0 +1,131 @@ +package timestamp + +import ( + "fmt" + "math" + "strconv" + "strings" + "time" +) + +// These are additional predefined layouts for use in Time.Format and Time.Parse +// with --since and --until parameters for `docker logs` and `docker events` +const ( + rFC3339Local = "2006-01-02T15:04:05" // RFC3339 with local timezone + rFC3339NanoLocal = "2006-01-02T15:04:05.999999999" // RFC3339Nano with local timezone + dateWithZone = "2006-01-02Z07:00" // RFC3339 with time at 00:00:00 + dateLocal = "2006-01-02" // RFC3339 with local timezone and time at 00:00:00 +) + +// GetTimestamp tries to parse given string as golang duration, +// then RFC3339 time and finally as a Unix timestamp. If +// any of these were successful, it returns a Unix timestamp +// as string otherwise returns the given value back. +// In case of duration input, the returned timestamp is computed +// as the given reference time minus the amount of the duration. +func GetTimestamp(value string, reference time.Time) (string, error) { + if d, err := time.ParseDuration(value); value != "0" && err == nil { + return strconv.FormatInt(reference.Add(-d).Unix(), 10), nil + } + + var format string + // if the string has a Z or a + or three dashes use parse otherwise use parseinlocation + parseInLocation := !strings.ContainsAny(value, "zZ+") && strings.Count(value, "-") != 3 + + if strings.Contains(value, ".") { + if parseInLocation { + format = rFC3339NanoLocal + } else { + format = time.RFC3339Nano + } + } else if strings.Contains(value, "T") { + // we want the number of colons in the T portion of the timestamp + tcolons := strings.Count(value, ":") + // if parseInLocation is off and we have a +/- zone offset (not Z) then + // there will be an extra colon in the input for the tz offset subtract that + // colon from the tcolons count + if !parseInLocation && !strings.ContainsAny(value, "zZ") && tcolons > 0 { + tcolons-- + } + if parseInLocation { + switch tcolons { + case 0: + format = "2006-01-02T15" + case 1: + format = "2006-01-02T15:04" + default: + format = rFC3339Local + } + } else { + switch tcolons { + case 0: + format = "2006-01-02T15Z07:00" + case 1: + format = "2006-01-02T15:04Z07:00" + default: + format = time.RFC3339 + } + } + } else if parseInLocation { + format = dateLocal + } else { + format = dateWithZone + } + + var t time.Time + var err error + + if parseInLocation { + t, err = time.ParseInLocation(format, value, time.FixedZone(reference.Zone())) + } else { + t, err = time.Parse(format, value) + } + + if err != nil { + // if there is a `-` then it's an RFC3339 like timestamp + if strings.Contains(value, "-") { + return "", err // was probably an RFC3339 like timestamp but the parser failed with an error + } + if _, _, err := parseTimestamp(value); err != nil { + return "", fmt.Errorf("failed to parse value as time or duration: %q", value) + } + return value, nil // unix timestamp in and out case (meaning: the value passed at the command line is already in the right format for passing to the server) + } + + return fmt.Sprintf("%d.%09d", t.Unix(), int64(t.Nanosecond())), nil +} + +// ParseTimestamps returns seconds and nanoseconds from a timestamp that has +// the format ("%d.%09d", time.Unix(), int64(time.Nanosecond())). +// If the incoming nanosecond portion is longer than 9 digits it is truncated. +// The expectation is that the seconds and nanoseconds will be used to create a +// time variable. For example: +// +// seconds, nanoseconds, _ := ParseTimestamp("1136073600.000000001",0) +// since := time.Unix(seconds, nanoseconds) +// +// returns seconds as defaultSeconds if value == "" +func ParseTimestamps(value string, defaultSeconds int64) (seconds int64, nanoseconds int64, _ error) { + if value == "" { + return defaultSeconds, 0, nil + } + return parseTimestamp(value) +} + +func parseTimestamp(value string) (seconds int64, nanoseconds int64, _ error) { + s, n, ok := strings.Cut(value, ".") + sec, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return sec, 0, err + } + if !ok { + return sec, 0, nil + } + nsec, err := strconv.ParseInt(n, 10, 64) + if err != nil { + return sec, nsec, err + } + // should already be in nanoseconds but just in case convert n to nanoseconds + nsec = int64(float64(nsec) * math.Pow(float64(10), float64(9-len(n)))) + return sec, nsec, nil +} diff --git a/vendor/github.com/moby/moby/client/login.go b/vendor/github.com/moby/moby/client/login.go new file mode 100644 index 000000000000..9cb365338d66 --- /dev/null +++ b/vendor/github.com/moby/moby/client/login.go @@ -0,0 +1,24 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/registry" +) + +// RegistryLogin authenticates the docker server with a given docker registry. +// It returns unauthorizedError when the authentication fails. +func (cli *Client) RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error) { + resp, err := cli.post(ctx, "/auth", url.Values{}, auth, nil) + defer ensureReaderClosed(resp) + + if err != nil { + return registry.AuthenticateOKBody{}, err + } + + var response registry.AuthenticateOKBody + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} diff --git a/vendor/github.com/moby/moby/client/network_connect.go b/vendor/github.com/moby/moby/client/network_connect.go new file mode 100644 index 000000000000..74a856e83382 --- /dev/null +++ b/vendor/github.com/moby/moby/client/network_connect.go @@ -0,0 +1,28 @@ +package client + +import ( + "context" + + "github.com/moby/moby/api/types/network" +) + +// NetworkConnect connects a container to an existent network in the docker host. +func (cli *Client) NetworkConnect(ctx context.Context, networkID, containerID string, config *network.EndpointSettings) error { + networkID, err := trimID("network", networkID) + if err != nil { + return err + } + + containerID, err = trimID("container", containerID) + if err != nil { + return err + } + + nc := network.ConnectOptions{ + Container: containerID, + EndpointConfig: config, + } + resp, err := cli.post(ctx, "/networks/"+networkID+"/connect", nil, nc, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/network_create.go b/vendor/github.com/moby/moby/client/network_create.go new file mode 100644 index 000000000000..9babf0cb9c0c --- /dev/null +++ b/vendor/github.com/moby/moby/client/network_create.go @@ -0,0 +1,40 @@ +package client + +import ( + "context" + "encoding/json" + + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/api/types/versions" +) + +// NetworkCreate creates a new network in the docker host. +func (cli *Client) NetworkCreate(ctx context.Context, name string, options network.CreateOptions) (network.CreateResponse, error) { + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + return network.CreateResponse{}, err + } + + networkCreateRequest := network.CreateRequest{ + CreateOptions: options, + Name: name, + } + if versions.LessThan(cli.version, "1.44") { + enabled := true + networkCreateRequest.CheckDuplicate = &enabled //nolint:staticcheck // ignore SA1019: CheckDuplicate is deprecated since API v1.44. + } + + resp, err := cli.post(ctx, "/networks/create", nil, networkCreateRequest, nil) + defer ensureReaderClosed(resp) + if err != nil { + return network.CreateResponse{}, err + } + + var response network.CreateResponse + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} diff --git a/vendor/github.com/moby/moby/client/network_disconnect.go b/vendor/github.com/moby/moby/client/network_disconnect.go new file mode 100644 index 000000000000..5f52c84d48c4 --- /dev/null +++ b/vendor/github.com/moby/moby/client/network_disconnect.go @@ -0,0 +1,28 @@ +package client + +import ( + "context" + + "github.com/moby/moby/api/types/network" +) + +// NetworkDisconnect disconnects a container from an existent network in the docker host. +func (cli *Client) NetworkDisconnect(ctx context.Context, networkID, containerID string, force bool) error { + networkID, err := trimID("network", networkID) + if err != nil { + return err + } + + containerID, err = trimID("container", containerID) + if err != nil { + return err + } + + nd := network.DisconnectOptions{ + Container: containerID, + Force: force, + } + resp, err := cli.post(ctx, "/networks/"+networkID+"/disconnect", nil, nd, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/network_inspect.go b/vendor/github.com/moby/moby/client/network_inspect.go new file mode 100644 index 000000000000..83d91f55c974 --- /dev/null +++ b/vendor/github.com/moby/moby/client/network_inspect.go @@ -0,0 +1,47 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "io" + "net/url" + + "github.com/moby/moby/api/types/network" +) + +// NetworkInspect returns the information for a specific network configured in the docker host. +func (cli *Client) NetworkInspect(ctx context.Context, networkID string, options network.InspectOptions) (network.Inspect, error) { + networkResource, _, err := cli.NetworkInspectWithRaw(ctx, networkID, options) + return networkResource, err +} + +// NetworkInspectWithRaw returns the information for a specific network configured in the docker host and its raw representation. +func (cli *Client) NetworkInspectWithRaw(ctx context.Context, networkID string, options network.InspectOptions) (network.Inspect, []byte, error) { + networkID, err := trimID("network", networkID) + if err != nil { + return network.Inspect{}, nil, err + } + query := url.Values{} + if options.Verbose { + query.Set("verbose", "true") + } + if options.Scope != "" { + query.Set("scope", options.Scope) + } + + resp, err := cli.get(ctx, "/networks/"+networkID, query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return network.Inspect{}, nil, err + } + + raw, err := io.ReadAll(resp.Body) + if err != nil { + return network.Inspect{}, nil, err + } + + var nw network.Inspect + err = json.NewDecoder(bytes.NewReader(raw)).Decode(&nw) + return nw, raw, err +} diff --git a/vendor/github.com/moby/moby/client/network_list.go b/vendor/github.com/moby/moby/client/network_list.go new file mode 100644 index 000000000000..5069c3bfe4c1 --- /dev/null +++ b/vendor/github.com/moby/moby/client/network_list.go @@ -0,0 +1,39 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/api/types/versions" +) + +// NetworkList returns the list of networks configured in the docker host. +func (cli *Client) NetworkList(ctx context.Context, options network.ListOptions) ([]network.Summary, error) { + query := url.Values{} + if options.Filters.Len() > 0 { + filterJSON, err := filters.ToJSON(options.Filters) + if err != nil { + return nil, err + } + if cli.version != "" && versions.LessThan(cli.version, "1.22") { + legacyFormat, err := encodeLegacyFilters(filterJSON) + if err != nil { + return nil, err + } + filterJSON = legacyFormat + } + + query.Set("filters", filterJSON) + } + var networkResources []network.Summary + resp, err := cli.get(ctx, "/networks", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return networkResources, err + } + err = json.NewDecoder(resp.Body).Decode(&networkResources) + return networkResources, err +} diff --git a/vendor/github.com/moby/moby/client/network_prune.go b/vendor/github.com/moby/moby/client/network_prune.go new file mode 100644 index 000000000000..ae4b8c28474d --- /dev/null +++ b/vendor/github.com/moby/moby/client/network_prune.go @@ -0,0 +1,35 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/network" +) + +// NetworksPrune requests the daemon to delete unused networks +func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters filters.Args) (network.PruneReport, error) { + if err := cli.NewVersionError(ctx, "1.25", "network prune"); err != nil { + return network.PruneReport{}, err + } + + query, err := getFiltersQuery(pruneFilters) + if err != nil { + return network.PruneReport{}, err + } + + resp, err := cli.post(ctx, "/networks/prune", query, nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return network.PruneReport{}, err + } + + var report network.PruneReport + if err := json.NewDecoder(resp.Body).Decode(&report); err != nil { + return network.PruneReport{}, fmt.Errorf("Error retrieving network prune report: %v", err) + } + + return report, nil +} diff --git a/vendor/github.com/moby/moby/client/network_remove.go b/vendor/github.com/moby/moby/client/network_remove.go new file mode 100644 index 000000000000..9b164d3eae46 --- /dev/null +++ b/vendor/github.com/moby/moby/client/network_remove.go @@ -0,0 +1,14 @@ +package client + +import "context" + +// NetworkRemove removes an existent network from the docker host. +func (cli *Client) NetworkRemove(ctx context.Context, networkID string) error { + networkID, err := trimID("network", networkID) + if err != nil { + return err + } + resp, err := cli.delete(ctx, "/networks/"+networkID, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/node_inspect.go b/vendor/github.com/moby/moby/client/node_inspect.go new file mode 100644 index 000000000000..816eb19f6688 --- /dev/null +++ b/vendor/github.com/moby/moby/client/node_inspect.go @@ -0,0 +1,33 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "io" + + "github.com/moby/moby/api/types/swarm" +) + +// NodeInspectWithRaw returns the node information. +func (cli *Client) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) { + nodeID, err := trimID("node", nodeID) + if err != nil { + return swarm.Node{}, nil, err + } + resp, err := cli.get(ctx, "/nodes/"+nodeID, nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return swarm.Node{}, nil, err + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return swarm.Node{}, nil, err + } + + var response swarm.Node + rdr := bytes.NewReader(body) + err = json.NewDecoder(rdr).Decode(&response) + return response, body, err +} diff --git a/vendor/github.com/moby/moby/client/node_list.go b/vendor/github.com/moby/moby/client/node_list.go new file mode 100644 index 000000000000..f6d2cad23e04 --- /dev/null +++ b/vendor/github.com/moby/moby/client/node_list.go @@ -0,0 +1,34 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/swarm" +) + +// NodeList returns the list of nodes. +func (cli *Client) NodeList(ctx context.Context, options swarm.NodeListOptions) ([]swarm.Node, error) { + query := url.Values{} + + if options.Filters.Len() > 0 { + filterJSON, err := filters.ToJSON(options.Filters) + if err != nil { + return nil, err + } + + query.Set("filters", filterJSON) + } + + resp, err := cli.get(ctx, "/nodes", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return nil, err + } + + var nodes []swarm.Node + err = json.NewDecoder(resp.Body).Decode(&nodes) + return nodes, err +} diff --git a/vendor/github.com/moby/moby/client/node_remove.go b/vendor/github.com/moby/moby/client/node_remove.go new file mode 100644 index 000000000000..9499a5efbc43 --- /dev/null +++ b/vendor/github.com/moby/moby/client/node_remove.go @@ -0,0 +1,25 @@ +package client + +import ( + "context" + "net/url" + + "github.com/moby/moby/api/types/swarm" +) + +// NodeRemove removes a Node. +func (cli *Client) NodeRemove(ctx context.Context, nodeID string, options swarm.NodeRemoveOptions) error { + nodeID, err := trimID("node", nodeID) + if err != nil { + return err + } + + query := url.Values{} + if options.Force { + query.Set("force", "1") + } + + resp, err := cli.delete(ctx, "/nodes/"+nodeID, query, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/node_update.go b/vendor/github.com/moby/moby/client/node_update.go new file mode 100644 index 000000000000..6dfa11b3a688 --- /dev/null +++ b/vendor/github.com/moby/moby/client/node_update.go @@ -0,0 +1,22 @@ +package client + +import ( + "context" + "net/url" + + "github.com/moby/moby/api/types/swarm" +) + +// NodeUpdate updates a Node. +func (cli *Client) NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error { + nodeID, err := trimID("node", nodeID) + if err != nil { + return err + } + + query := url.Values{} + query.Set("version", version.String()) + resp, err := cli.post(ctx, "/nodes/"+nodeID+"/update", query, node, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/options.go b/vendor/github.com/moby/moby/client/options.go new file mode 100644 index 000000000000..2df970f82234 --- /dev/null +++ b/vendor/github.com/moby/moby/client/options.go @@ -0,0 +1,248 @@ +package client + +import ( + "context" + "fmt" + "net" + "net/http" + "os" + "path/filepath" + "strings" + "time" + + "github.com/docker/go-connections/sockets" + "github.com/docker/go-connections/tlsconfig" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + "go.opentelemetry.io/otel/trace" +) + +// Opt is a configuration option to initialize a [Client]. +type Opt func(*Client) error + +// FromEnv configures the client with values from environment variables. It +// is the equivalent of using the [WithTLSClientConfigFromEnv], [WithHostFromEnv], +// and [WithVersionFromEnv] options. +// +// FromEnv uses the following environment variables: +// +// - DOCKER_HOST ([EnvOverrideHost]) to set the URL to the docker server. +// - DOCKER_API_VERSION ([EnvOverrideAPIVersion]) to set the version of the +// API to use, leave empty for latest. +// - DOCKER_CERT_PATH ([EnvOverrideCertPath]) to specify the directory from +// which to load the TLS certificates ("ca.pem", "cert.pem", "key.pem'). +// - DOCKER_TLS_VERIFY ([EnvTLSVerify]) to enable or disable TLS verification +// (off by default). +func FromEnv(c *Client) error { + ops := []Opt{ + WithTLSClientConfigFromEnv(), + WithHostFromEnv(), + WithVersionFromEnv(), + } + for _, op := range ops { + if err := op(c); err != nil { + return err + } + } + return nil +} + +// WithDialContext applies the dialer to the client transport. This can be +// used to set the Timeout and KeepAlive settings of the client. It returns +// an error if the client does not have a [http.Transport] configured. +func WithDialContext(dialContext func(ctx context.Context, network, addr string) (net.Conn, error)) Opt { + return func(c *Client) error { + if transport, ok := c.client.Transport.(*http.Transport); ok { + transport.DialContext = dialContext + return nil + } + return fmt.Errorf("cannot apply dialer to transport: %T", c.client.Transport) + } +} + +// WithHost overrides the client host with the specified one. +func WithHost(host string) Opt { + return func(c *Client) error { + hostURL, err := ParseHostURL(host) + if err != nil { + return err + } + c.host = host + c.proto = hostURL.Scheme + c.addr = hostURL.Host + c.basePath = hostURL.Path + if transport, ok := c.client.Transport.(*http.Transport); ok { + return sockets.ConfigureTransport(transport, c.proto, c.addr) + } + return fmt.Errorf("cannot apply host to transport: %T", c.client.Transport) + } +} + +// WithHostFromEnv overrides the client host with the host specified in the +// DOCKER_HOST ([EnvOverrideHost]) environment variable. If DOCKER_HOST is not set, +// or set to an empty value, the host is not modified. +func WithHostFromEnv() Opt { + return func(c *Client) error { + if host := os.Getenv(EnvOverrideHost); host != "" { + return WithHost(host)(c) + } + return nil + } +} + +// WithHTTPClient overrides the client's HTTP client with the specified one. +func WithHTTPClient(client *http.Client) Opt { + return func(c *Client) error { + if client != nil { + c.client = client + } + return nil + } +} + +// WithTimeout configures the time limit for requests made by the HTTP client. +func WithTimeout(timeout time.Duration) Opt { + return func(c *Client) error { + c.client.Timeout = timeout + return nil + } +} + +// WithUserAgent configures the User-Agent header to use for HTTP requests. +// It overrides any User-Agent set in headers. When set to an empty string, +// the User-Agent header is removed, and no header is sent. +func WithUserAgent(ua string) Opt { + return func(c *Client) error { + c.userAgent = &ua + return nil + } +} + +// WithHTTPHeaders appends custom HTTP headers to the client's default headers. +// It does not allow for built-in headers (such as "User-Agent", if set) to +// be overridden. Also see [WithUserAgent]. +func WithHTTPHeaders(headers map[string]string) Opt { + return func(c *Client) error { + c.customHTTPHeaders = headers + return nil + } +} + +// WithScheme overrides the client scheme with the specified one. +func WithScheme(scheme string) Opt { + return func(c *Client) error { + c.scheme = scheme + return nil + } +} + +// WithTLSClientConfig applies a TLS config to the client transport. +func WithTLSClientConfig(cacertPath, certPath, keyPath string) Opt { + return func(c *Client) error { + transport, ok := c.client.Transport.(*http.Transport) + if !ok { + return fmt.Errorf("cannot apply tls config to transport: %T", c.client.Transport) + } + config, err := tlsconfig.Client(tlsconfig.Options{ + CAFile: cacertPath, + CertFile: certPath, + KeyFile: keyPath, + ExclusiveRootPools: true, + }) + if err != nil { + return fmt.Errorf("failed to create tls config: %w", err) + } + transport.TLSClientConfig = config + return nil + } +} + +// WithTLSClientConfigFromEnv configures the client's TLS settings with the +// settings in the DOCKER_CERT_PATH ([EnvOverrideCertPath]) and DOCKER_TLS_VERIFY +// ([EnvTLSVerify]) environment variables. If DOCKER_CERT_PATH is not set or empty, +// TLS configuration is not modified. +// +// WithTLSClientConfigFromEnv uses the following environment variables: +// +// - DOCKER_CERT_PATH ([EnvOverrideCertPath]) to specify the directory from +// which to load the TLS certificates ("ca.pem", "cert.pem", "key.pem"). +// - DOCKER_TLS_VERIFY ([EnvTLSVerify]) to enable or disable TLS verification +// (off by default). +func WithTLSClientConfigFromEnv() Opt { + return func(c *Client) error { + dockerCertPath := os.Getenv(EnvOverrideCertPath) + if dockerCertPath == "" { + return nil + } + tlsc, err := tlsconfig.Client(tlsconfig.Options{ + CAFile: filepath.Join(dockerCertPath, "ca.pem"), + CertFile: filepath.Join(dockerCertPath, "cert.pem"), + KeyFile: filepath.Join(dockerCertPath, "key.pem"), + InsecureSkipVerify: os.Getenv(EnvTLSVerify) == "", + }) + if err != nil { + return err + } + + c.client = &http.Client{ + Transport: &http.Transport{TLSClientConfig: tlsc}, + CheckRedirect: CheckRedirect, + } + return nil + } +} + +// WithVersion overrides the client version with the specified one. If an empty +// version is provided, the value is ignored to allow version negotiation +// (see [WithAPIVersionNegotiation]). +// +// WithVersion does not validate if the client supports the given version, +// and callers should verify if the version is in the correct format and +// lower than the maximum supported version as defined by [DefaultAPIVersion]. +func WithVersion(version string) Opt { + return func(c *Client) error { + if v := strings.TrimPrefix(version, "v"); v != "" { + c.version = v + c.manualOverride = true + } + return nil + } +} + +// WithVersionFromEnv overrides the client version with the version specified in +// the DOCKER_API_VERSION ([EnvOverrideAPIVersion]) environment variable. +// If DOCKER_API_VERSION is not set, or set to an empty value, the version +// is not modified. +// +// WithVersion does not validate if the client supports the given version, +// and callers should verify if the version is in the correct format and +// lower than the maximum supported version as defined by [DefaultAPIVersion]. +func WithVersionFromEnv() Opt { + return func(c *Client) error { + return WithVersion(os.Getenv(EnvOverrideAPIVersion))(c) + } +} + +// WithAPIVersionNegotiation enables automatic API version negotiation for the client. +// With this option enabled, the client automatically negotiates the API version +// to use when making requests. API version negotiation is performed on the first +// request; subsequent requests do not re-negotiate. +func WithAPIVersionNegotiation() Opt { + return func(c *Client) error { + c.negotiateVersion = true + return nil + } +} + +// WithTraceProvider sets the trace provider for the client. +// If this is not set then the global trace provider is used. +func WithTraceProvider(provider trace.TracerProvider) Opt { + return WithTraceOptions(otelhttp.WithTracerProvider(provider)) +} + +// WithTraceOptions sets tracing span options for the client. +func WithTraceOptions(opts ...otelhttp.Option) Opt { + return func(c *Client) error { + c.traceOpts = append(c.traceOpts, opts...) + return nil + } +} diff --git a/vendor/github.com/moby/moby/client/ping.go b/vendor/github.com/moby/moby/client/ping.go new file mode 100644 index 000000000000..96ee7bef665d --- /dev/null +++ b/vendor/github.com/moby/moby/client/ping.go @@ -0,0 +1,74 @@ +package client + +import ( + "context" + "net/http" + "path" + "strings" + + "github.com/moby/moby/api/types" + "github.com/moby/moby/api/types/build" + "github.com/moby/moby/api/types/swarm" +) + +// Ping pings the server and returns the value of the "Docker-Experimental", +// "Builder-Version", "OS-Type" & "API-Version" headers. It attempts to use +// a HEAD request on the endpoint, but falls back to GET if HEAD is not supported +// by the daemon. It ignores internal server errors returned by the API, which +// may be returned if the daemon is in an unhealthy state, but returns errors +// for other non-success status codes, failing to connect to the API, or failing +// to parse the API response. +func (cli *Client) Ping(ctx context.Context) (types.Ping, error) { + // Using cli.buildRequest() + cli.doRequest() instead of cli.sendRequest() + // because ping requests are used during API version negotiation, so we want + // to hit the non-versioned /_ping endpoint, not /v1.xx/_ping + req, err := cli.buildRequest(ctx, http.MethodHead, path.Join(cli.basePath, "/_ping"), nil, nil) + if err != nil { + return types.Ping{}, err + } + resp, err := cli.doRequest(req) + defer ensureReaderClosed(resp) + if err == nil && resp.StatusCode == http.StatusOK { + // Fast-path; successfully connected using a HEAD request and + // we got a "OK" (200) status. For non-200 status-codes, we fall + // back to doing a GET request, as a HEAD request won't have a + // response-body to get error details from. + return newPingResponse(resp), nil + } + + // HEAD failed or returned a non-OK status; fallback to GET. + req.Method = http.MethodGet + resp, err = cli.doRequest(req) + defer ensureReaderClosed(resp) + if err != nil { + // Failed to connect. + return types.Ping{}, err + } + + // GET request succeeded but may have returned a non-200 status. + // Return a Ping response, together with any error returned by + // the API server. + return newPingResponse(resp), checkResponseErr(resp) +} + +func newPingResponse(resp *http.Response) types.Ping { + if resp == nil { + return types.Ping{} + } + var swarmStatus *swarm.Status + if si := resp.Header.Get("Swarm"); si != "" { + state, role, _ := strings.Cut(si, "/") + swarmStatus = &swarm.Status{ + NodeState: swarm.LocalNodeState(state), + ControlAvailable: role == "manager", + } + } + + return types.Ping{ + APIVersion: resp.Header.Get("Api-Version"), + OSType: resp.Header.Get("Ostype"), + Experimental: resp.Header.Get("Docker-Experimental") == "true", + BuilderVersion: build.BuilderVersion(resp.Header.Get("Builder-Version")), + SwarmStatus: swarmStatus, + } +} diff --git a/vendor/github.com/moby/moby/client/plugin_create.go b/vendor/github.com/moby/moby/client/plugin_create.go new file mode 100644 index 000000000000..c143db7061e5 --- /dev/null +++ b/vendor/github.com/moby/moby/client/plugin_create.go @@ -0,0 +1,26 @@ +package client + +import ( + "context" + "io" + "net/http" + "net/url" +) + +// PluginCreateOptions hold all options to plugin create. +type PluginCreateOptions struct { + RepoName string +} + +// PluginCreate creates a plugin +func (cli *Client) PluginCreate(ctx context.Context, createContext io.Reader, createOptions PluginCreateOptions) error { + headers := http.Header(make(map[string][]string)) + headers.Set("Content-Type", "application/x-tar") + + query := url.Values{} + query.Set("name", createOptions.RepoName) + + resp, err := cli.postRaw(ctx, "/plugins/create", query, createContext, headers) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/plugin_disable.go b/vendor/github.com/moby/moby/client/plugin_disable.go new file mode 100644 index 000000000000..b368dc6e58ea --- /dev/null +++ b/vendor/github.com/moby/moby/client/plugin_disable.go @@ -0,0 +1,26 @@ +package client + +import ( + "context" + "net/url" +) + +// PluginDisableOptions holds parameters to disable plugins. +type PluginDisableOptions struct { + Force bool +} + +// PluginDisable disables a plugin +func (cli *Client) PluginDisable(ctx context.Context, name string, options PluginDisableOptions) error { + name, err := trimID("plugin", name) + if err != nil { + return err + } + query := url.Values{} + if options.Force { + query.Set("force", "1") + } + resp, err := cli.post(ctx, "/plugins/"+name+"/disable", query, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/plugin_enable.go b/vendor/github.com/moby/moby/client/plugin_enable.go new file mode 100644 index 000000000000..c79361a47363 --- /dev/null +++ b/vendor/github.com/moby/moby/client/plugin_enable.go @@ -0,0 +1,26 @@ +package client + +import ( + "context" + "net/url" + "strconv" +) + +// PluginEnableOptions holds parameters to enable plugins. +type PluginEnableOptions struct { + Timeout int +} + +// PluginEnable enables a plugin +func (cli *Client) PluginEnable(ctx context.Context, name string, options PluginEnableOptions) error { + name, err := trimID("plugin", name) + if err != nil { + return err + } + query := url.Values{} + query.Set("timeout", strconv.Itoa(options.Timeout)) + + resp, err := cli.post(ctx, "/plugins/"+name+"/enable", query, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/plugin_inspect.go b/vendor/github.com/moby/moby/client/plugin_inspect.go new file mode 100644 index 000000000000..da30f1545850 --- /dev/null +++ b/vendor/github.com/moby/moby/client/plugin_inspect.go @@ -0,0 +1,32 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "io" + + "github.com/moby/moby/api/types/plugin" +) + +// PluginInspectWithRaw inspects an existing plugin +func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*plugin.Plugin, []byte, error) { + name, err := trimID("plugin", name) + if err != nil { + return nil, nil, err + } + resp, err := cli.get(ctx, "/plugins/"+name+"/json", nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return nil, nil, err + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, nil, err + } + var p plugin.Plugin + rdr := bytes.NewReader(body) + err = json.NewDecoder(rdr).Decode(&p) + return &p, body, err +} diff --git a/vendor/github.com/moby/moby/client/plugin_install.go b/vendor/github.com/moby/moby/client/plugin_install.go new file mode 100644 index 000000000000..2ec6f062e746 --- /dev/null +++ b/vendor/github.com/moby/moby/client/plugin_install.go @@ -0,0 +1,136 @@ +package client + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + + cerrdefs "github.com/containerd/errdefs" + "github.com/distribution/reference" + "github.com/moby/moby/api/types/plugin" + "github.com/moby/moby/api/types/registry" +) + +// 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 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/moby/moby/api/types/registry.RequestAuthConfig]. + PrivilegeFunc func(context.Context) (string, error) + AcceptPermissionsFunc func(context.Context, plugin.Privileges) (bool, error) + Args []string +} + +// PluginInstall installs a plugin +func (cli *Client) PluginInstall(ctx context.Context, name string, options PluginInstallOptions) (_ io.ReadCloser, retErr error) { + query := url.Values{} + if _, err := reference.ParseNormalizedNamed(options.RemoteRef); err != nil { + return nil, fmt.Errorf("invalid remote reference: %w", err) + } + query.Set("remote", options.RemoteRef) + + privileges, err := cli.checkPluginPermissions(ctx, query, options) + if err != nil { + return nil, err + } + + // set name for plugin pull, if empty should default to remote reference + query.Set("name", name) + + resp, err := cli.tryPluginPull(ctx, query, privileges, options.RegistryAuth) + if err != nil { + return nil, err + } + + name = resp.Header.Get("Docker-Plugin-Name") + + pr, pw := io.Pipe() + go func() { // todo: the client should probably be designed more around the actual api + _, err := io.Copy(pw, resp.Body) + if err != nil { + _ = pw.CloseWithError(err) + return + } + defer func() { + if retErr != nil { + delResp, _ := cli.delete(ctx, "/plugins/"+name, nil, nil) + ensureReaderClosed(delResp) + } + }() + if len(options.Args) > 0 { + if err := cli.PluginSet(ctx, name, options.Args); err != nil { + _ = pw.CloseWithError(err) + return + } + } + + if options.Disabled { + _ = pw.Close() + return + } + + enableErr := cli.PluginEnable(ctx, name, PluginEnableOptions{Timeout: 0}) + _ = pw.CloseWithError(enableErr) + }() + return pr, nil +} + +func (cli *Client) tryPluginPrivileges(ctx context.Context, query url.Values, registryAuth string) (*http.Response, error) { + return cli.get(ctx, "/plugins/privileges", query, http.Header{ + registry.AuthHeader: {registryAuth}, + }) +} + +func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileges plugin.Privileges, registryAuth string) (*http.Response, error) { + return cli.post(ctx, "/plugins/pull", query, privileges, http.Header{ + registry.AuthHeader: {registryAuth}, + }) +} + +func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, options PluginInstallOptions) (plugin.Privileges, error) { + resp, err := cli.tryPluginPrivileges(ctx, query, options.RegistryAuth) + if cerrdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { + // TODO: do inspect before to check existing name before checking privileges + newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx) + if privilegeErr != nil { + ensureReaderClosed(resp) + return nil, privilegeErr + } + options.RegistryAuth = newAuthHeader + resp, err = cli.tryPluginPrivileges(ctx, query, options.RegistryAuth) + } + if err != nil { + ensureReaderClosed(resp) + return nil, err + } + + var privileges plugin.Privileges + if err := json.NewDecoder(resp.Body).Decode(&privileges); err != nil { + ensureReaderClosed(resp) + return nil, err + } + ensureReaderClosed(resp) + + if !options.AcceptAllPermissions && options.AcceptPermissionsFunc != nil && len(privileges) > 0 { + accept, err := options.AcceptPermissionsFunc(ctx, privileges) + if err != nil { + return nil, err + } + if !accept { + return nil, errors.New("permission denied while installing plugin " + options.RemoteRef) + } + } + return privileges, nil +} diff --git a/vendor/github.com/moby/moby/client/plugin_list.go b/vendor/github.com/moby/moby/client/plugin_list.go new file mode 100644 index 000000000000..a7f80ebc23ea --- /dev/null +++ b/vendor/github.com/moby/moby/client/plugin_list.go @@ -0,0 +1,40 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/plugin" + "github.com/moby/moby/api/types/versions" +) + +// PluginList returns the installed plugins +func (cli *Client) PluginList(ctx context.Context, filter filters.Args) (plugin.ListResponse, error) { + var plugins plugin.ListResponse + query := url.Values{} + + if filter.Len() > 0 { + filterJSON, err := filters.ToJSON(filter) + if err != nil { + return plugins, err + } + if cli.version != "" && versions.LessThan(cli.version, "1.22") { + legacyFormat, err := encodeLegacyFilters(filterJSON) + if err != nil { + return plugins, err + } + filterJSON = legacyFormat + } + query.Set("filters", filterJSON) + } + resp, err := cli.get(ctx, "/plugins", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return plugins, err + } + + err = json.NewDecoder(resp.Body).Decode(&plugins) + return plugins, err +} diff --git a/vendor/github.com/moby/moby/client/plugin_push.go b/vendor/github.com/moby/moby/client/plugin_push.go new file mode 100644 index 000000000000..778a9b99b1c9 --- /dev/null +++ b/vendor/github.com/moby/moby/client/plugin_push.go @@ -0,0 +1,24 @@ +package client + +import ( + "context" + "io" + "net/http" + + "github.com/moby/moby/api/types/registry" +) + +// PluginPush pushes a plugin to a registry +func (cli *Client) PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) { + name, err := trimID("plugin", name) + if err != nil { + return nil, err + } + resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, http.Header{ + registry.AuthHeader: {registryAuth}, + }) + if err != nil { + return nil, err + } + return resp.Body, nil +} diff --git a/vendor/github.com/moby/moby/client/plugin_remove.go b/vendor/github.com/moby/moby/client/plugin_remove.go new file mode 100644 index 000000000000..fee1a7ad367e --- /dev/null +++ b/vendor/github.com/moby/moby/client/plugin_remove.go @@ -0,0 +1,28 @@ +package client + +import ( + "context" + "net/url" +) + +// PluginRemoveOptions holds parameters to remove plugins. +type PluginRemoveOptions struct { + Force bool +} + +// PluginRemove removes a plugin +func (cli *Client) PluginRemove(ctx context.Context, name string, options PluginRemoveOptions) error { + name, err := trimID("plugin", name) + if err != nil { + return err + } + + query := url.Values{} + if options.Force { + query.Set("force", "1") + } + + resp, err := cli.delete(ctx, "/plugins/"+name, query, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/plugin_set.go b/vendor/github.com/moby/moby/client/plugin_set.go new file mode 100644 index 000000000000..f60631160238 --- /dev/null +++ b/vendor/github.com/moby/moby/client/plugin_set.go @@ -0,0 +1,17 @@ +package client + +import ( + "context" +) + +// PluginSet modifies settings for an existing plugin +func (cli *Client) PluginSet(ctx context.Context, name string, args []string) error { + name, err := trimID("plugin", name) + if err != nil { + return err + } + + resp, err := cli.post(ctx, "/plugins/"+name+"/set", nil, args, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/plugin_upgrade.go b/vendor/github.com/moby/moby/client/plugin_upgrade.go new file mode 100644 index 000000000000..b1a5cf3bb5af --- /dev/null +++ b/vendor/github.com/moby/moby/client/plugin_upgrade.go @@ -0,0 +1,47 @@ +package client + +import ( + "context" + "fmt" + "io" + "net/http" + "net/url" + + "github.com/distribution/reference" + "github.com/moby/moby/api/types/plugin" + "github.com/moby/moby/api/types/registry" +) + +// PluginUpgrade upgrades a plugin +func (cli *Client) PluginUpgrade(ctx context.Context, name string, options PluginInstallOptions) (io.ReadCloser, error) { + name, err := trimID("plugin", name) + if err != nil { + return nil, err + } + + if err := cli.NewVersionError(ctx, "1.26", "plugin upgrade"); err != nil { + return nil, err + } + query := url.Values{} + if _, err := reference.ParseNormalizedNamed(options.RemoteRef); err != nil { + return nil, fmt.Errorf("invalid remote reference: %w", err) + } + query.Set("remote", options.RemoteRef) + + privileges, err := cli.checkPluginPermissions(ctx, query, options) + if err != nil { + return nil, err + } + + resp, err := cli.tryPluginUpgrade(ctx, query, privileges, name, options.RegistryAuth) + if err != nil { + return nil, err + } + return resp.Body, nil +} + +func (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges plugin.Privileges, name, registryAuth string) (*http.Response, error) { + return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, http.Header{ + registry.AuthHeader: {registryAuth}, + }) +} diff --git a/vendor/github.com/moby/moby/client/request.go b/vendor/github.com/moby/moby/client/request.go new file mode 100644 index 000000000000..cd6643b1c407 --- /dev/null +++ b/vendor/github.com/moby/moby/client/request.go @@ -0,0 +1,340 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net" + "net/http" + "net/url" + "os" + "reflect" + "strings" + + "github.com/moby/moby/api/types/common" +) + +// head sends an http request to the docker API using the method HEAD. +func (cli *Client) head(ctx context.Context, path string, query url.Values, headers http.Header) (*http.Response, error) { + return cli.sendRequest(ctx, http.MethodHead, path, query, nil, headers) +} + +// get sends an http request to the docker API using the method GET with a specific Go context. +func (cli *Client) get(ctx context.Context, path string, query url.Values, headers http.Header) (*http.Response, error) { + return cli.sendRequest(ctx, http.MethodGet, path, query, nil, headers) +} + +// post sends an http POST request to the API. +func (cli *Client) post(ctx context.Context, path string, query url.Values, body any, headers http.Header) (*http.Response, error) { + jsonBody, headers, err := prepareJSONRequest(body, headers) + if err != nil { + return nil, err + } + return cli.sendRequest(ctx, http.MethodPost, path, query, jsonBody, headers) +} + +func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers http.Header) (*http.Response, error) { + return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers) +} + +func (cli *Client) put(ctx context.Context, path string, query url.Values, body any, headers http.Header) (*http.Response, error) { + jsonBody, headers, err := prepareJSONRequest(body, headers) + if err != nil { + return nil, err + } + return cli.putRaw(ctx, path, query, jsonBody, headers) +} + +// putRaw sends an http request to the docker API using the method PUT. +func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers http.Header) (*http.Response, error) { + // PUT requests are expected to always have a body (apparently) + // so explicitly pass an empty body to sendRequest to signal that + // it should set the Content-Type header if not already present. + if body == nil { + body = http.NoBody + } + return cli.sendRequest(ctx, http.MethodPut, path, query, body, headers) +} + +// delete sends an http request to the docker API using the method DELETE. +func (cli *Client) delete(ctx context.Context, path string, query url.Values, headers http.Header) (*http.Response, error) { + return cli.sendRequest(ctx, http.MethodDelete, path, query, nil, headers) +} + +// prepareJSONRequest encodes the given body to JSON and returns it as an [io.Reader], and sets the Content-Type +// header. If body is nil, or a nil-interface, a "nil" body is returned without +// error. +// +// TODO(thaJeztah): should this return an error if a different Content-Type is already set? +// TODO(thaJeztah): is "nil" the appropriate approach for an empty body, or should we use [http.NoBody] (or similar)? +func prepareJSONRequest(body any, headers http.Header) (io.Reader, http.Header, error) { + if body == nil { + return nil, headers, nil + } + // encoding/json encodes a nil pointer as the JSON document `null`, + // irrespective of whether the type implements json.Marshaler or encoding.TextMarshaler. + // That is almost certainly not what the caller intended as the request body. + // + // TODO(thaJeztah): consider moving this to jsonEncode, which would also allow returning an (empty) reader instead of nil. + if reflect.TypeOf(body).Kind() == reflect.Ptr && reflect.ValueOf(body).IsNil() { + return nil, headers, nil + } + + jsonBody, err := jsonEncode(body) + if err != nil { + return nil, headers, err + } + hdr := http.Header{} + if headers != nil { + hdr = headers.Clone() + } + + hdr.Set("Content-Type", "application/json") + return jsonBody, hdr, nil +} + +func (cli *Client) buildRequest(ctx context.Context, method, path string, body io.Reader, headers http.Header) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, method, path, body) + if err != nil { + return nil, err + } + req = cli.addHeaders(req, headers) + req.URL.Scheme = cli.scheme + req.URL.Host = cli.addr + + if cli.proto == "unix" || cli.proto == "npipe" { + // Override host header for non-tcp connections. + req.Host = DummyHost + } + + if body != nil && req.Header.Get("Content-Type") == "" { + req.Header.Set("Content-Type", "text/plain") + } + return req, nil +} + +func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers http.Header) (*http.Response, error) { + req, err := cli.buildRequest(ctx, method, cli.getAPIPath(ctx, path, query), body, headers) + if err != nil { + return nil, err + } + + resp, err := cli.doRequest(req) + if err != nil { + // Failed to connect or context error. + return resp, err + } + + // Successfully made a request; return the response and handle any + // API HTTP response errors. + return resp, checkResponseErr(resp) +} + +// doRequest sends an HTTP request and returns an HTTP response. It is a +// wrapper around [http.Client.Do] with extra handling to decorate errors. +// +// Otherwise, it behaves identical to [http.Client.Do]; an error is returned +// when failing to make a connection, On error, any Response can be ignored. +// A non-2xx status code doesn't cause an error. +func (cli *Client) doRequest(req *http.Request) (*http.Response, error) { + resp, err := cli.client.Do(req) + if err == nil { + return resp, nil + } + + if cli.scheme != "https" && strings.Contains(err.Error(), "malformed HTTP response") { + return nil, errConnectionFailed{fmt.Errorf("%w.\n* Are you trying to connect to a TLS-enabled daemon without TLS?", err)} + } + + if cli.scheme == "https" && strings.Contains(err.Error(), "bad certificate") { + return nil, errConnectionFailed{fmt.Errorf("the server probably has client authentication (--tlsverify) enabled; check your TLS client certification settings: %w", err)} + } + + // Don't decorate context sentinel errors; users may be comparing to + // them directly. + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return nil, err + } + + if errors.Is(err, os.ErrPermission) { + // Don't include request errors ("Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.51/version"), + // which are irrelevant if we weren't able to connect. + return nil, errConnectionFailed{fmt.Errorf("permission denied while trying to connect to the docker API at %v", cli.host)} + } + if errors.Is(err, os.ErrNotExist) { + // Unwrap the error to remove request errors ("Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.51/version"), + // which are irrelevant if we weren't able to connect. + err = errors.Unwrap(err) + return nil, errConnectionFailed{fmt.Errorf("failed to connect to the docker API at %v; check if the path is correct and if the daemon is running: %w", cli.host, err)} + } + var dnsErr *net.DNSError + if errors.As(err, &dnsErr) { + return nil, errConnectionFailed{fmt.Errorf("failed to connect to the docker API at %v: %w", cli.host, dnsErr)} + } + + var nErr net.Error + if errors.As(err, &nErr) { + // FIXME(thaJeztah): any net.Error should be considered a connection error (but we should include the original error)? + if nErr.Timeout() { + return nil, connectionFailed(cli.host) + } + if strings.Contains(nErr.Error(), "connection refused") || strings.Contains(nErr.Error(), "dial unix") { + return nil, connectionFailed(cli.host) + } + } + + // Although there's not a strongly typed error for this in go-winio, + // lots of people are using the default configuration for the docker + // daemon on Windows where the daemon is listening on a named pipe + // `//./pipe/docker_engine, and the client must be running elevated. + // Give users a clue rather than the not-overly useful message + // such as `error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.26/info: + // open //./pipe/docker_engine: The system cannot find the file specified.`. + // Note we can't string compare "The system cannot find the file specified" as + // this is localised - for example in French the error would be + // `open //./pipe/docker_engine: Le fichier spécifié est introuvable.` + if strings.Contains(err.Error(), `open //./pipe/docker_engine`) { + // Checks if client is running with elevated privileges + if f, elevatedErr := os.Open(`\\.\PHYSICALDRIVE0`); elevatedErr != nil { + err = fmt.Errorf("in the default daemon configuration on Windows, the docker client must be run with elevated privileges to connect: %w", err) + } else { + _ = f.Close() + err = fmt.Errorf("this error may indicate that the docker daemon is not running: %w", err) + } + } + + return nil, errConnectionFailed{fmt.Errorf("error during connect: %w", err)} +} + +func checkResponseErr(serverResp *http.Response) (retErr error) { + if serverResp == nil { + return nil + } + if serverResp.StatusCode >= http.StatusOK && serverResp.StatusCode < http.StatusBadRequest { + return nil + } + defer func() { + retErr = httpErrorFromStatusCode(retErr, serverResp.StatusCode) + }() + + var body []byte + var err error + var reqURL string + if serverResp.Request != nil { + reqURL = serverResp.Request.URL.String() + } + statusMsg := serverResp.Status + if statusMsg == "" { + statusMsg = http.StatusText(serverResp.StatusCode) + } + if serverResp.Body != nil { + bodyMax := 1 * 1024 * 1024 // 1 MiB + bodyR := &io.LimitedReader{ + R: serverResp.Body, + N: int64(bodyMax), + } + body, err = io.ReadAll(bodyR) + if err != nil { + return err + } + if bodyR.N == 0 { + if reqURL != "" { + return fmt.Errorf("request returned %s with a message (> %d bytes) for API route and version %s, check if the server supports the requested API version", statusMsg, bodyMax, reqURL) + } + return fmt.Errorf("request returned %s with a message (> %d bytes); check if the server supports the requested API version", statusMsg, bodyMax) + } + } + if len(body) == 0 { + if reqURL != "" { + return fmt.Errorf("request returned %s for API route and version %s, check if the server supports the requested API version", statusMsg, reqURL) + } + return fmt.Errorf("request returned %s; check if the server supports the requested API version", statusMsg) + } + + var daemonErr error + if serverResp.Header.Get("Content-Type") == "application/json" { + var errorResponse common.ErrorResponse + if err := json.Unmarshal(body, &errorResponse); err != nil { + return fmt.Errorf("error reading JSON: %w", err) + } + if errorResponse.Message == "" { + // Error-message is empty, which means that we successfully parsed the + // JSON-response (no error produced), but it didn't contain an error + // message. This could either be because the response was empty, or + // the response was valid JSON, but not with the expected schema + // ([common.ErrorResponse]). + // + // We cannot use "strict" JSON handling (json.NewDecoder with DisallowUnknownFields) + // due to the API using an open schema (we must anticipate fields + // being added to [common.ErrorResponse] in the future, and not + // reject those responses. + // + // For these cases, we construct an error with the status-code + // returned, but we could consider returning (a truncated version + // of) the actual response as-is. + // + // TODO(thaJeztah): consider adding a log.Debug to allow clients to debug the actual response when enabling debug logging. + daemonErr = fmt.Errorf(`API returned a %d (%s) but provided no error-message`, + serverResp.StatusCode, + http.StatusText(serverResp.StatusCode), + ) + } else { + daemonErr = errors.New(strings.TrimSpace(errorResponse.Message)) + } + } else { + // Fall back to returning the response as-is for API versions < 1.24 + // that didn't support JSON error responses, and for situations + // where a plain text error is returned. This branch may also catch + // situations where a proxy is involved, returning a HTML response. + daemonErr = errors.New(strings.TrimSpace(string(body))) + } + return fmt.Errorf("Error response from daemon: %w", daemonErr) +} + +func (cli *Client) addHeaders(req *http.Request, headers http.Header) *http.Request { + // Add CLI Config's HTTP Headers BEFORE we set the Docker headers + // then the user can't change OUR headers + for k, v := range cli.customHTTPHeaders { + req.Header.Set(k, v) + } + + for k, v := range headers { + req.Header[http.CanonicalHeaderKey(k)] = v + } + + if cli.userAgent != nil { + if *cli.userAgent == "" { + req.Header.Del("User-Agent") + } else { + req.Header.Set("User-Agent", *cli.userAgent) + } + } + return req +} + +func jsonEncode(data any) (io.Reader, error) { + var params bytes.Buffer + if data != nil { + if err := json.NewEncoder(¶ms).Encode(data); err != nil { + return nil, err + } + } + return ¶ms, nil +} + +func ensureReaderClosed(response *http.Response) { + if response != nil && response.Body != nil { + // Drain up to 512 bytes and close the body to let the Transport reuse the connection + // see https://github.com/google/go-github/pull/317/files#r57536827 + // + // TODO(thaJeztah): see if this optimization is still needed, or already implemented in stdlib, + // and check if context-cancellation should handle this as well. If still needed, consider + // wrapping response.Body, or returning a "closer()" from [Client.sendRequest] and related + // methods. + _, _ = io.CopyN(io.Discard, response.Body, 512) + _ = response.Body.Close() + } +} diff --git a/vendor/github.com/moby/moby/client/secret_create.go b/vendor/github.com/moby/moby/client/secret_create.go new file mode 100644 index 000000000000..f7081f4c4f6d --- /dev/null +++ b/vendor/github.com/moby/moby/client/secret_create.go @@ -0,0 +1,24 @@ +package client + +import ( + "context" + "encoding/json" + + "github.com/moby/moby/api/types/swarm" +) + +// SecretCreate creates a new secret. +func (cli *Client) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (swarm.SecretCreateResponse, error) { + if err := cli.NewVersionError(ctx, "1.25", "secret create"); err != nil { + return swarm.SecretCreateResponse{}, err + } + resp, err := cli.post(ctx, "/secrets/create", nil, secret, nil) + defer ensureReaderClosed(resp) + if err != nil { + return swarm.SecretCreateResponse{}, err + } + + var response swarm.SecretCreateResponse + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} diff --git a/vendor/github.com/moby/moby/client/secret_inspect.go b/vendor/github.com/moby/moby/client/secret_inspect.go new file mode 100644 index 000000000000..da3191ec73de --- /dev/null +++ b/vendor/github.com/moby/moby/client/secret_inspect.go @@ -0,0 +1,37 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "io" + + "github.com/moby/moby/api/types/swarm" +) + +// SecretInspectWithRaw returns the secret information with raw data +func (cli *Client) SecretInspectWithRaw(ctx context.Context, id string) (swarm.Secret, []byte, error) { + id, err := trimID("secret", id) + if err != nil { + return swarm.Secret{}, nil, err + } + if err := cli.NewVersionError(ctx, "1.25", "secret inspect"); err != nil { + return swarm.Secret{}, nil, err + } + resp, err := cli.get(ctx, "/secrets/"+id, nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return swarm.Secret{}, nil, err + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return swarm.Secret{}, nil, err + } + + var secret swarm.Secret + rdr := bytes.NewReader(body) + err = json.NewDecoder(rdr).Decode(&secret) + + return secret, body, err +} diff --git a/vendor/github.com/moby/moby/client/secret_list.go b/vendor/github.com/moby/moby/client/secret_list.go new file mode 100644 index 000000000000..2ed1997a0a86 --- /dev/null +++ b/vendor/github.com/moby/moby/client/secret_list.go @@ -0,0 +1,37 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/swarm" +) + +// SecretList returns the list of secrets. +func (cli *Client) SecretList(ctx context.Context, options swarm.SecretListOptions) ([]swarm.Secret, error) { + if err := cli.NewVersionError(ctx, "1.25", "secret list"); err != nil { + return nil, err + } + query := url.Values{} + + if options.Filters.Len() > 0 { + filterJSON, err := filters.ToJSON(options.Filters) + if err != nil { + return nil, err + } + + query.Set("filters", filterJSON) + } + + resp, err := cli.get(ctx, "/secrets", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return nil, err + } + + var secrets []swarm.Secret + err = json.NewDecoder(resp.Body).Decode(&secrets) + return secrets, err +} diff --git a/vendor/github.com/moby/moby/client/secret_remove.go b/vendor/github.com/moby/moby/client/secret_remove.go new file mode 100644 index 000000000000..d1044aaf857b --- /dev/null +++ b/vendor/github.com/moby/moby/client/secret_remove.go @@ -0,0 +1,17 @@ +package client + +import "context" + +// SecretRemove removes a secret. +func (cli *Client) SecretRemove(ctx context.Context, id string) error { + id, err := trimID("secret", id) + if err != nil { + return err + } + if err := cli.NewVersionError(ctx, "1.25", "secret remove"); err != nil { + return err + } + resp, err := cli.delete(ctx, "/secrets/"+id, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/secret_update.go b/vendor/github.com/moby/moby/client/secret_update.go new file mode 100644 index 000000000000..ebc2007d5b7a --- /dev/null +++ b/vendor/github.com/moby/moby/client/secret_update.go @@ -0,0 +1,24 @@ +package client + +import ( + "context" + "net/url" + + "github.com/moby/moby/api/types/swarm" +) + +// SecretUpdate attempts to update a secret. +func (cli *Client) SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error { + id, err := trimID("secret", id) + if err != nil { + return err + } + if err := cli.NewVersionError(ctx, "1.25", "secret update"); err != nil { + return err + } + query := url.Values{} + query.Set("version", version.String()) + resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, secret, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/service_create.go b/vendor/github.com/moby/moby/client/service_create.go new file mode 100644 index 000000000000..e593ab91f200 --- /dev/null +++ b/vendor/github.com/moby/moby/client/service_create.go @@ -0,0 +1,212 @@ +package client + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "strings" + + "github.com/distribution/reference" + "github.com/moby/moby/api/types/registry" + "github.com/moby/moby/api/types/swarm" + "github.com/moby/moby/api/types/versions" + "github.com/opencontainers/go-digest" +) + +// ServiceCreate creates a new service. +func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options swarm.ServiceCreateOptions) (swarm.ServiceCreateResponse, error) { + var response swarm.ServiceCreateResponse + + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + return response, err + } + + // Make sure containerSpec is not nil when no runtime is set or the runtime is set to container + if service.TaskTemplate.ContainerSpec == nil && (service.TaskTemplate.Runtime == "" || service.TaskTemplate.Runtime == swarm.RuntimeContainer) { + service.TaskTemplate.ContainerSpec = &swarm.ContainerSpec{} + } + + if err := validateServiceSpec(service); err != nil { + return response, err + } + if versions.LessThan(cli.version, "1.30") { + if err := validateAPIVersion(service, cli.version); err != nil { + return response, err + } + } + + // ensure that the image is tagged + var resolveWarning string + switch { + case service.TaskTemplate.ContainerSpec != nil: + if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" { + service.TaskTemplate.ContainerSpec.Image = taggedImg + } + if options.QueryRegistry { + resolveWarning = resolveContainerSpecImage(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth) + } + case service.TaskTemplate.PluginSpec != nil: + if taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != "" { + service.TaskTemplate.PluginSpec.Remote = taggedImg + } + if options.QueryRegistry { + resolveWarning = resolvePluginSpecRemote(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth) + } + } + + headers := http.Header{} + if versions.LessThan(cli.version, "1.30") { + // the custom "version" header was used by engine API before 20.10 + // (API 1.30) to switch between client- and server-side lookup of + // image digests. + headers["version"] = []string{cli.version} + } + if options.EncodedRegistryAuth != "" { + headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth} + } + resp, err := cli.post(ctx, "/services/create", nil, service, headers) + defer ensureReaderClosed(resp) + if err != nil { + return response, err + } + + err = json.NewDecoder(resp.Body).Decode(&response) + if resolveWarning != "" { + response.Warnings = append(response.Warnings, resolveWarning) + } + + return response, err +} + +func resolveContainerSpecImage(ctx context.Context, cli DistributionAPIClient, taskSpec *swarm.TaskSpec, encodedAuth string) string { + var warning string + if img, imgPlatforms, err := imageDigestAndPlatforms(ctx, cli, taskSpec.ContainerSpec.Image, encodedAuth); err != nil { + warning = digestWarning(taskSpec.ContainerSpec.Image) + } else { + taskSpec.ContainerSpec.Image = img + if len(imgPlatforms) > 0 { + if taskSpec.Placement == nil { + taskSpec.Placement = &swarm.Placement{} + } + taskSpec.Placement.Platforms = imgPlatforms + } + } + return warning +} + +func resolvePluginSpecRemote(ctx context.Context, cli DistributionAPIClient, taskSpec *swarm.TaskSpec, encodedAuth string) string { + var warning string + if img, imgPlatforms, err := imageDigestAndPlatforms(ctx, cli, taskSpec.PluginSpec.Remote, encodedAuth); err != nil { + warning = digestWarning(taskSpec.PluginSpec.Remote) + } else { + taskSpec.PluginSpec.Remote = img + if len(imgPlatforms) > 0 { + if taskSpec.Placement == nil { + taskSpec.Placement = &swarm.Placement{} + } + taskSpec.Placement.Platforms = imgPlatforms + } + } + return warning +} + +func imageDigestAndPlatforms(ctx context.Context, cli DistributionAPIClient, image, encodedAuth string) (string, []swarm.Platform, error) { + distributionInspect, err := cli.DistributionInspect(ctx, image, encodedAuth) + var platforms []swarm.Platform + if err != nil { + return "", nil, err + } + + imageWithDigest := imageWithDigestString(image, distributionInspect.Descriptor.Digest) + + if len(distributionInspect.Platforms) > 0 { + platforms = make([]swarm.Platform, 0, len(distributionInspect.Platforms)) + for _, p := range distributionInspect.Platforms { + // clear architecture field for arm. This is a temporary patch to address + // https://github.com/docker/swarmkit/issues/2294. The issue is that while + // image manifests report "arm" as the architecture, the node reports + // something like "armv7l" (includes the variant), which causes arm images + // to stop working with swarm mode. This patch removes the architecture + // constraint for arm images to ensure tasks get scheduled. + arch := p.Architecture + if strings.ToLower(arch) == "arm" { + arch = "" + } + platforms = append(platforms, swarm.Platform{ + Architecture: arch, + OS: p.OS, + }) + } + } + return imageWithDigest, platforms, err +} + +// imageWithDigestString takes an image string and a digest, and updates +// the image string if it didn't originally contain a digest. It returns +// image unmodified in other situations. +func imageWithDigestString(image string, dgst digest.Digest) string { + namedRef, err := reference.ParseNormalizedNamed(image) + if err == nil { + if _, isCanonical := namedRef.(reference.Canonical); !isCanonical { + // ensure that image gets a default tag if none is provided + img, err := reference.WithDigest(namedRef, dgst) + if err == nil { + return reference.FamiliarString(img) + } + } + } + return image +} + +// imageWithTagString takes an image string, and returns a tagged image +// string, adding a 'latest' tag if one was not provided. It returns an +// empty string if a canonical reference was provided +func imageWithTagString(image string) string { + namedRef, err := reference.ParseNormalizedNamed(image) + if err == nil { + return reference.FamiliarString(reference.TagNameOnly(namedRef)) + } + return "" +} + +// digestWarning constructs a formatted warning string using the +// image name that could not be pinned by digest. The formatting +// is hardcoded, but could me made smarter in the future +func digestWarning(image string) string { + return fmt.Sprintf("image %s could not be accessed on a registry to record\nits digest. Each node will access %s independently,\npossibly leading to different nodes running different\nversions of the image.\n", image, image) +} + +func validateServiceSpec(s swarm.ServiceSpec) error { + if s.TaskTemplate.ContainerSpec != nil && s.TaskTemplate.PluginSpec != nil { + return errors.New("must not specify both a container spec and a plugin spec in the task template") + } + if s.TaskTemplate.PluginSpec != nil && s.TaskTemplate.Runtime != swarm.RuntimePlugin { + return errors.New("mismatched runtime with plugin spec") + } + if s.TaskTemplate.ContainerSpec != nil && (s.TaskTemplate.Runtime != "" && s.TaskTemplate.Runtime != swarm.RuntimeContainer) { + return errors.New("mismatched runtime with container spec") + } + return nil +} + +func validateAPIVersion(c swarm.ServiceSpec, apiVersion string) error { + for _, m := range c.TaskTemplate.ContainerSpec.Mounts { + if m.BindOptions != nil { + if m.BindOptions.NonRecursive && versions.LessThan(apiVersion, "1.40") { + return errors.New("bind-recursive=disabled requires API v1.40 or later") + } + // ReadOnlyNonRecursive can be safely ignored when API < 1.44 + if m.BindOptions.ReadOnlyForceRecursive && versions.LessThan(apiVersion, "1.44") { + return errors.New("bind-recursive=readonly requires API v1.44 or later") + } + } + } + return nil +} diff --git a/vendor/github.com/moby/moby/client/service_inspect.go b/vendor/github.com/moby/moby/client/service_inspect.go new file mode 100644 index 000000000000..dab40392a294 --- /dev/null +++ b/vendor/github.com/moby/moby/client/service_inspect.go @@ -0,0 +1,38 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/url" + + "github.com/moby/moby/api/types/swarm" +) + +// ServiceInspectWithRaw returns the service information and the raw data. +func (cli *Client) ServiceInspectWithRaw(ctx context.Context, serviceID string, opts swarm.ServiceInspectOptions) (swarm.Service, []byte, error) { + serviceID, err := trimID("service", serviceID) + if err != nil { + return swarm.Service{}, nil, err + } + + query := url.Values{} + query.Set("insertDefaults", fmt.Sprintf("%v", opts.InsertDefaults)) + resp, err := cli.get(ctx, "/services/"+serviceID, query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return swarm.Service{}, nil, err + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return swarm.Service{}, nil, err + } + + var response swarm.Service + rdr := bytes.NewReader(body) + err = json.NewDecoder(rdr).Decode(&response) + return response, body, err +} diff --git a/vendor/github.com/moby/moby/client/service_list.go b/vendor/github.com/moby/moby/client/service_list.go new file mode 100644 index 000000000000..78b039d19859 --- /dev/null +++ b/vendor/github.com/moby/moby/client/service_list.go @@ -0,0 +1,38 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/swarm" +) + +// ServiceList returns the list of services. +func (cli *Client) ServiceList(ctx context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error) { + query := url.Values{} + + if options.Filters.Len() > 0 { + filterJSON, err := filters.ToJSON(options.Filters) + if err != nil { + return nil, err + } + + query.Set("filters", filterJSON) + } + + if options.Status { + query.Set("status", "true") + } + + resp, err := cli.get(ctx, "/services", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return nil, err + } + + var services []swarm.Service + err = json.NewDecoder(resp.Body).Decode(&services) + return services, err +} diff --git a/vendor/github.com/moby/moby/client/service_logs.go b/vendor/github.com/moby/moby/client/service_logs.go new file mode 100644 index 000000000000..7062914aecdb --- /dev/null +++ b/vendor/github.com/moby/moby/client/service_logs.go @@ -0,0 +1,57 @@ +package client + +import ( + "context" + "fmt" + "io" + "net/url" + "time" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client/internal/timestamp" +) + +// ServiceLogs returns the logs generated by a service in an [io.ReadCloser]. +// It's up to the caller to close the stream. +func (cli *Client) ServiceLogs(ctx context.Context, serviceID string, options container.LogsOptions) (io.ReadCloser, error) { + serviceID, err := trimID("service", serviceID) + if err != nil { + return nil, err + } + + query := url.Values{} + if options.ShowStdout { + query.Set("stdout", "1") + } + + if options.ShowStderr { + query.Set("stderr", "1") + } + + if options.Since != "" { + ts, err := timestamp.GetTimestamp(options.Since, time.Now()) + if err != nil { + return nil, fmt.Errorf(`invalid value for "since": %w`, err) + } + query.Set("since", ts) + } + + if options.Timestamps { + query.Set("timestamps", "1") + } + + if options.Details { + query.Set("details", "1") + } + + if options.Follow { + query.Set("follow", "1") + } + query.Set("tail", options.Tail) + + resp, err := cli.get(ctx, "/services/"+serviceID+"/logs", query, nil) + if err != nil { + return nil, err + } + return resp.Body, nil +} diff --git a/vendor/github.com/moby/moby/client/service_remove.go b/vendor/github.com/moby/moby/client/service_remove.go new file mode 100644 index 000000000000..0c7cc571e0c4 --- /dev/null +++ b/vendor/github.com/moby/moby/client/service_remove.go @@ -0,0 +1,15 @@ +package client + +import "context" + +// ServiceRemove kills and removes a service. +func (cli *Client) ServiceRemove(ctx context.Context, serviceID string) error { + serviceID, err := trimID("service", serviceID) + if err != nil { + return err + } + + resp, err := cli.delete(ctx, "/services/"+serviceID, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/service_update.go b/vendor/github.com/moby/moby/client/service_update.go new file mode 100644 index 000000000000..159d393ad59d --- /dev/null +++ b/vendor/github.com/moby/moby/client/service_update.go @@ -0,0 +1,90 @@ +package client + +import ( + "context" + "encoding/json" + "net/http" + "net/url" + + "github.com/moby/moby/api/types/registry" + "github.com/moby/moby/api/types/swarm" + "github.com/moby/moby/api/types/versions" +) + +// ServiceUpdate updates a Service. The version number is required to avoid +// conflicting writes. It must be the value as set *before* the update. +// You can find this value in the [swarm.Service.Meta] field, which can +// be found using [Client.ServiceInspectWithRaw]. +func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) { + serviceID, err := trimID("service", serviceID) + if err != nil { + return swarm.ServiceUpdateResponse{}, err + } + + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + return swarm.ServiceUpdateResponse{}, err + } + + query := url.Values{} + if options.RegistryAuthFrom != "" { + query.Set("registryAuthFrom", options.RegistryAuthFrom) + } + + if options.Rollback != "" { + query.Set("rollback", options.Rollback) + } + + query.Set("version", version.String()) + + if err := validateServiceSpec(service); err != nil { + return swarm.ServiceUpdateResponse{}, err + } + + // ensure that the image is tagged + var resolveWarning string + switch { + case service.TaskTemplate.ContainerSpec != nil: + if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" { + service.TaskTemplate.ContainerSpec.Image = taggedImg + } + if options.QueryRegistry { + resolveWarning = resolveContainerSpecImage(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth) + } + case service.TaskTemplate.PluginSpec != nil: + if taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != "" { + service.TaskTemplate.PluginSpec.Remote = taggedImg + } + if options.QueryRegistry { + resolveWarning = resolvePluginSpecRemote(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth) + } + } + + headers := http.Header{} + if versions.LessThan(cli.version, "1.30") { + // the custom "version" header was used by engine API before 20.10 + // (API 1.30) to switch between client- and server-side lookup of + // image digests. + headers["version"] = []string{cli.version} + } + if options.EncodedRegistryAuth != "" { + headers.Set(registry.AuthHeader, options.EncodedRegistryAuth) + } + resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, service, headers) + defer ensureReaderClosed(resp) + if err != nil { + return swarm.ServiceUpdateResponse{}, err + } + + var response swarm.ServiceUpdateResponse + err = json.NewDecoder(resp.Body).Decode(&response) + if resolveWarning != "" { + response.Warnings = append(response.Warnings, resolveWarning) + } + + return response, err +} diff --git a/vendor/github.com/moby/moby/client/swarm_get_unlock_key.go b/vendor/github.com/moby/moby/client/swarm_get_unlock_key.go new file mode 100644 index 000000000000..9a41f0ac3197 --- /dev/null +++ b/vendor/github.com/moby/moby/client/swarm_get_unlock_key.go @@ -0,0 +1,21 @@ +package client + +import ( + "context" + "encoding/json" + + "github.com/moby/moby/api/types/swarm" +) + +// SwarmGetUnlockKey retrieves the swarm's unlock key. +func (cli *Client) SwarmGetUnlockKey(ctx context.Context) (swarm.UnlockKeyResponse, error) { + resp, err := cli.get(ctx, "/swarm/unlockkey", nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return swarm.UnlockKeyResponse{}, err + } + + var response swarm.UnlockKeyResponse + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} diff --git a/vendor/github.com/moby/moby/client/swarm_init.go b/vendor/github.com/moby/moby/client/swarm_init.go new file mode 100644 index 000000000000..a8d02a920f3b --- /dev/null +++ b/vendor/github.com/moby/moby/client/swarm_init.go @@ -0,0 +1,21 @@ +package client + +import ( + "context" + "encoding/json" + + "github.com/moby/moby/api/types/swarm" +) + +// SwarmInit initializes the swarm. +func (cli *Client) SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) { + resp, err := cli.post(ctx, "/swarm/init", nil, req, nil) + defer ensureReaderClosed(resp) + if err != nil { + return "", err + } + + var response string + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} diff --git a/vendor/github.com/moby/moby/client/swarm_inspect.go b/vendor/github.com/moby/moby/client/swarm_inspect.go new file mode 100644 index 000000000000..56e0ec42504b --- /dev/null +++ b/vendor/github.com/moby/moby/client/swarm_inspect.go @@ -0,0 +1,21 @@ +package client + +import ( + "context" + "encoding/json" + + "github.com/moby/moby/api/types/swarm" +) + +// SwarmInspect inspects the swarm. +func (cli *Client) SwarmInspect(ctx context.Context) (swarm.Swarm, error) { + resp, err := cli.get(ctx, "/swarm", nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return swarm.Swarm{}, err + } + + var response swarm.Swarm + err = json.NewDecoder(resp.Body).Decode(&response) + return response, err +} diff --git a/vendor/github.com/moby/moby/client/swarm_join.go b/vendor/github.com/moby/moby/client/swarm_join.go new file mode 100644 index 000000000000..7a9fa076d67f --- /dev/null +++ b/vendor/github.com/moby/moby/client/swarm_join.go @@ -0,0 +1,14 @@ +package client + +import ( + "context" + + "github.com/moby/moby/api/types/swarm" +) + +// SwarmJoin joins the swarm. +func (cli *Client) SwarmJoin(ctx context.Context, req swarm.JoinRequest) error { + resp, err := cli.post(ctx, "/swarm/join", nil, req, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/swarm_leave.go b/vendor/github.com/moby/moby/client/swarm_leave.go new file mode 100644 index 000000000000..fb0fe3b5d579 --- /dev/null +++ b/vendor/github.com/moby/moby/client/swarm_leave.go @@ -0,0 +1,17 @@ +package client + +import ( + "context" + "net/url" +) + +// SwarmLeave leaves the swarm. +func (cli *Client) SwarmLeave(ctx context.Context, force bool) error { + query := url.Values{} + if force { + query.Set("force", "1") + } + resp, err := cli.post(ctx, "/swarm/leave", query, nil, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/swarm_unlock.go b/vendor/github.com/moby/moby/client/swarm_unlock.go new file mode 100644 index 000000000000..5eb3d59399d1 --- /dev/null +++ b/vendor/github.com/moby/moby/client/swarm_unlock.go @@ -0,0 +1,14 @@ +package client + +import ( + "context" + + "github.com/moby/moby/api/types/swarm" +) + +// SwarmUnlock unlocks locked swarm. +func (cli *Client) SwarmUnlock(ctx context.Context, req swarm.UnlockRequest) error { + resp, err := cli.post(ctx, "/swarm/unlock", nil, req, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/swarm_update.go b/vendor/github.com/moby/moby/client/swarm_update.go new file mode 100644 index 000000000000..fc95ac6c3a12 --- /dev/null +++ b/vendor/github.com/moby/moby/client/swarm_update.go @@ -0,0 +1,21 @@ +package client + +import ( + "context" + "net/url" + "strconv" + + "github.com/moby/moby/api/types/swarm" +) + +// SwarmUpdate updates the swarm. +func (cli *Client) SwarmUpdate(ctx context.Context, version swarm.Version, swarm swarm.Spec, flags swarm.UpdateFlags) error { + query := url.Values{} + query.Set("version", version.String()) + query.Set("rotateWorkerToken", strconv.FormatBool(flags.RotateWorkerToken)) + query.Set("rotateManagerToken", strconv.FormatBool(flags.RotateManagerToken)) + query.Set("rotateManagerUnlockKey", strconv.FormatBool(flags.RotateManagerUnlockKey)) + resp, err := cli.post(ctx, "/swarm/update", query, swarm, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/system_disk_usage.go b/vendor/github.com/moby/moby/client/system_disk_usage.go new file mode 100644 index 000000000000..a26ad99d82d8 --- /dev/null +++ b/vendor/github.com/moby/moby/client/system_disk_usage.go @@ -0,0 +1,33 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + "net/url" + + "github.com/moby/moby/api/types/system" +) + +// DiskUsage requests the current data usage from the daemon +func (cli *Client) DiskUsage(ctx context.Context, options system.DiskUsageOptions) (system.DiskUsage, error) { + var query url.Values + if len(options.Types) > 0 { + query = url.Values{} + for _, t := range options.Types { + query.Add("type", string(t)) + } + } + + resp, err := cli.get(ctx, "/system/df", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return system.DiskUsage{}, err + } + + var du system.DiskUsage + if err := json.NewDecoder(resp.Body).Decode(&du); err != nil { + return system.DiskUsage{}, fmt.Errorf("Error retrieving disk usage: %v", err) + } + return du, nil +} diff --git a/vendor/github.com/moby/moby/client/system_events.go b/vendor/github.com/moby/moby/client/system_events.go new file mode 100644 index 000000000000..473c147b9c0f --- /dev/null +++ b/vendor/github.com/moby/moby/client/system_events.go @@ -0,0 +1,117 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + "time" + + "github.com/moby/moby/api/types/events" + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/versions" + "github.com/moby/moby/client/internal/timestamp" +) + +// Events returns a stream of events in the daemon. It's up to the caller to close the stream +// by cancelling the context. Once the stream has been completely read an [io.EOF] error is +// sent over the error channel. If an error is sent, all processing is stopped. It's up +// to the caller to reopen the stream in the event of an error by reinvoking this method. +func (cli *Client) Events(ctx context.Context, options events.ListOptions) (<-chan events.Message, <-chan error) { + messages := make(chan events.Message) + errs := make(chan error, 1) + + started := make(chan struct{}) + go func() { + defer close(errs) + + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + close(started) + errs <- err + return + } + query, err := buildEventsQueryParams(cli.version, options) + if err != nil { + close(started) + errs <- err + return + } + + resp, err := cli.get(ctx, "/events", query, nil) + if err != nil { + close(started) + errs <- err + return + } + defer resp.Body.Close() + + decoder := json.NewDecoder(resp.Body) + + close(started) + for { + select { + case <-ctx.Done(): + errs <- ctx.Err() + return + default: + var event events.Message + if err := decoder.Decode(&event); err != nil { + errs <- err + return + } + + select { + case messages <- event: + case <-ctx.Done(): + errs <- ctx.Err() + return + } + } + } + }() + <-started + + return messages, errs +} + +func buildEventsQueryParams(cliVersion string, options events.ListOptions) (url.Values, error) { + query := url.Values{} + ref := time.Now() + + if options.Since != "" { + ts, err := timestamp.GetTimestamp(options.Since, ref) + if err != nil { + return nil, err + } + query.Set("since", ts) + } + + if options.Until != "" { + ts, err := timestamp.GetTimestamp(options.Until, ref) + if err != nil { + return nil, err + } + query.Set("until", ts) + } + + if options.Filters.Len() > 0 { + filterJSON, err := filters.ToJSON(options.Filters) + if err != nil { + return nil, err + } + if cliVersion != "" && versions.LessThan(cliVersion, "1.22") { + legacyFormat, err := encodeLegacyFilters(filterJSON) + if err != nil { + return nil, err + } + filterJSON = legacyFormat + } + query.Set("filters", filterJSON) + } + + return query, nil +} diff --git a/vendor/github.com/moby/moby/client/system_info.go b/vendor/github.com/moby/moby/client/system_info.go new file mode 100644 index 000000000000..865cd35eee28 --- /dev/null +++ b/vendor/github.com/moby/moby/client/system_info.go @@ -0,0 +1,26 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + "net/url" + + "github.com/moby/moby/api/types/system" +) + +// Info returns information about the docker server. +func (cli *Client) Info(ctx context.Context) (system.Info, error) { + var info system.Info + resp, err := cli.get(ctx, "/info", url.Values{}, nil) + defer ensureReaderClosed(resp) + if err != nil { + return info, err + } + + if err := json.NewDecoder(resp.Body).Decode(&info); err != nil { + return info, fmt.Errorf("Error reading remote info: %v", err) + } + + return info, nil +} diff --git a/vendor/github.com/moby/moby/client/task_inspect.go b/vendor/github.com/moby/moby/client/task_inspect.go new file mode 100644 index 000000000000..f38392d4e66d --- /dev/null +++ b/vendor/github.com/moby/moby/client/task_inspect.go @@ -0,0 +1,34 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "io" + + "github.com/moby/moby/api/types/swarm" +) + +// TaskInspectWithRaw returns the task information and its raw representation. +func (cli *Client) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) { + taskID, err := trimID("task", taskID) + if err != nil { + return swarm.Task{}, nil, err + } + + resp, err := cli.get(ctx, "/tasks/"+taskID, nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return swarm.Task{}, nil, err + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return swarm.Task{}, nil, err + } + + var response swarm.Task + rdr := bytes.NewReader(body) + err = json.NewDecoder(rdr).Decode(&response) + return response, body, err +} diff --git a/vendor/github.com/moby/moby/client/task_list.go b/vendor/github.com/moby/moby/client/task_list.go new file mode 100644 index 000000000000..b0e612cfca83 --- /dev/null +++ b/vendor/github.com/moby/moby/client/task_list.go @@ -0,0 +1,34 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/swarm" +) + +// TaskList returns the list of tasks. +func (cli *Client) TaskList(ctx context.Context, options swarm.TaskListOptions) ([]swarm.Task, error) { + query := url.Values{} + + if options.Filters.Len() > 0 { + filterJSON, err := filters.ToJSON(options.Filters) + if err != nil { + return nil, err + } + + query.Set("filters", filterJSON) + } + + resp, err := cli.get(ctx, "/tasks", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return nil, err + } + + var tasks []swarm.Task + err = json.NewDecoder(resp.Body).Decode(&tasks) + return tasks, err +} diff --git a/vendor/github.com/moby/moby/client/task_logs.go b/vendor/github.com/moby/moby/client/task_logs.go new file mode 100644 index 000000000000..3b6c31c1733f --- /dev/null +++ b/vendor/github.com/moby/moby/client/task_logs.go @@ -0,0 +1,51 @@ +package client + +import ( + "context" + "io" + "net/url" + "time" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client/internal/timestamp" +) + +// TaskLogs returns the logs generated by a task in an [io.ReadCloser]. +// It's up to the caller to close the stream. +func (cli *Client) TaskLogs(ctx context.Context, taskID string, options container.LogsOptions) (io.ReadCloser, error) { + query := url.Values{} + if options.ShowStdout { + query.Set("stdout", "1") + } + + if options.ShowStderr { + query.Set("stderr", "1") + } + + if options.Since != "" { + ts, err := timestamp.GetTimestamp(options.Since, time.Now()) + if err != nil { + return nil, err + } + query.Set("since", ts) + } + + if options.Timestamps { + query.Set("timestamps", "1") + } + + if options.Details { + query.Set("details", "1") + } + + if options.Follow { + query.Set("follow", "1") + } + query.Set("tail", options.Tail) + + resp, err := cli.get(ctx, "/tasks/"+taskID+"/logs", query, nil) + if err != nil { + return nil, err + } + return resp.Body, nil +} diff --git a/vendor/github.com/moby/moby/client/utils.go b/vendor/github.com/moby/moby/client/utils.go new file mode 100644 index 000000000000..8f99284c5a8a --- /dev/null +++ b/vendor/github.com/moby/moby/client/utils.go @@ -0,0 +1,121 @@ +package client + +import ( + "encoding/json" + "fmt" + "net/url" + "strings" + + cerrdefs "github.com/containerd/errdefs" + "github.com/moby/moby/api/types/filters" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +type emptyIDError string + +func (e emptyIDError) InvalidParameter() {} + +func (e emptyIDError) Error() string { + return "invalid " + string(e) + " name or ID: value is empty" +} + +// trimID trims the given object-ID / name, returning an error if it's empty. +func trimID(objType, id string) (string, error) { + id = strings.TrimSpace(id) + if id == "" { + return "", emptyIDError(objType) + } + return id, nil +} + +// getFiltersQuery returns a url query with "filters" query term, based on the +// filters provided. +func getFiltersQuery(f filters.Args) (url.Values, error) { + query := url.Values{} + if f.Len() > 0 { + filterJSON, err := filters.ToJSON(f) + if err != nil { + return query, err + } + query.Set("filters", filterJSON) + } + 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 "", fmt.Errorf("%w: invalid platform: %v", cerrdefs.ErrInvalidArgument, err) + } + return string(p), nil +} + +// encodeLegacyFilters encodes Args in the legacy format as used in API v1.21 and older. +// where values are a list of strings, instead of a set. +// +// Don't use in any new code; use [filters.ToJSON]] instead. +func encodeLegacyFilters(currentFormat string) (string, error) { + // The Args.fields field is not exported, but used to marshal JSON, + // so we'll marshal to the new format, then unmarshal to get the + // fields, and marshal again. + // + // This is far from optimal, but this code is only used for deprecated + // API versions, so should not be hit commonly. + var argsFields map[string]map[string]bool + err := json.Unmarshal([]byte(currentFormat), &argsFields) + if err != nil { + return "", err + } + + buf, err := json.Marshal(convertArgsToSlice(argsFields)) + if err != nil { + return "", err + } + return string(buf), nil +} + +func convertArgsToSlice(f map[string]map[string]bool) map[string][]string { + m := map[string][]string{} + for k, v := range f { + values := []string{} + for kk := range v { + if v[kk] { + values = append(values, kk) + } + } + m[k] = values + } + return m +} diff --git a/vendor/github.com/moby/moby/client/version.go b/vendor/github.com/moby/moby/client/version.go new file mode 100644 index 000000000000..46c70b8ad584 --- /dev/null +++ b/vendor/github.com/moby/moby/client/version.go @@ -0,0 +1,21 @@ +package client + +import ( + "context" + "encoding/json" + + "github.com/moby/moby/api/types" +) + +// ServerVersion returns information of the docker client and server host. +func (cli *Client) ServerVersion(ctx context.Context) (types.Version, error) { + resp, err := cli.get(ctx, "/version", nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return types.Version{}, err + } + + var server types.Version + err = json.NewDecoder(resp.Body).Decode(&server) + return server, err +} diff --git a/vendor/github.com/moby/moby/client/volume_create.go b/vendor/github.com/moby/moby/client/volume_create.go new file mode 100644 index 000000000000..dcbd453c5725 --- /dev/null +++ b/vendor/github.com/moby/moby/client/volume_create.go @@ -0,0 +1,21 @@ +package client + +import ( + "context" + "encoding/json" + + "github.com/moby/moby/api/types/volume" +) + +// VolumeCreate creates a volume in the docker host. +func (cli *Client) VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error) { + resp, err := cli.post(ctx, "/volumes/create", nil, options, nil) + defer ensureReaderClosed(resp) + if err != nil { + return volume.Volume{}, err + } + + var vol volume.Volume + err = json.NewDecoder(resp.Body).Decode(&vol) + return vol, err +} diff --git a/vendor/github.com/moby/moby/client/volume_inspect.go b/vendor/github.com/moby/moby/client/volume_inspect.go new file mode 100644 index 000000000000..f763bdbf66b6 --- /dev/null +++ b/vendor/github.com/moby/moby/client/volume_inspect.go @@ -0,0 +1,40 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "io" + + "github.com/moby/moby/api/types/volume" +) + +// VolumeInspect returns the information about a specific volume in the docker host. +func (cli *Client) VolumeInspect(ctx context.Context, volumeID string) (volume.Volume, error) { + vol, _, err := cli.VolumeInspectWithRaw(ctx, volumeID) + return vol, err +} + +// VolumeInspectWithRaw returns the information about a specific volume in the docker host and its raw representation +func (cli *Client) VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error) { + volumeID, err := trimID("volume", volumeID) + if err != nil { + return volume.Volume{}, nil, err + } + + resp, err := cli.get(ctx, "/volumes/"+volumeID, nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return volume.Volume{}, nil, err + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return volume.Volume{}, nil, err + } + + var vol volume.Volume + rdr := bytes.NewReader(body) + err = json.NewDecoder(rdr).Decode(&vol) + return vol, body, err +} diff --git a/vendor/github.com/moby/moby/client/volume_list.go b/vendor/github.com/moby/moby/client/volume_list.go new file mode 100644 index 000000000000..656dfb05dea0 --- /dev/null +++ b/vendor/github.com/moby/moby/client/volume_list.go @@ -0,0 +1,40 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/versions" + "github.com/moby/moby/api/types/volume" +) + +// VolumeList returns the volumes configured in the docker host. +func (cli *Client) VolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error) { + query := url.Values{} + + if options.Filters.Len() > 0 { + filterJSON, err := filters.ToJSON(options.Filters) + if err != nil { + return volume.ListResponse{}, err + } + if cli.version != "" && versions.LessThan(cli.version, "1.22") { + legacyFormat, err := encodeLegacyFilters(filterJSON) + if err != nil { + return volume.ListResponse{}, err + } + filterJSON = legacyFormat + } + query.Set("filters", filterJSON) + } + resp, err := cli.get(ctx, "/volumes", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return volume.ListResponse{}, err + } + + var volumes volume.ListResponse + err = json.NewDecoder(resp.Body).Decode(&volumes) + return volumes, err +} diff --git a/vendor/github.com/moby/moby/client/volume_prune.go b/vendor/github.com/moby/moby/client/volume_prune.go new file mode 100644 index 000000000000..aee6de98ab8a --- /dev/null +++ b/vendor/github.com/moby/moby/client/volume_prune.go @@ -0,0 +1,35 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/volume" +) + +// VolumesPrune requests the daemon to delete unused data +func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters filters.Args) (volume.PruneReport, error) { + if err := cli.NewVersionError(ctx, "1.25", "volume prune"); err != nil { + return volume.PruneReport{}, err + } + + query, err := getFiltersQuery(pruneFilters) + if err != nil { + return volume.PruneReport{}, err + } + + resp, err := cli.post(ctx, "/volumes/prune", query, nil, nil) + defer ensureReaderClosed(resp) + if err != nil { + return volume.PruneReport{}, err + } + + var report volume.PruneReport + if err := json.NewDecoder(resp.Body).Decode(&report); err != nil { + return volume.PruneReport{}, fmt.Errorf("Error retrieving volume prune report: %v", err) + } + + return report, nil +} diff --git a/vendor/github.com/moby/moby/client/volume_remove.go b/vendor/github.com/moby/moby/client/volume_remove.go new file mode 100644 index 000000000000..c165b22f4e2a --- /dev/null +++ b/vendor/github.com/moby/moby/client/volume_remove.go @@ -0,0 +1,34 @@ +package client + +import ( + "context" + "net/url" + + "github.com/moby/moby/api/types/versions" +) + +// VolumeRemove removes a volume from the docker host. +func (cli *Client) VolumeRemove(ctx context.Context, volumeID string, force bool) error { + volumeID, err := trimID("volume", volumeID) + if err != nil { + return err + } + + query := url.Values{} + if force { + // Make sure we negotiated (if the client is configured to do so), + // as code below contains API-version specific handling of options. + // + // Normally, version-negotiation (if enabled) would not happen until + // the API request is made. + if err := cli.checkVersion(ctx); err != nil { + return err + } + if versions.GreaterThanOrEqualTo(cli.version, "1.25") { + query.Set("force", "1") + } + } + resp, err := cli.delete(ctx, "/volumes/"+volumeID, query, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/github.com/moby/moby/client/volume_update.go b/vendor/github.com/moby/moby/client/volume_update.go new file mode 100644 index 000000000000..7094c9937e36 --- /dev/null +++ b/vendor/github.com/moby/moby/client/volume_update.go @@ -0,0 +1,28 @@ +package client + +import ( + "context" + "net/url" + + "github.com/moby/moby/api/types/swarm" + "github.com/moby/moby/api/types/volume" +) + +// VolumeUpdate updates a volume. This only works for Cluster Volumes, and +// only some fields can be updated. +func (cli *Client) VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error { + volumeID, err := trimID("volume", volumeID) + if err != nil { + return err + } + if err := cli.NewVersionError(ctx, "1.42", "volume update"); err != nil { + return err + } + + query := url.Values{} + query.Set("version", version.String()) + + resp, err := cli.put(ctx, "/volumes/"+volumeID, query, options, nil) + defer ensureReaderClosed(resp) + return err +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 8ccf406adc1f..4345774a871c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -65,7 +65,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 v28.3.3+incompatible +# github.com/docker/docker v28.3.3+incompatible => github.com/thaJeztah/docker v24.0.0-rc.1.0.20250821102143-9382f0e13085+incompatible ## explicit github.com/docker/docker/api github.com/docker/docker/api/types @@ -73,7 +73,6 @@ github.com/docker/docker/api/types/auxprogress github.com/docker/docker/api/types/blkiodev github.com/docker/docker/api/types/build github.com/docker/docker/api/types/checkpoint -github.com/docker/docker/api/types/common github.com/docker/docker/api/types/container github.com/docker/docker/api/types/events github.com/docker/docker/api/types/filters @@ -81,17 +80,12 @@ 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 github.com/docker/docker/api/types/system github.com/docker/docker/api/types/time github.com/docker/docker/api/types/versions github.com/docker/docker/api/types/volume github.com/docker/docker/client -github.com/docker/docker/internal/lazyregexp -github.com/docker/docker/internal/multierror github.com/docker/docker/pkg/jsonmessage github.com/docker/docker/pkg/progress github.com/docker/docker/pkg/stdcopy @@ -103,7 +97,7 @@ github.com/docker/docker-credential-helpers/credentials # github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c ## explicit github.com/docker/go/canonical/json -# github.com/docker/go-connections v0.5.0 +# github.com/docker/go-connections v0.6.0 ## explicit; go 1.18 github.com/docker/go-connections/nat github.com/docker/go-connections/sockets @@ -199,6 +193,34 @@ github.com/moby/docker-image-spec/specs-go/v1 github.com/moby/go-archive github.com/moby/go-archive/compression github.com/moby/go-archive/tarheader +# github.com/moby/moby/api v1.52.0-alpha.1 => github.com/moby/moby/api v1.52.0-alpha.1.0.20250820163354-c8c4996ebfdf +## explicit; go 1.23.0 +github.com/moby/moby/api/pkg/progress +github.com/moby/moby/api/pkg/stdcopy +github.com/moby/moby/api/types +github.com/moby/moby/api/types/auxprogress +github.com/moby/moby/api/types/blkiodev +github.com/moby/moby/api/types/build +github.com/moby/moby/api/types/checkpoint +github.com/moby/moby/api/types/common +github.com/moby/moby/api/types/container +github.com/moby/moby/api/types/events +github.com/moby/moby/api/types/filters +github.com/moby/moby/api/types/image +github.com/moby/moby/api/types/jsonstream +github.com/moby/moby/api/types/mount +github.com/moby/moby/api/types/network +github.com/moby/moby/api/types/plugin +github.com/moby/moby/api/types/registry +github.com/moby/moby/api/types/storage +github.com/moby/moby/api/types/swarm +github.com/moby/moby/api/types/system +github.com/moby/moby/api/types/versions +github.com/moby/moby/api/types/volume +# github.com/moby/moby/client v0.0.0-00010101000000-000000000000 => github.com/moby/moby/client v0.1.0-alpha.0.0.20250820163354-c8c4996ebfdf +## explicit; go 1.23.0 +github.com/moby/moby/client +github.com/moby/moby/client/internal/timestamp # github.com/moby/patternmatcher v0.6.0 ## explicit; go 1.19 github.com/moby/patternmatcher @@ -571,3 +593,6 @@ gotest.tools/v3/skip # tags.cncf.io/container-device-interface v0.8.0 ## explicit; go 1.20 tags.cncf.io/container-device-interface/pkg/parser +# github.com/docker/docker => github.com/thaJeztah/docker v24.0.0-rc.1.0.20250821102143-9382f0e13085+incompatible +# github.com/moby/moby/api => github.com/moby/moby/api v1.52.0-alpha.1.0.20250820163354-c8c4996ebfdf +# github.com/moby/moby/client => github.com/moby/moby/client v0.1.0-alpha.0.0.20250820163354-c8c4996ebfdf