diff --git a/go.mod b/go.mod index 1da8789b..a9a5cb90 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/cenkalti/backoff/v5 v5.0.3 github.com/containerd/platforms v0.2.1 github.com/mholt/archives v0.1.5 - github.com/moby/moby/client v0.4.1 + github.com/moby/moby/client v0.6.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.1 github.com/pkg/errors v0.9.1 @@ -71,7 +71,7 @@ require ( github.com/minio/minlz v1.0.1 // indirect github.com/mistifyio/go-zfs/v4 v4.0.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/moby/api v1.54.2 // indirect + github.com/moby/moby/api v1.56.0 // indirect github.com/moby/sys/capability v0.4.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect github.com/moby/sys/user v0.4.0 // indirect diff --git a/go.sum b/go.sum index 21f600d0..643c85ac 100644 --- a/go.sum +++ b/go.sum @@ -192,10 +192,10 @@ github.com/mistifyio/go-zfs/v4 v4.0.0 h1:sU0+5dX45tdDK5xNZ3HBi95nxUc48FS92qbIZEv github.com/mistifyio/go-zfs/v4 v4.0.0/go.mod h1:weotFtXTHvBwhr9Mv96KYnDkTPBOHFUbm9cBmQpesL0= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg= -github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= -github.com/moby/moby/client v0.4.1 h1:DMQgisVoMkmMs7fp3ROSdiBnoAu8+vo3GggFl06M/wY= -github.com/moby/moby/client v0.4.1/go.mod h1:z52C9O2POPOsnxZAy//WtKcQ32P+jT/NGeXu/7nfjGQ= +github.com/moby/moby/api v1.56.0 h1:GQzua3NA599ASSIICx0iFgiJeO9YkdDARvQsm23ZZuQ= +github.com/moby/moby/api v1.56.0/go.mod h1:sZ+THbVWkjOmBPPfbnzdD/G1LuIexWhqlSHHPTDQ1Uk= +github.com/moby/moby/client v0.6.0 h1:AJjEB21QPbXSXjDsZorFBoDZPhMrfbpaPLgSMAW9Bgs= +github.com/moby/moby/client v0.6.0/go.mod h1:OCo00wNRyA3m4lmJ228W3JbyCN4ZNNYjpOXiJydBdcQ= github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk= github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= diff --git a/vendor/github.com/moby/moby/api/types/container/hostconfig.go b/vendor/github.com/moby/moby/api/types/container/hostconfig.go index 0f889c65..297ebc35 100644 --- a/vendor/github.com/moby/moby/api/types/container/hostconfig.go +++ b/vendor/github.com/moby/moby/api/types/container/hostconfig.go @@ -454,6 +454,7 @@ type HostConfig struct { ShmSize int64 // Total shm memory usage Sysctls map[string]string `json:",omitempty"` // List of Namespaced sysctls used for the container Runtime string `json:",omitempty"` // Runtime to use with this container + Umask *uint32 `json:",omitempty"` // Initial process umask // Applicable to Windows Isolation Isolation // Isolation technology of the container (e.g. default, hyperv) diff --git a/vendor/github.com/moby/moby/api/types/image/attestation.go b/vendor/github.com/moby/moby/api/types/image/attestation.go new file mode 100644 index 00000000..4233d683 --- /dev/null +++ b/vendor/github.com/moby/moby/api/types/image/attestation.go @@ -0,0 +1,19 @@ +package image + +import ( + "encoding/json" + + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +// AttestationStatement is a single in-toto statement attached to an image. +type AttestationStatement struct { + // Descriptor is the OCI descriptor of the statement blob (media type, + // digest, size, annotations). + Descriptor ocispec.Descriptor `json:"Descriptor"` + // PredicateType is the in-toto predicate type URI of this statement. + PredicateType string `json:"PredicateType"` + // Statement is the verbatim in-toto statement JSON. Omitted unless the + // caller opts in via the statement=true query parameter. + Statement *json.RawMessage `json:"Statement,omitempty"` +} diff --git a/vendor/github.com/moby/moby/api/types/image/image_inspect.go b/vendor/github.com/moby/moby/api/types/image/image_inspect.go index df09c951..90ebfd89 100644 --- a/vendor/github.com/moby/moby/api/types/image/image_inspect.go +++ b/vendor/github.com/moby/moby/api/types/image/image_inspect.go @@ -72,7 +72,11 @@ type InspectResponse struct { // run on (especially for Windows). OsVersion string `json:",omitempty"` - // Size is the total size of the image including all layers it is composed of. + // Size is the total size of the selected image variant, including all layers + // it is composed of. + // + // When using the containerd image store, this includes both the image content + // that's present locally and the unpacked snapshot data. Size int64 // GraphDriver holds information about the storage driver used to store the 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 index 91b327eb..f4b22430 100644 --- a/vendor/github.com/moby/moby/api/types/plugin/plugin_responses.go +++ b/vendor/github.com/moby/moby/api/types/plugin/plugin_responses.go @@ -1,9 +1,5 @@ package plugin -import ( - "sort" -) - // ListResponse contains the response for the Engine API type ListResponse []Plugin @@ -15,19 +11,26 @@ type Privilege struct { Value []string } -// Privileges is a list of Privilege +// Privileges is a list of Privilege. type Privileges []Privilege +// Len implements [sort.Interface]. +// +// Deprecated: use [slices.SortFunc] to sort privileges instead. func (s Privileges) Len() int { return len(s) } +// Less implements [sort.Interface]. +// +// Deprecated: use [slices.SortFunc] to sort privileges instead. func (s Privileges) Less(i, j int) bool { return s[i].Name < s[j].Name } +// Swap implements [sort.Interface]. +// +// Deprecated: use [slices.SortFunc] to sort privileges instead. 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/moby/moby/client/README.md b/vendor/github.com/moby/moby/client/README.md index aed3e641..ebe29495 100644 --- a/vendor/github.com/moby/moby/client/README.md +++ b/vendor/github.com/moby/moby/client/README.md @@ -2,7 +2,6 @@ [![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) diff --git a/vendor/github.com/moby/moby/client/checkpoint_create.go b/vendor/github.com/moby/moby/client/checkpoint_create.go index b3ba5459..46867643 100644 --- a/vendor/github.com/moby/moby/client/checkpoint_create.go +++ b/vendor/github.com/moby/moby/client/checkpoint_create.go @@ -24,13 +24,11 @@ func (cli *Client) CheckpointCreate(ctx context.Context, containerID string, opt if err != nil { return CheckpointCreateResult{}, err } - requestBody := checkpoint.CreateRequest{ + resp, err := cli.post(ctx, "/containers/"+containerID+"/checkpoints", nil, nil, checkpoint.CreateRequest{ CheckpointID: options.CheckpointID, CheckpointDir: options.CheckpointDir, Exit: options.Exit, - } - - resp, err := cli.post(ctx, "/containers/"+containerID+"/checkpoints", nil, requestBody, nil) + }) defer ensureReaderClosed(resp) return CheckpointCreateResult{}, err } diff --git a/vendor/github.com/moby/moby/client/client.go b/vendor/github.com/moby/moby/client/client.go index 89ba88ee..3dbcacde 100644 --- a/vendor/github.com/moby/moby/client/client.go +++ b/vendor/github.com/moby/moby/client/client.go @@ -109,7 +109,7 @@ const DummyHost = "api.moby.localhost" // overriding the version and disable API-version negotiation. // // This version may be lower than the version of the api library module used. -const MaxAPIVersion = "1.54" +const MaxAPIVersion = "1.56" // MinAPIVersion is the minimum API version supported by the client. API versions // below this version are not considered when performing API-version negotiation. diff --git a/vendor/github.com/moby/moby/client/client_interfaces.go b/vendor/github.com/moby/moby/client/client_interfaces.go index 4bbd45a6..fd1b9dac 100644 --- a/vendor/github.com/moby/moby/client/client_interfaces.go +++ b/vendor/github.com/moby/moby/client/client_interfaces.go @@ -133,6 +133,7 @@ type ImageAPIClient interface { ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (ImageInspectResult, error) ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) (ImageHistoryResult, error) + ImageAttestations(ctx context.Context, image string, _ ...ImageAttestationsOption) (ImageAttestationsResult, error) ImageLoad(ctx context.Context, input io.Reader, _ ...ImageLoadOption) (ImageLoadResult, error) ImageSave(ctx context.Context, images []string, _ ...ImageSaveOption) (ImageSaveResult, error) diff --git a/vendor/github.com/moby/moby/client/config_create.go b/vendor/github.com/moby/moby/client/config_create.go index 874e2c94..3c37ea9e 100644 --- a/vendor/github.com/moby/moby/client/config_create.go +++ b/vendor/github.com/moby/moby/client/config_create.go @@ -19,7 +19,7 @@ type ConfigCreateResult struct { // ConfigCreate creates a new config. func (cli *Client) ConfigCreate(ctx context.Context, options ConfigCreateOptions) (ConfigCreateResult, error) { - resp, err := cli.post(ctx, "/configs/create", nil, options.Spec, nil) + resp, err := cli.post(ctx, "/configs/create", nil, nil, options.Spec) defer ensureReaderClosed(resp) if err != nil { return ConfigCreateResult{}, err diff --git a/vendor/github.com/moby/moby/client/config_update.go b/vendor/github.com/moby/moby/client/config_update.go index 31bdd795..bfbac46d 100644 --- a/vendor/github.com/moby/moby/client/config_update.go +++ b/vendor/github.com/moby/moby/client/config_update.go @@ -24,7 +24,7 @@ func (cli *Client) ConfigUpdate(ctx context.Context, id string, options ConfigUp } query := url.Values{} query.Set("version", options.Version.String()) - resp, err := cli.post(ctx, "/configs/"+id+"/update", query, options.Spec, nil) + resp, err := cli.post(ctx, "/configs/"+id+"/update", query, nil, options.Spec) defer ensureReaderClosed(resp) if err != nil { return ConfigUpdateResult{}, err diff --git a/vendor/github.com/moby/moby/client/container_commit.go b/vendor/github.com/moby/moby/client/container_commit.go index 79da44a5..47981bec 100644 --- a/vendor/github.com/moby/moby/client/container_commit.go +++ b/vendor/github.com/moby/moby/client/container_commit.go @@ -31,8 +31,9 @@ func (cli *Client) ContainerCommit(ctx context.Context, containerID string, opti if err != nil { return ContainerCommitResult{}, err } + query := url.Values{} + query.Set("container", containerID) - var repository, tag string if options.Reference != "" { ref, err := reference.ParseNormalizedNamed(options.Reference) if err != nil { @@ -44,18 +45,18 @@ func (cli *Client) ContainerCommit(ctx context.Context, containerID string, opti } ref = reference.TagNameOnly(ref) + query.Set("repo", ref.Name()) if tagged, ok := ref.(reference.Tagged); ok { - tag = tagged.Tag() + query.Set("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) + if options.Comment != "" { + query.Set("comment", options.Comment) + } + if options.Author != "" { + query.Set("author", options.Author) + } for _, change := range options.Changes { query.Add("changes", change) } @@ -64,7 +65,7 @@ func (cli *Client) ContainerCommit(ctx context.Context, containerID string, opti } var response container.CommitResponse - resp, err := cli.post(ctx, "/commit", query, options.Config, nil) + resp, err := cli.post(ctx, "/commit", query, nil, options.Config) defer ensureReaderClosed(resp) if err != nil { return ContainerCommitResult{}, err diff --git a/vendor/github.com/moby/moby/client/container_copy.go b/vendor/github.com/moby/moby/client/container_copy.go index b37d1765..b91babd3 100644 --- a/vendor/github.com/moby/moby/client/container_copy.go +++ b/vendor/github.com/moby/moby/client/container_copy.go @@ -77,7 +77,7 @@ func (cli *Client) CopyToContainer(ctx context.Context, containerID string, opti query.Set("copyUIDGID", "true") } - response, err := cli.putRaw(ctx, "/containers/"+containerID+"/archive", query, options.Content, nil) + response, err := cli.putRaw(ctx, "/containers/"+containerID+"/archive", query, nil, options.Content) defer ensureReaderClosed(response) if err != nil { return CopyToContainerResult{}, err diff --git a/vendor/github.com/moby/moby/client/container_create.go b/vendor/github.com/moby/moby/client/container_create.go index d941a372..7e6b15a9 100644 --- a/vendor/github.com/moby/moby/client/container_create.go +++ b/vendor/github.com/moby/moby/client/container_create.go @@ -5,7 +5,7 @@ import ( "encoding/json" "net/url" "path" - "sort" + "slices" "strings" cerrdefs "github.com/containerd/errdefs" @@ -35,13 +35,6 @@ func (cli *Client) ContainerCreate(ctx context.Context, options ContainerCreateO return ContainerCreateResult{}, cerrdefs.ErrInvalidArgument.WithMessage("config.Image or Image is required") } - var response container.CreateResponse - - if options.HostConfig != nil { - options.HostConfig.CapAdd = normalizeCapabilities(options.HostConfig.CapAdd) - options.HostConfig.CapDrop = normalizeCapabilities(options.HostConfig.CapDrop) - } - query := url.Values{} if options.Platform != nil { if p := formatPlatform(*options.Platform); p != "unknown" { @@ -53,18 +46,17 @@ func (cli *Client) ContainerCreate(ctx context.Context, options ContainerCreateO query.Set("name", options.Name) } - body := container.CreateRequest{ + resp, err := cli.post(ctx, "/containers/create", query, nil, container.CreateRequest{ Config: cfg, - HostConfig: options.HostConfig, + HostConfig: normalizeHostConfig(options.HostConfig), NetworkingConfig: options.NetworkingConfig, - } - - resp, err := cli.post(ctx, "/containers/create", query, body, nil) + }) defer ensureReaderClosed(resp) if err != nil { return ContainerCreateResult{}, err } + var response container.CreateResponse err = json.NewDecoder(resp.Body).Decode(&response) return ContainerCreateResult{ID: response.ID, Warnings: response.Warnings}, err } @@ -86,6 +78,17 @@ func formatPlatform(platform ocispec.Platform) string { // allCapabilities is a magic value for "all capabilities" const allCapabilities = "ALL" +// 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(c string) string { + c = strings.ToUpper(c) + if c != allCapabilities && !strings.HasPrefix(c, "CAP_") { + c = "CAP_" + c + } + return c +} + // normalizeCapabilities normalizes capabilities to their canonical form, // removes duplicates, and sorts the results. // @@ -94,32 +97,22 @@ const allCapabilities = "ALL" // // [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) + normalized := slices.Clone(caps) + for i, c := range normalized { + normalized[i] = normalizeCap(c) } - - sort.Strings(normalized) - return normalized + slices.Sort(normalized) + return slices.Compact(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 +// normalizeHostConfig returns a shallow copy of hostConfig with capabilities normalized. +func normalizeHostConfig(hostConfig *container.HostConfig) *container.HostConfig { + if hostConfig == nil { + return nil } - if !strings.HasPrefix(capability, "CAP_") { - capability = "CAP_" + capability - } - return capability + + normalized := *hostConfig + normalized.CapAdd = normalizeCapabilities(hostConfig.CapAdd) + normalized.CapDrop = normalizeCapabilities(hostConfig.CapDrop) + return &normalized } diff --git a/vendor/github.com/moby/moby/client/container_exec.go b/vendor/github.com/moby/moby/client/container_exec.go index 30ed00ea..86c9474b 100644 --- a/vendor/github.com/moby/moby/client/container_exec.go +++ b/vendor/github.com/moby/moby/client/container_exec.go @@ -42,7 +42,7 @@ func (cli *Client) ExecCreate(ctx context.Context, containerID string, options E return ExecCreateResult{}, err } - req := container.ExecCreateRequest{ + resp, err := cli.post(ctx, "/containers/"+containerID+"/exec", nil, nil, container.ExecCreateRequest{ User: options.User, Privileged: options.Privileged, Tty: options.TTY, @@ -54,9 +54,7 @@ func (cli *Client) ExecCreate(ctx context.Context, containerID string, options E Env: options.Env, WorkingDir: options.WorkingDir, Cmd: options.Cmd, - } - - resp, err := cli.post(ctx, "/containers/"+containerID+"/exec", nil, req, nil) + }) defer ensureReaderClosed(resp) if err != nil { return ExecCreateResult{}, err @@ -91,12 +89,11 @@ func (cli *Client) ExecStart(ctx context.Context, execID string, options ExecSta return ExecStartResult{}, err } - req := container.ExecStartRequest{ + resp, err := cli.post(ctx, "/exec/"+execID+"/start", nil, nil, container.ExecStartRequest{ Detach: options.Detach, Tty: options.TTY, ConsoleSize: consoleSize, - } - resp, err := cli.post(ctx, "/exec/"+execID+"/start", nil, req, nil) + }) defer ensureReaderClosed(resp) return ExecStartResult{}, err } diff --git a/vendor/github.com/moby/moby/client/container_restart.go b/vendor/github.com/moby/moby/client/container_restart.go index e883f758..df7ca4c7 100644 --- a/vendor/github.com/moby/moby/client/container_restart.go +++ b/vendor/github.com/moby/moby/client/container_restart.go @@ -16,7 +16,8 @@ type ContainerRestartOptions struct { // Timeout (optional) is the timeout (in seconds) to wait for the container // to stop gracefully before forcibly terminating it with SIGKILL. // - // - Use nil to use the default timeout (10 seconds). + // - Use nil to use the container's configured timeout, or the engine default + // if the container has no configured timeout. // - Use '-1' to wait indefinitely. // - Use '0' to not wait for the container to exit gracefully, and // immediately proceeds to forcibly terminating the container. diff --git a/vendor/github.com/moby/moby/client/container_stop.go b/vendor/github.com/moby/moby/client/container_stop.go index d4d47d8f..d72358c5 100644 --- a/vendor/github.com/moby/moby/client/container_stop.go +++ b/vendor/github.com/moby/moby/client/container_stop.go @@ -16,7 +16,8 @@ type ContainerStopOptions struct { // Timeout (optional) is the timeout (in seconds) to wait for the container // to stop gracefully before forcibly terminating it with SIGKILL. // - // - Use nil to use the default timeout (10 seconds). + // - Use nil to use the container's configured timeout, or the engine default + // if the container has no configured timeout. // - Use '-1' to wait indefinitely. // - Use '0' to not wait for the container to exit gracefully, and // immediately proceeds to forcibly terminating the container. diff --git a/vendor/github.com/moby/moby/client/container_update.go b/vendor/github.com/moby/moby/client/container_update.go index a1d4d249..197d8da4 100644 --- a/vendor/github.com/moby/moby/client/container_update.go +++ b/vendor/github.com/moby/moby/client/container_update.go @@ -26,15 +26,10 @@ func (cli *Client) ContainerUpdate(ctx context.Context, containerID string, opti return ContainerUpdateResult{}, err } - updateConfig := container.UpdateConfig{} - if options.Resources != nil { - updateConfig.Resources = *options.Resources - } - if options.RestartPolicy != nil { - updateConfig.RestartPolicy = *options.RestartPolicy - } - - resp, err := cli.post(ctx, "/containers/"+containerID+"/update", nil, updateConfig, nil) + resp, err := cli.post(ctx, "/containers/"+containerID+"/update", nil, nil, container.UpdateConfig{ + Resources: valueOrZero(options.Resources), + RestartPolicy: valueOrZero(options.RestartPolicy), + }) defer ensureReaderClosed(resp) if err != nil { return ContainerUpdateResult{}, err diff --git a/vendor/github.com/moby/moby/client/hijack.go b/vendor/github.com/moby/moby/client/hijack.go index 31c44e59..3b6b12c8 100644 --- a/vendor/github.com/moby/moby/client/hijack.go +++ b/vendor/github.com/moby/moby/client/hijack.go @@ -18,7 +18,7 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu if err != nil { return HijackedResponse{}, err } - req, err := cli.buildRequest(ctx, http.MethodPost, cli.getAPIPath(ctx, path, query), jsonBody, headers) + req, err := cli.buildRequest(ctx, http.MethodPost, cli.getAPIPath(ctx, path, query), headers, jsonBody) if err != nil { return HijackedResponse{}, err } diff --git a/vendor/github.com/moby/moby/client/image_attestations.go b/vendor/github.com/moby/moby/client/image_attestations.go new file mode 100644 index 00000000..c02d9751 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_attestations.go @@ -0,0 +1,51 @@ +package client + +import ( + "context" + "encoding/json" + "net/url" +) + +// ImageAttestations returns the in-toto attestation statements attached to an +// image for the given platform. This requires API version 1.55 or higher. +func (cli *Client) ImageAttestations(ctx context.Context, imageID string, opts ...ImageAttestationsOption) (ImageAttestationsResult, error) { + if imageID == "" { + return ImageAttestationsResult{}, objectNotFoundError{object: "image", id: imageID} + } + + if err := cli.requiresVersion(ctx, "1.55", "attestations"); err != nil { + return ImageAttestationsResult{}, err + } + + var o imageAttestationsOpts + for _, opt := range opts { + if err := opt.Apply(&o); err != nil { + return ImageAttestationsResult{}, err + } + } + + query := url.Values{} + if o.platform != nil { + p, err := encodePlatform(o.platform) + if err != nil { + return ImageAttestationsResult{}, err + } + query.Set("platform", p) + } + for _, pt := range o.predicateTypes { + query.Add("type", pt) + } + if o.includeStatement { + query.Set("statement", "1") + } + + resp, err := cli.get(ctx, "/images/"+imageID+"/attestations", query, nil) + defer ensureReaderClosed(resp) + if err != nil { + return ImageAttestationsResult{}, err + } + + var result ImageAttestationsResult + err = json.NewDecoder(resp.Body).Decode(&result.Items) + return result, err +} diff --git a/vendor/github.com/moby/moby/client/image_attestations_opts.go b/vendor/github.com/moby/moby/client/image_attestations_opts.go new file mode 100644 index 00000000..4a7c3bcf --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_attestations_opts.go @@ -0,0 +1,56 @@ +package client + +import ( + "github.com/moby/moby/api/types/image" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +// ImageAttestationsResult is the result of an ImageAttestations operation. +type ImageAttestationsResult struct { + Items []image.AttestationStatement +} + +// ImageAttestationsOption is a functional option for the ImageAttestations operation. +type ImageAttestationsOption interface { + Apply(*imageAttestationsOpts) error +} + +type imageAttestationsOptionFunc func(*imageAttestationsOpts) error + +func (f imageAttestationsOptionFunc) Apply(o *imageAttestationsOpts) error { return f(o) } + +type imageAttestationsOpts struct { + platform *ocispec.Platform + predicateTypes []string + includeStatement bool +} + +// ImageAttestationsWithPlatform filters attestations to those for the given +// platform variant. If omitted, the daemon's default platform is used. +func ImageAttestationsWithPlatform(platform ocispec.Platform) ImageAttestationsOption { + return imageAttestationsOptionFunc(func(o *imageAttestationsOpts) error { + o.platform = &platform + return nil + }) +} + +// ImageAttestationsWithPredicateTypes filters returned statements to those +// whose in-toto predicate type matches one of the given URIs. +// If not set, all statements are returned. +func ImageAttestationsWithPredicateTypes(types ...string) ImageAttestationsOption { + return imageAttestationsOptionFunc(func(o *imageAttestationsOpts) error { + o.predicateTypes = append(o.predicateTypes, types...) + return nil + }) +} + +// ImageAttestationsWithStatement asks the daemon to include the verbatim +// in-toto statement body in each returned entry. Without this option, only +// the descriptor and predicate type are returned and statement blobs are +// not read. +func ImageAttestationsWithStatement() ImageAttestationsOption { + return imageAttestationsOptionFunc(func(o *imageAttestationsOpts) error { + o.includeStatement = true + return nil + }) +} diff --git a/vendor/github.com/moby/moby/client/image_build.go b/vendor/github.com/moby/moby/client/image_build.go index 67ac204a..82ddc8ee 100644 --- a/vendor/github.com/moby/moby/client/image_build.go +++ b/vendor/github.com/moby/moby/client/image_build.go @@ -32,7 +32,7 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio 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) + resp, err := cli.postRaw(ctx, "/build", query, headers, buildContext) if err != nil { return ImageBuildResult{}, err } diff --git a/vendor/github.com/moby/moby/client/image_import.go b/vendor/github.com/moby/moby/client/image_import.go index 6c9f2286..66186f22 100644 --- a/vendor/github.com/moby/moby/client/image_import.go +++ b/vendor/github.com/moby/moby/client/image_import.go @@ -46,7 +46,7 @@ func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, re query.Add("changes", change) } - resp, err := cli.postRaw(ctx, "/images/create", query, source.Source, nil) + resp, err := cli.postRaw(ctx, "/images/create", query, nil, source.Source) if err != nil { return nil, err } diff --git a/vendor/github.com/moby/moby/client/image_load.go b/vendor/github.com/moby/moby/client/image_load.go index ec5fcae6..3edd491d 100644 --- a/vendor/github.com/moby/moby/client/image_load.go +++ b/vendor/github.com/moby/moby/client/image_load.go @@ -42,9 +42,8 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...I query["platform"] = p } - resp, err := cli.postRaw(ctx, "/images/load", query, input, http.Header{ - "Content-Type": {"application/x-tar"}, - }) + headers := http.Header{"Content-Type": {"application/x-tar"}} + resp, err := cli.postRaw(ctx, "/images/load", query, headers, input) if err != nil { return nil, err } diff --git a/vendor/github.com/moby/moby/client/image_pull.go b/vendor/github.com/moby/moby/client/image_pull.go index 11c0afa4..04d9edf1 100644 --- a/vendor/github.com/moby/moby/client/image_pull.go +++ b/vendor/github.com/moby/moby/client/image_pull.go @@ -89,5 +89,5 @@ func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, resolve hdr.Set(registry.AuthHeader, registryAuth) } } - return cli.post(ctx, "/images/create", query, nil, hdr) + return cli.post(ctx, "/images/create", query, hdr, nil) } diff --git a/vendor/github.com/moby/moby/client/image_push.go b/vendor/github.com/moby/moby/client/image_push.go index 5dd8bc14..d7729841 100644 --- a/vendor/github.com/moby/moby/client/image_push.go +++ b/vendor/github.com/moby/moby/client/image_push.go @@ -94,5 +94,5 @@ func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.V // 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) + return cli.post(ctx, "/images/"+imageID+"/push", query, hdr, http.NoBody) } diff --git a/vendor/github.com/moby/moby/client/internal/mod/mod.go b/vendor/github.com/moby/moby/client/internal/mod/mod.go index 355eb953..c9a11b3e 100644 --- a/vendor/github.com/moby/moby/client/internal/mod/mod.go +++ b/vendor/github.com/moby/moby/client/internal/mod/mod.go @@ -87,7 +87,7 @@ func getVersion(name string, dep *debug.Module) (string, bool) { func normalize(v string) string { base, metas, dirty := splitMetadata(v) - out := base + var out strings.Builder if base2, rev, undoPatch, ok := splitPseudo(base); ok { if undoPatch { // Downgrade the patch version that was raised by pseudo-versions: @@ -102,18 +102,22 @@ func normalize(v string) string { if len(rev) > 12 { rev = rev[:12] } - out = base2 + "+" + rev + out.WriteString(base2) + out.WriteByte('+') + out.WriteString(rev) + } else { + out.WriteString(base) } // Preserve other metadata (except for "+incompatible"). for _, m := range metas { - out += m + out.WriteString(m) } if dirty { // +dirty goes last - out += "+dirty" + out.WriteString("+dirty") } - return out + return out.String() } func splitMetadata(v string) (base string, metas []string, dirty bool) { diff --git a/vendor/github.com/moby/moby/client/login.go b/vendor/github.com/moby/moby/client/login.go index b295080a..9d9e5fad 100644 --- a/vendor/github.com/moby/moby/client/login.go +++ b/vendor/github.com/moby/moby/client/login.go @@ -32,7 +32,7 @@ func (cli *Client) RegistryLogin(ctx context.Context, options RegistryLoginOptio RegistryToken: options.RegistryToken, } - resp, err := cli.post(ctx, "/auth", url.Values{}, auth, nil) + resp, err := cli.post(ctx, "/auth", url.Values{}, nil, auth) defer ensureReaderClosed(resp) if err != nil { diff --git a/vendor/github.com/moby/moby/client/network_connect.go b/vendor/github.com/moby/moby/client/network_connect.go index 40db955a..1a5cd645 100644 --- a/vendor/github.com/moby/moby/client/network_connect.go +++ b/vendor/github.com/moby/moby/client/network_connect.go @@ -34,7 +34,7 @@ func (cli *Client) NetworkConnect(ctx context.Context, networkID string, options Container: containerID, EndpointConfig: options.EndpointConfig, } - resp, err := cli.post(ctx, "/networks/"+networkID+"/connect", nil, nc, nil) + resp, err := cli.post(ctx, "/networks/"+networkID+"/connect", nil, nil, nc) defer ensureReaderClosed(resp) return NetworkConnectResult{}, err } diff --git a/vendor/github.com/moby/moby/client/network_create.go b/vendor/github.com/moby/moby/client/network_create.go index 25ea32af..b5dae82b 100644 --- a/vendor/github.com/moby/moby/client/network_create.go +++ b/vendor/github.com/moby/moby/client/network_create.go @@ -51,7 +51,7 @@ func (cli *Client) NetworkCreate(ctx context.Context, name string, options Netwo req.ConfigFrom = &network.ConfigReference{Network: options.ConfigFrom} } - resp, err := cli.post(ctx, "/networks/create", nil, req, nil) + resp, err := cli.post(ctx, "/networks/create", nil, nil, req) defer ensureReaderClosed(resp) if err != nil { return NetworkCreateResult{}, err diff --git a/vendor/github.com/moby/moby/client/network_disconnect.go b/vendor/github.com/moby/moby/client/network_disconnect.go index 64a1796b..4b1a6f55 100644 --- a/vendor/github.com/moby/moby/client/network_disconnect.go +++ b/vendor/github.com/moby/moby/client/network_disconnect.go @@ -30,11 +30,10 @@ func (cli *Client) NetworkDisconnect(ctx context.Context, networkID string, opti return NetworkDisconnectResult{}, err } - req := network.DisconnectRequest{ + resp, err := cli.post(ctx, "/networks/"+networkID+"/disconnect", nil, nil, network.DisconnectRequest{ Container: containerID, Force: options.Force, - } - resp, err := cli.post(ctx, "/networks/"+networkID+"/disconnect", nil, req, nil) + }) defer ensureReaderClosed(resp) return NetworkDisconnectResult{}, err } diff --git a/vendor/github.com/moby/moby/client/node_update.go b/vendor/github.com/moby/moby/client/node_update.go index 24f87a4d..cdd80fba 100644 --- a/vendor/github.com/moby/moby/client/node_update.go +++ b/vendor/github.com/moby/moby/client/node_update.go @@ -25,7 +25,7 @@ func (cli *Client) NodeUpdate(ctx context.Context, nodeID string, options NodeUp query := url.Values{} query.Set("version", options.Version.String()) - resp, err := cli.post(ctx, "/nodes/"+nodeID+"/update", query, options.Spec, nil) + resp, err := cli.post(ctx, "/nodes/"+nodeID+"/update", query, nil, options.Spec) defer ensureReaderClosed(resp) return NodeUpdateResult{}, err } diff --git a/vendor/github.com/moby/moby/client/plugin_create.go b/vendor/github.com/moby/moby/client/plugin_create.go index c1a2dd5a..f4e7c9a0 100644 --- a/vendor/github.com/moby/moby/client/plugin_create.go +++ b/vendor/github.com/moby/moby/client/plugin_create.go @@ -25,7 +25,7 @@ func (cli *Client) PluginCreate(ctx context.Context, createContext io.Reader, cr query := url.Values{} query.Set("name", createOptions.RepoName) - resp, err := cli.postRaw(ctx, "/plugins/create", query, createContext, headers) + resp, err := cli.postRaw(ctx, "/plugins/create", query, headers, createContext) defer ensureReaderClosed(resp) return PluginCreateResult{}, err } diff --git a/vendor/github.com/moby/moby/client/plugin_install.go b/vendor/github.com/moby/moby/client/plugin_install.go index a589b2e1..d26ee782 100644 --- a/vendor/github.com/moby/moby/client/plugin_install.go +++ b/vendor/github.com/moby/moby/client/plugin_install.go @@ -99,13 +99,12 @@ func (cli *Client) tryPluginPrivileges(ctx context.Context, query url.Values, re }) } -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) tryPluginPull(ctx context.Context, query url.Values, privileges []plugin.Privilege, registryAuth string) (*http.Response, error) { + headers := http.Header{registry.AuthHeader: {registryAuth}} + return cli.post(ctx, "/plugins/pull", query, headers, privileges) } -func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, options pluginOptions) (plugin.Privileges, error) { +func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, options pluginOptions) ([]plugin.Privilege, error) { resp, err := cli.tryPluginPrivileges(ctx, query, options.getRegistryAuth()) if cerrdefs.IsUnauthorized(err) && options.getPrivilegeFunc() != nil { // TODO: do inspect before to check existing name before checking privileges @@ -122,7 +121,7 @@ func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, return nil, err } - var privileges plugin.Privileges + var privileges []plugin.Privilege if err := json.NewDecoder(resp.Body).Decode(&privileges); err != nil { ensureReaderClosed(resp) return nil, err diff --git a/vendor/github.com/moby/moby/client/plugin_push.go b/vendor/github.com/moby/moby/client/plugin_push.go index 4ba25d13..d206fd26 100644 --- a/vendor/github.com/moby/moby/client/plugin_push.go +++ b/vendor/github.com/moby/moby/client/plugin_push.go @@ -24,9 +24,8 @@ func (cli *Client) PluginPush(ctx context.Context, name string, options PluginPu if err != nil { return PluginPushResult{}, err } - resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, http.Header{ - registry.AuthHeader: {options.RegistryAuth}, - }) + headers := http.Header{registry.AuthHeader: {options.RegistryAuth}} + resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, headers, nil) if err != nil { return PluginPushResult{}, err } diff --git a/vendor/github.com/moby/moby/client/plugin_set.go b/vendor/github.com/moby/moby/client/plugin_set.go index c1f6bb5f..309a30c0 100644 --- a/vendor/github.com/moby/moby/client/plugin_set.go +++ b/vendor/github.com/moby/moby/client/plugin_set.go @@ -21,7 +21,7 @@ func (cli *Client) PluginSet(ctx context.Context, name string, options PluginSet return PluginSetResult{}, err } - resp, err := cli.post(ctx, "/plugins/"+name+"/set", nil, options.Args, nil) + resp, err := cli.post(ctx, "/plugins/"+name+"/set", nil, nil, options.Args) defer ensureReaderClosed(resp) return PluginSetResult{}, err } diff --git a/vendor/github.com/moby/moby/client/plugin_upgrade.go b/vendor/github.com/moby/moby/client/plugin_upgrade.go index f9df6e58..bcfb1eac 100644 --- a/vendor/github.com/moby/moby/client/plugin_upgrade.go +++ b/vendor/github.com/moby/moby/client/plugin_upgrade.go @@ -58,10 +58,9 @@ func (cli *Client) PluginUpgrade(ctx context.Context, name string, options Plugi 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}, - }) +func (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges []plugin.Privilege, name, registryAuth string) (*http.Response, error) { + headers := http.Header{registry.AuthHeader: {registryAuth}} + return cli.post(ctx, "/plugins/"+name+"/upgrade", query, headers, privileges) } func (o *PluginUpgradeOptions) getRegistryAuth() string { diff --git a/vendor/github.com/moby/moby/client/request.go b/vendor/github.com/moby/moby/client/request.go index 10ed36dc..7d57b6b6 100644 --- a/vendor/github.com/moby/moby/client/request.go +++ b/vendor/github.com/moby/moby/client/request.go @@ -19,49 +19,49 @@ import ( // 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) + return cli.sendRequest(ctx, http.MethodHead, path, query, headers, nil) } // 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) + return cli.sendRequest(ctx, http.MethodGet, path, query, headers, nil) } // 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) { +func (cli *Client) post(ctx context.Context, path string, query url.Values, headers http.Header, body any) (*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) + return cli.sendRequest(ctx, http.MethodPost, path, query, headers, jsonBody) } -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) postRaw(ctx context.Context, path string, query url.Values, headers http.Header, body io.Reader) (*http.Response, error) { + return cli.sendRequest(ctx, http.MethodPost, path, query, headers, body) } -func (cli *Client) put(ctx context.Context, path string, query url.Values, body any, headers http.Header) (*http.Response, error) { +func (cli *Client) put(ctx context.Context, path string, query url.Values, headers http.Header, body any) (*http.Response, error) { jsonBody, headers, err := prepareJSONRequest(body, headers) if err != nil { return nil, err } - return cli.putRaw(ctx, path, query, jsonBody, headers) + return cli.putRaw(ctx, path, query, headers, jsonBody) } // 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) { +func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, headers http.Header, body io.Reader) (*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) + return cli.sendRequest(ctx, http.MethodPut, path, query, headers, body) } // 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) + return cli.sendRequest(ctx, http.MethodDelete, path, query, headers, nil) } // prepareJSONRequest encodes the given body to JSON and returns it as an [io.Reader], and sets the Content-Type @@ -87,7 +87,7 @@ func prepareJSONRequest(body any, headers http.Header) (io.Reader, http.Header, return jsonBody, hdr, nil } -func (cli *Client) buildRequest(ctx context.Context, method, path string, body io.Reader, headers http.Header) (*http.Request, error) { +func (cli *Client) buildRequest(ctx context.Context, method, path string, headers http.Header, body io.Reader) (*http.Request, error) { req, err := http.NewRequestWithContext(ctx, method, path, body) if err != nil { return nil, err @@ -104,8 +104,8 @@ func (cli *Client) buildRequest(ctx context.Context, method, path string, body i 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) +func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, headers http.Header, body io.Reader) (*http.Response, error) { + req, err := cli.buildRequest(ctx, method, cli.getAPIPath(ctx, path, query), headers, body) if err != nil { return nil, err } diff --git a/vendor/github.com/moby/moby/client/secret_create.go b/vendor/github.com/moby/moby/client/secret_create.go index 8e59a42c..22d5362d 100644 --- a/vendor/github.com/moby/moby/client/secret_create.go +++ b/vendor/github.com/moby/moby/client/secret_create.go @@ -19,7 +19,7 @@ type SecretCreateResult struct { // SecretCreate creates a new secret. func (cli *Client) SecretCreate(ctx context.Context, options SecretCreateOptions) (SecretCreateResult, error) { - resp, err := cli.post(ctx, "/secrets/create", nil, options.Spec, nil) + resp, err := cli.post(ctx, "/secrets/create", nil, nil, options.Spec) defer ensureReaderClosed(resp) if err != nil { return SecretCreateResult{}, err diff --git a/vendor/github.com/moby/moby/client/secret_update.go b/vendor/github.com/moby/moby/client/secret_update.go index d50fba4d..b9fe94c7 100644 --- a/vendor/github.com/moby/moby/client/secret_update.go +++ b/vendor/github.com/moby/moby/client/secret_update.go @@ -24,7 +24,7 @@ func (cli *Client) SecretUpdate(ctx context.Context, id string, options SecretUp } query := url.Values{} query.Set("version", options.Version.String()) - resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, options.Spec, nil) + resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, nil, options.Spec) defer ensureReaderClosed(resp) if err != nil { return SecretUpdateResult{}, err diff --git a/vendor/github.com/moby/moby/client/service_create.go b/vendor/github.com/moby/moby/client/service_create.go index 319bca6f..e911e578 100644 --- a/vendor/github.com/moby/moby/client/service_create.go +++ b/vendor/github.com/moby/moby/client/service_create.go @@ -78,7 +78,7 @@ func (cli *Client) ServiceCreate(ctx context.Context, options ServiceCreateOptio if options.EncodedRegistryAuth != "" { headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth} } - resp, err := cli.post(ctx, "/services/create", nil, options.Spec, headers) + resp, err := cli.post(ctx, "/services/create", nil, headers, options.Spec) defer ensureReaderClosed(resp) if err != nil { return ServiceCreateResult{}, err @@ -137,21 +137,37 @@ func imageDigestAndPlatforms(ctx context.Context, cli DistributionAPIClient, ima if len(distributionInspect.Platforms) > 0 { platforms = make([]swarm.Platform, 0, len(distributionInspect.Platforms)) + seen := make(map[swarm.Platform]struct{}, len(distributionInspect.Platforms)) for _, p := range distributionInspect.Platforms { + // skip attestations and other data included in the manifest index. + if p.OS == "unknown" || p.Architecture == "unknown" { + continue + } // clear architecture field for arm. This is a temporary patch to address - // https://github.com/docker/swarmkit/issues/2294. The issue is that while + // https://github.com/moby/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" { + if strings.EqualFold(arch, "arm") { arch = "" } - platforms = append(platforms, swarm.Platform{ + platform := swarm.Platform{ Architecture: arch, OS: p.OS, - }) + } + + // Skip duplicates. Swarm currently only uses os/arch, and doesn't + // support other fields (Variant, OSVersion, OSFeatures), which + // usually results in duplicate "os/arch" combinations coming from + // the image. + if _, ok := seen[platform]; ok { + continue + } + seen[platform] = struct{}{} + + platforms = append(platforms, platform) } } return imageWithDigest, platforms, err diff --git a/vendor/github.com/moby/moby/client/service_inspect.go b/vendor/github.com/moby/moby/client/service_inspect.go index 9bda43f8..7b7d0989 100644 --- a/vendor/github.com/moby/moby/client/service_inspect.go +++ b/vendor/github.com/moby/moby/client/service_inspect.go @@ -3,7 +3,6 @@ package client import ( "context" "encoding/json" - "fmt" "net/url" "github.com/moby/moby/api/types/swarm" @@ -28,7 +27,9 @@ func (cli *Client) ServiceInspect(ctx context.Context, serviceID string, options } query := url.Values{} - query.Set("insertDefaults", fmt.Sprintf("%v", options.InsertDefaults)) + if options.InsertDefaults { + query.Set("insertDefaults", "1") + } resp, err := cli.get(ctx, "/services/"+serviceID, query, nil) if err != nil { return ServiceInspectResult{}, err diff --git a/vendor/github.com/moby/moby/client/service_update.go b/vendor/github.com/moby/moby/client/service_update.go index 2505fe4b..4f179f0a 100644 --- a/vendor/github.com/moby/moby/client/service_update.go +++ b/vendor/github.com/moby/moby/client/service_update.go @@ -101,7 +101,7 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, options if options.EncodedRegistryAuth != "" { headers.Set(registry.AuthHeader, options.EncodedRegistryAuth) } - resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, options.Spec, headers) + resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, headers, options.Spec) defer ensureReaderClosed(resp) if err != nil { return ServiceUpdateResult{}, err diff --git a/vendor/github.com/moby/moby/client/swarm_init.go b/vendor/github.com/moby/moby/client/swarm_init.go index caad5608..87be2ce1 100644 --- a/vendor/github.com/moby/moby/client/swarm_init.go +++ b/vendor/github.com/moby/moby/client/swarm_init.go @@ -29,7 +29,7 @@ type SwarmInitResult struct { // SwarmInit initializes the swarm. func (cli *Client) SwarmInit(ctx context.Context, options SwarmInitOptions) (SwarmInitResult, error) { - req := swarm.InitRequest{ + resp, err := cli.post(ctx, "/swarm/init", nil, nil, swarm.InitRequest{ ListenAddr: options.ListenAddr, AdvertiseAddr: options.AdvertiseAddr, DataPathAddr: options.DataPathAddr, @@ -40,9 +40,7 @@ func (cli *Client) SwarmInit(ctx context.Context, options SwarmInitOptions) (Swa Availability: options.Availability, DefaultAddrPool: options.DefaultAddrPool, SubnetSize: options.SubnetSize, - } - - resp, err := cli.post(ctx, "/swarm/init", nil, req, nil) + }) defer ensureReaderClosed(resp) if err != nil { return SwarmInitResult{}, err diff --git a/vendor/github.com/moby/moby/client/swarm_join.go b/vendor/github.com/moby/moby/client/swarm_join.go index 66a75448..9d33ef6e 100644 --- a/vendor/github.com/moby/moby/client/swarm_join.go +++ b/vendor/github.com/moby/moby/client/swarm_join.go @@ -23,16 +23,14 @@ type SwarmJoinResult struct { // SwarmJoin joins the swarm. func (cli *Client) SwarmJoin(ctx context.Context, options SwarmJoinOptions) (SwarmJoinResult, error) { - req := swarm.JoinRequest{ + resp, err := cli.post(ctx, "/swarm/join", nil, nil, swarm.JoinRequest{ ListenAddr: options.ListenAddr, AdvertiseAddr: options.AdvertiseAddr, DataPathAddr: options.DataPathAddr, RemoteAddrs: options.RemoteAddrs, JoinToken: options.JoinToken, Availability: options.Availability, - } - - resp, err := cli.post(ctx, "/swarm/join", nil, req, nil) + }) defer ensureReaderClosed(resp) return SwarmJoinResult{}, err } diff --git a/vendor/github.com/moby/moby/client/swarm_unlock.go b/vendor/github.com/moby/moby/client/swarm_unlock.go index 92335afb..a6aee229 100644 --- a/vendor/github.com/moby/moby/client/swarm_unlock.go +++ b/vendor/github.com/moby/moby/client/swarm_unlock.go @@ -16,10 +16,9 @@ type SwarmUnlockResult struct{} // SwarmUnlock unlocks locked swarm. func (cli *Client) SwarmUnlock(ctx context.Context, options SwarmUnlockOptions) (SwarmUnlockResult, error) { - req := &swarm.UnlockRequest{ + resp, err := cli.post(ctx, "/swarm/unlock", nil, nil, swarm.UnlockRequest{ UnlockKey: options.Key, - } - resp, err := cli.post(ctx, "/swarm/unlock", nil, req, nil) + }) defer ensureReaderClosed(resp) return SwarmUnlockResult{}, err } diff --git a/vendor/github.com/moby/moby/client/swarm_update.go b/vendor/github.com/moby/moby/client/swarm_update.go index 81f62b2c..0e6257ad 100644 --- a/vendor/github.com/moby/moby/client/swarm_update.go +++ b/vendor/github.com/moby/moby/client/swarm_update.go @@ -27,7 +27,7 @@ func (cli *Client) SwarmUpdate(ctx context.Context, options SwarmUpdateOptions) query.Set("rotateWorkerToken", strconv.FormatBool(options.RotateWorkerToken)) query.Set("rotateManagerToken", strconv.FormatBool(options.RotateManagerToken)) query.Set("rotateManagerUnlockKey", strconv.FormatBool(options.RotateManagerUnlockKey)) - resp, err := cli.post(ctx, "/swarm/update", query, options.Spec, nil) + resp, err := cli.post(ctx, "/swarm/update", query, nil, options.Spec) defer ensureReaderClosed(resp) return SwarmUpdateResult{}, err } diff --git a/vendor/github.com/moby/moby/client/utils.go b/vendor/github.com/moby/moby/client/utils.go index 1c0d09df..ceecafa5 100644 --- a/vendor/github.com/moby/moby/client/utils.go +++ b/vendor/github.com/moby/moby/client/utils.go @@ -33,6 +33,14 @@ func trimID(objType, id string) (string, error) { return id, nil } +// valueOrZero returns the value pointed to by p, or the zero value of T if p is nil. +func valueOrZero[T any](p *T) (zero T) { + if p != nil { + return *p + } + return zero +} + // parseAPIVersion checks v to be a well-formed (".") // API version. It returns an error if the value is empty or does not // have the correct format, but does not validate if the API version is diff --git a/vendor/github.com/moby/moby/client/volume_create.go b/vendor/github.com/moby/moby/client/volume_create.go index 674e0633..5212f09a 100644 --- a/vendor/github.com/moby/moby/client/volume_create.go +++ b/vendor/github.com/moby/moby/client/volume_create.go @@ -23,14 +23,13 @@ type VolumeCreateResult struct { // VolumeCreate creates a volume in the docker host. func (cli *Client) VolumeCreate(ctx context.Context, options VolumeCreateOptions) (VolumeCreateResult, error) { - createRequest := volume.CreateRequest{ + resp, err := cli.post(ctx, "/volumes/create", nil, nil, volume.CreateRequest{ Name: options.Name, Driver: options.Driver, DriverOpts: options.DriverOpts, Labels: options.Labels, ClusterVolumeSpec: options.ClusterVolumeSpec, - } - resp, err := cli.post(ctx, "/volumes/create", nil, createRequest, nil) + }) defer ensureReaderClosed(resp) if err != nil { return VolumeCreateResult{}, err diff --git a/vendor/github.com/moby/moby/client/volume_update.go b/vendor/github.com/moby/moby/client/volume_update.go index 5aa2a0aa..3810267e 100644 --- a/vendor/github.com/moby/moby/client/volume_update.go +++ b/vendor/github.com/moby/moby/client/volume_update.go @@ -31,7 +31,7 @@ func (cli *Client) VolumeUpdate(ctx context.Context, volumeID string, options Vo query := url.Values{} query.Set("version", options.Version.String()) - resp, err := cli.put(ctx, "/volumes/"+volumeID, query, options, nil) + resp, err := cli.put(ctx, "/volumes/"+volumeID, query, nil, options) defer ensureReaderClosed(resp) if err != nil { return VolumeUpdateResult{}, err diff --git a/vendor/modules.txt b/vendor/modules.txt index e014980e..be1a91ba 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -240,7 +240,7 @@ github.com/mistifyio/go-zfs/v4 # github.com/moby/docker-image-spec v1.3.1 ## explicit; go 1.18 github.com/moby/docker-image-spec/specs-go/v1 -# github.com/moby/moby/api v1.54.2 +# github.com/moby/moby/api v1.56.0 ## explicit; go 1.24 github.com/moby/moby/api/types github.com/moby/moby/api/types/blkiodev @@ -259,7 +259,7 @@ 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/volume -# github.com/moby/moby/client v0.4.1 +# github.com/moby/moby/client v0.6.0 ## explicit; go 1.24 github.com/moby/moby/client github.com/moby/moby/client/internal