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/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client"
specs "github.com/opencontainers/image-spec/specs-go/v1"
)
@ -23,7 +24,7 @@ type fakeClient struct {
containerName string) (container.CreateResponse, error)
containerStartFunc func(container string, options types.ContainerStartOptions) 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)
containerCopyFromFunc func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, 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
}
func (f *fakeClient) Info(_ context.Context) (types.Info, error) {
func (f *fakeClient) Info(_ context.Context) (system.Info, error) {
if f.infoFunc != nil {
return f.infoFunc()
}
return types.Info{}, nil
return system.Info{}, nil
}
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/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/system"
"github.com/google/go-cmp/cmp"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/pflag"
@ -137,8 +138,8 @@ func TestCreateContainerImagePullPolicy(t *testing.T) {
defer func() { pullCounter++ }()
return io.NopCloser(strings.NewReader("")), nil
},
infoFunc: func() (types.Info, error) {
return types.Info{IndexServerAddress: "https://indexserver.example.com"}, nil
infoFunc: func() (system.Info, error) {
return system.Info{IndexServerAddress: "https://indexserver.example.com"}, nil
},
}
fakeCLI := test.NewFakeCli(client)

View File

@ -9,6 +9,7 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client"
)
@ -18,7 +19,7 @@ type fakeClient struct {
imageSaveFunc func(images []string) (io.ReadCloser, error)
imageRemoveFunc func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, 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)
imagesPruneFunc func(pruneFilter filters.Args) (types.ImagesPruneReport, 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
}
func (cli *fakeClient) Info(_ context.Context) (types.Info, error) {
func (cli *fakeClient) Info(_ context.Context) (system.Info, error) {
if cli.infoFunc != nil {
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) {

View File

@ -5,12 +5,13 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client"
)
type fakeClient struct {
client.Client
infoFunc func() (types.Info, error)
infoFunc func() (system.Info, error)
nodeInspectFunc func() (swarm.Node, []byte, error)
nodeListFunc func() ([]swarm.Node, error)
nodeRemoveFunc func() error
@ -48,11 +49,11 @@ func (cli *fakeClient) NodeUpdate(_ context.Context, nodeID string, version swar
return nil
}
func (cli *fakeClient) Info(context.Context) (types.Info, error) {
func (cli *fakeClient) Info(context.Context) (system.Info, error) {
if cli.infoFunc != nil {
return cli.infoFunc()
}
return types.Info{}, nil
return system.Info{}, nil
}
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/formatter"
"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/system"
units "github.com/docker/go-units"
)
@ -100,7 +100,7 @@ func NewFormat(source string, quiet bool) formatter.Format {
}
// 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 {
for _, node := range nodes {
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 {
formatter.HeaderContext
n swarm.Node
info types.Info
info system.Info
}
func (c *nodeContext) MarshalJSON() ([]byte, error) {

View File

@ -9,8 +9,8 @@ import (
"github.com/docker/cli/cli/command/formatter"
"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/system"
"github.com/docker/docker/pkg/stringid"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@ -204,7 +204,7 @@ foobar_boo Unknown
var out bytes.Buffer
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 {
assert.Error(t, err, tc.expected)
} else {
@ -217,7 +217,7 @@ foobar_boo Unknown
func TestNodeContextWriteJSON(t *testing.T) {
cases := []struct {
expected []map[string]interface{}
info types.Info
info system.Info
}{
{
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_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "18.03.0-ce"},
},
info: types.Info{},
info: system.Info{},
},
{
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_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "18.03.0-ce"},
},
info: types.Info{
info: system.Info{
Swarm: swarm.Info{
Cluster: &swarm.ClusterInfo{
TLSInfo: swarm.TLSInfo{TrustRoot: "hi"},
@ -271,7 +271,7 @@ func TestNodeContextWriteJSONField(t *testing.T) {
{ID: "nodeID2", Description: swarm.NodeDescription{Hostname: "foobar_bar"}},
}
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 {
t.Fatal(err)
}

View File

@ -7,8 +7,8 @@ import (
"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/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
"gotest.tools/v3/golden"
@ -19,7 +19,7 @@ func TestNodeInspectErrors(t *testing.T) {
args []string
flags map[string]string
nodeInspectFunc func() (swarm.Node, []byte, error)
infoFunc func() (types.Info, error)
infoFunc func() (system.Info, error)
expectedError string
}{
{
@ -27,8 +27,8 @@ func TestNodeInspectErrors(t *testing.T) {
},
{
args: []string{"self"},
infoFunc: func() (types.Info, error) {
return types.Info{}, errors.Errorf("error asking for node info")
infoFunc: func() (system.Info, error) {
return system.Info{}, errors.Errorf("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) {
return swarm.Node{}, []byte{}, errors.Errorf("error inspecting the node")
},
infoFunc: func() (types.Info, error) {
return types.Info{}, errors.Errorf("error asking for node info")
infoFunc: func() (system.Info, error) {
return system.Info{}, errors.Errorf("error asking for node info")
},
expectedError: "error inspecting the node",
},
@ -47,8 +47,8 @@ func TestNodeInspectErrors(t *testing.T) {
nodeInspectFunc: func() (swarm.Node, []byte, error) {
return swarm.Node{}, []byte{}, errors.Errorf("error inspecting the node")
},
infoFunc: func() (types.Info, error) {
return types.Info{Swarm: swarm.Info{NodeID: "abc"}}, nil
infoFunc: func() (system.Info, error) {
return system.Info{Swarm: swarm.Info{NodeID: "abc"}}, nil
},
expectedError: "error inspecting the node",
},
@ -57,8 +57,8 @@ func TestNodeInspectErrors(t *testing.T) {
flags: map[string]string{
"pretty": "true",
},
infoFunc: func() (types.Info, error) {
return types.Info{}, errors.Errorf("error asking for node info")
infoFunc: func() (system.Info, error) {
return system.Info{}, errors.Errorf("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"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/system"
"github.com/fvbommel/sortorder"
"github.com/spf13/cobra"
)
@ -53,7 +54,7 @@ func runList(dockerCli command.Cli, options listOptions) error {
return err
}
info := types.Info{}
info := system.Info{}
if len(nodes) > 0 && !options.quiet {
// only non-empty nodes and not quiet, should we call /info api
info, err = client.Info(ctx)

View File

@ -7,8 +7,8 @@ import (
"github.com/docker/cli/cli/config/configfile"
"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/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@ -18,7 +18,7 @@ import (
func TestNodeListErrorOnAPIFailure(t *testing.T) {
testCases := []struct {
nodeListFunc func() ([]swarm.Node, error)
infoFunc func() (types.Info, error)
infoFunc func() (system.Info, error)
expectedError string
}{
{
@ -35,8 +35,8 @@ func TestNodeListErrorOnAPIFailure(t *testing.T) {
},
}, nil
},
infoFunc: func() (types.Info, error) {
return types.Info{}, errors.Errorf("error asking for node info")
infoFunc: func() (system.Info, error) {
return system.Info{}, errors.Errorf("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")),
}, nil
},
infoFunc: func() (types.Info, error) {
return types.Info{
infoFunc: func() (system.Info, error) {
return system.Info{
Swarm: swarm.Info{
NodeID: "nodeID1",
},
@ -98,8 +98,8 @@ func TestNodeListDefaultFormatFromConfig(t *testing.T) {
*Node(NodeID("nodeID3"), Hostname("nodeHostname3")),
}, nil
},
infoFunc: func() (types.Info, error) {
return types.Info{
infoFunc: func() (system.Info, error) {
return system.Info{
Swarm: swarm.Info{
NodeID: "nodeID1",
},
@ -122,8 +122,8 @@ func TestNodeListFormat(t *testing.T) {
*Node(NodeID("nodeID2"), Hostname("nodeHostname2"), Manager()),
}, nil
},
infoFunc: func() (types.Info, error) {
return types.Info{
infoFunc: func() (system.Info, error) {
return system.Info{
Swarm: swarm.Info{
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/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
"gotest.tools/v3/golden"
@ -20,15 +21,15 @@ func TestNodePsErrors(t *testing.T) {
testCases := []struct {
args []string
flags map[string]string
infoFunc func() (types.Info, error)
infoFunc func() (system.Info, error)
nodeInspectFunc func() (swarm.Node, []byte, error)
taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error)
taskInspectFunc func(taskID string) (swarm.Task, []byte, error)
expectedError string
}{
{
infoFunc: func() (types.Info, error) {
return types.Info{}, errors.Errorf("error asking for node info")
infoFunc: func() (system.Info, error) {
return system.Info{}, errors.Errorf("error asking for node info")
},
expectedError: "error asking for node info",
},
@ -69,7 +70,7 @@ func TestNodePs(t *testing.T) {
name string
args []string
flags map[string]string
infoFunc func() (types.Info, error)
infoFunc func() (system.Info, error)
nodeInspectFunc func() (swarm.Node, []byte, error)
taskListFunc func(options types.TaskListOptions) ([]swarm.Task, 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/filters"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client"
)
@ -71,6 +72,6 @@ func (c *fakeClient) PluginInspectWithRaw(_ context.Context, name string) (*type
return nil, nil, nil
}
func (c *fakeClient) Info(context.Context) (types.Info, error) {
return types.Info{}, nil
func (c *fakeClient) Info(context.Context) (system.Info, error) {
return system.Info{}, nil
}

View File

@ -8,8 +8,8 @@ import (
configtypes "github.com/docker/cli/cli/config/types"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@ -34,8 +34,8 @@ type fakeClient struct {
client.Client
}
func (c fakeClient) Info(context.Context) (types.Info, error) {
return types.Info{}, nil
func (c fakeClient) Info(context.Context) (system.Info, error) {
return system.Info{}, nil
}
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"
configtypes "github.com/docker/cli/cli/config/types"
"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/system"
"github.com/docker/docker/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@ -18,7 +18,7 @@ import (
type fakeClient struct {
client.Client
infoFunc func() (types.Info, error)
infoFunc func() (system.Info, error)
}
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 {
return cli.infoFunc()
}
return types.Info{}, nil
return system.Info{}, nil
}
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/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"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)
serviceListFunc func(context.Context, types.ServiceListOptions) ([]swarm.Service, 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)
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
}
func (f *fakeClient) Info(ctx context.Context) (types.Info, error) {
func (f *fakeClient) Info(ctx context.Context) (system.Info, error) {
if f.infoFunc == nil {
return types.Info{}, nil
return system.Info{}, nil
}
return f.infoFunc(ctx)
}

View File

@ -9,6 +9,7 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system"
"github.com/google/go-cmp/cmp"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@ -117,8 +118,8 @@ func TestUpdateNodeFilter(t *testing.T) {
)
client := &fakeClient{
infoFunc: func(_ context.Context) (types.Info, error) {
return types.Info{Swarm: swarm.Info{NodeID: selfNodeID}}, nil
infoFunc: func(_ context.Context) (system.Info, error) {
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/swarm"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/client"
)
type fakeClient struct {
client.Client
infoFunc func() (types.Info, error)
infoFunc func() (system.Info, error)
swarmInitFunc func() (string, error)
swarmInspectFunc func() (swarm.Swarm, error)
nodeInspectFunc func() (swarm.Node, []byte, error)
@ -21,11 +22,11 @@ type fakeClient struct {
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 {
return cli.infoFunc()
}
return types.Info{}, nil
return system.Info{}, nil
}
func (cli *fakeClient) NodeInspectWithRaw(context.Context, string) (swarm.Node, []byte, error) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/cli/internal/test"
notaryfake "github.com/docker/cli/internal/test/notary"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/system"
apiclient "github.com/docker/docker/client"
"github.com/theupdateframework/notary"
"github.com/theupdateframework/notary/client"
@ -27,8 +28,8 @@ type fakeClient struct {
apiclient.Client
}
func (c *fakeClient) Info(context.Context) (types.Info, error) {
return types.Info{}, nil
func (c *fakeClient) Info(context.Context) (system.Info, error) {
return system.Info{}, nil
}
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/creack/pty v1.1.18
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/go-connections v0.4.0
github.com/docker/go-units v0.5.0
@ -24,7 +24,7 @@ require (
github.com/mitchellh/mapstructure v1.3.2
github.com/moby/buildkit v0.11.6
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/signal v0.7.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.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/docker v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible h1:XccikgvtGCEZE9ZQoaEApdx9ZvruGYakfi2tw4d/vUg=
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 h1:lQ7FvH3oFGtG/ODOr0oAlRHQxJJkkbG+RyNHmiMWdI8=
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/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
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/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
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-20230627115642-ad0f3ae162fa/go.mod h1:pC/nyFbvVvSV+Gm1rARMgMR3FrCumwEyoMjqVwEzJvA=
github.com/moby/swarmkit/v2 v2.0.0-20230707182847-6f78b8199b05 h1:lvMq6zHXnGp6i+6iYDs1Uw9Q5bqiAYd6Sz08hZoxSmY=
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/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI=

View File

@ -9900,7 +9900,9 @@ paths:
Id: "22be93d5babb089c5aab8dbc369042fad48ff791584ca2da2100db837a1c7c30"
Warning: ""
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:
$ref: "#/definitions/ErrorResponse"
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"
import (
"errors"
"fmt"
"io"
"os"
"strings"
"time"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/volume"
"github.com/docker/go-connections/nat"
@ -232,155 +228,6 @@ type Version struct {
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
// Config fields is part of ExecConfig in runconfig package
type ExecStartCheck struct {
@ -652,19 +499,6 @@ type Checkpoint struct {
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.
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"
)
// 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.
var ErrRedirect = errors.New("unexpected redirect in response")

View File

@ -2,6 +2,7 @@ package client // import "github.com/docker/docker/client"
import (
"context"
"net/http"
"net/url"
"github.com/docker/docker/api/types"
@ -52,8 +53,7 @@ func (cli *Client) ContainerAttach(ctx context.Context, container string, option
query.Set("logs", "1")
}
headers := map[string][]string{
return cli.postHijacked(ctx, "/containers/"+container+"/attach", query, nil, http.Header{
"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 (
"context"
"encoding/json"
"net/http"
"github.com/docker/docker/api/types"
"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") {
config.ConsoleSize = nil
}
headers := map[string][]string{
return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, http.Header{
"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.

View File

@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"net/http"
"net/url"
"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 {
return distributionInspect, err
}
var headers map[string][]string
var headers http.Header
if encodedRegistryAuth != "" {
headers = map[string][]string{
headers = http.Header{
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) {
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("Upgrade", proto)

View File

@ -23,13 +23,13 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio
return types.ImageBuildResponse{}, err
}
headers := http.Header(make(map[string][]string))
buf, err := json.Marshal(options.AuthConfigs)
if err != nil {
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")
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
}
osType := getDockerOS(serverResp.header.Get("Server"))
return types.ImageBuildResponse{
Body: serverResp.body,
OSType: osType,
OSType: getDockerOS(serverResp.header.Get("Server")),
}, nil
}

View File

@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
import (
"context"
"io"
"net/http"
"net/url"
"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) {
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
return cli.post(ctx, "/images/create", query, nil, headers)
return cli.post(ctx, "/images/create", query, nil, http.Header{
registry.AuthHeader: {registryAuth},
})
}

View File

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

View File

@ -4,6 +4,7 @@ import (
"context"
"errors"
"io"
"net/http"
"net/url"
"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) {
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
return cli.post(ctx, "/images/"+imageID+"/push", query, nil, headers)
return cli.post(ctx, "/images/"+imageID+"/push", query, nil, http.Header{
registry.AuthHeader: {registryAuth},
})
}

View File

@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"net/http"
"net/url"
"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) {
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
return cli.get(ctx, "/images/search", query, headers)
return cli.get(ctx, "/images/search", query, http.Header{
registry.AuthHeader: {registryAuth},
})
}

View File

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

View File

@ -14,6 +14,7 @@ import (
"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/system"
"github.com/docker/docker/api/types/volume"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@ -165,7 +166,7 @@ type SwarmAPIClient interface {
// SystemAPIClient defines API client methods for the system
type SystemAPIClient interface {
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)
DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error)
Ping(ctx context.Context) (types.Ping, error)

View File

@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"io"
"net/http"
"net/url"
"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) {
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
return cli.get(ctx, "/plugins/privileges", query, headers)
return cli.get(ctx, "/plugins/privileges", query, http.Header{
registry.AuthHeader: {registryAuth},
})
}
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, headers)
return cli.post(ctx, "/plugins/pull", query, privileges, http.Header{
registry.AuthHeader: {registryAuth},
})
}
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 (
"context"
"io"
"net/http"
"github.com/docker/docker/api/types/registry"
)
// PluginPush pushes a plugin to a registry
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, headers)
resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, http.Header{
registry.AuthHeader: {registryAuth},
})
if err != nil {
return nil, err
}

View File

@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
import (
"context"
"io"
"net/http"
"net/url"
"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) {
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, headers)
return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, http.Header{
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.
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)
}
// 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)
}
// 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)
if err != nil {
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)
}
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)
}
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)
if err != nil {
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.
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)
// so explicitly pass an empty body to sendRequest to signal that
// 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.
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)
}
type headers map[string][]string
func encodeBody(obj interface{}, headers headers) (io.Reader, headers, error) {
func encodeBody(obj interface{}, headers http.Header) (io.Reader, http.Header, error) {
if obj == nil {
return nil, headers, nil
}
@ -98,32 +96,27 @@ func encodeBody(obj interface{}, headers headers) (io.Reader, headers, error) {
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)
if err != nil {
return nil, err
}
req = cli.addHeaders(req, headers)
req.URL.Scheme = cli.scheme
req.URL.Host = cli.addr
if cli.proto == "unix" || cli.proto == "npipe" {
// For local communications, it doesn't matter what the host is. We just
// need a valid and meaningful host name. For details, see:
//
// - https://github.com/docker/engine-api/issues/189
// - https://github.com/golang/go/issues/13624
req.Host = "docker"
// Override host header for non-tcp connections.
req.Host = DummyHost
}
req.URL.Host = cli.addr
req.URL.Scheme = cli.scheme
if body != nil && req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "text/plain")
}
return req, nil
}
func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers 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)
if err != nil {
return serverResponse{}, err
@ -161,19 +154,19 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp
return serverResp, err
}
if nErr, ok := err.(*url.Error); ok {
if nErr, ok := nErr.Err.(*net.OpError); ok {
if uErr, ok := err.(*url.Error); ok {
if nErr, ok := uErr.Err.(*net.OpError); ok {
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)
}
}
}
if err, ok := err.(net.Error); ok {
if err.Timeout() {
if nErr, ok := err.(net.Error); ok {
if nErr.Timeout() {
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)
}
}
@ -253,7 +246,7 @@ func (cli *Client) checkResponseErr(serverResp serverResponse) error {
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
// then the user can't change OUR headers
for k, v := range cli.customHTTPHeaders {

View File

@ -4,12 +4,14 @@ import (
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/versions"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
)
@ -17,13 +19,6 @@ import (
// ServiceCreate creates a new service.
func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (types.ServiceCreateResponse, error) {
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
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)
defer ensureReaderClosed(resp)
if err != nil {

View File

@ -3,11 +3,13 @@ package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"net/http"
"net/url"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"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.
@ -19,14 +21,6 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version
response = types.ServiceUpdateResponse{}
)
headers := map[string][]string{
"version": {cli.version},
}
if options.EncodedRegistryAuth != "" {
headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth}
}
if 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)
defer ensureReaderClosed(resp)
if err != nil {

View File

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

View File

@ -9,6 +9,7 @@ import (
"net/http"
"net/http/cookiejar"
"net/url"
"strconv"
"strings"
"sync"
@ -192,8 +193,8 @@ func (r *session) searchRepositories(term string, limit int) (*registry.SearchRe
if limit < 1 || limit > 100 {
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))
log.G(context.TODO()).WithField("url", u).Debug("searchRepositories")
req, err := http.NewRequest(http.MethodGet, u, nil)
if err != nil {
@ -208,10 +209,14 @@ func (r *session) searchRepositories(term string, limit int) (*registry.SearchRe
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
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,
})
}
result := new(registry.SearchResults)
return result, errors.Wrap(json.NewDecoder(res.Body).Decode(result), "error decoding registry search results")
result := &registry.SearchResults{}
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/memory
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
github.com/docker/docker/api
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/swarm
github.com/docker/docker/api/types/swarm/runtime
github.com/docker/docker/api/types/system
github.com/docker/docker/api/types/time
github.com/docker/docker/api/types/versions
github.com/docker/docker/api/types/volume
@ -168,7 +169,7 @@ github.com/moby/buildkit/util/appcontext
# github.com/moby/patternmatcher v0.5.0
## explicit; go 1.19
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
github.com/moby/swarmkit/v2/api
github.com/moby/swarmkit/v2/api/deepcopy