Merge pull request #6232 from thaJeztah/bump_engine
vendor: moby/moby/api v1.52.0-alpha.1, moby/moby/client v0.1.0-alpha.0
This commit is contained in:
@@ -239,7 +239,7 @@ func TestRunPullTermination(t *testing.T) {
|
||||
return client.HijackedResponse{}, errors.New("shouldn't try to attach to a container")
|
||||
},
|
||||
imageCreateFunc: func(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error) {
|
||||
server, client := net.Pipe()
|
||||
server, respReader := net.Pipe()
|
||||
t.Cleanup(func() {
|
||||
_ = server.Close()
|
||||
})
|
||||
@@ -269,7 +269,7 @@ func TestRunPullTermination(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
attachCh <- struct{}{}
|
||||
return client, nil
|
||||
return respReader, nil
|
||||
},
|
||||
Version: "1.30",
|
||||
})
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
"github.com/moby/moby/api/types/system"
|
||||
"github.com/moby/moby/client"
|
||||
)
|
||||
@@ -17,8 +17,8 @@ type fakeClient struct {
|
||||
pluginEnableFunc func(name string, options client.PluginEnableOptions) error
|
||||
pluginRemoveFunc func(name string, options client.PluginRemoveOptions) error
|
||||
pluginInstallFunc func(name string, options client.PluginInstallOptions) (io.ReadCloser, error)
|
||||
pluginListFunc func(filter filters.Args) (types.PluginsListResponse, error)
|
||||
pluginInspectFunc func(name string) (*types.Plugin, []byte, error)
|
||||
pluginListFunc func(filter filters.Args) (plugin.ListResponse, error)
|
||||
pluginInspectFunc func(name string) (*plugin.Plugin, []byte, error)
|
||||
pluginUpgradeFunc func(name string, options client.PluginInstallOptions) (io.ReadCloser, error)
|
||||
}
|
||||
|
||||
@@ -57,15 +57,15 @@ func (c *fakeClient) PluginInstall(_ context.Context, name string, installOption
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *fakeClient) PluginList(_ context.Context, filter filters.Args) (types.PluginsListResponse, error) {
|
||||
func (c *fakeClient) PluginList(_ context.Context, filter filters.Args) (plugin.ListResponse, error) {
|
||||
if c.pluginListFunc != nil {
|
||||
return c.pluginListFunc(filter)
|
||||
}
|
||||
|
||||
return types.PluginsListResponse{}, nil
|
||||
return plugin.ListResponse{}, nil
|
||||
}
|
||||
|
||||
func (c *fakeClient) PluginInspectWithRaw(_ context.Context, name string) (*types.Plugin, []byte, error) {
|
||||
func (c *fakeClient) PluginInspectWithRaw(_ context.Context, name string) (*plugin.Plugin, []byte, error) {
|
||||
if c.pluginInspectFunc != nil {
|
||||
return c.pluginInspectFunc(name)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/moby/go-archive"
|
||||
"github.com/moby/go-archive/compression"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -34,7 +34,7 @@ func validateConfig(path string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
m := types.PluginConfig{}
|
||||
m := plugin.Config{}
|
||||
err = json.NewDecoder(dt).Decode(&m)
|
||||
_ = dt.Close()
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -38,10 +38,10 @@ func NewFormat(source string, quiet bool) formatter.Format {
|
||||
}
|
||||
|
||||
// FormatWrite writes the context
|
||||
func FormatWrite(ctx formatter.Context, plugins []*types.Plugin) error {
|
||||
func FormatWrite(ctx formatter.Context, plugins []*plugin.Plugin) error {
|
||||
render := func(format func(subContext formatter.SubContext) error) error {
|
||||
for _, plugin := range plugins {
|
||||
pluginCtx := &pluginContext{trunc: ctx.Trunc, p: *plugin}
|
||||
for _, p := range plugins {
|
||||
pluginCtx := &pluginContext{trunc: ctx.Trunc, p: *p}
|
||||
if err := format(pluginCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -62,7 +62,7 @@ func FormatWrite(ctx formatter.Context, plugins []*types.Plugin) error {
|
||||
type pluginContext struct {
|
||||
formatter.HeaderContext
|
||||
trunc bool
|
||||
p types.Plugin
|
||||
p plugin.Plugin
|
||||
}
|
||||
|
||||
func (c *pluginContext) MarshalJSON() ([]byte, error) {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
@@ -27,7 +27,7 @@ func TestPluginContext(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
pluginCtx: pluginContext{
|
||||
p: types.Plugin{ID: pluginID},
|
||||
p: plugin.Plugin{ID: pluginID},
|
||||
trunc: false,
|
||||
},
|
||||
expValue: pluginID,
|
||||
@@ -35,7 +35,7 @@ func TestPluginContext(t *testing.T) {
|
||||
},
|
||||
{
|
||||
pluginCtx: pluginContext{
|
||||
p: types.Plugin{ID: pluginID},
|
||||
p: plugin.Plugin{ID: pluginID},
|
||||
trunc: true,
|
||||
},
|
||||
expValue: formatter.TruncateID(pluginID),
|
||||
@@ -43,14 +43,14 @@ func TestPluginContext(t *testing.T) {
|
||||
},
|
||||
{
|
||||
pluginCtx: pluginContext{
|
||||
p: types.Plugin{Name: "plugin_name"},
|
||||
p: plugin.Plugin{Name: "plugin_name"},
|
||||
},
|
||||
expValue: "plugin_name",
|
||||
call: pCtx.Name,
|
||||
},
|
||||
{
|
||||
pluginCtx: pluginContext{
|
||||
p: types.Plugin{Config: types.PluginConfig{Description: "plugin_description"}},
|
||||
p: plugin.Plugin{Config: plugin.Config{Description: "plugin_description"}},
|
||||
},
|
||||
expValue: "plugin_description",
|
||||
call: pCtx.Description,
|
||||
@@ -146,9 +146,9 @@ foobar_bar
|
||||
},
|
||||
}
|
||||
|
||||
plugins := []*types.Plugin{
|
||||
{ID: "pluginID1", Name: "foobar_baz", Config: types.PluginConfig{Description: "description 1"}, Enabled: true},
|
||||
{ID: "pluginID2", Name: "foobar_bar", Config: types.PluginConfig{Description: "description 2"}, Enabled: false},
|
||||
plugins := []*plugin.Plugin{
|
||||
{ID: "pluginID1", Name: "foobar_baz", Config: plugin.Config{Description: "description 1"}, Enabled: true},
|
||||
{ID: "pluginID2", Name: "foobar_bar", Config: plugin.Config{Description: "description 2"}, Enabled: false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
@@ -167,7 +167,7 @@ foobar_bar
|
||||
}
|
||||
|
||||
func TestPluginContextWriteJSON(t *testing.T) {
|
||||
plugins := []*types.Plugin{
|
||||
plugins := []*plugin.Plugin{
|
||||
{ID: "pluginID1", Name: "foobar_baz"},
|
||||
{ID: "pluginID2", Name: "foobar_bar"},
|
||||
}
|
||||
@@ -191,7 +191,7 @@ func TestPluginContextWriteJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPluginContextWriteJSONField(t *testing.T) {
|
||||
plugins := []*types.Plugin{
|
||||
plugins := []*plugin.Plugin{
|
||||
{ID: "pluginID1", Name: "foobar_baz"},
|
||||
{ID: "pluginID2", Name: "foobar_bar"},
|
||||
}
|
||||
|
||||
@@ -7,27 +7,27 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/golden"
|
||||
)
|
||||
|
||||
var pluginFoo = &types.Plugin{
|
||||
var pluginFoo = &plugin.Plugin{
|
||||
ID: "id-foo",
|
||||
Name: "name-foo",
|
||||
Config: types.PluginConfig{
|
||||
Config: plugin.Config{
|
||||
Description: "plugin foo description",
|
||||
DockerVersion: "17.12.1-ce",
|
||||
Documentation: "plugin foo documentation",
|
||||
Entrypoint: []string{"/foo"},
|
||||
Interface: types.PluginConfigInterface{
|
||||
Interface: plugin.Interface{
|
||||
Socket: "plugin-foo.sock",
|
||||
},
|
||||
Linux: types.PluginConfigLinux{
|
||||
Linux: plugin.LinuxConfig{
|
||||
Capabilities: []string{"CAP_SYS_ADMIN"},
|
||||
},
|
||||
WorkDir: "workdir-foo",
|
||||
Rootfs: &types.PluginConfigRootfs{
|
||||
Rootfs: &plugin.RootFS{
|
||||
DiffIds: []string{"sha256:deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"},
|
||||
Type: "layers",
|
||||
},
|
||||
@@ -40,7 +40,7 @@ func TestInspectErrors(t *testing.T) {
|
||||
args []string
|
||||
flags map[string]string
|
||||
expectedError string
|
||||
inspectFunc func(name string) (*types.Plugin, []byte, error)
|
||||
inspectFunc func(name string) (*plugin.Plugin, []byte, error)
|
||||
}{
|
||||
{
|
||||
description: "too few arguments",
|
||||
@@ -51,7 +51,7 @@ func TestInspectErrors(t *testing.T) {
|
||||
description: "error inspecting plugin",
|
||||
args: []string{"foo"},
|
||||
expectedError: "error inspecting plugin",
|
||||
inspectFunc: func(name string) (*types.Plugin, []byte, error) {
|
||||
inspectFunc: func(name string) (*plugin.Plugin, []byte, error) {
|
||||
return nil, nil, errors.New("error inspecting plugin")
|
||||
},
|
||||
},
|
||||
@@ -86,7 +86,7 @@ func TestInspect(t *testing.T) {
|
||||
args []string
|
||||
flags map[string]string
|
||||
golden string
|
||||
inspectFunc func(name string) (*types.Plugin, []byte, error)
|
||||
inspectFunc func(name string) (*plugin.Plugin, []byte, error)
|
||||
}{
|
||||
{
|
||||
description: "inspect single plugin with format",
|
||||
@@ -95,8 +95,8 @@ func TestInspect(t *testing.T) {
|
||||
"format": "{{ .Name }}",
|
||||
},
|
||||
golden: "plugin-inspect-single-with-format.golden",
|
||||
inspectFunc: func(name string) (*types.Plugin, []byte, error) {
|
||||
return &types.Plugin{
|
||||
inspectFunc: func(name string) (*plugin.Plugin, []byte, error) {
|
||||
return &plugin.Plugin{
|
||||
ID: "id-foo",
|
||||
Name: "name-foo",
|
||||
}, []byte{}, nil
|
||||
@@ -106,7 +106,7 @@ func TestInspect(t *testing.T) {
|
||||
description: "inspect single plugin without format",
|
||||
args: []string{"foo"},
|
||||
golden: "plugin-inspect-single-without-format.golden",
|
||||
inspectFunc: func(name string) (*types.Plugin, []byte, error) {
|
||||
inspectFunc: func(name string) (*plugin.Plugin, []byte, error) {
|
||||
return pluginFoo, nil, nil
|
||||
},
|
||||
},
|
||||
@@ -117,15 +117,15 @@ func TestInspect(t *testing.T) {
|
||||
"format": "{{ .Name }}",
|
||||
},
|
||||
golden: "plugin-inspect-multiple-with-format.golden",
|
||||
inspectFunc: func(name string) (*types.Plugin, []byte, error) {
|
||||
inspectFunc: func(name string) (*plugin.Plugin, []byte, error) {
|
||||
switch name {
|
||||
case "foo":
|
||||
return &types.Plugin{
|
||||
return &plugin.Plugin{
|
||||
ID: "id-foo",
|
||||
Name: "name-foo",
|
||||
}, []byte{}, nil
|
||||
case "bar":
|
||||
return &types.Plugin{
|
||||
return &plugin.Plugin{
|
||||
ID: "id-bar",
|
||||
Name: "name-bar",
|
||||
}, []byte{}, nil
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"github.com/docker/cli/internal/jsonstream"
|
||||
"github.com/docker/cli/internal/prompt"
|
||||
"github.com/docker/cli/internal/registry"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
registrytypes "github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/pkg/errors"
|
||||
@@ -136,8 +136,8 @@ func runInstall(ctx context.Context, dockerCLI command.Cli, opts pluginOptions)
|
||||
return nil
|
||||
}
|
||||
|
||||
func acceptPrivileges(dockerCLI command.Streams, name string) func(ctx context.Context, privileges types.PluginPrivileges) (bool, error) {
|
||||
return func(ctx context.Context, privileges types.PluginPrivileges) (bool, error) {
|
||||
func acceptPrivileges(dockerCLI command.Streams, name string) func(ctx context.Context, privileges plugin.Privileges) (bool, error) {
|
||||
return func(ctx context.Context, privileges plugin.Privileges) (bool, error) {
|
||||
_, _ = fmt.Fprintf(dockerCLI.Out(), "Plugin %q is requesting the following privileges:\n", name)
|
||||
for _, privilege := range privileges {
|
||||
_, _ = fmt.Fprintf(dockerCLI.Out(), " - %s: %v\n", privilege.Name, privilege.Value)
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
@@ -20,7 +20,7 @@ func TestListErrors(t *testing.T) {
|
||||
args []string
|
||||
flags map[string]string
|
||||
expectedError string
|
||||
listFunc func(filter filters.Args) (types.PluginsListResponse, error)
|
||||
listFunc func(filter filters.Args) (plugin.ListResponse, error)
|
||||
}{
|
||||
{
|
||||
description: "too many arguments",
|
||||
@@ -31,8 +31,8 @@ func TestListErrors(t *testing.T) {
|
||||
description: "error listing plugins",
|
||||
args: []string{},
|
||||
expectedError: "error listing plugins",
|
||||
listFunc: func(filter filters.Args) (types.PluginsListResponse, error) {
|
||||
return types.PluginsListResponse{}, errors.New("error listing plugins")
|
||||
listFunc: func(filter filters.Args) (plugin.ListResponse, error) {
|
||||
return plugin.ListResponse{}, errors.New("error listing plugins")
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -61,13 +61,13 @@ func TestListErrors(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
singlePluginListFunc := func(_ filters.Args) (types.PluginsListResponse, error) {
|
||||
return types.PluginsListResponse{
|
||||
singlePluginListFunc := func(_ filters.Args) (plugin.ListResponse, error) {
|
||||
return plugin.ListResponse{
|
||||
{
|
||||
ID: "id-foo",
|
||||
Name: "name-foo",
|
||||
Enabled: true,
|
||||
Config: types.PluginConfig{
|
||||
Config: plugin.Config{
|
||||
Description: "desc-bar",
|
||||
},
|
||||
},
|
||||
@@ -79,7 +79,7 @@ func TestList(t *testing.T) {
|
||||
args []string
|
||||
flags map[string]string
|
||||
golden string
|
||||
listFunc func(filter filters.Args) (types.PluginsListResponse, error)
|
||||
listFunc func(filter filters.Args) (plugin.ListResponse, error)
|
||||
}{
|
||||
{
|
||||
description: "list with no additional flags",
|
||||
@@ -94,7 +94,7 @@ func TestList(t *testing.T) {
|
||||
"filter": "foo=bar",
|
||||
},
|
||||
golden: "plugin-list-without-format.golden",
|
||||
listFunc: func(filter filters.Args) (types.PluginsListResponse, error) {
|
||||
listFunc: func(filter filters.Args) (plugin.ListResponse, error) {
|
||||
assert.Check(t, is.Equal("bar", filter.Get("foo")[0]))
|
||||
return singlePluginListFunc(filter)
|
||||
},
|
||||
@@ -116,13 +116,13 @@ func TestList(t *testing.T) {
|
||||
"format": "{{ .ID }}",
|
||||
},
|
||||
golden: "plugin-list-with-no-trunc-option.golden",
|
||||
listFunc: func(_ filters.Args) (types.PluginsListResponse, error) {
|
||||
return types.PluginsListResponse{
|
||||
listFunc: func(_ filters.Args) (plugin.ListResponse, error) {
|
||||
return plugin.ListResponse{
|
||||
{
|
||||
ID: "xyg4z2hiSLO5yTnBJfg4OYia9gKA6Qjd",
|
||||
Name: "name-foo",
|
||||
Enabled: true,
|
||||
Config: types.PluginConfig{
|
||||
Config: plugin.Config{
|
||||
Description: "desc-bar",
|
||||
},
|
||||
},
|
||||
@@ -145,8 +145,8 @@ func TestList(t *testing.T) {
|
||||
"format": "{{ .Name }}",
|
||||
},
|
||||
golden: "plugin-list-sort.golden",
|
||||
listFunc: func(_ filters.Args) (types.PluginsListResponse, error) {
|
||||
return types.PluginsListResponse{
|
||||
listFunc: func(_ filters.Args) (plugin.ListResponse, error) {
|
||||
return plugin.ListResponse{
|
||||
{
|
||||
ID: "id-1",
|
||||
Name: "plugin-1-foo",
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
"github.com/moby/moby/client"
|
||||
"gotest.tools/v3/golden"
|
||||
)
|
||||
@@ -20,8 +20,8 @@ func TestUpgradePromptTermination(t *testing.T) {
|
||||
pluginUpgradeFunc: func(name string, options client.PluginInstallOptions) (io.ReadCloser, error) {
|
||||
return nil, errors.New("should not be called")
|
||||
},
|
||||
pluginInspectFunc: func(name string) (*types.Plugin, []byte, error) {
|
||||
return &types.Plugin{
|
||||
pluginInspectFunc: func(name string) (*plugin.Plugin, []byte, error) {
|
||||
return &plugin.Plugin{
|
||||
ID: "5724e2c8652da337ab2eedd19fc6fc0ec908e4bd907c7421bf6a8dfc70c4c078",
|
||||
Name: "foo/bar",
|
||||
Enabled: false,
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/fs"
|
||||
"gotest.tools/v3/icmd"
|
||||
@@ -26,13 +26,17 @@ var plugins embed.FS
|
||||
func SetupPlugin(t *testing.T, ctx context.Context) *fs.Dir {
|
||||
t.Helper()
|
||||
|
||||
p := &types.PluginConfig{
|
||||
Linux: types.PluginConfigLinux{
|
||||
p := &plugin.Config{
|
||||
Linux: plugin.LinuxConfig{
|
||||
Capabilities: []string{"CAP_SYS_ADMIN"},
|
||||
},
|
||||
Interface: types.PluginConfigInterface{
|
||||
Interface: plugin.Interface{
|
||||
Socket: "basic.sock",
|
||||
Types: []types.PluginInterfaceType{{Capability: "docker.dummy/1.0"}},
|
||||
Types: []plugin.CapabilityID{{
|
||||
Capability: "dummy",
|
||||
Prefix: "docker",
|
||||
Version: "1.0",
|
||||
}},
|
||||
},
|
||||
Entrypoint: []string{"/basic"},
|
||||
}
|
||||
|
||||
+2
-8
@@ -6,12 +6,6 @@ module github.com/docker/cli
|
||||
|
||||
go 1.23.0
|
||||
|
||||
replace (
|
||||
// FIXME(thaJeztah): temporarily need to pin on commits, otherwise go modules won't resolve until these are tagged.
|
||||
github.com/moby/moby/api => github.com/moby/moby/api v0.0.0-20250731152656-4faedf2bec36
|
||||
github.com/moby/moby/client => github.com/moby/moby/client v0.0.0-20250731152656-4faedf2bec36
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.1
|
||||
github.com/containerd/errdefs v1.0.0
|
||||
@@ -34,8 +28,8 @@ require (
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/mattn/go-runewidth v0.0.16
|
||||
github.com/moby/go-archive v0.1.0
|
||||
github.com/moby/moby/api v0.0.0
|
||||
github.com/moby/moby/client v0.0.0
|
||||
github.com/moby/moby/api v1.52.0-alpha.1
|
||||
github.com/moby/moby/client v0.1.0-alpha.0
|
||||
github.com/moby/patternmatcher v0.6.0
|
||||
github.com/moby/swarmkit/v2 v2.0.0
|
||||
github.com/moby/sys/atomicwriter v0.1.0
|
||||
|
||||
+6
-4
@@ -170,10 +170,10 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
|
||||
github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=
|
||||
github.com/moby/moby/api v0.0.0-20250731152656-4faedf2bec36 h1:2o6bmPZvLOYqE6mQGqnyt+556TMpa26ZtSxvgSpT+98=
|
||||
github.com/moby/moby/api v0.0.0-20250731152656-4faedf2bec36/go.mod h1:GNQ0zU3WJGeJIcrLPE3xiQnsnLElvfqXQZZZiOqWuiE=
|
||||
github.com/moby/moby/client v0.0.0-20250731152656-4faedf2bec36 h1:o32ntpp76dDd5Hf9+XL09+qs06120KvZl+Ogt+RkYG0=
|
||||
github.com/moby/moby/client v0.0.0-20250731152656-4faedf2bec36/go.mod h1:+TFnycF6RuAUAq1tGTjZiSXuRcywpKUGo2dLkJ6tC48=
|
||||
github.com/moby/moby/api v1.52.0-alpha.1 h1:fzxPD0h6l4LmvPd/rySW7T3G45G8eFTo9qEAEp5UZX0=
|
||||
github.com/moby/moby/api v1.52.0-alpha.1/go.mod h1:MuA35dxT3DVZpImg0ORGCoZtT2dC1jgPjwH9/CQ/afQ=
|
||||
github.com/moby/moby/client v0.1.0-alpha.0 h1:1Q393KgwO8L3SznKE+xGZJVDdApgcSM0vIhAEff+acc=
|
||||
github.com/moby/moby/client v0.1.0-alpha.0/go.mod h1:pVMvmGeD4P9tbgBtEHZKW993Qkj4d1Nu6qhiW3GGJ6k=
|
||||
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
||||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/swarmkit/v2 v2.0.0 h1:jkWQKQaJ4ltA61/mC9UdPe1McLma55RUcacTO+pPweY=
|
||||
@@ -416,5 +416,7 @@ gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
|
||||
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
|
||||
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
|
||||
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=
|
||||
pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
|
||||
tags.cncf.io/container-device-interface v0.8.0 h1:8bCFo/g9WODjWx3m6EYl3GfUG31eKJbaggyBDxEldRc=
|
||||
tags.cncf.io/container-device-interface v0.8.0/go.mod h1:Apb7N4VdILW0EVdEMRYXIDVRZfNJZ+kmEUss2kRRQ6Y=
|
||||
|
||||
+4
-4
@@ -23,7 +23,7 @@ type Progress struct {
|
||||
|
||||
// Aux contains extra information not presented to the user, such as
|
||||
// digests for push signing.
|
||||
Aux interface{}
|
||||
Aux any
|
||||
|
||||
LastUpdate bool
|
||||
}
|
||||
@@ -71,7 +71,7 @@ func Update(out Output, id, action string) {
|
||||
|
||||
// Updatef is a convenience function to write a printf-formatted progress update
|
||||
// to the channel.
|
||||
func Updatef(out Output, id, format string, a ...interface{}) {
|
||||
func Updatef(out Output, id, format string, a ...any) {
|
||||
Update(out, id, fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
@@ -82,12 +82,12 @@ func Message(out Output, id, message string) {
|
||||
|
||||
// Messagef is a convenience function to write a printf-formatted progress
|
||||
// message to the channel.
|
||||
func Messagef(out Output, id, format string, a ...interface{}) {
|
||||
func Messagef(out Output, id, format string, a ...any) {
|
||||
Message(out, id, fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Aux sends auxiliary information over a progress interface, which will not be
|
||||
// formatted for the UI. This is used for things such as push signing.
|
||||
func Aux(out Output, a interface{}) {
|
||||
func Aux(out Output, a any) {
|
||||
out.WriteProgress(Progress{Aux: a})
|
||||
}
|
||||
|
||||
+28
-16
@@ -14,16 +14,13 @@ import (
|
||||
type StdType byte
|
||||
|
||||
const (
|
||||
// Stdin represents standard input stream type.
|
||||
Stdin StdType = iota
|
||||
// Stdout represents standard output stream type.
|
||||
Stdout
|
||||
// Stderr represents standard error steam type.
|
||||
Stderr
|
||||
// Systemerr represents errors originating from the system that make it
|
||||
// into the multiplexed stream.
|
||||
Systemerr
|
||||
Stdin StdType = 0 // Stdin represents standard input stream. It is present for completeness and should NOT be used. When reading the stream with [StdCopy] it is output on [Stdout].
|
||||
Stdout StdType = 1 // Stdout represents standard output stream.
|
||||
Stderr StdType = 2 // Stderr represents standard error steam.
|
||||
Systemerr StdType = 3 // Systemerr represents errors originating from the system. When reading the stream with [StdCopy] it is returned as an error.
|
||||
)
|
||||
|
||||
const (
|
||||
stdWriterPrefixLen = 8
|
||||
stdWriterFdIndex = 0
|
||||
stdWriterSizeIndex = 4
|
||||
@@ -31,7 +28,7 @@ const (
|
||||
startingBufLen = 32*1024 + stdWriterPrefixLen + 1
|
||||
)
|
||||
|
||||
var bufPool = &sync.Pool{New: func() interface{} { return bytes.NewBuffer(nil) }}
|
||||
var bufPool = &sync.Pool{New: func() any { return bytes.NewBuffer(nil) }}
|
||||
|
||||
// stdWriter is wrapper of io.Writer with extra customized info.
|
||||
type stdWriter struct {
|
||||
@@ -75,9 +72,20 @@ func (w *stdWriter) Write(p []byte) (int, error) {
|
||||
// stream "w".
|
||||
//
|
||||
// Writers created through NewStdWriter allow for multiple write streams
|
||||
// (e.g. stdout ([Stdout]) and stderr ([Stderr]) to be multiplexed into a
|
||||
// (e.g., stdout ([Stdout]) and stderr ([Stderr]) to be multiplexed into a
|
||||
// single connection. "streamType" indicates the type of stream to encapsulate,
|
||||
// and can be [Stdin], [Stdout], pr [Stderr].
|
||||
// commonly, [Stdout] or [Stderr]. The [Systemerr] stream can be used to
|
||||
// include server-side errors in the stream. Information on this stream
|
||||
// is returned as an error by [StdCopy] and terminates processing the
|
||||
// stream.
|
||||
//
|
||||
// The [Stdin] stream is present for completeness and should generally
|
||||
// NOT be used. It is output on [Stdout] when reading the stream with
|
||||
// [StdCopy].
|
||||
//
|
||||
// All streams must share the same underlying [io.Writer] to ensure proper
|
||||
// multiplexing. Each call to NewStdWriter wraps that shared writer with
|
||||
// a header indicating the target stream.
|
||||
func NewStdWriter(w io.Writer, streamType StdType) io.Writer {
|
||||
return &stdWriter{
|
||||
Writer: w,
|
||||
@@ -94,11 +102,15 @@ func NewStdWriter(w io.Writer, streamType StdType) io.Writer {
|
||||
// [NewStdWriter].
|
||||
//
|
||||
// As it reads from "multiplexedSource", StdCopy writes [Stdout] messages
|
||||
// to "destOut", and [Stderr] message to "destErr].
|
||||
// to "destOut", and [Stderr] message to "destErr]. For backward-compatibility,
|
||||
// [Stdin] messages are output to "destOut". The [Systemerr] stream provides
|
||||
// errors produced by the daemon. It is returned as an error, and terminates
|
||||
// processing the stream.
|
||||
//
|
||||
// StdCopy it reads until it hits [io.EOF] on "multiplexedSource", after
|
||||
// which it returns a nil error. In other words: any error returned indicates
|
||||
// a real underlying error.
|
||||
// a real underlying error, which may be when an unknown [StdType] stream
|
||||
// is received.
|
||||
//
|
||||
// The "written" return holds the total number of bytes written to "destOut"
|
||||
// and "destErr" combined.
|
||||
@@ -129,8 +141,8 @@ func StdCopy(destOut, destErr io.Writer, multiplexedSource io.Reader) (written i
|
||||
}
|
||||
}
|
||||
|
||||
stream := StdType(buf[stdWriterFdIndex])
|
||||
// Check the first byte to know where to write
|
||||
stream := StdType(buf[stdWriterFdIndex])
|
||||
switch stream {
|
||||
case Stdin:
|
||||
fallthrough
|
||||
@@ -146,7 +158,7 @@ func StdCopy(destOut, destErr io.Writer, multiplexedSource io.Reader) (written i
|
||||
// to outstream if Systemerr is the stream
|
||||
out = nil
|
||||
default:
|
||||
return 0, fmt.Errorf("unrecognized input header: %d", buf[stdWriterFdIndex])
|
||||
return 0, fmt.Errorf("unrecognized stream: %d", stream)
|
||||
}
|
||||
|
||||
// Retrieve the size of the frame
|
||||
|
||||
+8
-8
@@ -42,7 +42,7 @@ func appendNewline(source []byte) []byte {
|
||||
}
|
||||
|
||||
// FormatStatus formats the specified objects according to the specified format (and id).
|
||||
func FormatStatus(id, format string, a ...interface{}) []byte {
|
||||
func FormatStatus(id, format string, a ...any) []byte {
|
||||
str := fmt.Sprintf(format, a...)
|
||||
b, err := json.Marshal(&jsonMessage{ID: id, Status: str})
|
||||
if err != nil {
|
||||
@@ -63,12 +63,12 @@ func FormatError(err error) []byte {
|
||||
return []byte(`{"error":"format error"}` + streamNewline)
|
||||
}
|
||||
|
||||
func (sf *jsonProgressFormatter) formatStatus(id, format string, a ...interface{}) []byte {
|
||||
func (sf *jsonProgressFormatter) formatStatus(id, format string, a ...any) []byte {
|
||||
return FormatStatus(id, format, a...)
|
||||
}
|
||||
|
||||
// formatProgress formats the progress information for a specified action.
|
||||
func (sf *jsonProgressFormatter) formatProgress(id, action string, progress *jsonstream.Progress, aux interface{}) []byte {
|
||||
func (sf *jsonProgressFormatter) formatProgress(id, action string, progress *jsonstream.Progress, aux any) []byte {
|
||||
if progress == nil {
|
||||
progress = &jsonstream.Progress{}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ func (sf *jsonProgressFormatter) formatProgress(id, action string, progress *jso
|
||||
|
||||
type rawProgressFormatter struct{}
|
||||
|
||||
func (sf *rawProgressFormatter) formatStatus(id, format string, a ...interface{}) []byte {
|
||||
func (sf *rawProgressFormatter) formatStatus(id, format string, a ...any) []byte {
|
||||
return []byte(fmt.Sprintf(format, a...) + streamNewline)
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ func rawProgressString(p *jsonstream.Progress) string {
|
||||
return pbBox + numbersBox + timeLeftBox
|
||||
}
|
||||
|
||||
func (sf *rawProgressFormatter) formatProgress(id, action string, progress *jsonstream.Progress, aux interface{}) []byte {
|
||||
func (sf *rawProgressFormatter) formatProgress(id, action string, progress *jsonstream.Progress, aux any) []byte {
|
||||
if progress == nil {
|
||||
progress = &jsonstream.Progress{}
|
||||
}
|
||||
@@ -180,8 +180,8 @@ func NewJSONProgressOutput(out io.Writer, newLines bool) progress.Output {
|
||||
}
|
||||
|
||||
type formatProgress interface {
|
||||
formatStatus(id, format string, a ...interface{}) []byte
|
||||
formatProgress(id, action string, progress *jsonstream.Progress, aux interface{}) []byte
|
||||
formatStatus(id, format string, a ...any) []byte
|
||||
formatProgress(id, action string, progress *jsonstream.Progress, aux any) []byte
|
||||
}
|
||||
|
||||
type progressOutput struct {
|
||||
@@ -227,7 +227,7 @@ type AuxFormatter struct {
|
||||
}
|
||||
|
||||
// Emit emits the given interface as an aux progress message
|
||||
func (sf *AuxFormatter) Emit(id string, aux interface{}) error {
|
||||
func (sf *AuxFormatter) Emit(id string, aux any) error {
|
||||
auxJSONBytes, err := json.Marshal(aux)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Generated
Vendored
+5
-1
@@ -1,9 +1,13 @@
|
||||
package types
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package common
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// ErrorResponse Represents an error.
|
||||
// Example: {"message":"Something went wrong."}
|
||||
//
|
||||
// swagger:model ErrorResponse
|
||||
type ErrorResponse struct {
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
package types
|
||||
package common
|
||||
|
||||
// Error returns the error message
|
||||
func (e ErrorResponse) Error() string {
|
||||
+3
@@ -1,9 +1,12 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package common
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// IDResponse Response to an API call that returns just an Id
|
||||
//
|
||||
// swagger:model IDResponse
|
||||
type IDResponse struct {
|
||||
|
||||
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package container
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
|
||||
+6
-1
@@ -1,3 +1,5 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package container
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
@@ -5,15 +7,18 @@ package container
|
||||
|
||||
// CreateResponse ContainerCreateResponse
|
||||
//
|
||||
// OK response to ContainerCreate operation
|
||||
// # OK response to ContainerCreate operation
|
||||
//
|
||||
// swagger:model CreateResponse
|
||||
type CreateResponse struct {
|
||||
|
||||
// The ID of the created container
|
||||
// Example: ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743
|
||||
// Required: true
|
||||
ID string `json:"Id"`
|
||||
|
||||
// Warnings encountered when creating the container
|
||||
// Example: []
|
||||
// Required: true
|
||||
Warnings []string `json:"Warnings"`
|
||||
}
|
||||
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package container
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
|
||||
+5
@@ -1,9 +1,13 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package container
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// Port An open port on a container
|
||||
// Example: {"PrivatePort":8080,"PublicPort":80,"Type":"tcp"}
|
||||
//
|
||||
// swagger:model Port
|
||||
type Port struct {
|
||||
|
||||
@@ -19,5 +23,6 @@ type Port struct {
|
||||
|
||||
// type
|
||||
// Required: true
|
||||
// Enum: ["tcp","udp","sctp"]
|
||||
Type string `json:"Type"`
|
||||
}
|
||||
|
||||
+5
@@ -1,3 +1,5 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package container
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
@@ -6,13 +8,16 @@ package container
|
||||
// TopResponse ContainerTopResponse
|
||||
//
|
||||
// Container "top" response.
|
||||
//
|
||||
// swagger:model TopResponse
|
||||
type TopResponse struct {
|
||||
|
||||
// Each process running in the container, where each process
|
||||
// is an array of values corresponding to the titles.
|
||||
// Example: {"Processes":[["root","13642","882","0","17:03","pts/0","00:00:00","/bin/bash"],["root","13735","13642","0","17:06","pts/0","00:00:00","sleep 10"]]}
|
||||
Processes [][]string `json:"Processes"`
|
||||
|
||||
// The ps column titles
|
||||
// Example: {"Titles":["UID","PID","PPID","C","STIME","TTY","TIME","CMD"]}
|
||||
Titles []string `json:"Titles"`
|
||||
}
|
||||
|
||||
+4
@@ -1,3 +1,5 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package container
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
@@ -6,9 +8,11 @@ package container
|
||||
// UpdateResponse ContainerUpdateResponse
|
||||
//
|
||||
// Response for a successful container-update.
|
||||
//
|
||||
// swagger:model UpdateResponse
|
||||
type UpdateResponse struct {
|
||||
|
||||
// Warnings encountered when updating the container.
|
||||
// Example: ["Published ports are discarded when using host network mode"]
|
||||
Warnings []string `json:"Warnings"`
|
||||
}
|
||||
|
||||
+3
@@ -1,9 +1,12 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package container
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// WaitExitError container waiting error, if any
|
||||
//
|
||||
// swagger:model WaitExitError
|
||||
type WaitExitError struct {
|
||||
|
||||
|
||||
+4
-1
@@ -1,3 +1,5 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package container
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
@@ -5,7 +7,8 @@ package container
|
||||
|
||||
// WaitResponse ContainerWaitResponse
|
||||
//
|
||||
// OK response to ContainerWait operation
|
||||
// # OK response to ContainerWait operation
|
||||
//
|
||||
// swagger:model WaitResponse
|
||||
type WaitResponse struct {
|
||||
|
||||
|
||||
+3
@@ -1,9 +1,12 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package image
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// DeleteResponse delete response
|
||||
//
|
||||
// swagger:model DeleteResponse
|
||||
type DeleteResponse struct {
|
||||
|
||||
|
||||
+1
@@ -7,6 +7,7 @@ package image
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// HistoryResponseItem individual image layer information in response to ImageHistory operation
|
||||
//
|
||||
// swagger:model HistoryResponseItem
|
||||
type HistoryResponseItem struct {
|
||||
|
||||
|
||||
+5
-1
@@ -1,3 +1,5 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package network
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
@@ -5,11 +7,13 @@ package network
|
||||
|
||||
// CreateResponse NetworkCreateResponse
|
||||
//
|
||||
// OK response to NetworkCreate operation
|
||||
// # OK response to NetworkCreate operation
|
||||
//
|
||||
// swagger:model CreateResponse
|
||||
type CreateResponse struct {
|
||||
|
||||
// The ID of the created network.
|
||||
// Example: b5c4fc71e8022147cd25de22b22173de4e3b170134117172eb595cb91b4e7e5d
|
||||
// Required: true
|
||||
ID string `json:"Id"`
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
testdata/rapid/**
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type CapabilityID struct {
|
||||
Capability string
|
||||
Prefix string
|
||||
Version string
|
||||
}
|
||||
|
||||
var (
|
||||
_ fmt.Stringer = CapabilityID{}
|
||||
_ encoding.TextUnmarshaler = (*CapabilityID)(nil)
|
||||
_ encoding.TextMarshaler = CapabilityID{}
|
||||
)
|
||||
|
||||
// String implements [fmt.Stringer] for CapabilityID
|
||||
func (t CapabilityID) String() string {
|
||||
return fmt.Sprintf("%s.%s/%s", t.Prefix, t.Capability, t.Version)
|
||||
}
|
||||
|
||||
// UnmarshalText implements [encoding.TextUnmarshaler] for CapabilityID
|
||||
func (t *CapabilityID) UnmarshalText(p []byte) error {
|
||||
fqcap, version, _ := bytes.Cut(p, []byte{'/'})
|
||||
idx := bytes.LastIndexByte(fqcap, '.')
|
||||
if idx < 0 {
|
||||
t.Prefix = ""
|
||||
t.Capability = string(fqcap)
|
||||
} else {
|
||||
t.Prefix = string(fqcap[:idx])
|
||||
t.Capability = string(fqcap[idx+1:])
|
||||
}
|
||||
t.Version = string(version)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalText implements [encoding.TextMarshaler] for CapabilityID
|
||||
func (t CapabilityID) MarshalText() ([]byte, error) {
|
||||
// Assert that the value can be round-tripped successfully.
|
||||
if strings.Contains(t.Capability, ".") {
|
||||
return nil, fmt.Errorf("capability %q cannot contain a dot", t.Capability)
|
||||
}
|
||||
if strings.Contains(t.Prefix, "/") {
|
||||
return nil, fmt.Errorf("prefix %q cannot contain a slash", t.Prefix)
|
||||
}
|
||||
if strings.Contains(t.Capability, "/") {
|
||||
return nil, fmt.Errorf("capability %q cannot contain a slash", t.Capability)
|
||||
}
|
||||
return []byte(t.String()), nil
|
||||
}
|
||||
Generated
Vendored
+8
-4
@@ -1,11 +1,14 @@
|
||||
package types
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package plugin
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// PluginDevice plugin device
|
||||
// swagger:model PluginDevice
|
||||
type PluginDevice struct {
|
||||
// Device device
|
||||
//
|
||||
// swagger:model Device
|
||||
type Device struct {
|
||||
|
||||
// description
|
||||
// Required: true
|
||||
@@ -16,6 +19,7 @@ type PluginDevice struct {
|
||||
Name string `json:"Name"`
|
||||
|
||||
// path
|
||||
// Example: /dev/fuse
|
||||
// Required: true
|
||||
Path *string `json:"Path"`
|
||||
|
||||
Generated
Vendored
+7
-4
@@ -1,11 +1,14 @@
|
||||
package types
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package plugin
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// PluginEnv plugin env
|
||||
// swagger:model PluginEnv
|
||||
type PluginEnv struct {
|
||||
// Env env
|
||||
//
|
||||
// swagger:model Env
|
||||
type Env struct {
|
||||
|
||||
// description
|
||||
// Required: true
|
||||
Generated
Vendored
+13
-4
@@ -1,25 +1,32 @@
|
||||
package types
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package plugin
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// PluginMount plugin mount
|
||||
// swagger:model PluginMount
|
||||
type PluginMount struct {
|
||||
// Mount mount
|
||||
//
|
||||
// swagger:model Mount
|
||||
type Mount struct {
|
||||
|
||||
// description
|
||||
// Example: This is a mount that's used by the plugin.
|
||||
// Required: true
|
||||
Description string `json:"Description"`
|
||||
|
||||
// destination
|
||||
// Example: /mnt/state
|
||||
// Required: true
|
||||
Destination string `json:"Destination"`
|
||||
|
||||
// name
|
||||
// Example: some-mount
|
||||
// Required: true
|
||||
Name string `json:"Name"`
|
||||
|
||||
// options
|
||||
// Example: ["rbind","rw"]
|
||||
// Required: true
|
||||
Options []string `json:"Options"`
|
||||
|
||||
@@ -28,10 +35,12 @@ type PluginMount struct {
|
||||
Settable []string `json:"Settable"`
|
||||
|
||||
// source
|
||||
// Example: /var/lib/docker/plugins/
|
||||
// Required: true
|
||||
Source *string `json:"Source"`
|
||||
|
||||
// type
|
||||
// Example: bind
|
||||
// Required: true
|
||||
Type string `json:"Type"`
|
||||
}
|
||||
Generated
Vendored
+77
-39
@@ -1,110 +1,130 @@
|
||||
package types
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package plugin
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// Plugin A plugin for the Engine API
|
||||
//
|
||||
// swagger:model Plugin
|
||||
type Plugin struct {
|
||||
|
||||
// config
|
||||
// Required: true
|
||||
Config PluginConfig `json:"Config"`
|
||||
Config Config `json:"Config"`
|
||||
|
||||
// True if the plugin is running. False if the plugin is not running, only installed.
|
||||
// Example: true
|
||||
// Required: true
|
||||
Enabled bool `json:"Enabled"`
|
||||
|
||||
// Id
|
||||
// Example: 5724e2c8652da337ab2eedd19fc6fc0ec908e4bd907c7421bf6a8dfc70c4c078
|
||||
ID string `json:"Id,omitempty"`
|
||||
|
||||
// name
|
||||
// Example: tiborvass/sample-volume-plugin
|
||||
// Required: true
|
||||
Name string `json:"Name"`
|
||||
|
||||
// plugin remote reference used to push/pull the plugin
|
||||
// Example: localhost:5000/tiborvass/sample-volume-plugin:latest
|
||||
PluginReference string `json:"PluginReference,omitempty"`
|
||||
|
||||
// settings
|
||||
// Required: true
|
||||
Settings PluginSettings `json:"Settings"`
|
||||
Settings Settings `json:"Settings"`
|
||||
}
|
||||
|
||||
// PluginConfig The config of a plugin.
|
||||
// swagger:model PluginConfig
|
||||
type PluginConfig struct {
|
||||
// Config The config of a plugin.
|
||||
//
|
||||
// swagger:model Config
|
||||
type Config struct {
|
||||
|
||||
// args
|
||||
// Required: true
|
||||
Args PluginConfigArgs `json:"Args"`
|
||||
Args Args `json:"Args"`
|
||||
|
||||
// description
|
||||
// Example: A sample volume plugin for Docker
|
||||
// Required: true
|
||||
Description string `json:"Description"`
|
||||
|
||||
// Docker Version used to create the plugin
|
||||
// Example: 17.06.0-ce
|
||||
DockerVersion string `json:"DockerVersion,omitempty"`
|
||||
|
||||
// documentation
|
||||
// Example: https://docs.docker.com/engine/extend/plugins/
|
||||
// Required: true
|
||||
Documentation string `json:"Documentation"`
|
||||
|
||||
// entrypoint
|
||||
// Example: ["/usr/bin/sample-volume-plugin","/data"]
|
||||
// Required: true
|
||||
Entrypoint []string `json:"Entrypoint"`
|
||||
|
||||
// env
|
||||
// Example: [{"Description":"If set, prints debug messages","Name":"DEBUG","Settable":null,"Value":"0"}]
|
||||
// Required: true
|
||||
Env []PluginEnv `json:"Env"`
|
||||
Env []Env `json:"Env"`
|
||||
|
||||
// interface
|
||||
// Required: true
|
||||
Interface PluginConfigInterface `json:"Interface"`
|
||||
Interface Interface `json:"Interface"`
|
||||
|
||||
// ipc host
|
||||
// Example: false
|
||||
// Required: true
|
||||
IpcHost bool `json:"IpcHost"`
|
||||
|
||||
// linux
|
||||
// Required: true
|
||||
Linux PluginConfigLinux `json:"Linux"`
|
||||
Linux LinuxConfig `json:"Linux"`
|
||||
|
||||
// mounts
|
||||
// Required: true
|
||||
Mounts []PluginMount `json:"Mounts"`
|
||||
Mounts []Mount `json:"Mounts"`
|
||||
|
||||
// network
|
||||
// Required: true
|
||||
Network PluginConfigNetwork `json:"Network"`
|
||||
Network NetworkConfig `json:"Network"`
|
||||
|
||||
// pid host
|
||||
// Example: false
|
||||
// Required: true
|
||||
PidHost bool `json:"PidHost"`
|
||||
|
||||
// propagated mount
|
||||
// Example: /mnt/volumes
|
||||
// Required: true
|
||||
PropagatedMount string `json:"PropagatedMount"`
|
||||
|
||||
// user
|
||||
User PluginConfigUser `json:"User,omitempty"`
|
||||
User User `json:"User,omitempty"`
|
||||
|
||||
// work dir
|
||||
// Example: /bin/
|
||||
// Required: true
|
||||
WorkDir string `json:"WorkDir"`
|
||||
|
||||
// rootfs
|
||||
Rootfs *PluginConfigRootfs `json:"rootfs,omitempty"`
|
||||
Rootfs *RootFS `json:"rootfs,omitempty"`
|
||||
}
|
||||
|
||||
// PluginConfigArgs plugin config args
|
||||
// swagger:model PluginConfigArgs
|
||||
type PluginConfigArgs struct {
|
||||
// Args args
|
||||
//
|
||||
// swagger:model Args
|
||||
type Args struct {
|
||||
|
||||
// description
|
||||
// Example: command line arguments
|
||||
// Required: true
|
||||
Description string `json:"Description"`
|
||||
|
||||
// name
|
||||
// Example: args
|
||||
// Required: true
|
||||
Name string `json:"Name"`
|
||||
|
||||
@@ -117,73 +137,90 @@ type PluginConfigArgs struct {
|
||||
Value []string `json:"Value"`
|
||||
}
|
||||
|
||||
// PluginConfigInterface The interface between Docker and the plugin
|
||||
// swagger:model PluginConfigInterface
|
||||
type PluginConfigInterface struct {
|
||||
// Interface The interface between Docker and the plugin
|
||||
//
|
||||
// swagger:model Interface
|
||||
type Interface struct {
|
||||
|
||||
// Protocol to use for clients connecting to the plugin.
|
||||
// Example: some.protocol/v1.0
|
||||
// Enum: ["","moby.plugins.http/v1"]
|
||||
ProtocolScheme string `json:"ProtocolScheme,omitempty"`
|
||||
|
||||
// socket
|
||||
// Example: plugins.sock
|
||||
// Required: true
|
||||
Socket string `json:"Socket"`
|
||||
|
||||
// types
|
||||
// Example: ["docker.volumedriver/1.0"]
|
||||
// Required: true
|
||||
Types []PluginInterfaceType `json:"Types"`
|
||||
Types []CapabilityID `json:"Types"`
|
||||
}
|
||||
|
||||
// PluginConfigLinux plugin config linux
|
||||
// swagger:model PluginConfigLinux
|
||||
type PluginConfigLinux struct {
|
||||
// LinuxConfig linux config
|
||||
//
|
||||
// swagger:model LinuxConfig
|
||||
type LinuxConfig struct {
|
||||
|
||||
// allow all devices
|
||||
// Example: false
|
||||
// Required: true
|
||||
AllowAllDevices bool `json:"AllowAllDevices"`
|
||||
|
||||
// capabilities
|
||||
// Example: ["CAP_SYS_ADMIN","CAP_SYSLOG"]
|
||||
// Required: true
|
||||
Capabilities []string `json:"Capabilities"`
|
||||
|
||||
// devices
|
||||
// Required: true
|
||||
Devices []PluginDevice `json:"Devices"`
|
||||
Devices []Device `json:"Devices"`
|
||||
}
|
||||
|
||||
// PluginConfigNetwork plugin config network
|
||||
// swagger:model PluginConfigNetwork
|
||||
type PluginConfigNetwork struct {
|
||||
// NetworkConfig network config
|
||||
//
|
||||
// swagger:model NetworkConfig
|
||||
type NetworkConfig struct {
|
||||
|
||||
// type
|
||||
// Example: host
|
||||
// Required: true
|
||||
Type string `json:"Type"`
|
||||
}
|
||||
|
||||
// PluginConfigRootfs plugin config rootfs
|
||||
// swagger:model PluginConfigRootfs
|
||||
type PluginConfigRootfs struct {
|
||||
// RootFS root f s
|
||||
//
|
||||
// swagger:model RootFS
|
||||
type RootFS struct {
|
||||
|
||||
// diff ids
|
||||
// Example: ["sha256:675532206fbf3030b8458f88d6e26d4eb1577688a25efec97154c94e8b6b4887","sha256:e216a057b1cb1efc11f8a268f37ef62083e70b1b38323ba252e25ac88904a7e8"]
|
||||
DiffIds []string `json:"diff_ids"`
|
||||
|
||||
// type
|
||||
// Example: layers
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// PluginConfigUser plugin config user
|
||||
// swagger:model PluginConfigUser
|
||||
type PluginConfigUser struct {
|
||||
// User user
|
||||
//
|
||||
// swagger:model User
|
||||
type User struct {
|
||||
|
||||
// g ID
|
||||
// Example: 1000
|
||||
GID uint32 `json:"GID,omitempty"`
|
||||
|
||||
// UID
|
||||
// Example: 1000
|
||||
UID uint32 `json:"UID,omitempty"`
|
||||
}
|
||||
|
||||
// PluginSettings Settings that can be modified by users.
|
||||
// swagger:model PluginSettings
|
||||
type PluginSettings struct {
|
||||
// Settings user-configurable settings for the plugin.
|
||||
//
|
||||
// swagger:model Settings
|
||||
type Settings struct {
|
||||
|
||||
// args
|
||||
// Required: true
|
||||
@@ -191,13 +228,14 @@ type PluginSettings struct {
|
||||
|
||||
// devices
|
||||
// Required: true
|
||||
Devices []PluginDevice `json:"Devices"`
|
||||
Devices []Device `json:"Devices"`
|
||||
|
||||
// env
|
||||
// Example: ["DEBUG=0"]
|
||||
// Required: true
|
||||
Env []string `json:"Env"`
|
||||
|
||||
// mounts
|
||||
// Required: true
|
||||
Mounts []PluginMount `json:"Mounts"`
|
||||
Mounts []Mount `json:"Mounts"`
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// ListResponse contains the response for the Engine API
|
||||
type ListResponse []*Plugin
|
||||
|
||||
// Privilege describes a permission the user has to accept
|
||||
// upon installing a plugin.
|
||||
type Privilege struct {
|
||||
Name string
|
||||
Description string
|
||||
Value []string
|
||||
}
|
||||
|
||||
// Privileges is a list of Privilege
|
||||
type Privileges []Privilege
|
||||
|
||||
func (s Privileges) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s Privileges) Less(i, j int) bool {
|
||||
return s[i].Name < s[j].Name
|
||||
}
|
||||
|
||||
func (s Privileges) Swap(i, j int) {
|
||||
sort.Strings(s[i].Value)
|
||||
sort.Strings(s[j].Value)
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
package types
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// PluginInterfaceType plugin interface type
|
||||
// swagger:model PluginInterfaceType
|
||||
type PluginInterfaceType struct {
|
||||
|
||||
// capability
|
||||
// Required: true
|
||||
Capability string `json:"Capability"`
|
||||
|
||||
// prefix
|
||||
// Required: true
|
||||
Prefix string `json:"Prefix"`
|
||||
|
||||
// version
|
||||
// Required: true
|
||||
Version string `json:"Version"`
|
||||
}
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// PluginsListResponse contains the response for the Engine API
|
||||
type PluginsListResponse []*Plugin
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler for PluginInterfaceType
|
||||
func (t *PluginInterfaceType) UnmarshalJSON(p []byte) error {
|
||||
versionIndex := len(p)
|
||||
prefixIndex := 0
|
||||
if len(p) < 2 || p[0] != '"' || p[len(p)-1] != '"' {
|
||||
return fmt.Errorf("%q is not a plugin interface type", p)
|
||||
}
|
||||
p = p[1 : len(p)-1]
|
||||
loop:
|
||||
for i, b := range p {
|
||||
switch b {
|
||||
case '.':
|
||||
prefixIndex = i
|
||||
case '/':
|
||||
versionIndex = i
|
||||
break loop
|
||||
}
|
||||
}
|
||||
t.Prefix = string(p[:prefixIndex])
|
||||
t.Capability = string(p[prefixIndex+1 : versionIndex])
|
||||
if versionIndex < len(p) {
|
||||
t.Version = string(p[versionIndex+1:])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler for PluginInterfaceType
|
||||
func (t *PluginInterfaceType) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(t.String())
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer for PluginInterfaceType
|
||||
func (t PluginInterfaceType) String() string {
|
||||
return fmt.Sprintf("%s.%s/%s", t.Prefix, t.Capability, t.Version)
|
||||
}
|
||||
|
||||
// PluginPrivilege describes a permission the user has to accept
|
||||
// upon installing a plugin.
|
||||
type PluginPrivilege struct {
|
||||
Name string
|
||||
Description string
|
||||
Value []string
|
||||
}
|
||||
|
||||
// PluginPrivileges is a list of PluginPrivilege
|
||||
type PluginPrivileges []PluginPrivilege
|
||||
|
||||
func (s PluginPrivileges) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s PluginPrivileges) Less(i, j int) bool {
|
||||
return s[i].Name < s[j].Name
|
||||
}
|
||||
|
||||
func (s PluginPrivileges) Swap(i, j int) {
|
||||
sort.Strings(s[i].Value)
|
||||
sort.Strings(s[j].Value)
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
+4
@@ -1,3 +1,5 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package storage
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
@@ -14,10 +16,12 @@ type DriverData struct {
|
||||
// This information is driver-specific, and depends on the storage-driver
|
||||
// in use, and should be used for informational purposes only.
|
||||
//
|
||||
// Example: {"MergedDir":"/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/merged","UpperDir":"/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/diff","WorkDir":"/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/work"}
|
||||
// Required: true
|
||||
Data map[string]string `json:"Data"`
|
||||
|
||||
// Name of the storage driver.
|
||||
// Example: overlay2
|
||||
// Required: true
|
||||
Name string `json:"Name"`
|
||||
}
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ type SecretSpec struct {
|
||||
// This field is only used to create the secret, and is not returned
|
||||
// by other endpoints.
|
||||
//
|
||||
// [MaxSecretSize]: https://pkg.go.dev/github.com/moby/swarmkit/v2@v2.0.0-20250103191802-8c1959736554/api/validation#MaxSecretSize
|
||||
// [MaxSecretSize]: https://pkg.go.dev/github.com/moby/swarmkit/v2@v2.0.0/api/validation#MaxSecretSize
|
||||
Data []byte `json:",omitempty"`
|
||||
|
||||
// Driver is the name of the secrets driver used to fetch the secret's
|
||||
|
||||
+4
@@ -1,3 +1,5 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package swarm
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
@@ -10,11 +12,13 @@ package swarm
|
||||
type ServiceCreateResponse struct {
|
||||
|
||||
// The ID of the created service.
|
||||
// Example: ak7w3gjqoa3kuz8xcpnyy0pvl
|
||||
ID string `json:"ID,omitempty"`
|
||||
|
||||
// Optional warning message.
|
||||
//
|
||||
// FIXME(thaJeztah): this should have "omitempty" in the generated type.
|
||||
//
|
||||
// Example: ["unable to pin image doesnotexist:latest to digest: image library/doesnotexist:latest not found"]
|
||||
Warnings []string `json:"Warnings"`
|
||||
}
|
||||
|
||||
+4
@@ -1,9 +1,13 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package swarm
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// ServiceUpdateResponse service update response
|
||||
// Example: {"Warnings":["unable to pin image doesnotexist:latest to digest: image library/doesnotexist:latest not found"]}
|
||||
//
|
||||
// swagger:model ServiceUpdateResponse
|
||||
type ServiceUpdateResponse struct {
|
||||
|
||||
|
||||
+2
-2
@@ -9,8 +9,8 @@ type Runtime struct {
|
||||
|
||||
// Shimv2 runtime configuration. Mutually exclusive with the legacy config above.
|
||||
|
||||
Type string `json:"runtimeType,omitempty"`
|
||||
Options map[string]interface{} `json:"options,omitempty"`
|
||||
Type string `json:"runtimeType,omitempty"`
|
||||
Options map[string]any `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
// RuntimeWithStatus extends [Runtime] to hold [RuntimeStatus].
|
||||
|
||||
+8
-1
@@ -1,3 +1,5 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package volume
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
@@ -5,7 +7,8 @@ package volume
|
||||
|
||||
// CreateOptions VolumeConfig
|
||||
//
|
||||
// Volume configuration
|
||||
// # Volume configuration
|
||||
//
|
||||
// swagger:model CreateOptions
|
||||
type CreateOptions struct {
|
||||
|
||||
@@ -13,17 +16,21 @@ type CreateOptions struct {
|
||||
ClusterVolumeSpec *ClusterVolumeSpec `json:"ClusterVolumeSpec,omitempty"`
|
||||
|
||||
// Name of the volume driver to use.
|
||||
// Example: custom
|
||||
Driver string `json:"Driver,omitempty"`
|
||||
|
||||
// A mapping of driver options and values. These options are
|
||||
// passed directly to the driver and are driver specific.
|
||||
//
|
||||
// Example: {"device":"tmpfs","o":"size=100m,uid=1000","type":"tmpfs"}
|
||||
DriverOpts map[string]string `json:"DriverOpts,omitempty"`
|
||||
|
||||
// User-defined key/value metadata.
|
||||
// Example: {"com.example.some-label":"some-value","com.example.some-other-label":"some-other-value"}
|
||||
Labels map[string]string `json:"Labels,omitempty"`
|
||||
|
||||
// The new volume's name. If not specified, Docker generates a name.
|
||||
//
|
||||
// Example: tardis
|
||||
Name string `json:"Name,omitempty"`
|
||||
}
|
||||
|
||||
+5
-1
@@ -1,3 +1,5 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package volume
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
@@ -5,7 +7,8 @@ package volume
|
||||
|
||||
// ListResponse VolumeListResponse
|
||||
//
|
||||
// Volume list response
|
||||
// # Volume list response
|
||||
//
|
||||
// swagger:model ListResponse
|
||||
type ListResponse struct {
|
||||
|
||||
@@ -14,5 +17,6 @@ type ListResponse struct {
|
||||
|
||||
// Warnings that occurred when fetching the list of volumes.
|
||||
//
|
||||
// Example: []
|
||||
Warnings []string `json:"Warnings"`
|
||||
}
|
||||
|
||||
+12
@@ -1,9 +1,12 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package volume
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// Volume volume
|
||||
//
|
||||
// swagger:model Volume
|
||||
type Volume struct {
|
||||
|
||||
@@ -11,33 +14,41 @@ type Volume struct {
|
||||
ClusterVolume *ClusterVolume `json:"ClusterVolume,omitempty"`
|
||||
|
||||
// Date/Time the volume was created.
|
||||
// Example: 2016-06-07T20:31:11.853781916Z
|
||||
CreatedAt string `json:"CreatedAt,omitempty"`
|
||||
|
||||
// Name of the volume driver used by the volume.
|
||||
// Example: custom
|
||||
// Required: true
|
||||
Driver string `json:"Driver"`
|
||||
|
||||
// User-defined key/value metadata.
|
||||
// Example: {"com.example.some-label":"some-value","com.example.some-other-label":"some-other-value"}
|
||||
// Required: true
|
||||
Labels map[string]string `json:"Labels"`
|
||||
|
||||
// Mount path of the volume on the host.
|
||||
// Example: /var/lib/docker/volumes/tardis
|
||||
// Required: true
|
||||
Mountpoint string `json:"Mountpoint"`
|
||||
|
||||
// Name of the volume.
|
||||
// Example: tardis
|
||||
// Required: true
|
||||
Name string `json:"Name"`
|
||||
|
||||
// The driver specific options used when creating the volume.
|
||||
//
|
||||
// Example: {"device":"tmpfs","o":"size=100m,uid=1000","type":"tmpfs"}
|
||||
// Required: true
|
||||
Options map[string]string `json:"Options"`
|
||||
|
||||
// The level at which the volume exists. Either `global` for cluster-wide,
|
||||
// or `local` for machine level.
|
||||
//
|
||||
// Example: local
|
||||
// Required: true
|
||||
// Enum: ["local","global"]
|
||||
Scope string `json:"Scope"`
|
||||
|
||||
// Low-level details about the volume, provided by the volume driver.
|
||||
@@ -47,6 +58,7 @@ type Volume struct {
|
||||
// The `Status` field is optional, and is omitted if the volume driver
|
||||
// does not support this feature.
|
||||
//
|
||||
// Example: {"hello":"world"}
|
||||
Status map[string]interface{} `json:"Status,omitempty"`
|
||||
|
||||
// usage data
|
||||
|
||||
+2
-1
@@ -5,7 +5,8 @@ import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// BuildCancel requests the daemon to cancel the ongoing build request.
|
||||
// BuildCancel requests the daemon to cancel the ongoing build request
|
||||
// with the given id.
|
||||
func (cli *Client) BuildCancel(ctx context.Context, id string) error {
|
||||
query := url.Values{}
|
||||
query.Set("id", id)
|
||||
|
||||
+4
-4
@@ -3,15 +3,15 @@ package client
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// BuildCachePrune requests the daemon to delete unused cache data
|
||||
// BuildCachePrune requests the daemon to delete unused cache data.
|
||||
func (cli *Client) BuildCachePrune(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error) {
|
||||
if err := cli.NewVersionError(ctx, "1.31", "build prune"); err != nil {
|
||||
return nil, err
|
||||
@@ -36,7 +36,7 @@ func (cli *Client) BuildCachePrune(ctx context.Context, opts build.CachePruneOpt
|
||||
}
|
||||
f, err := filters.ToJSON(opts.Filters)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "prune could not marshal filters option")
|
||||
return nil, fmt.Errorf("prune could not marshal filters option: %w", err)
|
||||
}
|
||||
query.Set("filters", f)
|
||||
|
||||
@@ -49,7 +49,7 @@ func (cli *Client) BuildCachePrune(ctx context.Context, opts build.CachePruneOpt
|
||||
|
||||
report := build.CachePruneReport{}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&report); err != nil {
|
||||
return nil, errors.Wrap(err, "error retrieving disk usage")
|
||||
return nil, fmt.Errorf("error retrieving disk usage: %w", err)
|
||||
}
|
||||
|
||||
return &report, nil
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/moby/moby/api/types/checkpoint"
|
||||
)
|
||||
|
||||
// CheckpointCreate creates a checkpoint from the given container with the given name
|
||||
// CheckpointCreate creates a checkpoint from the given container.
|
||||
func (cli *Client) CheckpointCreate(ctx context.Context, containerID string, options checkpoint.CreateOptions) error {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/moby/moby/api/types/checkpoint"
|
||||
)
|
||||
|
||||
// CheckpointDelete deletes the checkpoint with the given name from the given container
|
||||
// CheckpointDelete deletes the checkpoint with the given name from the given container.
|
||||
func (cli *Client) CheckpointDelete(ctx context.Context, containerID string, options checkpoint.DeleteOptions) error {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/moby/moby/api/types/checkpoint"
|
||||
)
|
||||
|
||||
// CheckpointList returns the checkpoints of the given container in the docker host
|
||||
// CheckpointList returns the checkpoints of the given container in the docker host.
|
||||
func (cli *Client) CheckpointList(ctx context.Context, container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {
|
||||
var checkpoints []checkpoint.Summary
|
||||
|
||||
|
||||
+3
-2
@@ -44,6 +44,8 @@ package client
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -56,7 +58,6 @@ import (
|
||||
"github.com/docker/go-connections/sockets"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/pkg/errors"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
|
||||
@@ -421,7 +422,7 @@ func (cli *Client) HTTPClient() *http.Client {
|
||||
func ParseHostURL(host string) (*url.URL, error) {
|
||||
proto, addr, ok := strings.Cut(host, "://")
|
||||
if !ok || addr == "" {
|
||||
return nil, errors.Errorf("unable to parse docker host `%s`", host)
|
||||
return nil, fmt.Errorf("unable to parse docker host `%s`", host)
|
||||
}
|
||||
|
||||
var basePath string
|
||||
|
||||
+3
-2
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/image"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/system"
|
||||
@@ -147,7 +148,7 @@ type NodeAPIClient interface {
|
||||
|
||||
// PluginAPIClient defines API client methods for the plugins
|
||||
type PluginAPIClient interface {
|
||||
PluginList(ctx context.Context, filter filters.Args) (types.PluginsListResponse, error)
|
||||
PluginList(ctx context.Context, filter filters.Args) (plugin.ListResponse, error)
|
||||
PluginRemove(ctx context.Context, name string, options PluginRemoveOptions) error
|
||||
PluginEnable(ctx context.Context, name string, options PluginEnableOptions) error
|
||||
PluginDisable(ctx context.Context, name string, options PluginDisableOptions) error
|
||||
@@ -155,7 +156,7 @@ type PluginAPIClient interface {
|
||||
PluginUpgrade(ctx context.Context, name string, options PluginInstallOptions) (io.ReadCloser, error)
|
||||
PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error)
|
||||
PluginSet(ctx context.Context, name string, args []string) error
|
||||
PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error)
|
||||
PluginInspectWithRaw(ctx context.Context, name string) (*plugin.Plugin, []byte, error)
|
||||
PluginCreate(ctx context.Context, createContext io.Reader, options PluginCreateOptions) error
|
||||
}
|
||||
|
||||
|
||||
+20
-16
@@ -9,29 +9,33 @@ import (
|
||||
)
|
||||
|
||||
// ContainerAttach attaches a connection to a container in the server.
|
||||
// It returns a types.HijackedConnection with the hijacked connection
|
||||
// and the a reader to get output. It's up to the called to close
|
||||
// the hijacked connection by calling types.HijackedResponse.Close.
|
||||
// It returns a [HijackedResponse] with the hijacked connection
|
||||
// and a reader to get output. It's up to the called to close
|
||||
// the hijacked connection by calling [HijackedResponse.Close].
|
||||
//
|
||||
// The stream format on the response will be in one of two formats:
|
||||
// The stream format on the response uses one of two formats:
|
||||
//
|
||||
// If the container is using a TTY, there is only a single stream (stdout), and
|
||||
// data is copied directly from the container output stream, no extra
|
||||
// multiplexing or headers.
|
||||
// - If the container is using a TTY, there is only a single stream (stdout)
|
||||
// and data is copied directly from the container output stream, no extra
|
||||
// multiplexing or headers.
|
||||
// - If the container is *not* using a TTY, streams for stdout and stderr are
|
||||
// multiplexed.
|
||||
//
|
||||
// If the container is *not* using a TTY, streams for stdout and stderr are
|
||||
// multiplexed.
|
||||
// The format of the multiplexed stream is as follows:
|
||||
// The format of the multiplexed stream is defined in the [stdcopy] package,
|
||||
// and as follows:
|
||||
//
|
||||
// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
|
||||
//
|
||||
// STREAM_TYPE can be 1 for stdout and 2 for stderr
|
||||
// STREAM_TYPE can be 1 for [Stdout] and 2 for [Stderr]. Refer to [stdcopy.StdType]
|
||||
// for details. SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded
|
||||
// as big endian, this is the size of OUTPUT. You can use [stdcopy.StdCopy]
|
||||
// to demultiplex this stream.
|
||||
//
|
||||
// SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded as big endian.
|
||||
// This is the size of OUTPUT.
|
||||
//
|
||||
// You can use github.com/moby/moby/api/stdcopy.StdCopy to demultiplex this
|
||||
// stream.
|
||||
// [stdcopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy
|
||||
// [stdcopy.StdCopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdCopy
|
||||
// [stdcopy.StdType]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdType
|
||||
// [Stdout]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#Stdout
|
||||
// [Stderr]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#Stderr
|
||||
func (cli *Client) ContainerAttach(ctx context.Context, containerID string, options container.AttachOptions) (HijackedResponse, error) {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config
|
||||
hostConfig.CapDrop = normalizeCapabilities(hostConfig.CapDrop)
|
||||
}
|
||||
|
||||
// Since API 1.44, the container-wide MacAddress is deprecated and will trigger a WARNING if it's specified.
|
||||
// Since API 1.44, the container-wide MacAddress is deprecated and triggers a WARNING if it's specified.
|
||||
if versions.GreaterThanOrEqualTo(cli.ClientVersion(), "1.44") {
|
||||
config.MacAddress = "" //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
|
||||
}
|
||||
|
||||
+9
-8
@@ -64,21 +64,22 @@ func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config
|
||||
|
||||
// ContainerExecAttach attaches a connection to an exec process in the server.
|
||||
//
|
||||
// It returns a [types.HijackedResponse] with the hijacked connection
|
||||
// and the a reader to get output. It's up to the called to close
|
||||
// the hijacked connection by calling [types.HijackedResponse.Close].
|
||||
// It returns a [HijackedResponse] with the hijacked connection
|
||||
// and a reader to get output. It's up to the called to close
|
||||
// the hijacked connection by calling [HijackedResponse.Close].
|
||||
//
|
||||
// The stream format on the response uses one of two formats:
|
||||
//
|
||||
// - If the container is using a TTY, there is only a single stream (stdout), and
|
||||
// data is copied directly from the container output stream, no extra
|
||||
// - If the container is using a TTY, there is only a single stream (stdout)
|
||||
// and data is copied directly from the container output stream, no extra
|
||||
// multiplexing or headers.
|
||||
// - If the container is *not* using a TTY, streams for stdout and stderr are
|
||||
// multiplexed.
|
||||
//
|
||||
// You can use [github.com/moby/moby/api/stdcopy.StdCopy] to demultiplex this
|
||||
// stream. Refer to [Client.ContainerAttach] for details about the multiplexed
|
||||
// stream.
|
||||
// You can use [stdcopy.StdCopy] to demultiplex this stream. Refer to
|
||||
// [Client.ContainerAttach] for details about the multiplexed stream.
|
||||
//
|
||||
// [stdcopy.StdCopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdCopy
|
||||
func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config container.ExecAttachOptions) (HijackedResponse, error) {
|
||||
if versions.LessThan(cli.ClientVersion(), "1.42") {
|
||||
config.ConsoleSize = nil
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
// ContainerExport retrieves the raw contents of a container
|
||||
// and returns them as an io.ReadCloser. It's up to the caller
|
||||
// and returns them as an [io.ReadCloser]. It's up to the caller
|
||||
// to close the stream.
|
||||
func (cli *Client) ContainerExport(ctx context.Context, containerID string) (io.ReadCloser, error) {
|
||||
containerID, err := trimID("container", containerID)
|
||||
|
||||
+21
-17
@@ -2,37 +2,41 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
timetypes "github.com/moby/moby/api/types/time"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ContainerLogs returns the logs generated by a container in an io.ReadCloser.
|
||||
// ContainerLogs returns the logs generated by a container in an [io.ReadCloser].
|
||||
// It's up to the caller to close the stream.
|
||||
//
|
||||
// The stream format on the response will be in one of two formats:
|
||||
// The stream format on the response uses one of two formats:
|
||||
//
|
||||
// If the container is using a TTY, there is only a single stream (stdout), and
|
||||
// data is copied directly from the container output stream, no extra
|
||||
// multiplexing or headers.
|
||||
// - If the container is using a TTY, there is only a single stream (stdout)
|
||||
// and data is copied directly from the container output stream, no extra
|
||||
// multiplexing or headers.
|
||||
// - If the container is *not* using a TTY, streams for stdout and stderr are
|
||||
// multiplexed.
|
||||
//
|
||||
// If the container is *not* using a TTY, streams for stdout and stderr are
|
||||
// multiplexed.
|
||||
// The format of the multiplexed stream is as follows:
|
||||
// The format of the multiplexed stream is defined in the [stdcopy] package,
|
||||
// and as follows:
|
||||
//
|
||||
// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
|
||||
//
|
||||
// STREAM_TYPE can be 1 for stdout and 2 for stderr
|
||||
// STREAM_TYPE can be 1 for [Stdout] and 2 for [Stderr]. Refer to [stdcopy.StdType]
|
||||
// for details. SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded
|
||||
// as big endian, this is the size of OUTPUT. You can use [stdcopy.StdCopy]
|
||||
// to demultiplex this stream.
|
||||
//
|
||||
// SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded as big endian.
|
||||
// This is the size of OUTPUT.
|
||||
//
|
||||
// You can use github.com/moby/moby/api/stdcopy.StdCopy to demultiplex this
|
||||
// stream.
|
||||
// [stdcopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy
|
||||
// [stdcopy.StdCopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdCopy
|
||||
// [stdcopy.StdType]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdType
|
||||
// [Stdout]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#Stdout
|
||||
// [Stderr]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#Stderr
|
||||
func (cli *Client) ContainerLogs(ctx context.Context, containerID string, options container.LogsOptions) (io.ReadCloser, error) {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
@@ -51,7 +55,7 @@ func (cli *Client) ContainerLogs(ctx context.Context, containerID string, option
|
||||
if options.Since != "" {
|
||||
ts, err := timetypes.GetTimestamp(options.Since, time.Now())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, `invalid value for "since"`)
|
||||
return nil, fmt.Errorf(`invalid value for "since": %w`, err)
|
||||
}
|
||||
query.Set("since", ts)
|
||||
}
|
||||
@@ -59,7 +63,7 @@ func (cli *Client) ContainerLogs(ctx context.Context, containerID string, option
|
||||
if options.Until != "" {
|
||||
ts, err := timetypes.GetTimestamp(options.Until, time.Now())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, `invalid value for "until"`)
|
||||
return nil, fmt.Errorf(`invalid value for "until": %w`, err)
|
||||
}
|
||||
query.Set("until", ts)
|
||||
}
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/moby/moby/api/types/container"
|
||||
)
|
||||
|
||||
// ContainerResize changes the size of the tty for a container.
|
||||
// ContainerResize changes the size of the pseudo-TTY for a container.
|
||||
func (cli *Client) ContainerResize(ctx context.Context, containerID string, options container.ResizeOptions) error {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
)
|
||||
|
||||
// ContainerRestart stops and starts a container again.
|
||||
// ContainerRestart stops, and starts a container again.
|
||||
// It makes the daemon wait for the container to be up again for
|
||||
// a specific amount of time, given the timeout.
|
||||
func (cli *Client) ContainerRestart(ctx context.Context, containerID string, options container.StopOptions) error {
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// StatsResponseReader wraps an io.ReadCloser to read (a stream of) stats
|
||||
// StatsResponseReader wraps an [io.ReadCloser] to read (a stream of) stats
|
||||
// for a container, as produced by the GET "/stats" endpoint.
|
||||
//
|
||||
// The OSType field is set to the server's platform to allow
|
||||
@@ -19,7 +19,7 @@ type StatsResponseReader struct {
|
||||
}
|
||||
|
||||
// ContainerStats returns near realtime stats for a given container.
|
||||
// It's up to the caller to close the io.ReadCloser returned.
|
||||
// It's up to the caller to close the [io.ReadCloser] returned.
|
||||
func (cli *Client) ContainerStats(ctx context.Context, containerID string, stream bool) (StatsResponseReader, error) {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package client
|
||||
|
||||
import "context"
|
||||
|
||||
// ContainerUnpause resumes the process execution within a container
|
||||
// ContainerUnpause resumes the process execution within a container.
|
||||
func (cli *Client) ContainerUnpause(ctx context.Context, containerID string) error {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
|
||||
+8
-6
@@ -15,12 +15,13 @@ import (
|
||||
const containerWaitErrorMsgLimit = 2 * 1024 /* Max: 2KiB */
|
||||
|
||||
// ContainerWait waits until the specified container is in a certain state
|
||||
// indicated by the given condition, either "not-running" (default),
|
||||
// "next-exit", or "removed".
|
||||
// indicated by the given condition, either "not-running" ([container.WaitConditionNotRunning])
|
||||
// (default), "next-exit" ([container.WaitConditionNextExit]), or "removed".
|
||||
// ([container.WaitConditionRemoved]).
|
||||
//
|
||||
// If this client's API version is before 1.30, condition is ignored and
|
||||
// ContainerWait will return immediately with the two channels, as the server
|
||||
// will wait as if the condition were "not-running".
|
||||
// If this client's API version is before 1.30, "condition" is ignored and
|
||||
// ContainerWait returns immediately with the two channels, as the server
|
||||
// waits as if the condition were "not-running".
|
||||
//
|
||||
// If this client's API version is at least 1.30, ContainerWait blocks until
|
||||
// the request has been acknowledged by the server (with a response header),
|
||||
@@ -28,7 +29,8 @@ const containerWaitErrorMsgLimit = 2 * 1024 /* Max: 2KiB */
|
||||
// of the container or an error if there was a problem either beginning the
|
||||
// wait request or in getting the response. This allows the caller to
|
||||
// synchronize ContainerWait with other calls, such as specifying a
|
||||
// "next-exit" condition before issuing a ContainerStart request.
|
||||
// "next-exit" condition ([container.WaitConditionNextExit]) before
|
||||
// issuing a [Client.ContainerStart] request.
|
||||
func (cli *Client) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) {
|
||||
resultC := make(chan container.WaitResponse)
|
||||
errC := make(chan error, 1)
|
||||
|
||||
+22
-17
@@ -4,16 +4,16 @@ const (
|
||||
// EnvOverrideHost is the name of the environment variable that can be used
|
||||
// to override the default host to connect to (DefaultDockerHost).
|
||||
//
|
||||
// This env-var is read by FromEnv and WithHostFromEnv and when set to a
|
||||
// This env-var is read by [FromEnv] and [WithHostFromEnv] and when set to a
|
||||
// non-empty value, takes precedence over the default host (which is platform
|
||||
// specific), or any host already set.
|
||||
EnvOverrideHost = "DOCKER_HOST"
|
||||
|
||||
// EnvOverrideAPIVersion is the name of the environment variable that can
|
||||
// be used to override the API version to use. Value should be
|
||||
// be used to override the API version to use. Value must be
|
||||
// formatted as MAJOR.MINOR, for example, "1.19".
|
||||
//
|
||||
// This env-var is read by FromEnv and WithVersionFromEnv and when set to a
|
||||
// This env-var is read by [FromEnv] and [WithVersionFromEnv] and when set to a
|
||||
// non-empty value, takes precedence over API version negotiation.
|
||||
//
|
||||
// This environment variable should be used for debugging purposes only, as
|
||||
@@ -23,16 +23,15 @@ const (
|
||||
// EnvOverrideCertPath is the name of the environment variable that can be
|
||||
// used to specify the directory from which to load the TLS certificates
|
||||
// (ca.pem, cert.pem, key.pem) from. These certificates are used to configure
|
||||
// the Client for a TCP connection protected by TLS client authentication.
|
||||
// the [Client] for a TCP connection protected by TLS client authentication.
|
||||
//
|
||||
// TLS certificate verification is enabled by default if the Client is configured
|
||||
// to use a TLS connection. Refer to EnvTLSVerify below to learn how to
|
||||
// to use a TLS connection. Refer to [EnvTLSVerify] below to learn how to
|
||||
// disable verification for testing purposes.
|
||||
//
|
||||
// WARNING: Access to the remote API is equivalent to root access to the
|
||||
// host where the daemon runs. Do not expose the API without protection,
|
||||
// and only if needed. Make sure you are familiar with the "daemon attack
|
||||
// surface" (https://docs.docker.com/go/attack-surface/).
|
||||
// and only if needed. Make sure you are familiar with the ["daemon attack surface"].
|
||||
//
|
||||
// For local access to the API, it is recommended to connect with the daemon
|
||||
// using the default local socket connection (on Linux), or the named pipe
|
||||
@@ -43,11 +42,14 @@ const (
|
||||
// configuration if the host is accessible using ssh.
|
||||
//
|
||||
// If you cannot use the alternatives above, and you must expose the API over
|
||||
// a TCP connection, refer to https://docs.docker.com/engine/security/protect-access/
|
||||
// a TCP connection. Refer to [Protect the Docker daemon socket]
|
||||
// to learn how to configure the daemon and client to use a TCP connection
|
||||
// with TLS client authentication. Make sure you know the differences between
|
||||
// a regular TLS connection and a TLS connection protected by TLS client
|
||||
// authentication, and verify that the API cannot be accessed by other clients.
|
||||
//
|
||||
// ["daemon attack surface"]: https://docs.docker.com/go/attack-surface/
|
||||
// [Protect the Docker daemon socket]: https://docs.docker.com/engine/security/protect-access/
|
||||
EnvOverrideCertPath = "DOCKER_CERT_PATH"
|
||||
|
||||
// EnvTLSVerify is the name of the environment variable that can be used to
|
||||
@@ -59,26 +61,26 @@ const (
|
||||
//
|
||||
// WARNING: Access to the remote API is equivalent to root access to the
|
||||
// host where the daemon runs. Do not expose the API without protection,
|
||||
// and only if needed. Make sure you are familiar with the "daemon attack
|
||||
// surface" (https://docs.docker.com/go/attack-surface/).
|
||||
// and only if needed. Make sure you are familiar with the ["daemon attack surface"].
|
||||
//
|
||||
// Before setting up your client and daemon to use a TCP connection with TLS
|
||||
// client authentication, consider using one of the alternatives mentioned
|
||||
// in EnvOverrideCertPath above.
|
||||
// in [EnvOverrideCertPath].
|
||||
//
|
||||
// Disabling TLS certificate verification (for testing purposes)
|
||||
//
|
||||
// TLS certificate verification is enabled by default if the Client is configured
|
||||
// to use a TLS connection, and it is highly recommended to keep verification
|
||||
// enabled to prevent machine-in-the-middle attacks. Refer to the documentation
|
||||
// at https://docs.docker.com/engine/security/protect-access/ and pages linked
|
||||
// from that page to learn how to configure the daemon and client to use a
|
||||
// TCP connection with TLS client authentication enabled.
|
||||
// enabled to prevent machine-in-the-middle attacks. Refer to [Protect the Docker daemon socket]
|
||||
// in the documentation and pages linked from that page to learn how to
|
||||
// configure the daemon and client to use a TCP connection with TLS client
|
||||
// authentication enabled.
|
||||
//
|
||||
// Set the "DOCKER_TLS_VERIFY" environment to an empty string ("") to
|
||||
// disable TLS certificate verification. Disabling verification is insecure,
|
||||
// so should only be done for testing purposes. From the Go documentation
|
||||
// (https://pkg.go.dev/crypto/tls#Config):
|
||||
// so should only be done for testing purposes.
|
||||
//
|
||||
// From the[crypto/tls.Config] documentation:
|
||||
//
|
||||
// InsecureSkipVerify controls whether a client verifies the server's
|
||||
// certificate chain and host name. If InsecureSkipVerify is true, crypto/tls
|
||||
@@ -86,5 +88,8 @@ const (
|
||||
// certificate. In this mode, TLS is susceptible to machine-in-the-middle
|
||||
// attacks unless custom verification is used. This should be used only for
|
||||
// testing or in combination with VerifyConnection or VerifyPeerCertificate.
|
||||
//
|
||||
// ["daemon attack surface"]: https://docs.docker.com/go/attack-surface/
|
||||
// [Protect the Docker daemon socket]: https://docs.docker.com/engine/security/protect-access/
|
||||
EnvTLSVerify = "DOCKER_TLS_VERIFY"
|
||||
)
|
||||
|
||||
+5
-5
@@ -10,7 +10,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/pkg/errors"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
|
||||
@@ -56,18 +55,18 @@ func setupHijackConn(dialer func(context.Context) (net.Conn, error), req *http.R
|
||||
|
||||
conn, err := dialer(ctx)
|
||||
if err != nil {
|
||||
return nil, "", errors.Wrap(err, "cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")
|
||||
return nil, "", fmt.Errorf("cannot connect to the Docker daemon. Is 'docker daemon' running on this host?: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
conn.Close()
|
||||
_ = conn.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
// When we set up a TCP connection for hijack, there could be long periods
|
||||
// of inactivity (a long running command with no output) that in certain
|
||||
// network setups may cause ECONNTIMEOUT, leaving the client in an unknown
|
||||
// state. Setting TCP KeepAlive on the socket connection will prohibit
|
||||
// state. Setting TCP KeepAlive on the socket connection prohibits
|
||||
// ECONNTIMEOUT unless the socket connection truly is broken
|
||||
if tcpConn, ok := conn.(*net.TCPConn); ok {
|
||||
_ = tcpConn.SetKeepAlive(true)
|
||||
@@ -155,7 +154,8 @@ func (h *HijackedResponse) Close() {
|
||||
}
|
||||
|
||||
// MediaType let client know if HijackedResponse hold a raw or multiplexed stream.
|
||||
// returns false if HTTP Content-Type is not relevant, and container must be inspected
|
||||
// returns false if HTTP Content-Type is not relevant, and the container must be
|
||||
// inspected.
|
||||
func (h *HijackedResponse) MediaType() (string, bool) {
|
||||
if h.mediaType == "" {
|
||||
return "", false
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
// ImageBuild sends a request to the daemon to build images.
|
||||
// The Body in the response implements an io.ReadCloser and it's up to the caller to
|
||||
// The Body in the response implements an [io.ReadCloser] and it's up to the caller to
|
||||
// close it.
|
||||
func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error) {
|
||||
query, err := cli.imageBuildOptionsToQuery(ctx, options)
|
||||
|
||||
+4
-3
@@ -28,8 +28,9 @@ func ImageInspectWithRawResponse(raw *bytes.Buffer) ImageInspectOption {
|
||||
|
||||
// ImageInspectWithManifests sets manifests API option for the image inspect operation.
|
||||
// This option is only available for API version 1.48 and up.
|
||||
// With this option set, the image inspect operation response will have the
|
||||
// [image.InspectResponse.Manifests] field populated if the server is multi-platform capable.
|
||||
// With this option set, the image inspect operation response includes
|
||||
// the [image.InspectResponse.Manifests] field if the server is multi-platform
|
||||
// capable.
|
||||
func ImageInspectWithManifests(manifests bool) ImageInspectOption {
|
||||
return imageInspectOptionFunc(func(clientOpts *imageInspectOpts) error {
|
||||
clientOpts.apiOptions.Manifests = manifests
|
||||
@@ -39,7 +40,7 @@ func ImageInspectWithManifests(manifests bool) ImageInspectOption {
|
||||
|
||||
// ImageInspectWithPlatform sets platform API option for the image inspect operation.
|
||||
// This option is only available for API version 1.49 and up.
|
||||
// With this option set, the image inspect operation will return information for the
|
||||
// With this option set, the image inspect operation returns information for the
|
||||
// specified platform variant of the multi-platform image.
|
||||
func ImageInspectWithPlatform(platform *ocispec.Platform) ImageInspectOption {
|
||||
return imageInspectOptionFunc(func(clientOpts *imageInspectOpts) error {
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@ import (
|
||||
|
||||
// ImageList returns a list of images in the docker host.
|
||||
//
|
||||
// Experimental: Setting the [options.Manifest] will populate
|
||||
// [image.Summary.Manifests] with information about image manifests.
|
||||
// Experimental: Set the [image.ListOptions.Manifest] option
|
||||
// to include [image.Summary.Manifests] with information about image manifests.
|
||||
// This is experimental and might change in the future without any backward
|
||||
// compatibility.
|
||||
func (cli *Client) ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error) {
|
||||
|
||||
+4
-4
@@ -10,12 +10,12 @@ import (
|
||||
)
|
||||
|
||||
// ImageLoad loads an image in the docker host from the client host.
|
||||
// It's up to the caller to close the io.ReadCloser in the
|
||||
// ImageLoadResponse returned by this function.
|
||||
// It's up to the caller to close the [io.ReadCloser] in the
|
||||
// [image.LoadResponse] returned by this function.
|
||||
//
|
||||
// Platform is an optional parameter that specifies the platform to load from
|
||||
// the provided multi-platform image. This is only has effect if the input image
|
||||
// is a multi-platform image.
|
||||
// the provided multi-platform image. Passing a platform only has an effect
|
||||
// if the input image is a multi-platform image.
|
||||
func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...ImageLoadOption) (image.LoadResponse, error) {
|
||||
var opts imageLoadOpts
|
||||
for _, opt := range loadOpts {
|
||||
|
||||
+7
-5
@@ -14,12 +14,14 @@ import (
|
||||
// ImagePull requests the docker host to pull an image from a remote registry.
|
||||
// It executes the privileged function if the operation is unauthorized
|
||||
// and it tries one more time.
|
||||
// It's up to the caller to handle the io.ReadCloser and close it properly.
|
||||
//
|
||||
// FIXME(vdemeester): there is currently used in a few way in docker/docker
|
||||
// - if not in trusted content, ref is used to pass the whole reference, and tag is empty
|
||||
// - if in trusted content, ref is used to pass the reference name, and tag for the digest
|
||||
// It's up to the caller to handle the [io.ReadCloser] and close it.
|
||||
func (cli *Client) ImagePull(ctx context.Context, refStr string, options image.PullOptions) (io.ReadCloser, error) {
|
||||
// FIXME(vdemeester): there is currently used in a few way in docker/docker
|
||||
// - if not in trusted content, ref is used to pass the whole reference, and tag is empty
|
||||
// - if in trusted content, ref is used to pass the reference name, and tag for the digest
|
||||
//
|
||||
// ref; https://github.com/docker-archive-public/docker.engine-api/pull/162
|
||||
|
||||
ref, err := reference.ParseNormalizedNamed(refStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ import (
|
||||
// ImagePush requests the docker host to push an image to a remote registry.
|
||||
// It executes the privileged function if the operation is unauthorized
|
||||
// and it tries one more time.
|
||||
// It's up to the caller to handle the io.ReadCloser and close it properly.
|
||||
// It's up to the caller to handle the [io.ReadCloser] and close it.
|
||||
func (cli *Client) ImagePush(ctx context.Context, image string, options image.PushOptions) (io.ReadCloser, error) {
|
||||
ref, err := reference.ParseNormalizedNamed(image)
|
||||
if err != nil {
|
||||
|
||||
+5
-3
@@ -6,10 +6,12 @@ import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// ImageSave retrieves one or more images from the docker host as an io.ReadCloser.
|
||||
// ImageSave retrieves one or more images from the docker host as an
|
||||
// [io.ReadCloser].
|
||||
//
|
||||
// Platforms is an optional parameter that specifies the platforms to save from the image.
|
||||
// This is only has effect if the input image is a multi-platform image.
|
||||
// Platforms is an optional parameter that specifies the platforms to save
|
||||
// from the image. Passing a platform only has an effect if the input image
|
||||
// is a multi-platform image.
|
||||
func (cli *Client) ImageSave(ctx context.Context, imageIDs []string, saveOpts ...ImageSaveOption) (io.ReadCloser, error) {
|
||||
var opts imageSaveOpts
|
||||
for _, opt := range saveOpts {
|
||||
|
||||
+4
-3
@@ -2,21 +2,22 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ImageTag tags an image in the docker host
|
||||
func (cli *Client) ImageTag(ctx context.Context, source, target string) error {
|
||||
if _, err := reference.ParseAnyReference(source); err != nil {
|
||||
return errors.Wrapf(err, "Error parsing reference: %q is not a valid repository/tag", source)
|
||||
return fmt.Errorf("error parsing reference: %q is not a valid repository/tag: %w", source, err)
|
||||
}
|
||||
|
||||
ref, err := reference.ParseNormalizedNamed(target)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Error parsing reference: %q is not a valid repository/tag", target)
|
||||
return fmt.Errorf("error parsing reference: %q is not a valid repository/tag: %w", target, err)
|
||||
}
|
||||
|
||||
if _, isCanonical := ref.(reference.Canonical); isCanonical {
|
||||
|
||||
+6
-6
@@ -2,6 +2,7 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -11,7 +12,6 @@ import (
|
||||
|
||||
"github.com/docker/go-connections/sockets"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
"github.com/pkg/errors"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
@@ -55,7 +55,7 @@ func WithDialContext(dialContext func(ctx context.Context, network, addr string)
|
||||
transport.DialContext = dialContext
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf("cannot apply dialer to transport: %T", c.client.Transport)
|
||||
return fmt.Errorf("cannot apply dialer to transport: %T", c.client.Transport)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ func WithHost(host string) Opt {
|
||||
if transport, ok := c.client.Transport.(*http.Transport); ok {
|
||||
return sockets.ConfigureTransport(transport, c.proto, c.addr)
|
||||
}
|
||||
return errors.Errorf("cannot apply host to transport: %T", c.client.Transport)
|
||||
return fmt.Errorf("cannot apply host to transport: %T", c.client.Transport)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ func WithTLSClientConfig(cacertPath, certPath, keyPath string) Opt {
|
||||
return func(c *Client) error {
|
||||
transport, ok := c.client.Transport.(*http.Transport)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot apply tls config to transport: %T", c.client.Transport)
|
||||
return fmt.Errorf("cannot apply tls config to transport: %T", c.client.Transport)
|
||||
}
|
||||
config, err := tlsconfig.Client(tlsconfig.Options{
|
||||
CAFile: cacertPath,
|
||||
@@ -149,7 +149,7 @@ func WithTLSClientConfig(cacertPath, certPath, keyPath string) Opt {
|
||||
ExclusiveRootPools: true,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create tls config")
|
||||
return fmt.Errorf("failed to create tls config: %w", err)
|
||||
}
|
||||
transport.TLSClientConfig = config
|
||||
return nil
|
||||
@@ -234,7 +234,7 @@ func WithAPIVersionNegotiation() Opt {
|
||||
}
|
||||
|
||||
// WithTraceProvider sets the trace provider for the client.
|
||||
// If this is not set then the global trace provider will be used.
|
||||
// If this is not set then the global trace provider is used.
|
||||
func WithTraceProvider(provider trace.TracerProvider) Opt {
|
||||
return WithTraceOptions(otelhttp.WithTracerProvider(provider))
|
||||
}
|
||||
|
||||
+3
-3
@@ -6,11 +6,11 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
)
|
||||
|
||||
// PluginInspectWithRaw inspects an existing plugin
|
||||
func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) {
|
||||
func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*plugin.Plugin, []byte, error) {
|
||||
name, err := trimID("plugin", name)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -25,7 +25,7 @@ func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*type
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
var p types.Plugin
|
||||
var p plugin.Plugin
|
||||
rdr := bytes.NewReader(body)
|
||||
err = json.NewDecoder(rdr).Decode(&p)
|
||||
return &p, body, err
|
||||
|
||||
+10
-9
@@ -3,15 +3,16 @@ package client
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// PluginInstallOptions holds parameters to install a plugin.
|
||||
@@ -28,7 +29,7 @@ type PluginInstallOptions struct {
|
||||
//
|
||||
// For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig].
|
||||
PrivilegeFunc func(context.Context) (string, error)
|
||||
AcceptPermissionsFunc func(context.Context, types.PluginPrivileges) (bool, error)
|
||||
AcceptPermissionsFunc func(context.Context, plugin.Privileges) (bool, error)
|
||||
Args []string
|
||||
}
|
||||
|
||||
@@ -36,7 +37,7 @@ type PluginInstallOptions struct {
|
||||
func (cli *Client) PluginInstall(ctx context.Context, name string, options PluginInstallOptions) (_ io.ReadCloser, retErr error) {
|
||||
query := url.Values{}
|
||||
if _, err := reference.ParseNormalizedNamed(options.RemoteRef); err != nil {
|
||||
return nil, errors.Wrap(err, "invalid remote reference")
|
||||
return nil, fmt.Errorf("invalid remote reference: %w", err)
|
||||
}
|
||||
query.Set("remote", options.RemoteRef)
|
||||
|
||||
@@ -92,16 +93,16 @@ func (cli *Client) tryPluginPrivileges(ctx context.Context, query url.Values, re
|
||||
})
|
||||
}
|
||||
|
||||
func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileges types.PluginPrivileges, registryAuth string) (*http.Response, error) {
|
||||
func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileges plugin.Privileges, registryAuth string) (*http.Response, error) {
|
||||
return cli.post(ctx, "/plugins/pull", query, privileges, http.Header{
|
||||
registry.AuthHeader: {registryAuth},
|
||||
})
|
||||
}
|
||||
|
||||
func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, options PluginInstallOptions) (types.PluginPrivileges, error) {
|
||||
func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, options PluginInstallOptions) (plugin.Privileges, error) {
|
||||
resp, err := cli.tryPluginPrivileges(ctx, query, options.RegistryAuth)
|
||||
if cerrdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
|
||||
// todo: do inspect before to check existing name before checking privileges
|
||||
// TODO: do inspect before to check existing name before checking privileges
|
||||
newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx)
|
||||
if privilegeErr != nil {
|
||||
ensureReaderClosed(resp)
|
||||
@@ -115,7 +116,7 @@ func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var privileges types.PluginPrivileges
|
||||
var privileges plugin.Privileges
|
||||
if err := json.NewDecoder(resp.Body).Decode(&privileges); err != nil {
|
||||
ensureReaderClosed(resp)
|
||||
return nil, err
|
||||
@@ -128,7 +129,7 @@ func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values,
|
||||
return nil, err
|
||||
}
|
||||
if !accept {
|
||||
return nil, errors.Errorf("permission denied while installing plugin %s", options.RemoteRef)
|
||||
return nil, errors.New("permission denied while installing plugin " + options.RemoteRef)
|
||||
}
|
||||
}
|
||||
return privileges, nil
|
||||
|
||||
+3
-3
@@ -5,14 +5,14 @@ import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
)
|
||||
|
||||
// PluginList returns the installed plugins
|
||||
func (cli *Client) PluginList(ctx context.Context, filter filters.Args) (types.PluginsListResponse, error) {
|
||||
var plugins types.PluginsListResponse
|
||||
func (cli *Client) PluginList(ctx context.Context, filter filters.Args) (plugin.ListResponse, error) {
|
||||
var plugins plugin.ListResponse
|
||||
query := url.Values{}
|
||||
|
||||
if filter.Len() > 0 {
|
||||
|
||||
+4
-4
@@ -2,14 +2,14 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// PluginUpgrade upgrades a plugin
|
||||
@@ -24,7 +24,7 @@ func (cli *Client) PluginUpgrade(ctx context.Context, name string, options Plugi
|
||||
}
|
||||
query := url.Values{}
|
||||
if _, err := reference.ParseNormalizedNamed(options.RemoteRef); err != nil {
|
||||
return nil, errors.Wrap(err, "invalid remote reference")
|
||||
return nil, fmt.Errorf("invalid remote reference: %w", err)
|
||||
}
|
||||
query.Set("remote", options.RemoteRef)
|
||||
|
||||
@@ -40,7 +40,7 @@ func (cli *Client) PluginUpgrade(ctx context.Context, name string, options Plugi
|
||||
return resp.Body, nil
|
||||
}
|
||||
|
||||
func (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges types.PluginPrivileges, name, registryAuth string) (*http.Response, error) {
|
||||
func (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges plugin.Privileges, name, registryAuth string) (*http.Response, error) {
|
||||
return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, http.Header{
|
||||
registry.AuthHeader: {registryAuth},
|
||||
})
|
||||
|
||||
+13
-13
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
@@ -13,8 +14,7 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/moby/moby/api/types/common"
|
||||
)
|
||||
|
||||
// head sends an http request to the docker API using the method HEAD.
|
||||
@@ -144,7 +144,7 @@ func (cli *Client) doRequest(req *http.Request) (*http.Response, error) {
|
||||
}
|
||||
|
||||
if cli.scheme == "https" && strings.Contains(err.Error(), "bad certificate") {
|
||||
return nil, errConnectionFailed{errors.Wrap(err, "the server probably has client authentication (--tlsverify) enabled; check your TLS client certification settings")}
|
||||
return nil, errConnectionFailed{fmt.Errorf("the server probably has client authentication (--tlsverify) enabled; check your TLS client certification settings: %w", err)}
|
||||
}
|
||||
|
||||
// Don't decorate context sentinel errors; users may be comparing to
|
||||
@@ -162,11 +162,11 @@ func (cli *Client) doRequest(req *http.Request) (*http.Response, error) {
|
||||
// Unwrap the error to remove request errors ("Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.51/version"),
|
||||
// which are irrelevant if we weren't able to connect.
|
||||
err = errors.Unwrap(err)
|
||||
return nil, errConnectionFailed{errors.Wrapf(err, "failed to connect to the docker API at %v; check if the path is correct and if the daemon is running", cli.host)}
|
||||
return nil, errConnectionFailed{fmt.Errorf("failed to connect to the docker API at %v; check if the path is correct and if the daemon is running: %w", cli.host, err)}
|
||||
}
|
||||
var dnsErr *net.DNSError
|
||||
if errors.As(err, &dnsErr) {
|
||||
return nil, errConnectionFailed{errors.Wrapf(dnsErr, "failed to connect to the docker API at %v", cli.host)}
|
||||
return nil, errConnectionFailed{fmt.Errorf("failed to connect to the docker API at %v: %w", cli.host, dnsErr)}
|
||||
}
|
||||
|
||||
var nErr net.Error
|
||||
@@ -193,14 +193,14 @@ func (cli *Client) doRequest(req *http.Request) (*http.Response, error) {
|
||||
if strings.Contains(err.Error(), `open //./pipe/docker_engine`) {
|
||||
// Checks if client is running with elevated privileges
|
||||
if f, elevatedErr := os.Open(`\\.\PHYSICALDRIVE0`); elevatedErr != nil {
|
||||
err = errors.Wrap(err, "in the default daemon configuration on Windows, the docker client must be run with elevated privileges to connect")
|
||||
err = fmt.Errorf("in the default daemon configuration on Windows, the docker client must be run with elevated privileges to connect: %w", err)
|
||||
} else {
|
||||
_ = f.Close()
|
||||
err = errors.Wrap(err, "this error may indicate that the docker daemon is not running")
|
||||
err = fmt.Errorf("this error may indicate that the docker daemon is not running: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errConnectionFailed{errors.Wrap(err, "error during connect")}
|
||||
return nil, errConnectionFailed{fmt.Errorf("error during connect: %w", err)}
|
||||
}
|
||||
|
||||
func (cli *Client) checkResponseErr(serverResp *http.Response) (retErr error) {
|
||||
@@ -250,20 +250,20 @@ func (cli *Client) checkResponseErr(serverResp *http.Response) (retErr error) {
|
||||
|
||||
var daemonErr error
|
||||
if serverResp.Header.Get("Content-Type") == "application/json" {
|
||||
var errorResponse types.ErrorResponse
|
||||
var errorResponse common.ErrorResponse
|
||||
if err := json.Unmarshal(body, &errorResponse); err != nil {
|
||||
return errors.Wrap(err, "Error reading JSON")
|
||||
return fmt.Errorf("error reading JSON: %w", err)
|
||||
}
|
||||
if errorResponse.Message == "" {
|
||||
// Error-message is empty, which means that we successfully parsed the
|
||||
// JSON-response (no error produced), but it didn't contain an error
|
||||
// message. This could either be because the response was empty, or
|
||||
// the response was valid JSON, but not with the expected schema
|
||||
// ([types.ErrorResponse]).
|
||||
// ([common.ErrorResponse]).
|
||||
//
|
||||
// We cannot use "strict" JSON handling (json.NewDecoder with DisallowUnknownFields)
|
||||
// due to the API using an open schema (we must anticipate fields
|
||||
// being added to [types.ErrorResponse] in the future, and not
|
||||
// being added to [common.ErrorResponse] in the future, and not
|
||||
// reject those responses.
|
||||
//
|
||||
// For these cases, we construct an error with the status-code
|
||||
@@ -285,7 +285,7 @@ func (cli *Client) checkResponseErr(serverResp *http.Response) (retErr error) {
|
||||
// situations where a proxy is involved, returning a HTML response.
|
||||
daemonErr = errors.New(strings.TrimSpace(string(body)))
|
||||
}
|
||||
return errors.Wrap(daemonErr, "Error response from daemon")
|
||||
return fmt.Errorf("Error response from daemon: %w", daemonErr)
|
||||
}
|
||||
|
||||
func (cli *Client) addHeaders(req *http.Request, headers http.Header) *http.Request {
|
||||
|
||||
+3
-3
@@ -3,6 +3,7 @@ package client
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -12,7 +13,6 @@ import (
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ServiceCreate creates a new service.
|
||||
@@ -200,11 +200,11 @@ func validateAPIVersion(c swarm.ServiceSpec, apiVersion string) error {
|
||||
for _, m := range c.TaskTemplate.ContainerSpec.Mounts {
|
||||
if m.BindOptions != nil {
|
||||
if m.BindOptions.NonRecursive && versions.LessThan(apiVersion, "1.40") {
|
||||
return errors.Errorf("bind-recursive=disabled requires API v1.40 or later")
|
||||
return errors.New("bind-recursive=disabled requires API v1.40 or later")
|
||||
}
|
||||
// ReadOnlyNonRecursive can be safely ignored when API < 1.44
|
||||
if m.BindOptions.ReadOnlyForceRecursive && versions.LessThan(apiVersion, "1.44") {
|
||||
return errors.Errorf("bind-recursive=readonly requires API v1.44 or later")
|
||||
return errors.New("bind-recursive=readonly requires API v1.44 or later")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -2,16 +2,16 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
timetypes "github.com/moby/moby/api/types/time"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ServiceLogs returns the logs generated by a service in an io.ReadCloser.
|
||||
// ServiceLogs returns the logs generated by a service in an [io.ReadCloser].
|
||||
// It's up to the caller to close the stream.
|
||||
func (cli *Client) ServiceLogs(ctx context.Context, serviceID string, options container.LogsOptions) (io.ReadCloser, error) {
|
||||
serviceID, err := trimID("service", serviceID)
|
||||
@@ -31,7 +31,7 @@ func (cli *Client) ServiceLogs(ctx context.Context, serviceID string, options co
|
||||
if options.Since != "" {
|
||||
ts, err := timetypes.GetTimestamp(options.Since, time.Now())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, `invalid value for "since"`)
|
||||
return nil, fmt.Errorf(`invalid value for "since": %w`, err)
|
||||
}
|
||||
query.Set("since", ts)
|
||||
}
|
||||
|
||||
+4
-3
@@ -11,9 +11,10 @@ import (
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
)
|
||||
|
||||
// ServiceUpdate updates a Service. The version number is required to avoid conflicting writes.
|
||||
// It should be the value as set *before* the update. You can find this value in the Meta field
|
||||
// of swarm.Service, which can be found using ServiceInspectWithRaw.
|
||||
// ServiceUpdate updates a Service. The version number is required to avoid
|
||||
// conflicting writes. It must be the value as set *before* the update.
|
||||
// You can find this value in the [swarm.Service.Meta] field, which can
|
||||
// be found using [Client.ServiceInspectWithRaw].
|
||||
func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
serviceID, err := trimID("service", serviceID)
|
||||
if err != nil {
|
||||
|
||||
+2
-2
@@ -13,8 +13,8 @@ import (
|
||||
)
|
||||
|
||||
// Events returns a stream of events in the daemon. It's up to the caller to close the stream
|
||||
// by cancelling the context. Once the stream has been completely read an io.EOF error will
|
||||
// be sent over the error channel. If an error is sent all processing will be stopped. It's up
|
||||
// by cancelling the context. Once the stream has been completely read an [io.EOF] error is
|
||||
// sent over the error channel. If an error is sent, all processing is stopped. It's up
|
||||
// to the caller to reopen the stream in the event of an error by reinvoking this method.
|
||||
func (cli *Client) Events(ctx context.Context, options events.ListOptions) (<-chan events.Message, <-chan error) {
|
||||
messages := make(chan events.Message)
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import (
|
||||
timetypes "github.com/moby/moby/api/types/time"
|
||||
)
|
||||
|
||||
// TaskLogs returns the logs generated by a task in an io.ReadCloser.
|
||||
// TaskLogs returns the logs generated by a task in an [io.ReadCloser].
|
||||
// It's up to the caller to close the stream.
|
||||
func (cli *Client) TaskLogs(ctx context.Context, taskID string, options container.LogsOptions) (io.ReadCloser, error) {
|
||||
query := url.Values{}
|
||||
|
||||
Vendored
+3
-4
@@ -168,7 +168,7 @@ github.com/moby/docker-image-spec/specs-go/v1
|
||||
github.com/moby/go-archive
|
||||
github.com/moby/go-archive/compression
|
||||
github.com/moby/go-archive/tarheader
|
||||
# github.com/moby/moby/api v0.0.0 => github.com/moby/moby/api v0.0.0-20250731152656-4faedf2bec36
|
||||
# github.com/moby/moby/api v1.52.0-alpha.1
|
||||
## explicit; go 1.23.0
|
||||
github.com/moby/moby/api/pkg/progress
|
||||
github.com/moby/moby/api/pkg/stdcopy
|
||||
@@ -186,6 +186,7 @@ github.com/moby/moby/api/types/image
|
||||
github.com/moby/moby/api/types/jsonstream
|
||||
github.com/moby/moby/api/types/mount
|
||||
github.com/moby/moby/api/types/network
|
||||
github.com/moby/moby/api/types/plugin
|
||||
github.com/moby/moby/api/types/registry
|
||||
github.com/moby/moby/api/types/storage
|
||||
github.com/moby/moby/api/types/strslice
|
||||
@@ -194,7 +195,7 @@ github.com/moby/moby/api/types/system
|
||||
github.com/moby/moby/api/types/time
|
||||
github.com/moby/moby/api/types/versions
|
||||
github.com/moby/moby/api/types/volume
|
||||
# github.com/moby/moby/client v0.0.0 => github.com/moby/moby/client v0.0.0-20250731152656-4faedf2bec36
|
||||
# github.com/moby/moby/client v0.1.0-alpha.0
|
||||
## explicit; go 1.23.0
|
||||
github.com/moby/moby/client
|
||||
github.com/moby/moby/client/pkg/jsonmessage
|
||||
@@ -569,5 +570,3 @@ gotest.tools/v3/skip
|
||||
# tags.cncf.io/container-device-interface v0.8.0
|
||||
## explicit; go 1.20
|
||||
tags.cncf.io/container-device-interface/pkg/parser
|
||||
# github.com/moby/moby/api => github.com/moby/moby/api v0.0.0-20250731152656-4faedf2bec36
|
||||
# github.com/moby/moby/client => github.com/moby/moby/client v0.0.0-20250731152656-4faedf2bec36
|
||||
|
||||
Reference in New Issue
Block a user