Merge pull request #4422 from thaJeztah/update_engine

vendor: github.com/docker/docker dab9ffb252186f4c47416addb136d579f9314c6a (25.0-dev)
This commit is contained in:
Sebastiaan van Stijn 2023-07-15 14:07:30 +02:00 committed by GitHub
commit 6654ea1434
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 497 additions and 372 deletions

View File

@ -7,6 +7,7 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client" "github.com/docker/docker/client"
specs "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/image-spec/specs-go/v1"
) )
@ -23,7 +24,7 @@ type fakeClient struct {
containerName string) (container.CreateResponse, error) containerName string) (container.CreateResponse, error)
containerStartFunc func(container string, options types.ContainerStartOptions) error containerStartFunc func(container string, options types.ContainerStartOptions) error
imageCreateFunc func(parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) imageCreateFunc func(parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error)
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
containerStatPathFunc func(container, path string) (types.ContainerPathStat, error) containerStatPathFunc func(container, path string) (types.ContainerPathStat, error)
containerCopyFromFunc func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) containerCopyFromFunc func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error)
logFunc func(string, types.ContainerLogsOptions) (io.ReadCloser, error) logFunc func(string, types.ContainerLogsOptions) (io.ReadCloser, error)
@ -96,11 +97,11 @@ func (f *fakeClient) ImageCreate(_ context.Context, parentReference string, opti
return nil, nil return nil, nil
} }
func (f *fakeClient) Info(_ context.Context) (types.Info, error) { func (f *fakeClient) Info(_ context.Context) (system.Info, error) {
if f.infoFunc != nil { if f.infoFunc != nil {
return f.infoFunc() return f.infoFunc()
} }
return types.Info{}, nil return system.Info{}, nil
} }
func (f *fakeClient) ContainerStatPath(_ context.Context, container, path string) (types.ContainerPathStat, error) { func (f *fakeClient) ContainerStatPath(_ context.Context, container, path string) (types.ContainerPathStat, error) {

View File

@ -18,6 +18,7 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/system"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
specs "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/pflag" "github.com/spf13/pflag"
@ -137,8 +138,8 @@ func TestCreateContainerImagePullPolicy(t *testing.T) {
defer func() { pullCounter++ }() defer func() { pullCounter++ }()
return io.NopCloser(strings.NewReader("")), nil return io.NopCloser(strings.NewReader("")), nil
}, },
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{IndexServerAddress: "https://indexserver.example.com"}, nil return system.Info{IndexServerAddress: "https://indexserver.example.com"}, nil
}, },
} }
fakeCLI := test.NewFakeCli(client) fakeCLI := test.NewFakeCli(client)

View File

@ -9,6 +9,7 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client" "github.com/docker/docker/client"
) )
@ -18,7 +19,7 @@ type fakeClient struct {
imageSaveFunc func(images []string) (io.ReadCloser, error) imageSaveFunc func(images []string) (io.ReadCloser, error)
imageRemoveFunc func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) imageRemoveFunc func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error)
imagePushFunc func(ref string, options types.ImagePushOptions) (io.ReadCloser, error) imagePushFunc func(ref string, options types.ImagePushOptions) (io.ReadCloser, error)
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
imagePullFunc func(ref string, options types.ImagePullOptions) (io.ReadCloser, error) imagePullFunc func(ref string, options types.ImagePullOptions) (io.ReadCloser, error)
imagesPruneFunc func(pruneFilter filters.Args) (types.ImagesPruneReport, error) imagesPruneFunc func(pruneFilter filters.Args) (types.ImagesPruneReport, error)
imageLoadFunc func(input io.Reader, quiet bool) (types.ImageLoadResponse, error) imageLoadFunc func(input io.Reader, quiet bool) (types.ImageLoadResponse, error)
@ -59,11 +60,11 @@ func (cli *fakeClient) ImagePush(_ context.Context, ref string, options types.Im
return io.NopCloser(strings.NewReader("")), nil return io.NopCloser(strings.NewReader("")), nil
} }
func (cli *fakeClient) Info(_ context.Context) (types.Info, error) { func (cli *fakeClient) Info(_ context.Context) (system.Info, error) {
if cli.infoFunc != nil { if cli.infoFunc != nil {
return cli.infoFunc() return cli.infoFunc()
} }
return types.Info{}, nil return system.Info{}, nil
} }
func (cli *fakeClient) ImagePull(_ context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error) { func (cli *fakeClient) ImagePull(_ context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error) {

View File

@ -5,12 +5,13 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client" "github.com/docker/docker/client"
) )
type fakeClient struct { type fakeClient struct {
client.Client client.Client
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
nodeInspectFunc func() (swarm.Node, []byte, error) nodeInspectFunc func() (swarm.Node, []byte, error)
nodeListFunc func() ([]swarm.Node, error) nodeListFunc func() ([]swarm.Node, error)
nodeRemoveFunc func() error nodeRemoveFunc func() error
@ -48,11 +49,11 @@ func (cli *fakeClient) NodeUpdate(_ context.Context, nodeID string, version swar
return nil return nil
} }
func (cli *fakeClient) Info(context.Context) (types.Info, error) { func (cli *fakeClient) Info(context.Context) (system.Info, error) {
if cli.infoFunc != nil { if cli.infoFunc != nil {
return cli.infoFunc() return cli.infoFunc()
} }
return types.Info{}, nil return system.Info{}, nil
} }
func (cli *fakeClient) TaskInspectWithRaw(_ context.Context, taskID string) (swarm.Task, []byte, error) { func (cli *fakeClient) TaskInspectWithRaw(_ context.Context, taskID string) (swarm.Task, []byte, error) {

View File

@ -9,8 +9,8 @@ import (
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/command/formatter"
"github.com/docker/cli/cli/command/inspect" "github.com/docker/cli/cli/command/inspect"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
units "github.com/docker/go-units" units "github.com/docker/go-units"
) )
@ -100,7 +100,7 @@ func NewFormat(source string, quiet bool) formatter.Format {
} }
// FormatWrite writes the context // FormatWrite writes the context
func FormatWrite(ctx formatter.Context, nodes []swarm.Node, info types.Info) error { func FormatWrite(ctx formatter.Context, nodes []swarm.Node, info system.Info) error {
render := func(format func(subContext formatter.SubContext) error) error { render := func(format func(subContext formatter.SubContext) error) error {
for _, node := range nodes { for _, node := range nodes {
nodeCtx := &nodeContext{n: node, info: info} nodeCtx := &nodeContext{n: node, info: info}
@ -127,7 +127,7 @@ func FormatWrite(ctx formatter.Context, nodes []swarm.Node, info types.Info) err
type nodeContext struct { type nodeContext struct {
formatter.HeaderContext formatter.HeaderContext
n swarm.Node n swarm.Node
info types.Info info system.Info
} }
func (c *nodeContext) MarshalJSON() ([]byte, error) { func (c *nodeContext) MarshalJSON() ([]byte, error) {

View File

@ -9,8 +9,8 @@ import (
"github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/command/formatter"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/stringid"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@ -204,7 +204,7 @@ foobar_boo Unknown
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out
err := FormatWrite(tc.context, nodes, types.Info{Swarm: swarm.Info{Cluster: &tc.clusterInfo}}) err := FormatWrite(tc.context, nodes, system.Info{Swarm: swarm.Info{Cluster: &tc.clusterInfo}})
if err != nil { if err != nil {
assert.Error(t, err, tc.expected) assert.Error(t, err, tc.expected)
} else { } else {
@ -217,7 +217,7 @@ foobar_boo Unknown
func TestNodeContextWriteJSON(t *testing.T) { func TestNodeContextWriteJSON(t *testing.T) {
cases := []struct { cases := []struct {
expected []map[string]interface{} expected []map[string]interface{}
info types.Info info system.Info
}{ }{
{ {
expected: []map[string]interface{}{ expected: []map[string]interface{}{
@ -225,7 +225,7 @@ func TestNodeContextWriteJSON(t *testing.T) {
{"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": ""}, {"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": ""},
{"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "18.03.0-ce"}, {"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "18.03.0-ce"},
}, },
info: types.Info{}, info: system.Info{},
}, },
{ {
expected: []map[string]interface{}{ expected: []map[string]interface{}{
@ -233,7 +233,7 @@ func TestNodeContextWriteJSON(t *testing.T) {
{"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Needs Rotation", "EngineVersion": ""}, {"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Needs Rotation", "EngineVersion": ""},
{"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "18.03.0-ce"}, {"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "18.03.0-ce"},
}, },
info: types.Info{ info: system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
Cluster: &swarm.ClusterInfo{ Cluster: &swarm.ClusterInfo{
TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}, TLSInfo: swarm.TLSInfo{TrustRoot: "hi"},
@ -271,7 +271,7 @@ func TestNodeContextWriteJSONField(t *testing.T) {
{ID: "nodeID2", Description: swarm.NodeDescription{Hostname: "foobar_bar"}}, {ID: "nodeID2", Description: swarm.NodeDescription{Hostname: "foobar_bar"}},
} }
out := bytes.NewBufferString("") out := bytes.NewBufferString("")
err := FormatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, nodes, types.Info{}) err := FormatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, nodes, system.Info{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -7,8 +7,8 @@ import (
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package functions . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package functions
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
"gotest.tools/v3/golden" "gotest.tools/v3/golden"
@ -19,7 +19,7 @@ func TestNodeInspectErrors(t *testing.T) {
args []string args []string
flags map[string]string flags map[string]string
nodeInspectFunc func() (swarm.Node, []byte, error) nodeInspectFunc func() (swarm.Node, []byte, error)
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
expectedError string expectedError string
}{ }{
{ {
@ -27,8 +27,8 @@ func TestNodeInspectErrors(t *testing.T) {
}, },
{ {
args: []string{"self"}, args: []string{"self"},
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{}, errors.Errorf("error asking for node info") return system.Info{}, errors.Errorf("error asking for node info")
}, },
expectedError: "error asking for node info", expectedError: "error asking for node info",
}, },
@ -37,8 +37,8 @@ func TestNodeInspectErrors(t *testing.T) {
nodeInspectFunc: func() (swarm.Node, []byte, error) { nodeInspectFunc: func() (swarm.Node, []byte, error) {
return swarm.Node{}, []byte{}, errors.Errorf("error inspecting the node") return swarm.Node{}, []byte{}, errors.Errorf("error inspecting the node")
}, },
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{}, errors.Errorf("error asking for node info") return system.Info{}, errors.Errorf("error asking for node info")
}, },
expectedError: "error inspecting the node", expectedError: "error inspecting the node",
}, },
@ -47,8 +47,8 @@ func TestNodeInspectErrors(t *testing.T) {
nodeInspectFunc: func() (swarm.Node, []byte, error) { nodeInspectFunc: func() (swarm.Node, []byte, error) {
return swarm.Node{}, []byte{}, errors.Errorf("error inspecting the node") return swarm.Node{}, []byte{}, errors.Errorf("error inspecting the node")
}, },
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{Swarm: swarm.Info{NodeID: "abc"}}, nil return system.Info{Swarm: swarm.Info{NodeID: "abc"}}, nil
}, },
expectedError: "error inspecting the node", expectedError: "error inspecting the node",
}, },
@ -57,8 +57,8 @@ func TestNodeInspectErrors(t *testing.T) {
flags: map[string]string{ flags: map[string]string{
"pretty": "true", "pretty": "true",
}, },
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{}, errors.Errorf("error asking for node info") return system.Info{}, errors.Errorf("error asking for node info")
}, },
expectedError: "error asking for node info", expectedError: "error asking for node info",
}, },

View File

@ -11,6 +11,7 @@ import (
flagsHelper "github.com/docker/cli/cli/flags" flagsHelper "github.com/docker/cli/cli/flags"
"github.com/docker/cli/opts" "github.com/docker/cli/opts"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/system"
"github.com/fvbommel/sortorder" "github.com/fvbommel/sortorder"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -53,7 +54,7 @@ func runList(dockerCli command.Cli, options listOptions) error {
return err return err
} }
info := types.Info{} info := system.Info{}
if len(nodes) > 0 && !options.quiet { if len(nodes) > 0 && !options.quiet {
// only non-empty nodes and not quiet, should we call /info api // only non-empty nodes and not quiet, should we call /info api
info, err = client.Info(ctx) info, err = client.Info(ctx)

View File

@ -7,8 +7,8 @@ import (
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"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 +18,7 @@ import (
func TestNodeListErrorOnAPIFailure(t *testing.T) { func TestNodeListErrorOnAPIFailure(t *testing.T) {
testCases := []struct { testCases := []struct {
nodeListFunc func() ([]swarm.Node, error) nodeListFunc func() ([]swarm.Node, error)
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
expectedError string expectedError string
}{ }{
{ {
@ -35,8 +35,8 @@ func TestNodeListErrorOnAPIFailure(t *testing.T) {
}, },
}, nil }, nil
}, },
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{}, errors.Errorf("error asking for node info") return system.Info{}, errors.Errorf("error asking for node info")
}, },
expectedError: "error asking for node info", expectedError: "error asking for node info",
}, },
@ -61,8 +61,8 @@ func TestNodeList(t *testing.T) {
*Node(NodeID("nodeID3"), Hostname("node-1-foo")), *Node(NodeID("nodeID3"), Hostname("node-1-foo")),
}, nil }, nil
}, },
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{ return system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
NodeID: "nodeID1", NodeID: "nodeID1",
}, },
@ -98,8 +98,8 @@ func TestNodeListDefaultFormatFromConfig(t *testing.T) {
*Node(NodeID("nodeID3"), Hostname("nodeHostname3")), *Node(NodeID("nodeID3"), Hostname("nodeHostname3")),
}, nil }, nil
}, },
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{ return system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
NodeID: "nodeID1", NodeID: "nodeID1",
}, },
@ -122,8 +122,8 @@ func TestNodeListFormat(t *testing.T) {
*Node(NodeID("nodeID2"), Hostname("nodeHostname2"), Manager()), *Node(NodeID("nodeID2"), Hostname("nodeHostname2"), Manager()),
}, nil }, nil
}, },
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{ return system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
NodeID: "nodeID1", NodeID: "nodeID1",
}, },

View File

@ -11,6 +11,7 @@ import (
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
"gotest.tools/v3/golden" "gotest.tools/v3/golden"
@ -20,15 +21,15 @@ func TestNodePsErrors(t *testing.T) {
testCases := []struct { testCases := []struct {
args []string args []string
flags map[string]string flags map[string]string
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
nodeInspectFunc func() (swarm.Node, []byte, error) nodeInspectFunc func() (swarm.Node, []byte, error)
taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error) taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error)
taskInspectFunc func(taskID string) (swarm.Task, []byte, error) taskInspectFunc func(taskID string) (swarm.Task, []byte, error)
expectedError string expectedError string
}{ }{
{ {
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{}, errors.Errorf("error asking for node info") return system.Info{}, errors.Errorf("error asking for node info")
}, },
expectedError: "error asking for node info", expectedError: "error asking for node info",
}, },
@ -69,7 +70,7 @@ func TestNodePs(t *testing.T) {
name string name string
args []string args []string
flags map[string]string flags map[string]string
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
nodeInspectFunc func() (swarm.Node, []byte, error) nodeInspectFunc func() (swarm.Node, []byte, error)
taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error) taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error)
taskInspectFunc func(taskID string) (swarm.Task, []byte, error) taskInspectFunc func(taskID string) (swarm.Task, []byte, error)

View File

@ -6,6 +6,7 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client" "github.com/docker/docker/client"
) )
@ -71,6 +72,6 @@ func (c *fakeClient) PluginInspectWithRaw(_ context.Context, name string) (*type
return nil, nil, nil return nil, nil, nil
} }
func (c *fakeClient) Info(context.Context) (types.Info, error) { func (c *fakeClient) Info(context.Context) (system.Info, error) {
return types.Info{}, nil return system.Info{}, nil
} }

View File

@ -8,8 +8,8 @@ import (
configtypes "github.com/docker/cli/cli/config/types" configtypes "github.com/docker/cli/cli/config/types"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"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/api/types/system"
"github.com/docker/docker/client" "github.com/docker/docker/client"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@ -34,8 +34,8 @@ type fakeClient struct {
client.Client client.Client
} }
func (c fakeClient) Info(context.Context) (types.Info, error) { func (c fakeClient) Info(context.Context) (system.Info, error) {
return types.Info{}, nil return system.Info{}, nil
} }
func (c fakeClient) RegistryLogin(_ context.Context, auth registrytypes.AuthConfig) (registrytypes.AuthenticateOKBody, error) { func (c fakeClient) RegistryLogin(_ context.Context, auth registrytypes.AuthConfig) (registrytypes.AuthenticateOKBody, error) {

View File

@ -9,8 +9,8 @@ import (
. "github.com/docker/cli/cli/command" // Prevents a circular import with "github.com/docker/cli/internal/test" . "github.com/docker/cli/cli/command" // Prevents a circular import with "github.com/docker/cli/internal/test"
configtypes "github.com/docker/cli/cli/config/types" configtypes "github.com/docker/cli/cli/config/types"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client" "github.com/docker/docker/client"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@ -18,7 +18,7 @@ import (
type fakeClient struct { type fakeClient struct {
client.Client client.Client
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
} }
var testAuthConfigs = []registry.AuthConfig{ var testAuthConfigs = []registry.AuthConfig{
@ -34,11 +34,11 @@ var testAuthConfigs = []registry.AuthConfig{
}, },
} }
func (cli *fakeClient) Info(_ context.Context) (types.Info, error) { func (cli *fakeClient) Info(_ context.Context) (system.Info, error) {
if cli.infoFunc != nil { if cli.infoFunc != nil {
return cli.infoFunc() return cli.infoFunc()
} }
return types.Info{}, nil return system.Info{}, nil
} }
func TestGetDefaultAuthConfig(t *testing.T) { func TestGetDefaultAuthConfig(t *testing.T) {

View File

@ -6,6 +6,7 @@ import (
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client" "github.com/docker/docker/client"
) )
@ -15,7 +16,7 @@ type fakeClient struct {
serviceUpdateFunc func(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) serviceUpdateFunc func(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error)
serviceListFunc func(context.Context, types.ServiceListOptions) ([]swarm.Service, error) serviceListFunc func(context.Context, types.ServiceListOptions) ([]swarm.Service, error)
taskListFunc func(context.Context, types.TaskListOptions) ([]swarm.Task, error) taskListFunc func(context.Context, types.TaskListOptions) ([]swarm.Task, error)
infoFunc func(ctx context.Context) (types.Info, error) infoFunc func(ctx context.Context) (system.Info, error)
networkInspectFunc func(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, error) networkInspectFunc func(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, error)
nodeListFunc func(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) nodeListFunc func(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error)
} }
@ -58,9 +59,9 @@ func (f *fakeClient) ServiceUpdate(ctx context.Context, serviceID string, versio
return types.ServiceUpdateResponse{}, nil return types.ServiceUpdateResponse{}, nil
} }
func (f *fakeClient) Info(ctx context.Context) (types.Info, error) { func (f *fakeClient) Info(ctx context.Context) (system.Info, error) {
if f.infoFunc == nil { if f.infoFunc == nil {
return types.Info{}, nil return system.Info{}, nil
} }
return f.infoFunc(ctx) return f.infoFunc(ctx)
} }

View File

@ -9,6 +9,7 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@ -117,8 +118,8 @@ func TestUpdateNodeFilter(t *testing.T) {
) )
client := &fakeClient{ client := &fakeClient{
infoFunc: func(_ context.Context) (types.Info, error) { infoFunc: func(_ context.Context) (system.Info, error) {
return types.Info{Swarm: swarm.Info{NodeID: selfNodeID}}, nil return system.Info{Swarm: swarm.Info{NodeID: selfNodeID}}, nil
}, },
} }

View File

@ -5,12 +5,13 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client" "github.com/docker/docker/client"
) )
type fakeClient struct { type fakeClient struct {
client.Client client.Client
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
swarmInitFunc func() (string, error) swarmInitFunc func() (string, error)
swarmInspectFunc func() (swarm.Swarm, error) swarmInspectFunc func() (swarm.Swarm, error)
nodeInspectFunc func() (swarm.Node, []byte, error) nodeInspectFunc func() (swarm.Node, []byte, error)
@ -21,11 +22,11 @@ type fakeClient struct {
swarmUnlockFunc func(req swarm.UnlockRequest) error swarmUnlockFunc func(req swarm.UnlockRequest) error
} }
func (cli *fakeClient) Info(context.Context) (types.Info, error) { func (cli *fakeClient) Info(context.Context) (system.Info, error) {
if cli.infoFunc != nil { if cli.infoFunc != nil {
return cli.infoFunc() return cli.infoFunc()
} }
return types.Info{}, nil return system.Info{}, nil
} }
func (cli *fakeClient) NodeInspectWithRaw(context.Context, string) (swarm.Node, []byte, error) { func (cli *fakeClient) NodeInspectWithRaw(context.Context, string) (swarm.Node, []byte, error) {

View File

@ -6,8 +6,8 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"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 +18,7 @@ func TestSwarmJoinErrors(t *testing.T) {
name string name string
args []string args []string
swarmJoinFunc func() error swarmJoinFunc func() error
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
expectedError string expectedError string
}{ }{
{ {
@ -41,8 +41,8 @@ func TestSwarmJoinErrors(t *testing.T) {
{ {
name: "join-failed-on-init", name: "join-failed-on-init",
args: []string{"remote"}, args: []string{"remote"},
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{}, errors.Errorf("error asking for node info") return system.Info{}, errors.Errorf("error asking for node info")
}, },
expectedError: "error asking for node info", expectedError: "error asking for node info",
}, },
@ -62,13 +62,13 @@ func TestSwarmJoinErrors(t *testing.T) {
func TestSwarmJoin(t *testing.T) { func TestSwarmJoin(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
expected string expected string
}{ }{
{ {
name: "join-as-manager", name: "join-as-manager",
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{ return system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
ControlAvailable: true, ControlAvailable: true,
}, },
@ -78,8 +78,8 @@ func TestSwarmJoin(t *testing.T) {
}, },
{ {
name: "join-as-worker", name: "join-as-worker",
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{ return system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
ControlAvailable: false, ControlAvailable: false,
}, },

View File

@ -7,8 +7,8 @@ import (
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
"gotest.tools/v3/golden" "gotest.tools/v3/golden"
@ -19,7 +19,7 @@ func TestSwarmJoinTokenErrors(t *testing.T) {
name string name string
args []string args []string
flags map[string]string flags map[string]string
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
swarmInspectFunc func() (swarm.Swarm, error) swarmInspectFunc func() (swarm.Swarm, error)
swarmUpdateFunc func(swarm swarm.Spec, flags swarm.UpdateFlags) error swarmUpdateFunc func(swarm swarm.Spec, flags swarm.UpdateFlags) error
nodeInspectFunc func() (swarm.Node, []byte, error) nodeInspectFunc func() (swarm.Node, []byte, error)
@ -80,8 +80,8 @@ func TestSwarmJoinTokenErrors(t *testing.T) {
{ {
name: "info-failed", name: "info-failed",
args: []string{"worker"}, args: []string{"worker"},
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{}, errors.Errorf("error asking for node info") return system.Info{}, errors.Errorf("error asking for node info")
}, },
expectedError: "error asking for node info", expectedError: "error asking for node info",
}, },
@ -108,15 +108,15 @@ func TestSwarmJoinToken(t *testing.T) {
name string name string
args []string args []string
flags map[string]string flags map[string]string
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
swarmInspectFunc func() (swarm.Swarm, error) swarmInspectFunc func() (swarm.Swarm, error)
nodeInspectFunc func() (swarm.Node, []byte, error) nodeInspectFunc func() (swarm.Node, []byte, error)
}{ }{
{ {
name: "worker", name: "worker",
args: []string{"worker"}, args: []string{"worker"},
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{ return system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
NodeID: "nodeID", NodeID: "nodeID",
}, },
@ -132,8 +132,8 @@ func TestSwarmJoinToken(t *testing.T) {
{ {
name: "manager", name: "manager",
args: []string{"manager"}, args: []string{"manager"},
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{ return system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
NodeID: "nodeID", NodeID: "nodeID",
}, },
@ -152,8 +152,8 @@ func TestSwarmJoinToken(t *testing.T) {
flags: map[string]string{ flags: map[string]string{
flagRotate: "true", flagRotate: "true",
}, },
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{ return system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
NodeID: "nodeID", NodeID: "nodeID",
}, },

View File

@ -7,8 +7,8 @@ import (
"github.com/docker/cli/cli/streams" "github.com/docker/cli/cli/streams"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
) )
@ -18,7 +18,7 @@ func TestSwarmUnlockErrors(t *testing.T) {
name string name string
args []string args []string
swarmUnlockFunc func(req swarm.UnlockRequest) error swarmUnlockFunc func(req swarm.UnlockRequest) error
infoFunc func() (types.Info, error) infoFunc func() (system.Info, error)
expectedError string expectedError string
}{ }{
{ {
@ -28,8 +28,8 @@ func TestSwarmUnlockErrors(t *testing.T) {
}, },
{ {
name: "is-not-part-of-a-swarm", name: "is-not-part-of-a-swarm",
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{ return system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
LocalNodeState: swarm.LocalNodeStateInactive, LocalNodeState: swarm.LocalNodeStateInactive,
}, },
@ -39,8 +39,8 @@ func TestSwarmUnlockErrors(t *testing.T) {
}, },
{ {
name: "is-not-locked", name: "is-not-locked",
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{ return system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
LocalNodeState: swarm.LocalNodeStateActive, LocalNodeState: swarm.LocalNodeStateActive,
}, },
@ -50,8 +50,8 @@ func TestSwarmUnlockErrors(t *testing.T) {
}, },
{ {
name: "unlockrequest-failed", name: "unlockrequest-failed",
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{ return system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
LocalNodeState: swarm.LocalNodeStateLocked, LocalNodeState: swarm.LocalNodeStateLocked,
}, },
@ -78,8 +78,8 @@ func TestSwarmUnlockErrors(t *testing.T) {
func TestSwarmUnlock(t *testing.T) { func TestSwarmUnlock(t *testing.T) {
input := "unlockKey" input := "unlockKey"
dockerCli := test.NewFakeCli(&fakeClient{ dockerCli := test.NewFakeCli(&fakeClient{
infoFunc: func() (types.Info, error) { infoFunc: func() (system.Info, error) {
return types.Info{ return system.Info{
Swarm: swarm.Info{ Swarm: swarm.Info{
LocalNodeState: swarm.LocalNodeStateLocked, LocalNodeState: swarm.LocalNodeStateLocked,
}, },

View File

@ -16,8 +16,8 @@ import (
"github.com/docker/cli/cli/debug" "github.com/docker/cli/cli/debug"
flagsHelper "github.com/docker/cli/cli/flags" flagsHelper "github.com/docker/cli/cli/flags"
"github.com/docker/cli/templates" "github.com/docker/cli/templates"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/docker/go-units" "github.com/docker/go-units"
@ -40,7 +40,7 @@ type info struct {
// preserve backwards compatibility in the JSON rendering // preserve backwards compatibility in the JSON rendering
// which has ServerInfo immediately within the top-level // which has ServerInfo immediately within the top-level
// object. // object.
*types.Info `json:",omitempty"` *system.Info `json:",omitempty"`
ServerErrors []string `json:",omitempty"` ServerErrors []string `json:",omitempty"`
UserName string `json:"-"` UserName string `json:"-"`
@ -86,7 +86,7 @@ func runInfo(cmd *cobra.Command, dockerCli command.Cli, opts *infoOptions) error
clientVersion: newClientVersion(dockerCli.CurrentContext(), nil), clientVersion: newClientVersion(dockerCli.CurrentContext(), nil),
Debug: debug.IsEnabled(), Debug: debug.IsEnabled(),
}, },
Info: &types.Info{}, Info: &system.Info{},
} }
if plugins, err := pluginmanager.ListPlugins(dockerCli, cmd.Root()); err == nil { if plugins, err := pluginmanager.ListPlugins(dockerCli, cmd.Root()); err == nil {
info.ClientInfo.Plugins = plugins info.ClientInfo.Plugins = plugins
@ -267,7 +267,7 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error {
for _, ci := range []struct { for _, ci := range []struct {
Name string Name string
Commit types.Commit Commit system.Commit
}{ }{
{"containerd", info.ContainerdCommit}, {"containerd", info.ContainerdCommit},
{"runc", info.RuncCommit}, {"runc", info.RuncCommit},
@ -280,7 +280,7 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error {
fprintln(output) fprintln(output)
} }
if len(info.SecurityOptions) != 0 { if len(info.SecurityOptions) != 0 {
if kvs, err := types.DecodeSecurityOptions(info.SecurityOptions); err != nil { if kvs, err := system.DecodeSecurityOptions(info.SecurityOptions); err != nil {
errs = append(errs, err) errs = append(errs, err)
} else { } else {
fprintln(output, " Security Options:") fprintln(output, " Security Options:")
@ -377,7 +377,7 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error {
} }
//nolint:gocyclo //nolint:gocyclo
func printSwarmInfo(output io.Writer, info types.Info) { func printSwarmInfo(output io.Writer, info system.Info) {
if info.Swarm.LocalNodeState == swarm.LocalNodeStateInactive || info.Swarm.LocalNodeState == swarm.LocalNodeStateLocked { if info.Swarm.LocalNodeState == swarm.LocalNodeStateInactive || info.Swarm.LocalNodeState == swarm.LocalNodeStateLocked {
return return
} }
@ -464,11 +464,11 @@ func printServerWarnings(stdErr io.Writer, info *info) {
// info.Warnings. This function is used to provide backward compatibility with // info.Warnings. This function is used to provide backward compatibility with
// daemons that do not provide these warnings. No new warnings should be added // daemons that do not provide these warnings. No new warnings should be added
// here. // here.
func printSecurityOptionsWarnings(stdErr io.Writer, info types.Info) { func printSecurityOptionsWarnings(stdErr io.Writer, info system.Info) {
if info.OSType == "windows" { if info.OSType == "windows" {
return return
} }
kvs, _ := types.DecodeSecurityOptions(info.SecurityOptions) kvs, _ := system.DecodeSecurityOptions(info.SecurityOptions)
for _, so := range kvs { for _, so := range kvs {
if so.Name != "seccomp" { if so.Name != "seccomp" {
continue continue
@ -486,7 +486,7 @@ func printSecurityOptionsWarnings(stdErr io.Writer, info types.Info) {
// info.Warnings. This function is used to provide backward compatibility with // info.Warnings. This function is used to provide backward compatibility with
// daemons that do not provide these warnings. No new warnings should be added // daemons that do not provide these warnings. No new warnings should be added
// here. // here.
func printServerWarningsLegacy(stdErr io.Writer, info types.Info) { func printServerWarningsLegacy(stdErr io.Writer, info system.Info) {
if info.OSType == "windows" { if info.OSType == "windows" {
return return
} }

View File

@ -8,9 +8,9 @@ import (
pluginmanager "github.com/docker/cli/cli-plugins/manager" pluginmanager "github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"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/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/golden" "gotest.tools/v3/golden"
@ -24,7 +24,7 @@ func base64Decode(val string) []byte {
const sampleID = "EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX" const sampleID = "EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX"
var sampleInfoNoSwarm = types.Info{ var sampleInfoNoSwarm = system.Info{
ID: sampleID, ID: sampleID,
Containers: 0, Containers: 0,
ContainersRunning: 0, ContainersRunning: 0,
@ -39,7 +39,7 @@ var sampleInfoNoSwarm = types.Info{
{"Native Overlay Diff", "true"}, {"Native Overlay Diff", "true"},
}, },
SystemStatus: nil, SystemStatus: nil,
Plugins: types.PluginsInfo{ Plugins: system.PluginsInfo{
Volume: []string{"local"}, Volume: []string{"local"},
Network: []string{"bridge", "host", "macvlan", "null", "overlay"}, Network: []string{"bridge", "host", "macvlan", "null", "overlay"},
Authorization: nil, Authorization: nil,
@ -98,7 +98,7 @@ var sampleInfoNoSwarm = types.Info{
Labels: []string{"provider=digitalocean"}, Labels: []string{"provider=digitalocean"},
ExperimentalBuild: false, ExperimentalBuild: false,
ServerVersion: "17.06.1-ce", ServerVersion: "17.06.1-ce",
Runtimes: map[string]types.Runtime{ Runtimes: map[string]system.Runtime{
"runc": { "runc": {
Path: "docker-runc", Path: "docker-runc",
Args: nil, Args: nil,
@ -109,20 +109,20 @@ var sampleInfoNoSwarm = types.Info{
LiveRestoreEnabled: false, LiveRestoreEnabled: false,
Isolation: "", Isolation: "",
InitBinary: "docker-init", InitBinary: "docker-init",
ContainerdCommit: types.Commit{ ContainerdCommit: system.Commit{
ID: "6e23458c129b551d5c9871e5174f6b1b7f6d1170", ID: "6e23458c129b551d5c9871e5174f6b1b7f6d1170",
Expected: "6e23458c129b551d5c9871e5174f6b1b7f6d1170", Expected: "6e23458c129b551d5c9871e5174f6b1b7f6d1170",
}, },
RuncCommit: types.Commit{ RuncCommit: system.Commit{
ID: "810190ceaa507aa2727d7ae6f4790c76ec150bd2", ID: "810190ceaa507aa2727d7ae6f4790c76ec150bd2",
Expected: "810190ceaa507aa2727d7ae6f4790c76ec150bd2", Expected: "810190ceaa507aa2727d7ae6f4790c76ec150bd2",
}, },
InitCommit: types.Commit{ InitCommit: system.Commit{
ID: "949e6fa", ID: "949e6fa",
Expected: "949e6fa", Expected: "949e6fa",
}, },
SecurityOptions: []string{"name=apparmor", "name=seccomp,profile=default"}, SecurityOptions: []string{"name=apparmor", "name=seccomp,profile=default"},
DefaultAddressPools: []types.NetworkAddressPool{ DefaultAddressPools: []system.NetworkAddressPool{
{ {
Base: "10.123.0.0/16", Base: "10.123.0.0/16",
Size: 24, Size: 24,

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
notaryfake "github.com/docker/cli/internal/test/notary" notaryfake "github.com/docker/cli/internal/test/notary"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/system"
apiclient "github.com/docker/docker/client" apiclient "github.com/docker/docker/client"
"github.com/theupdateframework/notary" "github.com/theupdateframework/notary"
"github.com/theupdateframework/notary/client" "github.com/theupdateframework/notary/client"
@ -27,8 +28,8 @@ type fakeClient struct {
apiclient.Client apiclient.Client
} }
func (c *fakeClient) Info(context.Context) (types.Info, error) { func (c *fakeClient) Info(context.Context) (system.Info, error) {
return types.Info{}, nil return system.Info{}, nil
} }
func (c *fakeClient) ImageInspectWithRaw(context.Context, string) (types.ImageInspect, []byte, error) { func (c *fakeClient) ImageInspectWithRaw(context.Context, string) (types.ImageInspect, []byte, error) {

View File

@ -12,7 +12,7 @@ require (
github.com/containerd/containerd v1.6.21 github.com/containerd/containerd v1.6.21
github.com/creack/pty v1.1.18 github.com/creack/pty v1.1.18
github.com/docker/distribution v2.8.2+incompatible github.com/docker/distribution v2.8.2+incompatible
github.com/docker/docker v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible // master (v25.0.0-dev) github.com/docker/docker v24.0.0-rc.2.0.20230714195812-dab9ffb25218+incompatible // master (v25.0.0-dev)
github.com/docker/docker-credential-helpers v0.7.0 github.com/docker/docker-credential-helpers v0.7.0
github.com/docker/go-connections v0.4.0 github.com/docker/go-connections v0.4.0
github.com/docker/go-units v0.5.0 github.com/docker/go-units v0.5.0
@ -24,7 +24,7 @@ require (
github.com/mitchellh/mapstructure v1.3.2 github.com/mitchellh/mapstructure v1.3.2
github.com/moby/buildkit v0.11.6 github.com/moby/buildkit v0.11.6
github.com/moby/patternmatcher v0.5.0 github.com/moby/patternmatcher v0.5.0
github.com/moby/swarmkit/v2 v2.0.0-20230627115642-ad0f3ae162fa github.com/moby/swarmkit/v2 v2.0.0-20230707182847-6f78b8199b05
github.com/moby/sys/sequential v0.5.0 github.com/moby/sys/sequential v0.5.0
github.com/moby/sys/signal v0.7.0 github.com/moby/sys/signal v0.7.0
github.com/moby/term v0.5.0 github.com/moby/term v0.5.0

View File

@ -100,8 +100,8 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xb
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.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible h1:XccikgvtGCEZE9ZQoaEApdx9ZvruGYakfi2tw4d/vUg= github.com/docker/docker v24.0.0-rc.2.0.20230714195812-dab9ffb25218+incompatible h1:lQ7FvH3oFGtG/ODOr0oAlRHQxJJkkbG+RyNHmiMWdI8=
github.com/docker/docker v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v24.0.0-rc.2.0.20230714195812-dab9ffb25218+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
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=
@ -275,8 +275,8 @@ github.com/moby/buildkit v0.11.6 h1:VYNdoKk5TVxN7k4RvZgdeM4GOyRvIi4Z8MXOY7xvyUs=
github.com/moby/buildkit v0.11.6/go.mod h1:GCqKfHhz+pddzfgaR7WmHVEE3nKKZMMDPpK8mh3ZLv4= github.com/moby/buildkit v0.11.6/go.mod h1:GCqKfHhz+pddzfgaR7WmHVEE3nKKZMMDPpK8mh3ZLv4=
github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/swarmkit/v2 v2.0.0-20230627115642-ad0f3ae162fa h1:9IilX0rZvnrQA+a0Cr9a9LKpudNrOWhT3Fy7T4yKcPc= github.com/moby/swarmkit/v2 v2.0.0-20230707182847-6f78b8199b05 h1:lvMq6zHXnGp6i+6iYDs1Uw9Q5bqiAYd6Sz08hZoxSmY=
github.com/moby/swarmkit/v2 v2.0.0-20230627115642-ad0f3ae162fa/go.mod h1:pC/nyFbvVvSV+Gm1rARMgMR3FrCumwEyoMjqVwEzJvA= github.com/moby/swarmkit/v2 v2.0.0-20230707182847-6f78b8199b05/go.mod h1:XUMlwIIC+wrwBDMUjxEvk5Z8FPoIPM8LdBw7w/Zu1rg=
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI= github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI=

View File

@ -9900,7 +9900,9 @@ paths:
Id: "22be93d5babb089c5aab8dbc369042fad48ff791584ca2da2100db837a1c7c30" Id: "22be93d5babb089c5aab8dbc369042fad48ff791584ca2da2100db837a1c7c30"
Warning: "" Warning: ""
403: 403:
description: "operation not supported for pre-defined networks" description: |
Forbidden operation. This happens when trying to create a network named after a pre-defined network,
or when trying to create an overlay network on a daemon which is not part of a Swarm cluster.
schema: schema:
$ref: "#/definitions/ErrorResponse" $ref: "#/definitions/ErrorResponse"
404: 404:

View File

@ -0,0 +1,115 @@
package system
import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
)
// Info contains response of Engine API:
// GET "/info"
type Info struct {
ID string
Containers int
ContainersRunning int
ContainersPaused int
ContainersStopped int
Images int
Driver string
DriverStatus [][2]string
SystemStatus [][2]string `json:",omitempty"` // SystemStatus is only propagated by the Swarm standalone API
Plugins PluginsInfo
MemoryLimit bool
SwapLimit bool
KernelMemory bool `json:",omitempty"` // Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes
KernelMemoryTCP bool `json:",omitempty"` // KernelMemoryTCP is not supported on cgroups v2.
CPUCfsPeriod bool `json:"CpuCfsPeriod"`
CPUCfsQuota bool `json:"CpuCfsQuota"`
CPUShares bool
CPUSet bool
PidsLimit bool
IPv4Forwarding bool
BridgeNfIptables bool
BridgeNfIP6tables bool `json:"BridgeNfIp6tables"`
Debug bool
NFd int
OomKillDisable bool
NGoroutines int
SystemTime string
LoggingDriver string
CgroupDriver string
CgroupVersion string `json:",omitempty"`
NEventsListener int
KernelVersion string
OperatingSystem string
OSVersion string
OSType string
Architecture string
IndexServerAddress string
RegistryConfig *registry.ServiceConfig
NCPU int
MemTotal int64
GenericResources []swarm.GenericResource
DockerRootDir string
HTTPProxy string `json:"HttpProxy"`
HTTPSProxy string `json:"HttpsProxy"`
NoProxy string
Name string
Labels []string
ExperimentalBuild bool
ServerVersion string
Runtimes map[string]Runtime
DefaultRuntime string
Swarm swarm.Info
// LiveRestoreEnabled determines whether containers should be kept
// running when the daemon is shutdown or upon daemon start if
// running containers are detected
LiveRestoreEnabled bool
Isolation container.Isolation
InitBinary string
ContainerdCommit Commit
RuncCommit Commit
InitCommit Commit
SecurityOptions []string
ProductLicense string `json:",omitempty"`
DefaultAddressPools []NetworkAddressPool `json:",omitempty"`
// Legacy API fields for older API versions.
legacyFields
// Warnings contains a slice of warnings that occurred while collecting
// system information. These warnings are intended to be informational
// messages for the user, and are not intended to be parsed / used for
// other purposes, as they do not have a fixed format.
Warnings []string
}
type legacyFields struct {
ExecutionDriver string `json:",omitempty"` // Deprecated: deprecated since API v1.25, but returned for older versions.
}
// PluginsInfo is a temp struct holding Plugins name
// registered with docker daemon. It is used by [Info] struct
type PluginsInfo struct {
// List of Volume plugins registered
Volume []string
// List of Network plugins registered
Network []string
// List of Authorization plugins registered
Authorization []string
// List of Log plugins registered
Log []string
}
// Commit holds the Git-commit (SHA1) that a binary was built from, as reported
// in the version-string of external tools, such as containerd, or runC.
type Commit struct {
ID string // ID is the actual commit ID of external tool.
Expected string // Expected is the commit ID of external tool expected by dockerd as set at build time.
}
// NetworkAddressPool is a temp struct used by [Info] struct.
type NetworkAddressPool struct {
Base string
Size int
}

View File

@ -0,0 +1,14 @@
package system
// Runtime describes an OCI runtime
type Runtime struct {
// "Legacy" runtime configuration for runc-compatible runtimes.
Path string `json:"path,omitempty"`
Args []string `json:"runtimeArgs,omitempty"`
// Shimv2 runtime configuration. Mutually exclusive with the legacy config above.
Type string `json:"runtimeType,omitempty"`
Options map[string]interface{} `json:"options,omitempty"`
}

View File

@ -0,0 +1,48 @@
package system
import (
"errors"
"fmt"
"strings"
)
// SecurityOpt contains the name and options of a security option
type SecurityOpt struct {
Name string
Options []KeyValue
}
// DecodeSecurityOptions decodes a security options string slice to a
// type-safe [SecurityOpt].
func DecodeSecurityOptions(opts []string) ([]SecurityOpt, error) {
so := []SecurityOpt{}
for _, opt := range opts {
// support output from a < 1.13 docker daemon
if !strings.Contains(opt, "=") {
so = append(so, SecurityOpt{Name: opt})
continue
}
secopt := SecurityOpt{}
for _, s := range strings.Split(opt, ",") {
k, v, ok := strings.Cut(s, "=")
if !ok {
return nil, fmt.Errorf("invalid security option %q", s)
}
if k == "" || v == "" {
return nil, errors.New("invalid empty security option")
}
if k == "name" {
secopt.Name = v
continue
}
secopt.Options = append(secopt.Options, KeyValue{Key: k, Value: v})
}
so = append(so, secopt)
}
return so, nil
}
// KeyValue holds a key/value pair.
type KeyValue struct {
Key, Value string
}

View File

@ -1,18 +1,14 @@
package types // import "github.com/docker/docker/api/types" package types // import "github.com/docker/docker/api/types"
import ( import (
"errors"
"fmt"
"io" "io"
"os" "os"
"strings"
"time" "time"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/volume" "github.com/docker/docker/api/types/volume"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
@ -232,155 +228,6 @@ type Version struct {
BuildTime string `json:",omitempty"` BuildTime string `json:",omitempty"`
} }
// Commit holds the Git-commit (SHA1) that a binary was built from, as reported
// in the version-string of external tools, such as containerd, or runC.
type Commit struct {
ID string // ID is the actual commit ID of external tool.
Expected string // Expected is the commit ID of external tool expected by dockerd as set at build time.
}
// Info contains response of Engine API:
// GET "/info"
type Info struct {
ID string
Containers int
ContainersRunning int
ContainersPaused int
ContainersStopped int
Images int
Driver string
DriverStatus [][2]string
SystemStatus [][2]string `json:",omitempty"` // SystemStatus is only propagated by the Swarm standalone API
Plugins PluginsInfo
MemoryLimit bool
SwapLimit bool
KernelMemory bool `json:",omitempty"` // Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes
KernelMemoryTCP bool `json:",omitempty"` // KernelMemoryTCP is not supported on cgroups v2.
CPUCfsPeriod bool `json:"CpuCfsPeriod"`
CPUCfsQuota bool `json:"CpuCfsQuota"`
CPUShares bool
CPUSet bool
PidsLimit bool
IPv4Forwarding bool
BridgeNfIptables bool
BridgeNfIP6tables bool `json:"BridgeNfIp6tables"`
Debug bool
NFd int
OomKillDisable bool
NGoroutines int
SystemTime string
LoggingDriver string
CgroupDriver string
CgroupVersion string `json:",omitempty"`
NEventsListener int
KernelVersion string
OperatingSystem string
OSVersion string
OSType string
Architecture string
IndexServerAddress string
RegistryConfig *registry.ServiceConfig
NCPU int
MemTotal int64
GenericResources []swarm.GenericResource
DockerRootDir string
HTTPProxy string `json:"HttpProxy"`
HTTPSProxy string `json:"HttpsProxy"`
NoProxy string
Name string
Labels []string
ExperimentalBuild bool
ServerVersion string
Runtimes map[string]Runtime
DefaultRuntime string
Swarm swarm.Info
// LiveRestoreEnabled determines whether containers should be kept
// running when the daemon is shutdown or upon daemon start if
// running containers are detected
LiveRestoreEnabled bool
Isolation container.Isolation
InitBinary string
ContainerdCommit Commit
RuncCommit Commit
InitCommit Commit
SecurityOptions []string
ProductLicense string `json:",omitempty"`
DefaultAddressPools []NetworkAddressPool `json:",omitempty"`
// Legacy API fields for older API versions.
legacyFields
// Warnings contains a slice of warnings that occurred while collecting
// system information. These warnings are intended to be informational
// messages for the user, and are not intended to be parsed / used for
// other purposes, as they do not have a fixed format.
Warnings []string
}
type legacyFields struct {
ExecutionDriver string `json:",omitempty"` // Deprecated: deprecated since API v1.25, but returned for older versions.
}
// KeyValue holds a key/value pair
type KeyValue struct {
Key, Value string
}
// NetworkAddressPool is a temp struct used by Info struct
type NetworkAddressPool struct {
Base string
Size int
}
// SecurityOpt contains the name and options of a security option
type SecurityOpt struct {
Name string
Options []KeyValue
}
// DecodeSecurityOptions decodes a security options string slice to a type safe
// SecurityOpt
func DecodeSecurityOptions(opts []string) ([]SecurityOpt, error) {
so := []SecurityOpt{}
for _, opt := range opts {
// support output from a < 1.13 docker daemon
if !strings.Contains(opt, "=") {
so = append(so, SecurityOpt{Name: opt})
continue
}
secopt := SecurityOpt{}
for _, s := range strings.Split(opt, ",") {
k, v, ok := strings.Cut(s, "=")
if !ok {
return nil, fmt.Errorf("invalid security option %q", s)
}
if k == "" || v == "" {
return nil, errors.New("invalid empty security option")
}
if k == "name" {
secopt.Name = v
continue
}
secopt.Options = append(secopt.Options, KeyValue{Key: k, Value: v})
}
so = append(so, secopt)
}
return so, nil
}
// PluginsInfo is a temp struct holding Plugins name
// registered with docker daemon. It is used by Info struct
type PluginsInfo struct {
// List of Volume plugins registered
Volume []string
// List of Network plugins registered
Network []string
// List of Authorization plugins registered
Authorization []string
// List of Log plugins registered
Log []string
}
// ExecStartCheck is a temp struct used by execStart // ExecStartCheck is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package // Config fields is part of ExecConfig in runconfig package
type ExecStartCheck struct { type ExecStartCheck struct {
@ -652,19 +499,6 @@ type Checkpoint struct {
Name string // Name is the name of the checkpoint Name string // Name is the name of the checkpoint
} }
// Runtime describes an OCI runtime
type Runtime struct {
// "Legacy" runtime configuration for runc-compatible runtimes.
Path string `json:"path,omitempty"`
Args []string `json:"runtimeArgs,omitempty"`
// Shimv2 runtime configuration. Mutually exclusive with the legacy config above.
Type string `json:"runtimeType,omitempty"`
Options map[string]interface{} `json:"options,omitempty"`
}
// DiskUsageObject represents an object type used for disk usage query filtering. // DiskUsageObject represents an object type used for disk usage query filtering.
type DiskUsageObject string type DiskUsageObject string

View File

@ -0,0 +1,49 @@
package types
import "github.com/docker/docker/api/types/system"
// Info contains response of Engine API:
// GET "/info"
//
// Deprecated: use [system.Info].
type Info = system.Info
// Commit holds the Git-commit (SHA1) that a binary was built from, as reported
// in the version-string of external tools, such as containerd, or runC.
//
// Deprecated: use [system.Commit].
type Commit = system.Commit
// PluginsInfo is a temp struct holding Plugins name
// registered with docker daemon. It is used by [system.Info] struct
//
// Deprecated: use [system.PluginsInfo].
type PluginsInfo = system.PluginsInfo
// NetworkAddressPool is a temp struct used by [system.Info] struct.
//
// Deprecated: use [system.NetworkAddressPool].
type NetworkAddressPool = system.NetworkAddressPool
// Runtime describes an OCI runtime.
//
// Deprecated: use [system.Runtime].
type Runtime = system.Runtime
// SecurityOpt contains the name and options of a security option.
//
// Deprecated: use [system.SecurityOpt].
type SecurityOpt = system.SecurityOpt
// KeyValue holds a key/value pair.
//
// Deprecated: use [system.KeyValue].
type KeyValue = system.KeyValue
// DecodeSecurityOptions decodes a security options string slice to a type safe
// [system.SecurityOpt].
//
// Deprecated: use [system.DecodeSecurityOptions].
func DecodeSecurityOptions(opts []string) ([]system.SecurityOpt, error) {
return system.DecodeSecurityOptions(opts)
}

View File

@ -56,6 +56,36 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// DummyHost is a hostname used for local communication.
//
// It acts as a valid formatted hostname for local connections (such as "unix://"
// or "npipe://") which do not require a hostname. It should never be resolved,
// but uses the special-purpose ".localhost" TLD (as defined in [RFC 2606, Section 2]
// and [RFC 6761, Section 6.3]).
//
// [RFC 7230, Section 5.4] defines that an empty header must be used for such
// cases:
//
// If the authority component is missing or undefined for the target URI,
// then a client MUST send a Host header field with an empty field-value.
//
// However, [Go stdlib] enforces the semantics of HTTP(S) over TCP, does not
// allow an empty header to be used, and requires req.URL.Scheme to be either
// "http" or "https".
//
// For further details, refer to:
//
// - https://github.com/docker/engine-api/issues/189
// - https://github.com/golang/go/issues/13624
// - https://github.com/golang/go/issues/61076
// - https://github.com/moby/moby/issues/45935
//
// [RFC 2606, Section 2]: https://www.rfc-editor.org/rfc/rfc2606.html#section-2
// [RFC 6761, Section 6.3]: https://www.rfc-editor.org/rfc/rfc6761#section-6.3
// [RFC 7230, Section 5.4]: https://datatracker.ietf.org/doc/html/rfc7230#section-5.4
// [Go stdlib]: https://github.com/golang/go/blob/6244b1946bc2101b01955468f1be502dbadd6807/src/net/http/transport.go#L558-L569
const DummyHost = "api.moby.localhost"
// ErrRedirect is the error returned by checkRedirect when the request is non-GET. // ErrRedirect is the error returned by checkRedirect when the request is non-GET.
var ErrRedirect = errors.New("unexpected redirect in response") var ErrRedirect = errors.New("unexpected redirect in response")

View File

@ -2,6 +2,7 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"net/http"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -52,8 +53,7 @@ func (cli *Client) ContainerAttach(ctx context.Context, container string, option
query.Set("logs", "1") query.Set("logs", "1")
} }
headers := map[string][]string{ return cli.postHijacked(ctx, "/containers/"+container+"/attach", query, nil, http.Header{
"Content-Type": {"text/plain"}, "Content-Type": {"text/plain"},
} })
return cli.postHijacked(ctx, "/containers/"+container+"/attach", query, nil, headers)
} }

View File

@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"net/http"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
@ -46,10 +47,9 @@ func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, confi
if versions.LessThan(cli.ClientVersion(), "1.42") { if versions.LessThan(cli.ClientVersion(), "1.42") {
config.ConsoleSize = nil config.ConsoleSize = nil
} }
headers := map[string][]string{ return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, http.Header{
"Content-Type": {"application/json"}, "Content-Type": {"application/json"},
} })
return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, headers)
} }
// ContainerExecInspect returns information about a specific exec process on the docker host. // ContainerExecInspect returns information about a specific exec process on the docker host.

View File

@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"net/http"
"net/url" "net/url"
"github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/registry"
@ -19,10 +20,10 @@ func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegist
if err := cli.NewVersionError("1.30", "distribution inspect"); err != nil { if err := cli.NewVersionError("1.30", "distribution inspect"); err != nil {
return distributionInspect, err return distributionInspect, err
} }
var headers map[string][]string
var headers http.Header
if encodedRegistryAuth != "" { if encodedRegistryAuth != "" {
headers = map[string][]string{ headers = http.Header{
registry.AuthHeader: {encodedRegistryAuth}, registry.AuthHeader: {encodedRegistryAuth},
} }
} }

View File

@ -64,7 +64,11 @@ func fallbackDial(proto, addr string, tlsConfig *tls.Config) (net.Conn, error) {
} }
func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto string) (net.Conn, string, error) { func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto string) (net.Conn, string, error) {
req.Host = cli.addr req.URL.Host = cli.addr
if cli.proto == "unix" || cli.proto == "npipe" {
// Override host header for non-tcp connections.
req.Host = DummyHost
}
req.Header.Set("Connection", "Upgrade") req.Header.Set("Connection", "Upgrade")
req.Header.Set("Upgrade", proto) req.Header.Set("Upgrade", proto)

View File

@ -23,13 +23,13 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio
return types.ImageBuildResponse{}, err return types.ImageBuildResponse{}, err
} }
headers := http.Header(make(map[string][]string))
buf, err := json.Marshal(options.AuthConfigs) buf, err := json.Marshal(options.AuthConfigs)
if err != nil { if err != nil {
return types.ImageBuildResponse{}, err return types.ImageBuildResponse{}, err
} }
headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf))
headers := http.Header{}
headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf))
headers.Set("Content-Type", "application/x-tar") headers.Set("Content-Type", "application/x-tar")
serverResp, err := cli.postRaw(ctx, "/build", query, buildContext, headers) serverResp, err := cli.postRaw(ctx, "/build", query, buildContext, headers)
@ -37,11 +37,9 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio
return types.ImageBuildResponse{}, err return types.ImageBuildResponse{}, err
} }
osType := getDockerOS(serverResp.header.Get("Server"))
return types.ImageBuildResponse{ return types.ImageBuildResponse{
Body: serverResp.body, Body: serverResp.body,
OSType: osType, OSType: getDockerOS(serverResp.header.Get("Server")),
}, nil }, nil
} }

View File

@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"io" "io"
"net/http"
"net/url" "net/url"
"strings" "strings"
@ -33,6 +34,7 @@ func (cli *Client) ImageCreate(ctx context.Context, parentReference string, opti
} }
func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) { func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
headers := map[string][]string{registry.AuthHeader: {registryAuth}} return cli.post(ctx, "/images/create", query, nil, http.Header{
return cli.post(ctx, "/images/create", query, nil, headers) registry.AuthHeader: {registryAuth},
})
} }

View File

@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"io" "io"
"net/http"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -17,8 +18,9 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (
if quiet { if quiet {
v.Set("quiet", "1") v.Set("quiet", "1")
} }
headers := map[string][]string{"Content-Type": {"application/x-tar"}} resp, err := cli.postRaw(ctx, "/images/load", v, input, http.Header{
resp, err := cli.postRaw(ctx, "/images/load", v, input, headers) "Content-Type": {"application/x-tar"},
})
if err != nil { if err != nil {
return types.ImageLoadResponse{}, err return types.ImageLoadResponse{}, err
} }

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"errors" "errors"
"io" "io"
"net/http"
"net/url" "net/url"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
@ -50,6 +51,7 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options types.Im
} }
func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, registryAuth string) (serverResponse, error) { func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, registryAuth string) (serverResponse, error) {
headers := map[string][]string{registry.AuthHeader: {registryAuth}} return cli.post(ctx, "/images/"+imageID+"/push", query, nil, http.Header{
return cli.post(ctx, "/images/"+imageID+"/push", query, nil, headers) registry.AuthHeader: {registryAuth},
})
} }

View File

@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"net/http"
"net/url" "net/url"
"strconv" "strconv"
@ -48,6 +49,7 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options types.I
} }
func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) { func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
headers := map[string][]string{registry.AuthHeader: {registryAuth}} return cli.get(ctx, "/images/search", query, http.Header{
return cli.get(ctx, "/images/search", query, headers) registry.AuthHeader: {registryAuth},
})
} }

View File

@ -6,12 +6,12 @@ import (
"fmt" "fmt"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/system"
) )
// Info returns information about the docker server. // Info returns information about the docker server.
func (cli *Client) Info(ctx context.Context) (types.Info, error) { func (cli *Client) Info(ctx context.Context) (system.Info, error) {
var info types.Info var info system.Info
serverResp, err := cli.get(ctx, "/info", url.Values{}, nil) serverResp, err := cli.get(ctx, "/info", url.Values{}, nil)
defer ensureReaderClosed(serverResp) defer ensureReaderClosed(serverResp)
if err != nil { if err != nil {

View File

@ -14,6 +14,7 @@ import (
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/api/types/volume" "github.com/docker/docker/api/types/volume"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
) )
@ -165,7 +166,7 @@ type SwarmAPIClient interface {
// SystemAPIClient defines API client methods for the system // SystemAPIClient defines API client methods for the system
type SystemAPIClient interface { type SystemAPIClient interface {
Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error) Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error)
Info(ctx context.Context) (types.Info, error) Info(ctx context.Context) (system.Info, error)
RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error) RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error)
DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error) DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error)
Ping(ctx context.Context) (types.Ping, error) Ping(ctx context.Context) (types.Ping, error)

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"io" "io"
"net/http"
"net/url" "net/url"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
@ -68,13 +69,15 @@ func (cli *Client) PluginInstall(ctx context.Context, name string, options types
} }
func (cli *Client) tryPluginPrivileges(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) { func (cli *Client) tryPluginPrivileges(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
headers := map[string][]string{registry.AuthHeader: {registryAuth}} return cli.get(ctx, "/plugins/privileges", query, http.Header{
return cli.get(ctx, "/plugins/privileges", query, headers) registry.AuthHeader: {registryAuth},
})
} }
func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileges types.PluginPrivileges, registryAuth string) (serverResponse, error) { func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileges types.PluginPrivileges, registryAuth string) (serverResponse, error) {
headers := map[string][]string{registry.AuthHeader: {registryAuth}} return cli.post(ctx, "/plugins/pull", query, privileges, http.Header{
return cli.post(ctx, "/plugins/pull", query, privileges, headers) registry.AuthHeader: {registryAuth},
})
} }
func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, options types.PluginInstallOptions) (types.PluginPrivileges, error) { func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, options types.PluginInstallOptions) (types.PluginPrivileges, error) {

View File

@ -3,14 +3,16 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"io" "io"
"net/http"
"github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/registry"
) )
// PluginPush pushes a plugin to a registry // PluginPush pushes a plugin to a registry
func (cli *Client) PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) { func (cli *Client) PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) {
headers := map[string][]string{registry.AuthHeader: {registryAuth}} resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, http.Header{
resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, headers) registry.AuthHeader: {registryAuth},
})
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"io" "io"
"net/http"
"net/url" "net/url"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
@ -35,6 +36,7 @@ func (cli *Client) PluginUpgrade(ctx context.Context, name string, options types
} }
func (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges types.PluginPrivileges, name, registryAuth string) (serverResponse, error) { func (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges types.PluginPrivileges, name, registryAuth string) (serverResponse, error) {
headers := map[string][]string{registry.AuthHeader: {registryAuth}} return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, http.Header{
return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, headers) registry.AuthHeader: {registryAuth},
})
} }

View File

@ -28,17 +28,17 @@ type serverResponse struct {
} }
// head sends an http request to the docker API using the method HEAD. // 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 map[string][]string) (serverResponse, error) { func (cli *Client) head(ctx context.Context, path string, query url.Values, headers http.Header) (serverResponse, error) {
return cli.sendRequest(ctx, http.MethodHead, path, query, nil, headers) return cli.sendRequest(ctx, http.MethodHead, path, query, nil, headers)
} }
// get sends an http request to the docker API using the method GET with a specific Go context. // 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 map[string][]string) (serverResponse, error) { func (cli *Client) get(ctx context.Context, path string, query url.Values, headers http.Header) (serverResponse, error) {
return cli.sendRequest(ctx, http.MethodGet, path, query, nil, headers) return cli.sendRequest(ctx, http.MethodGet, path, query, nil, headers)
} }
// post sends an http request to the docker API using the method POST with a specific Go context. // post sends an http request to the docker API using the method POST with a specific Go context.
func (cli *Client) post(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) { func (cli *Client) post(ctx context.Context, path string, query url.Values, obj interface{}, headers http.Header) (serverResponse, error) {
body, headers, err := encodeBody(obj, headers) body, headers, err := encodeBody(obj, headers)
if err != nil { if err != nil {
return serverResponse{}, err return serverResponse{}, err
@ -46,11 +46,11 @@ func (cli *Client) post(ctx context.Context, path string, query url.Values, obj
return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers) return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers)
} }
func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) { func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers http.Header) (serverResponse, error) {
return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers) return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers)
} }
func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) { func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers http.Header) (serverResponse, error) {
body, headers, err := encodeBody(obj, headers) body, headers, err := encodeBody(obj, headers)
if err != nil { if err != nil {
return serverResponse{}, err return serverResponse{}, err
@ -59,7 +59,7 @@ func (cli *Client) put(ctx context.Context, path string, query url.Values, obj i
} }
// putRaw sends an http request to the docker API using the method PUT. // 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 map[string][]string) (serverResponse, error) { func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers http.Header) (serverResponse, error) {
// PUT requests are expected to always have a body (apparently) // PUT requests are expected to always have a body (apparently)
// so explicitly pass an empty body to sendRequest to signal that // so explicitly pass an empty body to sendRequest to signal that
// it should set the Content-Type header if not already present. // it should set the Content-Type header if not already present.
@ -70,13 +70,11 @@ func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, bo
} }
// delete sends an http request to the docker API using the method DELETE. // 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 map[string][]string) (serverResponse, error) { func (cli *Client) delete(ctx context.Context, path string, query url.Values, headers http.Header) (serverResponse, error) {
return cli.sendRequest(ctx, http.MethodDelete, path, query, nil, headers) return cli.sendRequest(ctx, http.MethodDelete, path, query, nil, headers)
} }
type headers map[string][]string func encodeBody(obj interface{}, headers http.Header) (io.Reader, http.Header, error) {
func encodeBody(obj interface{}, headers headers) (io.Reader, headers, error) {
if obj == nil { if obj == nil {
return nil, headers, nil return nil, headers, nil
} }
@ -98,32 +96,27 @@ func encodeBody(obj interface{}, headers headers) (io.Reader, headers, error) {
return body, headers, nil return body, headers, nil
} }
func (cli *Client) buildRequest(method, path string, body io.Reader, headers headers) (*http.Request, error) { func (cli *Client) buildRequest(method, path string, body io.Reader, headers http.Header) (*http.Request, error) {
req, err := http.NewRequest(method, path, body) req, err := http.NewRequest(method, path, body)
if err != nil { if err != nil {
return nil, err return nil, err
} }
req = cli.addHeaders(req, headers) req = cli.addHeaders(req, headers)
req.URL.Scheme = cli.scheme
req.URL.Host = cli.addr
if cli.proto == "unix" || cli.proto == "npipe" { if cli.proto == "unix" || cli.proto == "npipe" {
// For local communications, it doesn't matter what the host is. We just // Override host header for non-tcp connections.
// need a valid and meaningful host name. For details, see: req.Host = DummyHost
//
// - https://github.com/docker/engine-api/issues/189
// - https://github.com/golang/go/issues/13624
req.Host = "docker"
} }
req.URL.Host = cli.addr
req.URL.Scheme = cli.scheme
if body != nil && req.Header.Get("Content-Type") == "" { if body != nil && req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "text/plain") req.Header.Set("Content-Type", "text/plain")
} }
return req, nil return req, nil
} }
func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers headers) (serverResponse, error) { func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers http.Header) (serverResponse, error) {
req, err := cli.buildRequest(method, cli.getAPIPath(ctx, path, query), body, headers) req, err := cli.buildRequest(method, cli.getAPIPath(ctx, path, query), body, headers)
if err != nil { if err != nil {
return serverResponse{}, err return serverResponse{}, err
@ -161,19 +154,19 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp
return serverResp, err return serverResp, err
} }
if nErr, ok := err.(*url.Error); ok { if uErr, ok := err.(*url.Error); ok {
if nErr, ok := nErr.Err.(*net.OpError); ok { if nErr, ok := uErr.Err.(*net.OpError); ok {
if os.IsPermission(nErr.Err) { if os.IsPermission(nErr.Err) {
return serverResp, errors.Wrapf(err, "permission denied while trying to connect to the Docker daemon socket at %v", cli.host) return serverResp, errors.Wrapf(err, "permission denied while trying to connect to the Docker daemon socket at %v", cli.host)
} }
} }
} }
if err, ok := err.(net.Error); ok { if nErr, ok := err.(net.Error); ok {
if err.Timeout() { if nErr.Timeout() {
return serverResp, ErrorConnectionFailed(cli.host) return serverResp, ErrorConnectionFailed(cli.host)
} }
if strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "dial unix") { if strings.Contains(nErr.Error(), "connection refused") || strings.Contains(nErr.Error(), "dial unix") {
return serverResp, ErrorConnectionFailed(cli.host) return serverResp, ErrorConnectionFailed(cli.host)
} }
} }
@ -253,7 +246,7 @@ func (cli *Client) checkResponseErr(serverResp serverResponse) error {
return errors.Wrap(errors.New(errorMessage), "Error response from daemon") return errors.Wrap(errors.New(errorMessage), "Error response from daemon")
} }
func (cli *Client) addHeaders(req *http.Request, headers headers) *http.Request { func (cli *Client) addHeaders(req *http.Request, headers http.Header) *http.Request {
// Add CLI Config's HTTP Headers BEFORE we set the Docker headers // Add CLI Config's HTTP Headers BEFORE we set the Docker headers
// then the user can't change OUR headers // then the user can't change OUR headers
for k, v := range cli.customHTTPHeaders { for k, v := range cli.customHTTPHeaders {

View File

@ -4,12 +4,14 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http"
"strings" "strings"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/versions"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -17,13 +19,6 @@ import (
// ServiceCreate creates a new service. // ServiceCreate creates a new service.
func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (types.ServiceCreateResponse, error) { func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (types.ServiceCreateResponse, error) {
var response types.ServiceCreateResponse var response types.ServiceCreateResponse
headers := map[string][]string{
"version": {cli.version},
}
if options.EncodedRegistryAuth != "" {
headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth}
}
// Make sure containerSpec is not nil when no runtime is set or the runtime is set to container // Make sure containerSpec is not nil when no runtime is set or the runtime is set to container
if service.TaskTemplate.ContainerSpec == nil && (service.TaskTemplate.Runtime == "" || service.TaskTemplate.Runtime == swarm.RuntimeContainer) { if service.TaskTemplate.ContainerSpec == nil && (service.TaskTemplate.Runtime == "" || service.TaskTemplate.Runtime == swarm.RuntimeContainer) {
@ -53,6 +48,16 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec,
} }
} }
headers := http.Header{}
if versions.LessThan(cli.version, "1.30") {
// the custom "version" header was used by engine API before 20.10
// (API 1.30) to switch between client- and server-side lookup of
// image digests.
headers["version"] = []string{cli.version}
}
if options.EncodedRegistryAuth != "" {
headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth}
}
resp, err := cli.post(ctx, "/services/create", nil, service, headers) resp, err := cli.post(ctx, "/services/create", nil, service, headers)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {

View File

@ -3,11 +3,13 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"net/http"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/versions"
) )
// ServiceUpdate updates a Service. The version number is required to avoid conflicting writes. // ServiceUpdate updates a Service. The version number is required to avoid conflicting writes.
@ -19,14 +21,6 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version
response = types.ServiceUpdateResponse{} response = types.ServiceUpdateResponse{}
) )
headers := map[string][]string{
"version": {cli.version},
}
if options.EncodedRegistryAuth != "" {
headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth}
}
if options.RegistryAuthFrom != "" { if options.RegistryAuthFrom != "" {
query.Set("registryAuthFrom", options.RegistryAuthFrom) query.Set("registryAuthFrom", options.RegistryAuthFrom)
} }
@ -60,6 +54,16 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version
} }
} }
headers := http.Header{}
if versions.LessThan(cli.version, "1.30") {
// the custom "version" header was used by engine API before 20.10
// (API 1.30) to switch between client- and server-side lookup of
// image digests.
headers["version"] = []string{cli.version}
}
if options.EncodedRegistryAuth != "" {
headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth}
}
resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, service, headers) resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, service, headers)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {

View File

@ -439,10 +439,5 @@ func ParseRepositoryInfo(reposName reference.Named) (*RepositoryInfo, error) {
// for that. // for that.
func ParseSearchIndexInfo(reposName string) (*registry.IndexInfo, error) { func ParseSearchIndexInfo(reposName string) (*registry.IndexInfo, error) {
indexName, _ := splitReposSearchTerm(reposName) indexName, _ := splitReposSearchTerm(reposName)
return newIndexInfo(emptyServiceConfig, indexName)
indexInfo, err := newIndexInfo(emptyServiceConfig, indexName)
if err != nil {
return nil, err
}
return indexInfo, nil
} }

View File

@ -9,6 +9,7 @@ import (
"net/http" "net/http"
"net/http/cookiejar" "net/http/cookiejar"
"net/url" "net/url"
"strconv"
"strings" "strings"
"sync" "sync"
@ -192,8 +193,8 @@ func (r *session) searchRepositories(term string, limit int) (*registry.SearchRe
if limit < 1 || limit > 100 { if limit < 1 || limit > 100 {
return nil, invalidParamf("limit %d is outside the range of [1, 100]", limit) return nil, invalidParamf("limit %d is outside the range of [1, 100]", limit)
} }
log.G(context.TODO()).Debugf("Index server: %s", r.indexEndpoint)
u := r.indexEndpoint.String() + "search?q=" + url.QueryEscape(term) + "&n=" + url.QueryEscape(fmt.Sprintf("%d", limit)) u := r.indexEndpoint.String() + "search?q=" + url.QueryEscape(term) + "&n=" + url.QueryEscape(fmt.Sprintf("%d", limit))
log.G(context.TODO()).WithField("url", u).Debug("searchRepositories")
req, err := http.NewRequest(http.MethodGet, u, nil) req, err := http.NewRequest(http.MethodGet, u, nil)
if err != nil { if err != nil {
@ -208,10 +209,14 @@ func (r *session) searchRepositories(term string, limit int) (*registry.SearchRe
defer res.Body.Close() defer res.Body.Close()
if res.StatusCode != http.StatusOK { if res.StatusCode != http.StatusOK {
return nil, errdefs.Unknown(&jsonmessage.JSONError{ return nil, errdefs.Unknown(&jsonmessage.JSONError{
Message: fmt.Sprintf("Unexpected status code %d", res.StatusCode), Message: "Unexpected status code " + strconv.Itoa(res.StatusCode),
Code: res.StatusCode, Code: res.StatusCode,
}) })
} }
result := new(registry.SearchResults) result := &registry.SearchResults{}
return result, errors.Wrap(json.NewDecoder(res.Body).Decode(result), "error decoding registry search results") err = json.NewDecoder(res.Body).Decode(result)
if err != nil {
return nil, errdefs.System(errors.Wrap(err, "error decoding registry search results"))
}
return result, nil
} }

5
vendor/modules.txt vendored
View File

@ -46,7 +46,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 v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible # github.com/docker/docker v24.0.0-rc.2.0.20230714195812-dab9ffb25218+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
@ -61,6 +61,7 @@ github.com/docker/docker/api/types/registry
github.com/docker/docker/api/types/strslice github.com/docker/docker/api/types/strslice
github.com/docker/docker/api/types/swarm github.com/docker/docker/api/types/swarm
github.com/docker/docker/api/types/swarm/runtime github.com/docker/docker/api/types/swarm/runtime
github.com/docker/docker/api/types/system
github.com/docker/docker/api/types/time github.com/docker/docker/api/types/time
github.com/docker/docker/api/types/versions github.com/docker/docker/api/types/versions
github.com/docker/docker/api/types/volume github.com/docker/docker/api/types/volume
@ -168,7 +169,7 @@ github.com/moby/buildkit/util/appcontext
# github.com/moby/patternmatcher v0.5.0 # github.com/moby/patternmatcher v0.5.0
## explicit; go 1.19 ## explicit; go 1.19
github.com/moby/patternmatcher github.com/moby/patternmatcher
# github.com/moby/swarmkit/v2 v2.0.0-20230627115642-ad0f3ae162fa # github.com/moby/swarmkit/v2 v2.0.0-20230707182847-6f78b8199b05
## explicit; go 1.18 ## explicit; go 1.18
github.com/moby/swarmkit/v2/api github.com/moby/swarmkit/v2/api
github.com/moby/swarmkit/v2/api/deepcopy github.com/moby/swarmkit/v2/api/deepcopy