Merge pull request #5428 from thaJeztah/bump_docker_28

vendor: github.com/docker/docker 164cae56ed95 (master, v-next)
This commit is contained in:
Laura Brehm 2024-09-24 15:53:30 +01:00 committed by GitHub
commit 3a3fe840ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 241 additions and 107 deletions

View File

@ -16,17 +16,17 @@ import (
type fakeClient struct { type fakeClient struct {
client.Client client.Client
imageTagFunc func(string, string) error imageTagFunc func(string, string) error
imageSaveFunc func(images []string) (io.ReadCloser, error) imageSaveFunc func(images []string, options image.SaveOptions) (io.ReadCloser, error)
imageRemoveFunc func(image string, options image.RemoveOptions) ([]image.DeleteResponse, error) imageRemoveFunc func(image string, options image.RemoveOptions) ([]image.DeleteResponse, error)
imagePushFunc func(ref string, options image.PushOptions) (io.ReadCloser, error) imagePushFunc func(ref string, options image.PushOptions) (io.ReadCloser, error)
infoFunc func() (system.Info, error) infoFunc func() (system.Info, error)
imagePullFunc func(ref string, options image.PullOptions) (io.ReadCloser, error) imagePullFunc func(ref string, options image.PullOptions) (io.ReadCloser, error)
imagesPruneFunc func(pruneFilter filters.Args) (image.PruneReport, error) imagesPruneFunc func(pruneFilter filters.Args) (image.PruneReport, error)
imageLoadFunc func(input io.Reader, quiet bool) (image.LoadResponse, error) imageLoadFunc func(input io.Reader, options image.LoadOptions) (image.LoadResponse, error)
imageListFunc func(options image.ListOptions) ([]image.Summary, error) imageListFunc func(options image.ListOptions) ([]image.Summary, error)
imageInspectFunc func(img string) (image.InspectResponse, []byte, error) imageInspectFunc func(img string) (image.InspectResponse, []byte, error)
imageImportFunc func(source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) imageImportFunc func(source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error)
imageHistoryFunc func(img string) ([]image.HistoryResponseItem, error) imageHistoryFunc func(img string, options image.HistoryOptions) ([]image.HistoryResponseItem, error)
imageBuildFunc func(context.Context, io.Reader, types.ImageBuildOptions) (types.ImageBuildResponse, error) imageBuildFunc func(context.Context, io.Reader, types.ImageBuildOptions) (types.ImageBuildResponse, error)
} }
@ -37,9 +37,9 @@ func (cli *fakeClient) ImageTag(_ context.Context, img, ref string) error {
return nil return nil
} }
func (cli *fakeClient) ImageSave(_ context.Context, images []string) (io.ReadCloser, error) { func (cli *fakeClient) ImageSave(_ context.Context, images []string, options image.SaveOptions) (io.ReadCloser, error) {
if cli.imageSaveFunc != nil { if cli.imageSaveFunc != nil {
return cli.imageSaveFunc(images) return cli.imageSaveFunc(images, options)
} }
return io.NopCloser(strings.NewReader("")), nil return io.NopCloser(strings.NewReader("")), nil
} }
@ -81,9 +81,9 @@ func (cli *fakeClient) ImagesPrune(_ context.Context, pruneFilter filters.Args)
return image.PruneReport{}, nil return image.PruneReport{}, nil
} }
func (cli *fakeClient) ImageLoad(_ context.Context, input io.Reader, quiet bool) (image.LoadResponse, error) { func (cli *fakeClient) ImageLoad(_ context.Context, input io.Reader, options image.LoadOptions) (image.LoadResponse, error) {
if cli.imageLoadFunc != nil { if cli.imageLoadFunc != nil {
return cli.imageLoadFunc(input, quiet) return cli.imageLoadFunc(input, options)
} }
return image.LoadResponse{}, nil return image.LoadResponse{}, nil
} }
@ -111,9 +111,9 @@ func (cli *fakeClient) ImageImport(_ context.Context, source image.ImportSource,
return io.NopCloser(strings.NewReader("")), nil return io.NopCloser(strings.NewReader("")), nil
} }
func (cli *fakeClient) ImageHistory(_ context.Context, img string) ([]image.HistoryResponseItem, error) { func (cli *fakeClient) ImageHistory(_ context.Context, img string, options image.HistoryOptions) ([]image.HistoryResponseItem, error) {
if cli.imageHistoryFunc != nil { if cli.imageHistoryFunc != nil {
return cli.imageHistoryFunc(img) return cli.imageHistoryFunc(img, options)
} }
return []image.HistoryResponseItem{{ID: img, Created: time.Now().Unix()}}, nil return []image.HistoryResponseItem{{ID: img, Created: time.Now().Unix()}}, nil
} }

View File

@ -8,6 +8,7 @@ import (
"github.com/docker/cli/cli/command/completion" "github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/command/formatter"
flagsHelper "github.com/docker/cli/cli/flags" flagsHelper "github.com/docker/cli/cli/flags"
"github.com/docker/docker/api/types/image"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -49,7 +50,7 @@ func NewHistoryCommand(dockerCli command.Cli) *cobra.Command {
} }
func runHistory(ctx context.Context, dockerCli command.Cli, opts historyOptions) error { func runHistory(ctx context.Context, dockerCli command.Cli, opts historyOptions) error {
history, err := dockerCli.Client().ImageHistory(ctx, opts.image) history, err := dockerCli.Client().ImageHistory(ctx, opts.image, image.HistoryOptions{})
if err != nil { if err != nil {
return err return err
} }

View File

@ -18,7 +18,7 @@ func TestNewHistoryCommandErrors(t *testing.T) {
name string name string
args []string args []string
expectedError string expectedError string
imageHistoryFunc func(img string) ([]image.HistoryResponseItem, error) imageHistoryFunc func(img string, options image.HistoryOptions) ([]image.HistoryResponseItem, error)
}{ }{
{ {
name: "wrong-args", name: "wrong-args",
@ -29,7 +29,7 @@ func TestNewHistoryCommandErrors(t *testing.T) {
name: "client-error", name: "client-error",
args: []string{"image:tag"}, args: []string{"image:tag"},
expectedError: "something went wrong", expectedError: "something went wrong",
imageHistoryFunc: func(img string) ([]image.HistoryResponseItem, error) { imageHistoryFunc: func(img string, options image.HistoryOptions) ([]image.HistoryResponseItem, error) {
return []image.HistoryResponseItem{{}}, errors.Errorf("something went wrong") return []image.HistoryResponseItem{{}}, errors.Errorf("something went wrong")
}, },
}, },
@ -50,12 +50,12 @@ func TestNewHistoryCommandSuccess(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
args []string args []string
imageHistoryFunc func(img string) ([]image.HistoryResponseItem, error) imageHistoryFunc func(img string, options image.HistoryOptions) ([]image.HistoryResponseItem, error)
}{ }{
{ {
name: "simple", name: "simple",
args: []string{"image:tag"}, args: []string{"image:tag"},
imageHistoryFunc: func(img string) ([]image.HistoryResponseItem, error) { imageHistoryFunc: func(img string, options image.HistoryOptions) ([]image.HistoryResponseItem, error) {
return []image.HistoryResponseItem{{ return []image.HistoryResponseItem{{
ID: "1234567890123456789", ID: "1234567890123456789",
Created: time.Now().Unix(), Created: time.Now().Unix(),
@ -70,7 +70,7 @@ func TestNewHistoryCommandSuccess(t *testing.T) {
{ {
name: "non-human", name: "non-human",
args: []string{"--human=false", "image:tag"}, args: []string{"--human=false", "image:tag"},
imageHistoryFunc: func(img string) ([]image.HistoryResponseItem, error) { imageHistoryFunc: func(img string, options image.HistoryOptions) ([]image.HistoryResponseItem, error) {
return []image.HistoryResponseItem{{ return []image.HistoryResponseItem{{
ID: "abcdef", ID: "abcdef",
Created: time.Date(2017, 1, 1, 12, 0, 3, 0, time.UTC).Unix(), Created: time.Date(2017, 1, 1, 12, 0, 3, 0, time.UTC).Unix(),
@ -82,7 +82,7 @@ func TestNewHistoryCommandSuccess(t *testing.T) {
{ {
name: "quiet-no-trunc", name: "quiet-no-trunc",
args: []string{"--quiet", "--no-trunc", "image:tag"}, args: []string{"--quiet", "--no-trunc", "image:tag"},
imageHistoryFunc: func(img string) ([]image.HistoryResponseItem, error) { imageHistoryFunc: func(img string, options image.HistoryOptions) ([]image.HistoryResponseItem, error) {
return []image.HistoryResponseItem{{ return []image.HistoryResponseItem{{
ID: "1234567890123456789", ID: "1234567890123456789",
Created: time.Now().Unix(), Created: time.Now().Unix(),

View File

@ -7,6 +7,7 @@ import (
"github.com/docker/cli/cli" "github.com/docker/cli/cli"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion" "github.com/docker/cli/cli/command/completion"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/jsonmessage"
"github.com/moby/sys/sequential" "github.com/moby/sys/sequential"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -62,10 +63,12 @@ func runLoad(ctx context.Context, dockerCli command.Cli, opts loadOptions) error
return errors.Errorf("requested load from stdin, but stdin is empty") return errors.Errorf("requested load from stdin, but stdin is empty")
} }
if !dockerCli.Out().IsTerminal() { var loadOpts image.LoadOptions
opts.quiet = true if opts.quiet || !dockerCli.Out().IsTerminal() {
loadOpts.Quiet = true
} }
response, err := dockerCli.Client().ImageLoad(ctx, input, opts.quiet)
response, err := dockerCli.Client().ImageLoad(ctx, input, loadOpts)
if err != nil { if err != nil {
return err return err
} }

View File

@ -19,7 +19,7 @@ func TestNewLoadCommandErrors(t *testing.T) {
args []string args []string
isTerminalIn bool isTerminalIn bool
expectedError string expectedError string
imageLoadFunc func(input io.Reader, quiet bool) (image.LoadResponse, error) imageLoadFunc func(input io.Reader, options image.LoadOptions) (image.LoadResponse, error)
}{ }{
{ {
name: "wrong-args", name: "wrong-args",
@ -34,7 +34,7 @@ func TestNewLoadCommandErrors(t *testing.T) {
{ {
name: "pull-error", name: "pull-error",
expectedError: "something went wrong", expectedError: "something went wrong",
imageLoadFunc: func(input io.Reader, quiet bool) (image.LoadResponse, error) { imageLoadFunc: func(input io.Reader, options image.LoadOptions) (image.LoadResponse, error) {
return image.LoadResponse{}, errors.Errorf("something went wrong") return image.LoadResponse{}, errors.Errorf("something went wrong")
}, },
}, },
@ -67,17 +67,17 @@ func TestNewLoadCommandSuccess(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
args []string args []string
imageLoadFunc func(input io.Reader, quiet bool) (image.LoadResponse, error) imageLoadFunc func(input io.Reader, options image.LoadOptions) (image.LoadResponse, error)
}{ }{
{ {
name: "simple", name: "simple",
imageLoadFunc: func(input io.Reader, quiet bool) (image.LoadResponse, error) { imageLoadFunc: func(input io.Reader, options image.LoadOptions) (image.LoadResponse, error) {
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
}, },
}, },
{ {
name: "json", name: "json",
imageLoadFunc: func(input io.Reader, quiet bool) (image.LoadResponse, error) { imageLoadFunc: func(input io.Reader, options image.LoadOptions) (image.LoadResponse, error) {
json := "{\"ID\": \"1\"}" json := "{\"ID\": \"1\"}"
return image.LoadResponse{ return image.LoadResponse{
Body: io.NopCloser(strings.NewReader(json)), Body: io.NopCloser(strings.NewReader(json)),
@ -88,7 +88,7 @@ func TestNewLoadCommandSuccess(t *testing.T) {
{ {
name: "input-file", name: "input-file",
args: []string{"--input", "testdata/load-command-success.input.txt"}, args: []string{"--input", "testdata/load-command-success.input.txt"},
imageLoadFunc: func(input io.Reader, quiet bool) (image.LoadResponse, error) { imageLoadFunc: func(input io.Reader, options image.LoadOptions) (image.LoadResponse, error) {
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
}, },
}, },

View File

@ -7,6 +7,7 @@ import (
"github.com/docker/cli/cli" "github.com/docker/cli/cli"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion" "github.com/docker/cli/cli/command/completion"
"github.com/docker/docker/api/types/image"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -51,7 +52,7 @@ func RunSave(ctx context.Context, dockerCli command.Cli, opts saveOptions) error
return errors.Wrap(err, "failed to save image") return errors.Wrap(err, "failed to save image")
} }
responseBody, err := dockerCli.Client().ImageSave(ctx, opts.images) responseBody, err := dockerCli.Client().ImageSave(ctx, opts.images, image.SaveOptions{})
if err != nil { if err != nil {
return err return err
} }

View File

@ -7,6 +7,7 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/image"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@ -18,7 +19,7 @@ func TestNewSaveCommandErrors(t *testing.T) {
args []string args []string
isTerminal bool isTerminal bool
expectedError string expectedError string
imageSaveFunc func(images []string) (io.ReadCloser, error) imageSaveFunc func(images []string, options image.SaveOptions) (io.ReadCloser, error)
}{ }{
{ {
name: "wrong args", name: "wrong args",
@ -36,7 +37,7 @@ func TestNewSaveCommandErrors(t *testing.T) {
args: []string{"arg1"}, args: []string{"arg1"},
isTerminal: false, isTerminal: false,
expectedError: "error saving image", expectedError: "error saving image",
imageSaveFunc: func(images []string) (io.ReadCloser, error) { imageSaveFunc: func(images []string, options image.SaveOptions) (io.ReadCloser, error) {
return io.NopCloser(strings.NewReader("")), errors.Errorf("error saving image") return io.NopCloser(strings.NewReader("")), errors.Errorf("error saving image")
}, },
}, },
@ -99,7 +100,7 @@ func TestNewSaveCommandSuccess(t *testing.T) {
tc := tc tc := tc
t.Run(strings.Join(tc.args, " "), func(t *testing.T) { t.Run(strings.Join(tc.args, " "), func(t *testing.T) {
cmd := NewSaveCommand(test.NewFakeCli(&fakeClient{ cmd := NewSaveCommand(test.NewFakeCli(&fakeClient{
imageSaveFunc: func(images []string) (io.ReadCloser, error) { imageSaveFunc: func(images []string, options image.SaveOptions) (io.ReadCloser, error) {
return io.NopCloser(strings.NewReader("")), nil return io.NopCloser(strings.NewReader("")), nil
}, },
})) }))

View File

@ -13,7 +13,6 @@ import (
configtypes "github.com/docker/cli/cli/config/types" configtypes "github.com/docker/cli/cli/config/types"
"github.com/docker/cli/cli/hints" "github.com/docker/cli/cli/hints"
"github.com/docker/cli/cli/streams" "github.com/docker/cli/cli/streams"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry" registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -25,7 +24,7 @@ const patSuggest = "You can log in with your password or a Personal Access " +
// RegistryAuthenticationPrivilegedFunc returns a RequestPrivilegeFunc from the specified registry index info // RegistryAuthenticationPrivilegedFunc returns a RequestPrivilegeFunc from the specified registry index info
// for the given command. // for the given command.
func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInfo, cmdName string) types.RequestPrivilegeFunc { func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInfo, cmdName string) registrytypes.RequestAuthConfig {
return func(ctx context.Context) (string, error) { return func(ctx context.Context) (string, error) {
fmt.Fprintf(cli.Out(), "\nLogin prior to %s:\n", cmdName) fmt.Fprintf(cli.Out(), "\nLogin prior to %s:\n", cmdName)
indexServer := registry.GetAuthConfigKey(index) indexServer := registry.GetAuthConfigKey(index)

View File

@ -13,7 +13,7 @@ require (
github.com/distribution/reference v0.6.0 github.com/distribution/reference v0.6.0
github.com/docker/cli-docs-tool v0.8.0 github.com/docker/cli-docs-tool v0.8.0
github.com/docker/distribution v2.8.3+incompatible github.com/docker/distribution v2.8.3+incompatible
github.com/docker/docker v27.0.2-0.20240808103429-2269acc7a31d+incompatible // master (v-next) github.com/docker/docker v27.0.2-0.20240912171519-164cae56ed95+incompatible // master (v-next)
github.com/docker/docker-credential-helpers v0.8.2 github.com/docker/docker-credential-helpers v0.8.2
github.com/docker/go-connections v0.5.0 github.com/docker/go-connections v0.5.0
github.com/docker/go-units v0.5.0 github.com/docker/go-units v0.5.0

View File

@ -57,8 +57,8 @@ github.com/docker/cli-docs-tool v0.8.0/go.mod h1:8TQQ3E7mOXoYUs811LiPdUnAhXrcVsB
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.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 h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v27.0.2-0.20240808103429-2269acc7a31d+incompatible h1:kkRsJYOCMGRonT/rXx/m1Cy9IryWhEe1b3CkA3q5/oA= github.com/docker/docker v27.0.2-0.20240912171519-164cae56ed95+incompatible h1:HRK75BHG33htes7s+v/fJ8saCNw3B7f3spcgLsvbLRQ=
github.com/docker/docker v27.0.2-0.20240808103429-2269acc7a31d+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v27.0.2-0.20240912171519-164cae56ed95+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=

View File

@ -3,7 +3,7 @@ package api // import "github.com/docker/docker/api"
// Common constants for daemon and client. // Common constants for daemon and client.
const ( const (
// DefaultVersion of the current REST API. // DefaultVersion of the current REST API.
DefaultVersion = "1.47" DefaultVersion = "1.48"
// MinSupportedAPIVersion is the minimum API version that can be supported // MinSupportedAPIVersion is the minimum API version that can be supported
// by the API server, specified as "major.minor". Note that the daemon // by the API server, specified as "major.minor". Note that the daemon

View File

@ -19,10 +19,10 @@ produces:
consumes: consumes:
- "application/json" - "application/json"
- "text/plain" - "text/plain"
basePath: "/v1.47" basePath: "/v1.48"
info: info:
title: "Docker Engine API" title: "Docker Engine API"
version: "1.47" version: "1.48"
x-logo: x-logo:
url: "https://docs.docker.com/assets/images/logo-docker-main.png" url: "https://docs.docker.com/assets/images/logo-docker-main.png"
description: | description: |
@ -55,8 +55,8 @@ info:
the URL is not supported by the daemon, a HTTP `400 Bad Request` error message the URL is not supported by the daemon, a HTTP `400 Bad Request` error message
is returned. is returned.
If you omit the version-prefix, the current version of the API (v1.47) is used. If you omit the version-prefix, the current version of the API (v1.48) is used.
For example, calling `/info` is the same as calling `/v1.47/info`. Using the For example, calling `/info` is the same as calling `/v1.48/info`. Using the
API without a version-prefix is deprecated and will be removed in a future release. API without a version-prefix is deprecated and will be removed in a future release.
Engine releases in the near future should support this version of the API, Engine releases in the near future should support this version of the API,
@ -393,7 +393,7 @@ definitions:
Make the mount non-recursively read-only, but still leave the mount recursive Make the mount non-recursively read-only, but still leave the mount recursive
(unless NonRecursive is set to `true` in conjunction). (unless NonRecursive is set to `true` in conjunction).
Addded in v1.44, before that version all read-only mounts were Added in v1.44, before that version all read-only mounts were
non-recursive by default. To match the previous behaviour this non-recursive by default. To match the previous behaviour this
will default to `true` for clients on versions prior to v1.44. will default to `true` for clients on versions prior to v1.44.
type: "boolean" type: "boolean"
@ -1384,7 +1384,7 @@ definitions:
<p><br /></p> <p><br /></p>
> **Deprecated**: this field is not part of the image specification and is > **Deprecated**: this field is not part of the image specification and is
> always empty. It must not be used, and will be removed in API v1.47. > always empty. It must not be used, and will be removed in API v1.48.
type: "string" type: "string"
example: "" example: ""
Domainname: Domainname:
@ -1394,7 +1394,7 @@ definitions:
<p><br /></p> <p><br /></p>
> **Deprecated**: this field is not part of the image specification and is > **Deprecated**: this field is not part of the image specification and is
> always empty. It must not be used, and will be removed in API v1.47. > always empty. It must not be used, and will be removed in API v1.48.
type: "string" type: "string"
example: "" example: ""
User: User:
@ -1408,7 +1408,7 @@ definitions:
<p><br /></p> <p><br /></p>
> **Deprecated**: this field is not part of the image specification and is > **Deprecated**: this field is not part of the image specification and is
> always false. It must not be used, and will be removed in API v1.47. > always false. It must not be used, and will be removed in API v1.48.
type: "boolean" type: "boolean"
default: false default: false
example: false example: false
@ -1419,7 +1419,7 @@ definitions:
<p><br /></p> <p><br /></p>
> **Deprecated**: this field is not part of the image specification and is > **Deprecated**: this field is not part of the image specification and is
> always false. It must not be used, and will be removed in API v1.47. > always false. It must not be used, and will be removed in API v1.48.
type: "boolean" type: "boolean"
default: false default: false
example: false example: false
@ -1430,7 +1430,7 @@ definitions:
<p><br /></p> <p><br /></p>
> **Deprecated**: this field is not part of the image specification and is > **Deprecated**: this field is not part of the image specification and is
> always false. It must not be used, and will be removed in API v1.47. > always false. It must not be used, and will be removed in API v1.48.
type: "boolean" type: "boolean"
default: false default: false
example: false example: false
@ -1457,7 +1457,7 @@ definitions:
<p><br /></p> <p><br /></p>
> **Deprecated**: this field is not part of the image specification and is > **Deprecated**: this field is not part of the image specification and is
> always false. It must not be used, and will be removed in API v1.47. > always false. It must not be used, and will be removed in API v1.48.
type: "boolean" type: "boolean"
default: false default: false
example: false example: false
@ -1468,7 +1468,7 @@ definitions:
<p><br /></p> <p><br /></p>
> **Deprecated**: this field is not part of the image specification and is > **Deprecated**: this field is not part of the image specification and is
> always false. It must not be used, and will be removed in API v1.47. > always false. It must not be used, and will be removed in API v1.48.
type: "boolean" type: "boolean"
default: false default: false
example: false example: false
@ -1479,7 +1479,7 @@ definitions:
<p><br /></p> <p><br /></p>
> **Deprecated**: this field is not part of the image specification and is > **Deprecated**: this field is not part of the image specification and is
> always false. It must not be used, and will be removed in API v1.47. > always false. It must not be used, and will be removed in API v1.48.
type: "boolean" type: "boolean"
default: false default: false
example: false example: false
@ -1516,7 +1516,7 @@ definitions:
<p><br /></p> <p><br /></p>
> **Deprecated**: this field is not part of the image specification and is > **Deprecated**: this field is not part of the image specification and is
> always empty. It must not be used, and will be removed in API v1.47. > always empty. It must not be used, and will be removed in API v1.48.
type: "string" type: "string"
default: "" default: ""
example: "" example: ""
@ -1555,7 +1555,7 @@ definitions:
<p><br /></p> <p><br /></p>
> **Deprecated**: this field is not part of the image specification and is > **Deprecated**: this field is not part of the image specification and is
> always omitted. It must not be used, and will be removed in API v1.47. > always omitted. It must not be used, and will be removed in API v1.48.
type: "boolean" type: "boolean"
default: false default: false
example: false example: false
@ -1567,7 +1567,7 @@ definitions:
<p><br /></p> <p><br /></p>
> **Deprecated**: this field is not part of the image specification and is > **Deprecated**: this field is not part of the image specification and is
> always omitted. It must not be used, and will be removed in API v1.47. > always omitted. It must not be used, and will be removed in API v1.48.
type: "string" type: "string"
default: "" default: ""
example: "" example: ""
@ -1601,7 +1601,7 @@ definitions:
<p><br /></p> <p><br /></p>
> **Deprecated**: this field is not part of the image specification and is > **Deprecated**: this field is not part of the image specification and is
> always omitted. It must not be used, and will be removed in API v1.47. > always omitted. It must not be used, and will be removed in API v1.48.
type: "integer" type: "integer"
default: 10 default: 10
x-nullable: true x-nullable: true
@ -2216,7 +2216,7 @@ definitions:
Created: Created:
description: | description: |
Date and time at which the image was created as a Unix timestamp Date and time at which the image was created as a Unix timestamp
(number of seconds sinds EPOCH). (number of seconds since EPOCH).
type: "integer" type: "integer"
x-nullable: false x-nullable: false
example: "1644009612" example: "1644009612"
@ -2518,7 +2518,7 @@ definitions:
example: false example: false
Attachable: Attachable:
description: | description: |
Wheter a global / swarm scope network is manually attachable by regular Whether a global / swarm scope network is manually attachable by regular
containers from workers in swarm mode. containers from workers in swarm mode.
type: "boolean" type: "boolean"
default: false default: false
@ -3741,7 +3741,7 @@ definitions:
example: "json-file" example: "json-file"
Options: Options:
description: | description: |
Driver-specific options for the selectd log driver, specified Driver-specific options for the selected log driver, specified
as key/value pairs. as key/value pairs.
type: "object" type: "object"
additionalProperties: additionalProperties:
@ -5352,7 +5352,7 @@ definitions:
The version Go used to compile the daemon, and the version of the Go The version Go used to compile the daemon, and the version of the Go
runtime in use. runtime in use.
type: "string" type: "string"
example: "go1.21.13" example: "go1.22.7"
Os: Os:
description: | description: |
The operating system that the daemon is running on ("linux" or "windows") The operating system that the daemon is running on ("linux" or "windows")
@ -5848,13 +5848,13 @@ definitions:
- "/var/run/cdi" - "/var/run/cdi"
Containerd: Containerd:
$ref: "#/definitions/ContainerdInfo" $ref: "#/definitions/ContainerdInfo"
x-nullable: true
ContainerdInfo: ContainerdInfo:
description: | description: |
Information for connecting to the containerd instance that is used by the daemon. Information for connecting to the containerd instance that is used by the daemon.
This is included for debugging purposes only. This is included for debugging purposes only.
type: "object" type: "object"
x-nullable: true
properties: properties:
Address: Address:
description: "The address of the containerd socket." description: "The address of the containerd socket."
@ -7717,7 +7717,7 @@ paths:
* Memory usage % = `(used_memory / available_memory) * 100.0` * Memory usage % = `(used_memory / available_memory) * 100.0`
* cpu_delta = `cpu_stats.cpu_usage.total_usage - precpu_stats.cpu_usage.total_usage` * cpu_delta = `cpu_stats.cpu_usage.total_usage - precpu_stats.cpu_usage.total_usage`
* system_cpu_delta = `cpu_stats.system_cpu_usage - precpu_stats.system_cpu_usage` * system_cpu_delta = `cpu_stats.system_cpu_usage - precpu_stats.system_cpu_usage`
* number_cpus = `lenght(cpu_stats.cpu_usage.percpu_usage)` or `cpu_stats.online_cpus` * number_cpus = `length(cpu_stats.cpu_usage.percpu_usage)` or `cpu_stats.online_cpus`
* CPU usage % = `(cpu_delta / system_cpu_delta) * number_cpus * 100.0` * CPU usage % = `(cpu_delta / system_cpu_delta) * number_cpus * 100.0`
operationId: "ContainerStats" operationId: "ContainerStats"
produces: ["application/json"] produces: ["application/json"]
@ -9202,6 +9202,15 @@ paths:
description: "Image name or ID" description: "Image name or ID"
type: "string" type: "string"
required: true required: true
- name: "platform"
type: "string"
in: "query"
description: |
JSON encoded OCI platform describing platform to show the history for.
If not provided, the host platform will be used. If it's not
available, any present platform will be picked.
Example: `{"os": "linux", "architecture": "arm", "variant": "v5"}`
tags: ["Image"] tags: ["Image"]
/images/{name}/push: /images/{name}/push:
post: post:
@ -9231,12 +9240,23 @@ paths:
parameters: parameters:
- name: "name" - name: "name"
in: "path" in: "path"
description: "Image name or ID." description: |
Name of the image to push. For example, `registry.example.com/myimage`.
The image must be present in the local image store with the same name.
The name should be provided without tag; if a tag is provided, it
is ignored. For example, `registry.example.com/myimage:latest` is
considered equivalent to `registry.example.com/myimage`.
Use the `tag` parameter to specify the tag to push.
type: "string" type: "string"
required: true required: true
- name: "tag" - name: "tag"
in: "query" in: "query"
description: "The tag to associate with the image on the registry." description: |
Tag of the image to push. For example, `latest`. If no tag is provided,
all tags of the given image that are present in the local image store
are pushed.
type: "string" type: "string"
- name: "X-Registry-Auth" - name: "X-Registry-Auth"
in: "header" in: "header"
@ -9936,7 +9956,16 @@ paths:
description: "Image name or ID" description: "Image name or ID"
type: "string" type: "string"
required: true required: true
tags: ["Image"] - name: "platform"
type: "string"
in: "query"
description: |
JSON encoded OCI platform describing a platform which will be used
to select a platform-specific image to be saved if the image is
multi-platform.
If not provided, the full multi-platform image will be saved.
Example: `{"os": "linux", "architecture": "arm", "variant": "v5"}`
/images/get: /images/get:
get: get:
summary: "Export several images" summary: "Export several images"
@ -10003,6 +10032,16 @@ paths:
description: "Suppress progress details during load." description: "Suppress progress details during load."
type: "boolean" type: "boolean"
default: false default: false
- name: "platform"
type: "string"
in: "query"
description: |
JSON encoded OCI platform describing a platform which will be used
to select a platform-specific image to be load if the image is
multi-platform.
If not provided, the full multi-platform image will be loaded.
Example: `{"os": "linux", "architecture": "arm", "variant": "v5"}`
tags: ["Image"] tags: ["Image"]
/containers/{id}/exec: /containers/{id}/exec:
post: post:

View File

@ -129,14 +129,6 @@ type ImageBuildResponse struct {
OSType string OSType string
} }
// RequestPrivilegeFunc is a function interface that
// clients can supply to retry operations after
// getting an authorization error.
// This function returns the registry authentication
// header value in base 64 format, or an error
// if the privilege request fails.
type RequestPrivilegeFunc func(context.Context) (string, error)
// NodeListOptions holds parameters to list nodes with. // NodeListOptions holds parameters to list nodes with.
type NodeListOptions struct { type NodeListOptions struct {
Filters filters.Args Filters filters.Args
@ -235,11 +227,18 @@ type PluginDisableOptions struct {
// PluginInstallOptions holds parameters to install a plugin. // PluginInstallOptions holds parameters to install a plugin.
type PluginInstallOptions struct { type PluginInstallOptions struct {
Disabled bool Disabled bool
AcceptAllPermissions bool AcceptAllPermissions bool
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
RemoteRef string // RemoteRef is the plugin name on the registry RemoteRef string // RemoteRef is the plugin name on the registry
PrivilegeFunc RequestPrivilegeFunc
// 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) AcceptPermissionsFunc func(context.Context, PluginPrivileges) (bool, error)
Args []string Args []string
} }

View File

@ -1,6 +1,7 @@
package container // import "github.com/docker/docker/api/types/container" package container // import "github.com/docker/docker/api/types/container"
import ( import (
"errors"
"fmt" "fmt"
"strings" "strings"
@ -325,12 +326,12 @@ func ValidateRestartPolicy(policy RestartPolicy) error {
if policy.MaximumRetryCount < 0 { if policy.MaximumRetryCount < 0 {
msg += " and cannot be negative" msg += " and cannot be negative"
} }
return &errInvalidParameter{fmt.Errorf(msg)} return &errInvalidParameter{errors.New(msg)}
} }
return nil return nil
case RestartPolicyOnFailure: case RestartPolicyOnFailure:
if policy.MaximumRetryCount < 0 { if policy.MaximumRetryCount < 0 {
return &errInvalidParameter{fmt.Errorf("invalid restart policy: maximum retry count cannot be negative")} return &errInvalidParameter{errors.New("invalid restart policy: maximum retry count cannot be negative")}
} }
return nil return nil
case "": case "":

View File

@ -196,7 +196,7 @@ func (args Args) Match(field, source string) bool {
} }
// GetBoolOrDefault returns a boolean value of the key if the key is present // GetBoolOrDefault returns a boolean value of the key if the key is present
// and is intepretable as a boolean value. Otherwise the default value is returned. // and is interpretable as a boolean value. Otherwise the default value is returned.
// Error is not nil only if the filter values are not valid boolean or are conflicting. // Error is not nil only if the filter values are not valid boolean or are conflicting.
func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) { func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) {
fieldValues, ok := args.fields[key] fieldValues, ok := args.fields[key]

View File

@ -38,7 +38,7 @@ type PullOptions struct {
// authentication header value in base64 encoded format, or an error if the // authentication header value in base64 encoded format, or an error if the
// privilege request fails. // privilege request fails.
// //
// Also see [github.com/docker/docker/api/types.RequestPrivilegeFunc]. // For details, refer to [github.com/docker/docker/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error) PrivilegeFunc func(context.Context) (string, error)
Platform string Platform string
} }
@ -53,7 +53,7 @@ type PushOptions struct {
// authentication header value in base64 encoded format, or an error if the // authentication header value in base64 encoded format, or an error if the
// privilege request fails. // privilege request fails.
// //
// Also see [github.com/docker/docker/api/types.RequestPrivilegeFunc]. // For details, refer to [github.com/docker/docker/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error) PrivilegeFunc func(context.Context) (string, error)
// Platform is an optional field that selects a specific platform to push // Platform is an optional field that selects a specific platform to push
@ -86,3 +86,24 @@ type RemoveOptions struct {
Force bool Force bool
PruneChildren bool PruneChildren bool
} }
// HistoryOptions holds parameters to get image history.
type HistoryOptions struct {
// Platform from the manifest list to use for history.
Platform *ocispec.Platform
}
// LoadOptions holds parameters to load images.
type LoadOptions struct {
// Quiet suppresses progress output
Quiet bool
// Platform is a specific platform to load when the image is a multi-platform
Platform *ocispec.Platform
}
// SaveOptions holds parameters to save images.
type SaveOptions struct {
// Platform is a specific platform to save if the image is a multi-platform image.
Platform *ocispec.Platform
}

View File

@ -12,7 +12,7 @@ type Summary struct {
Containers int64 `json:"Containers"` Containers int64 `json:"Containers"`
// Date and time at which the image was created as a Unix timestamp // Date and time at which the image was created as a Unix timestamp
// (number of seconds sinds EPOCH). // (number of seconds since EPOCH).
// //
// Required: true // Required: true
Created int64 `json:"Created"` Created int64 `json:"Created"`

View File

@ -1,5 +1,6 @@
package registry // import "github.com/docker/docker/api/types/registry" package registry // import "github.com/docker/docker/api/types/registry"
import ( import (
"context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"io" "io"
@ -12,6 +13,18 @@ import (
// authorization credentials for registry operations (push/pull). // authorization credentials for registry operations (push/pull).
const AuthHeader = "X-Registry-Auth" const AuthHeader = "X-Registry-Auth"
// RequestAuthConfig is a function interface that clients can supply
// to retry operations after getting an authorization error.
//
// The function must return the [AuthHeader] value ([AuthConfig]), encoded
// in base64url format ([RFC4648, section 5]), which can be decoded by
// [DecodeAuthConfig].
//
// It must return an error if the privilege request fails.
//
// [RFC4648, section 5]: https://tools.ietf.org/html/rfc4648#section-5
type RequestAuthConfig func(context.Context) (string, error)
// AuthConfig contains authorization information for connecting to a Registry. // AuthConfig contains authorization information for connecting to a Registry.
type AuthConfig struct { type AuthConfig struct {
Username string `json:"username,omitempty"` Username string `json:"username,omitempty"`
@ -34,10 +47,9 @@ type AuthConfig struct {
} }
// EncodeAuthConfig serializes the auth configuration as a base64url encoded // 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]) JSON string for sending through the X-Registry-Auth header.
// //
// For details on base64url encoding, see: // [RFC4648, section 5]: https://tools.ietf.org/html/rfc4648#section-5
// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5
func EncodeAuthConfig(authConfig AuthConfig) (string, error) { func EncodeAuthConfig(authConfig AuthConfig) (string, error) {
buf, err := json.Marshal(authConfig) buf, err := json.Marshal(authConfig)
if err != nil { if err != nil {
@ -46,15 +58,14 @@ func EncodeAuthConfig(authConfig AuthConfig) (string, error) {
return base64.URLEncoding.EncodeToString(buf), nil return base64.URLEncoding.EncodeToString(buf), nil
} }
// DecodeAuthConfig decodes base64url encoded (RFC4648, section 5) JSON // DecodeAuthConfig decodes base64url encoded ([RFC4648, section 5]) JSON
// authentication information as sent through the X-Registry-Auth header. // authentication information as sent through the X-Registry-Auth header.
// //
// This function always returns an AuthConfig, even if an error occurs. It is up // 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 // to the caller to decide if authentication is required, and if the error can
// be ignored. // be ignored.
// //
// For details on base64url encoding, see: // [RFC4648, section 5]: https://tools.ietf.org/html/rfc4648#section-5
// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5
func DecodeAuthConfig(authEncoded string) (*AuthConfig, error) { func DecodeAuthConfig(authEncoded string) (*AuthConfig, error) {
if authEncoded == "" { if authEncoded == "" {
return &AuthConfig{}, nil return &AuthConfig{}, nil
@ -69,7 +80,7 @@ func DecodeAuthConfig(authEncoded string) (*AuthConfig, error) {
// clients and API versions. Current clients and API versions expect authentication // clients and API versions. Current clients and API versions expect authentication
// to be provided through the X-Registry-Auth header. // to be provided through the X-Registry-Auth header.
// //
// Like DecodeAuthConfig, this function always returns an AuthConfig, even if an // 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, // error occurs. It is up to the caller to decide if authentication is required,
// and if the error can be ignored. // and if the error can be ignored.
func DecodeAuthConfigBody(rdr io.ReadCloser) (*AuthConfig, error) { func DecodeAuthConfigBody(rdr io.ReadCloser) (*AuthConfig, error) {

View File

@ -10,11 +10,12 @@ import (
type SearchOptions struct { type SearchOptions struct {
RegistryAuth string RegistryAuth string
// PrivilegeFunc is a [types.RequestPrivilegeFunc] the client can // PrivilegeFunc is a function that clients can supply to retry operations
// supply to retry operations after getting an authorization error. // after getting an authorization error. This function returns the registry
// authentication header value in base64 encoded format, or an error if the
// privilege request fails.
// //
// It must return the registry authentication header value in base64 // For details, refer to [github.com/docker/docker/api/types/registry.RequestAuthConfig].
// format, or an error if the privilege request fails.
PrivilegeFunc func(context.Context) (string, error) PrivilegeFunc func(context.Context) (string, error)
Filters filters.Args Filters filters.Args
Limit int Limit int

View File

@ -122,7 +122,7 @@ type CAConfig struct {
SigningCAKey string `json:",omitempty"` SigningCAKey string `json:",omitempty"`
// If this value changes, and there is no specified signing cert and key, // If this value changes, and there is no specified signing cert and key,
// then the swarm is forced to generate a new root certificate ane key. // then the swarm is forced to generate a new root certificate and key.
ForceRotate uint64 `json:",omitempty"` ForceRotate uint64 `json:",omitempty"`
} }

View File

@ -1,6 +1,8 @@
package types package types
import ( import (
"context"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/storage" "github.com/docker/docker/api/types/storage"
@ -97,3 +99,11 @@ type RootFS = image.RootFS
// //
// Deprecated: use [image.InspectResponse]. // Deprecated: use [image.InspectResponse].
type ImageInspect = image.InspectResponse type ImageInspect = image.InspectResponse
// RequestPrivilegeFunc is a function interface that clients can supply to
// retry operations after getting an authorization error.
// This function returns the registry authentication header value in base64
// format, or an error if the privilege request fails.
//
// Deprecated: moved to [github.com/docker/docker/api/types/registry.RequestAuthConfig].
type RequestPrivilegeFunc func(context.Context) (string, error)

View File

@ -414,7 +414,7 @@ type Info struct {
// the Volume has not been successfully created yet. // the Volume has not been successfully created yet.
VolumeID string `json:",omitempty"` VolumeID string `json:",omitempty"`
// AccessibleTopolgoy is the topology this volume is actually accessible // AccessibleTopology is the topology this volume is actually accessible
// from. // from.
AccessibleTopology []Topology `json:",omitempty"` AccessibleTopology []Topology `json:",omitempty"`
} }

View File

@ -3,15 +3,29 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"net/url" "net/url"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
) )
// ImageHistory returns the changes in an image in history format. // ImageHistory returns the changes in an image in history format.
func (cli *Client) ImageHistory(ctx context.Context, imageID string) ([]image.HistoryResponseItem, error) { func (cli *Client) ImageHistory(ctx context.Context, imageID string, opts image.HistoryOptions) ([]image.HistoryResponseItem, error) {
values := url.Values{}
if opts.Platform != nil {
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
return nil, err
}
p, err := json.Marshal(*opts.Platform)
if err != nil {
return nil, fmt.Errorf("invalid platform: %v", err)
}
values.Set("platform", string(p))
}
var history []image.HistoryResponseItem var history []image.HistoryResponseItem
serverResp, err := cli.get(ctx, "/images/"+imageID+"/history", url.Values{}, nil) serverResp, err := cli.get(ctx, "/images/"+imageID+"/history", values, nil)
defer ensureReaderClosed(serverResp) defer ensureReaderClosed(serverResp)
if err != nil { if err != nil {
return history, err return history, err

View File

@ -2,6 +2,7 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"encoding/json"
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
@ -12,12 +13,28 @@ import (
// ImageLoad loads an image in the docker host from the client host. // 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 // It's up to the caller to close the io.ReadCloser in the
// ImageLoadResponse returned by this function. // ImageLoadResponse returned by this function.
func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (image.LoadResponse, error) { //
// Platform is an optional parameter that specifies the platform to load from
// the provided multi-platform image. This is only has effect if the input image
// is a multi-platform image.
func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, opts image.LoadOptions) (image.LoadResponse, error) {
v := url.Values{} v := url.Values{}
v.Set("quiet", "0") v.Set("quiet", "0")
if quiet { if opts.Quiet {
v.Set("quiet", "1") v.Set("quiet", "1")
} }
if opts.Platform != nil {
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
return image.LoadResponse{}, err
}
p, err := json.Marshal(*opts.Platform)
if err != nil {
return image.LoadResponse{}, err
}
v.Set("platform", string(p))
}
resp, err := cli.postRaw(ctx, "/images/load", v, input, http.Header{ resp, err := cli.postRaw(ctx, "/images/load", v, input, http.Header{
"Content-Type": {"application/x-tar"}, "Content-Type": {"application/x-tar"},
}) })

View File

@ -2,17 +2,33 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"encoding/json"
"fmt"
"io" "io"
"net/url" "net/url"
"github.com/docker/docker/api/types/image"
) )
// ImageSave retrieves one or more images from the docker host as an io.ReadCloser. // ImageSave retrieves one or more images from the docker host as an io.ReadCloser.
// It's up to the caller to store the images and close the stream. // It's up to the caller to store the images and close the stream.
func (cli *Client) ImageSave(ctx context.Context, imageIDs []string) (io.ReadCloser, error) { func (cli *Client) ImageSave(ctx context.Context, imageIDs []string, opts image.SaveOptions) (io.ReadCloser, error) {
query := url.Values{ query := url.Values{
"names": imageIDs, "names": imageIDs,
} }
if opts.Platform != nil {
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
return nil, err
}
p, err := json.Marshal(*opts.Platform)
if err != nil {
return nil, fmt.Errorf("invalid platform: %v", err)
}
query.Set("platform", string(p))
}
resp, err := cli.get(ctx, "/images/get", query, nil) resp, err := cli.get(ctx, "/images/get", query, nil)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -91,16 +91,16 @@ type ImageAPIClient interface {
BuildCachePrune(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error) BuildCachePrune(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error)
BuildCancel(ctx context.Context, id string) error BuildCancel(ctx context.Context, id string) error
ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error) ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error)
ImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, error) ImageHistory(ctx context.Context, image string, opts image.HistoryOptions) ([]image.HistoryResponseItem, error)
ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error)
ImageInspectWithRaw(ctx context.Context, image string) (image.InspectResponse, []byte, error) ImageInspectWithRaw(ctx context.Context, image string) (image.InspectResponse, []byte, error)
ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error) ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error)
ImageLoad(ctx context.Context, input io.Reader, quiet bool) (image.LoadResponse, error) ImageLoad(ctx context.Context, input io.Reader, opts image.LoadOptions) (image.LoadResponse, error)
ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error) ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error)
ImagePush(ctx context.Context, ref string, options image.PushOptions) (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) ImageRemove(ctx context.Context, image string, options image.RemoveOptions) ([]image.DeleteResponse, error)
ImageSave(ctx context.Context, images []string, opts image.SaveOptions) (io.ReadCloser, error)
ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error) ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error)
ImageSave(ctx context.Context, images []string) (io.ReadCloser, error)
ImageTag(ctx context.Context, image, ref string) error ImageTag(ctx context.Context, image, ref string) error
ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error) ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error)
} }

View File

@ -290,7 +290,7 @@ func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr,
} }
// Stream is an io.Writer for output with utilities to get the output's file // Stream is an io.Writer for output with utilities to get the output's file
// descriptor and to detect wether it's a terminal. // descriptor and to detect whether it's a terminal.
// //
// it is subset of the streams.Out type in // it is subset of the streams.Out type in
// https://pkg.go.dev/github.com/docker/cli@v20.10.17+incompatible/cli/streams#Out // https://pkg.go.dev/github.com/docker/cli@v20.10.17+incompatible/cli/streams#Out

View File

@ -124,7 +124,7 @@ func (bufPool *BufioWriterPool) Put(b *bufio.Writer) {
} }
// NewWriteCloserWrapper returns a wrapper which puts the bufio.Writer back // NewWriteCloserWrapper returns a wrapper which puts the bufio.Writer back
// into the pool and closes the writer if it's an io.Writecloser. // into the pool and closes the writer if it's an io.WriteCloser.
func (bufPool *BufioWriterPool) NewWriteCloserWrapper(buf *bufio.Writer, w io.Writer) io.WriteCloser { func (bufPool *BufioWriterPool) NewWriteCloserWrapper(buf *bufio.Writer, w io.Writer) io.WriteCloser {
return ioutils.NewWriteCloserWrapper(w, func() error { return ioutils.NewWriteCloserWrapper(w, func() error {
buf.Flush() buf.Flush()

View File

@ -6,7 +6,7 @@ import (
// Lgetxattr retrieves the value of the extended attribute identified by attr // Lgetxattr retrieves the value of the extended attribute identified by attr
// and associated with the given path in the file system. // and associated with the given path in the file system.
// It will returns a nil slice and nil error if the xattr is not set. // It returns a nil slice and nil error if the xattr is not set.
func Lgetxattr(path string, attr string) ([]byte, error) { func Lgetxattr(path string, attr string) ([]byte, error) {
sysErr := func(err error) ([]byte, error) { sysErr := func(err error) ([]byte, error) {
return nil, &XattrError{Op: "lgetxattr", Attr: attr, Path: path, Err: err} return nil, &XattrError{Op: "lgetxattr", Attr: attr, Path: path, Err: err}

View File

@ -359,7 +359,7 @@ func hasScheme(reposName string) bool {
} }
func validateHostPort(s string) error { func validateHostPort(s string) error {
// Split host and port, and in case s can not be splitted, assume host only // Split host and port, and in case s can not be split, assume host only
host, port, err := net.SplitHostPort(s) host, port, err := net.SplitHostPort(s)
if err != nil { if err != nil {
host = s host = s

2
vendor/modules.txt vendored
View File

@ -55,7 +55,7 @@ github.com/docker/distribution/registry/client/transport
github.com/docker/distribution/registry/storage/cache github.com/docker/distribution/registry/storage/cache
github.com/docker/distribution/registry/storage/cache/memory github.com/docker/distribution/registry/storage/cache/memory
github.com/docker/distribution/uuid github.com/docker/distribution/uuid
# github.com/docker/docker v27.0.2-0.20240808103429-2269acc7a31d+incompatible # github.com/docker/docker v27.0.2-0.20240912171519-164cae56ed95+incompatible
## explicit ## explicit
github.com/docker/docker/api github.com/docker/docker/api
github.com/docker/docker/api/types github.com/docker/docker/api/types