vendor: github.com/moby/moby/api v1.52.0-beta.1, client v0.1.0-beta.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Co-authored-by: Austin Vazquez <austin.vazquez@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-08-28 19:36:34 +02:00
parent 9fb049c8b6
commit b55fed5ef6
110 changed files with 1036 additions and 773 deletions

View File

@ -9,10 +9,10 @@ import (
type fakeClient struct {
client.Client
builderPruneFunc func(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error)
builderPruneFunc func(ctx context.Context, opts client.BuildCachePruneOptions) (*build.CachePruneReport, error)
}
func (c *fakeClient) BuildCachePrune(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error) {
func (c *fakeClient) BuildCachePrune(ctx context.Context, opts client.BuildCachePruneOptions) (*build.CachePruneReport, error) {
if c.builderPruneFunc != nil {
return c.builderPruneFunc(ctx, opts)
}

View File

@ -12,8 +12,8 @@ import (
"github.com/docker/cli/internal/prompt"
"github.com/docker/cli/opts"
"github.com/docker/go-units"
"github.com/moby/moby/api/types/build"
"github.com/moby/moby/api/types/versions"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@ -25,10 +25,10 @@ func init() {
}
type pruneOptions struct {
force bool
all bool
filter opts.FilterOpt
keepStorage opts.MemBytes
force bool
all bool
filter opts.FilterOpt
reservedSpace opts.MemBytes
}
// newPruneCommand returns a new cobra prune command for images
@ -59,7 +59,7 @@ func newPruneCommand(dockerCLI command.Cli) *cobra.Command {
flags.BoolVarP(&options.force, "force", "f", false, "Do not prompt for confirmation")
flags.BoolVarP(&options.all, "all", "a", false, "Remove all unused build cache, not just dangling ones")
flags.Var(&options.filter, "filter", `Provide filter values (e.g. "until=24h")`)
flags.Var(&options.keepStorage, "keep-storage", "Amount of disk space to keep for cache")
flags.Var(&options.reservedSpace, "keep-storage", "Amount of disk space to keep for cache")
return cmd
}
@ -87,12 +87,9 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
}
}
report, err := dockerCli.Client().BuildCachePrune(ctx, build.CachePruneOptions{
All: options.all,
// TODO(austinvazquez): remove when updated to use github.com/moby/moby/client@v0.1.0
// See https://github.com/moby/moby/pull/50772 for more details.
KeepStorage: options.keepStorage.Value(),
ReservedSpace: options.keepStorage.Value(),
report, err := dockerCli.Client().BuildCachePrune(ctx, client.BuildCachePruneOptions{
All: options.all,
ReservedSpace: options.reservedSpace.Value(),
Filters: pruneFilters,
})
if err != nil {

View File

@ -8,6 +8,7 @@ import (
"github.com/docker/cli/internal/test"
"github.com/moby/moby/api/types/build"
"github.com/moby/moby/client"
)
func TestBuilderPromptTermination(t *testing.T) {
@ -15,7 +16,7 @@ func TestBuilderPromptTermination(t *testing.T) {
t.Cleanup(cancel)
cli := test.NewFakeCli(&fakeClient{
builderPruneFunc: func(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error) {
builderPruneFunc: func(ctx context.Context, opts client.BuildCachePruneOptions) (*build.CachePruneReport, error) {
return nil, errors.New("fakeClient builderPruneFunc should not be called")
},
})

View File

@ -9,26 +9,26 @@ import (
type fakeClient struct {
client.Client
checkpointCreateFunc func(container string, options checkpoint.CreateOptions) error
checkpointDeleteFunc func(container string, options checkpoint.DeleteOptions) error
checkpointListFunc func(container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error)
checkpointCreateFunc func(container string, options client.CheckpointCreateOptions) error
checkpointDeleteFunc func(container string, options client.CheckpointDeleteOptions) error
checkpointListFunc func(container string, options client.CheckpointListOptions) ([]checkpoint.Summary, error)
}
func (cli *fakeClient) CheckpointCreate(_ context.Context, container string, options checkpoint.CreateOptions) error {
func (cli *fakeClient) CheckpointCreate(_ context.Context, container string, options client.CheckpointCreateOptions) error {
if cli.checkpointCreateFunc != nil {
return cli.checkpointCreateFunc(container, options)
}
return nil
}
func (cli *fakeClient) CheckpointDelete(_ context.Context, container string, options checkpoint.DeleteOptions) error {
func (cli *fakeClient) CheckpointDelete(_ context.Context, container string, options client.CheckpointDeleteOptions) error {
if cli.checkpointDeleteFunc != nil {
return cli.checkpointDeleteFunc(container, options)
}
return nil
}
func (cli *fakeClient) CheckpointList(_ context.Context, container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {
func (cli *fakeClient) CheckpointList(_ context.Context, container string, options client.CheckpointListOptions) ([]checkpoint.Summary, error) {
if cli.checkpointListFunc != nil {
return cli.checkpointListFunc(container, options)
}

View File

@ -6,7 +6,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/moby/moby/api/types/checkpoint"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@ -41,7 +41,7 @@ func newCreateCommand(dockerCLI command.Cli) *cobra.Command {
}
func runCreate(ctx context.Context, dockerCLI command.Cli, opts createOptions) error {
err := dockerCLI.Client().CheckpointCreate(ctx, opts.container, checkpoint.CreateOptions{
err := dockerCLI.Client().CheckpointCreate(ctx, opts.container, client.CheckpointCreateOptions{
CheckpointID: opts.checkpoint,
CheckpointDir: opts.checkpointDir,
Exit: !opts.leaveRunning,

View File

@ -8,7 +8,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/moby/moby/api/types/checkpoint"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@ -16,7 +16,7 @@ import (
func TestCheckpointCreateErrors(t *testing.T) {
testCases := []struct {
args []string
checkpointCreateFunc func(container string, options checkpoint.CreateOptions) error
checkpointCreateFunc func(container string, options client.CheckpointCreateOptions) error
expectedError string
}{
{
@ -29,7 +29,7 @@ func TestCheckpointCreateErrors(t *testing.T) {
},
{
args: []string{"foo", "bar"},
checkpointCreateFunc: func(container string, options checkpoint.CreateOptions) error {
checkpointCreateFunc: func(container string, options client.CheckpointCreateOptions) error {
return errors.New("error creating checkpoint for container foo")
},
expectedError: "error creating checkpoint for container foo",
@ -59,9 +59,9 @@ func TestCheckpointCreateWithOptions(t *testing.T) {
leaveRunning := strconv.FormatBool(tc)
t.Run("leave-running="+leaveRunning, func(t *testing.T) {
var actualContainerName string
var actualOptions checkpoint.CreateOptions
var actualOptions client.CheckpointCreateOptions
cli := test.NewFakeCli(&fakeClient{
checkpointCreateFunc: func(container string, options checkpoint.CreateOptions) error {
checkpointCreateFunc: func(container string, options client.CheckpointCreateOptions) error {
actualContainerName = container
actualOptions = options
return nil
@ -75,7 +75,7 @@ func TestCheckpointCreateWithOptions(t *testing.T) {
assert.Check(t, cmd.Flags().Set("checkpoint-dir", checkpointDir))
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal(actualContainerName, containerName))
expected := checkpoint.CreateOptions{
expected := client.CheckpointCreateOptions{
CheckpointID: checkpointName,
CheckpointDir: checkpointDir,
Exit: !tc,

View File

@ -7,7 +7,7 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/cli/command/formatter"
"github.com/moby/moby/api/types/checkpoint"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@ -37,7 +37,7 @@ func newListCommand(dockerCLI command.Cli) *cobra.Command {
}
func runList(ctx context.Context, dockerCli command.Cli, container string, opts listOptions) error {
checkpoints, err := dockerCli.Client().CheckpointList(ctx, container, checkpoint.ListOptions{
checkpoints, err := dockerCli.Client().CheckpointList(ctx, container, client.CheckpointListOptions{
CheckpointDir: opts.checkpointDir,
})
if err != nil {

View File

@ -7,6 +7,7 @@ import (
"github.com/docker/cli/internal/test"
"github.com/moby/moby/api/types/checkpoint"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/golden"
@ -15,7 +16,7 @@ import (
func TestCheckpointListErrors(t *testing.T) {
testCases := []struct {
args []string
checkpointListFunc func(container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error)
checkpointListFunc func(container string, options client.CheckpointListOptions) ([]checkpoint.Summary, error)
expectedError string
}{
{
@ -28,7 +29,7 @@ func TestCheckpointListErrors(t *testing.T) {
},
{
args: []string{"foo"},
checkpointListFunc: func(container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {
checkpointListFunc: func(container string, options client.CheckpointListOptions) ([]checkpoint.Summary, error) {
return []checkpoint.Summary{}, errors.New("error getting checkpoints for container foo")
},
expectedError: "error getting checkpoints for container foo",
@ -50,7 +51,7 @@ func TestCheckpointListErrors(t *testing.T) {
func TestCheckpointListWithOptions(t *testing.T) {
var containerID, checkpointDir string
cli := test.NewFakeCli(&fakeClient{
checkpointListFunc: func(container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {
checkpointListFunc: func(container string, options client.CheckpointListOptions) ([]checkpoint.Summary, error) {
containerID = container
checkpointDir = options.CheckpointDir
return []checkpoint.Summary{

View File

@ -5,7 +5,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/moby/moby/api/types/checkpoint"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@ -34,7 +34,7 @@ func newRemoveCommand(dockerCLI command.Cli) *cobra.Command {
}
func runRemove(ctx context.Context, dockerCli command.Cli, container string, checkpointID string, opts removeOptions) error {
return dockerCli.Client().CheckpointDelete(ctx, container, checkpoint.DeleteOptions{
return dockerCli.Client().CheckpointDelete(ctx, container, client.CheckpointDeleteOptions{
CheckpointID: checkpointID,
CheckpointDir: opts.checkpointDir,
})

View File

@ -6,7 +6,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/moby/moby/api/types/checkpoint"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@ -14,7 +14,7 @@ import (
func TestCheckpointRemoveErrors(t *testing.T) {
testCases := []struct {
args []string
checkpointDeleteFunc func(container string, options checkpoint.DeleteOptions) error
checkpointDeleteFunc func(container string, options client.CheckpointDeleteOptions) error
expectedError string
}{
{
@ -27,7 +27,7 @@ func TestCheckpointRemoveErrors(t *testing.T) {
},
{
args: []string{"foo", "bar"},
checkpointDeleteFunc: func(container string, options checkpoint.DeleteOptions) error {
checkpointDeleteFunc: func(container string, options client.CheckpointDeleteOptions) error {
return errors.New("error deleting checkpoint")
},
expectedError: "error deleting checkpoint",
@ -49,7 +49,7 @@ func TestCheckpointRemoveErrors(t *testing.T) {
func TestCheckpointRemoveWithOptions(t *testing.T) {
var containerID, checkpointID, checkpointDir string
cli := test.NewFakeCli(&fakeClient{
checkpointDeleteFunc: func(container string, options checkpoint.DeleteOptions) error {
checkpointDeleteFunc: func(container string, options client.CheckpointDeleteOptions) error {
containerID = container
checkpointID = options.CheckpointID
checkpointDir = options.CheckpointDir

View File

@ -87,9 +87,9 @@ type DockerCli struct {
enableGlobalMeter, enableGlobalTracer bool
}
// DefaultVersion returns [client.DefaultAPIVersion].
// DefaultVersion returns [client.MaxAPIVersion].
func (*DockerCli) DefaultVersion() string {
return client.DefaultAPIVersion
return client.MaxAPIVersion
}
// CurrentVersion returns the API version currently negotiated, or the default
@ -97,7 +97,7 @@ func (*DockerCli) DefaultVersion() string {
func (cli *DockerCli) CurrentVersion() string {
_ = cli.initialize()
if cli.client == nil {
return client.DefaultAPIVersion
return client.MaxAPIVersion
}
return cli.client.ClientVersion()
}

View File

@ -34,7 +34,7 @@ func TestNewAPIClientFromFlags(t *testing.T) {
apiClient, err := NewAPIClientFromFlags(opts, &configfile.ConfigFile{})
assert.NilError(t, err)
assert.Equal(t, apiClient.DaemonHost(), host)
assert.Equal(t, apiClient.ClientVersion(), client.DefaultAPIVersion)
assert.Equal(t, apiClient.ClientVersion(), client.MaxAPIVersion)
}
func TestNewAPIClientFromFlagsForDefaultSchema(t *testing.T) {
@ -47,7 +47,7 @@ func TestNewAPIClientFromFlagsForDefaultSchema(t *testing.T) {
apiClient, err := NewAPIClientFromFlags(opts, &configfile.ConfigFile{})
assert.NilError(t, err)
assert.Equal(t, apiClient.DaemonHost(), slug+host)
assert.Equal(t, apiClient.ClientVersion(), client.DefaultAPIVersion)
assert.Equal(t, apiClient.ClientVersion(), client.MaxAPIVersion)
}
func TestNewAPIClientFromFlagsWithCustomHeaders(t *testing.T) {
@ -71,7 +71,7 @@ func TestNewAPIClientFromFlagsWithCustomHeaders(t *testing.T) {
apiClient, err := NewAPIClientFromFlags(opts, configFile)
assert.NilError(t, err)
assert.Equal(t, apiClient.DaemonHost(), host)
assert.Equal(t, apiClient.ClientVersion(), client.DefaultAPIVersion)
assert.Equal(t, apiClient.ClientVersion(), client.MaxAPIVersion)
// verify User-Agent is not appended to the configfile. see https://github.com/docker/cli/pull/2756
assert.DeepEqual(t, configFile.HTTPHeaders, map[string]string{"My-Header": "Custom-Value"})
@ -106,7 +106,7 @@ func TestNewAPIClientFromFlagsWithCustomHeadersFromEnv(t *testing.T) {
apiClient, err := NewAPIClientFromFlags(opts, configFile)
assert.NilError(t, err)
assert.Equal(t, apiClient.DaemonHost(), host)
assert.Equal(t, apiClient.ClientVersion(), client.DefaultAPIVersion)
assert.Equal(t, apiClient.ClientVersion(), client.MaxAPIVersion)
expectedHeaders := http.Header{
"One": []string{"one-value"},

View File

@ -43,7 +43,7 @@ func ImageNames(dockerCLI APIClientProvider, limit int) cobra.CompletionFunc {
// Set DOCKER_COMPLETION_SHOW_CONTAINER_IDS=yes to also complete IDs.
func ContainerNames(dockerCLI APIClientProvider, all bool, filters ...func(container.Summary) bool) cobra.CompletionFunc {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, err := dockerCLI.Client().ContainerList(cmd.Context(), container.ListOptions{
list, err := dockerCLI.Client().ContainerList(cmd.Context(), client.ContainerListOptions{
All: all,
})
if err != nil {

View File

@ -30,13 +30,13 @@ func (c fakeCLI) Client() client.APIClient {
type fakeClient struct {
client.Client
containerListFunc func(options container.ListOptions) ([]container.Summary, error)
containerListFunc func(options client.ContainerListOptions) ([]container.Summary, error)
imageListFunc func(options client.ImageListOptions) ([]image.Summary, error)
networkListFunc func(ctx context.Context, options client.NetworkListOptions) ([]network.Summary, error)
volumeListFunc func(filter filters.Args) (volume.ListResponse, error)
}
func (c *fakeClient) ContainerList(_ context.Context, options container.ListOptions) ([]container.Summary, error) {
func (c *fakeClient) ContainerList(_ context.Context, options client.ContainerListOptions) ([]container.Summary, error) {
if c.containerListFunc != nil {
return c.containerListFunc(options)
}
@ -54,7 +54,7 @@ func (c *fakeClient) NetworkList(ctx context.Context, options client.NetworkList
if c.networkListFunc != nil {
return c.networkListFunc(ctx, options)
}
return []network.Inspect{}, nil
return []network.Summary{}, nil
}
func (c *fakeClient) VolumeList(_ context.Context, options client.VolumeListOptions) (volume.ListResponse, error) {
@ -71,7 +71,7 @@ func TestCompleteContainerNames(t *testing.T) {
filters []func(container.Summary) bool
containers []container.Summary
expOut []string
expOpts container.ListOptions
expOpts client.ContainerListOptions
expDirective cobra.ShellCompDirective
}{
{
@ -87,7 +87,7 @@ func TestCompleteContainerNames(t *testing.T) {
{ID: "id-a", State: container.StateExited, Names: []string{"/container-a"}},
},
expOut: []string{"container-c", "container-c/link-b", "container-b", "container-a"},
expOpts: container.ListOptions{All: true},
expOpts: client.ContainerListOptions{All: true},
expDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
@ -100,7 +100,7 @@ func TestCompleteContainerNames(t *testing.T) {
{ID: "id-a", State: container.StateExited, Names: []string{"/container-a"}},
},
expOut: []string{"id-c", "container-c", "container-c/link-b", "id-b", "container-b", "id-a", "container-a"},
expOpts: container.ListOptions{All: true},
expOpts: client.ContainerListOptions{All: true},
expDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
@ -124,7 +124,7 @@ func TestCompleteContainerNames(t *testing.T) {
{ID: "id-a", State: container.StateExited, Names: []string{"/container-a"}},
},
expOut: []string{"container-b"},
expOpts: container.ListOptions{All: true},
expOpts: client.ContainerListOptions{All: true},
expDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
@ -140,7 +140,7 @@ func TestCompleteContainerNames(t *testing.T) {
{ID: "id-a", State: container.StateCreated, Names: []string{"/container-a"}},
},
expOut: []string{"container-a"},
expOpts: container.ListOptions{All: true},
expOpts: client.ContainerListOptions{All: true},
expDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
@ -155,8 +155,8 @@ func TestCompleteContainerNames(t *testing.T) {
t.Setenv("DOCKER_COMPLETION_SHOW_CONTAINER_IDS", "yes")
}
comp := ContainerNames(fakeCLI{&fakeClient{
containerListFunc: func(opts container.ListOptions) ([]container.Summary, error) {
assert.Check(t, is.DeepEqual(opts, tc.expOpts, cmpopts.IgnoreUnexported(container.ListOptions{}, filters.Args{})))
containerListFunc: func(opts client.ContainerListOptions) ([]container.Summary, error) {
assert.Check(t, is.DeepEqual(opts, tc.expOpts, cmpopts.IgnoreUnexported(client.ContainerListOptions{}, filters.Args{})))
if tc.expDirective == cobra.ShellCompDirectiveError {
return nil, errors.New("some error occurred")
}
@ -257,9 +257,24 @@ func TestCompleteNetworkNames(t *testing.T) {
{
doc: "with results",
networks: []network.Summary{
{ID: "nw-c", Name: "network-c"},
{ID: "nw-b", Name: "network-b"},
{ID: "nw-a", Name: "network-a"},
{
Network: network.Network{
ID: "nw-c",
Name: "network-c",
},
},
{
Network: network.Network{
ID: "nw-b",
Name: "network-b",
},
},
{
Network: network.Network{
ID: "nw-a",
Name: "network-a",
},
},
},
expOut: []string{"network-c", "network-b", "network-a"},
expDirective: cobra.ShellCompDirectiveNoFileComp,

View File

@ -90,7 +90,7 @@ func RunAttach(ctx context.Context, dockerCLI command.Cli, containerID string, o
detachKeys = opts.DetachKeys
}
options := container.AttachOptions{
options := client.ContainerAttachOptions{
Stream: true,
Stdin: !opts.NoStdin && c.Config.OpenStdin,
Stdout: true,

View File

@ -22,30 +22,30 @@ type fakeClient struct {
networkingConfig *network.NetworkingConfig,
platform *ocispec.Platform,
containerName string) (container.CreateResponse, error)
containerStartFunc func(containerID string, options container.StartOptions) error
containerStartFunc func(containerID string, options client.ContainerStartOptions) error
imageCreateFunc func(ctx context.Context, parentReference string, options client.ImageCreateOptions) (io.ReadCloser, error)
infoFunc func() (system.Info, error)
containerStatPathFunc func(containerID, path string) (container.PathStat, error)
containerCopyFromFunc func(containerID, srcPath string) (io.ReadCloser, container.PathStat, error)
logFunc func(string, container.LogsOptions) (io.ReadCloser, error)
logFunc func(string, client.ContainerLogsOptions) (io.ReadCloser, error)
waitFunc func(string) (<-chan container.WaitResponse, <-chan error)
containerListFunc func(container.ListOptions) ([]container.Summary, error)
containerListFunc func(client.ContainerListOptions) ([]container.Summary, error)
containerExportFunc func(string) (io.ReadCloser, error)
containerExecResizeFunc func(id string, options client.ContainerResizeOptions) error
containerRemoveFunc func(ctx context.Context, containerID string, options container.RemoveOptions) error
containerRestartFunc func(ctx context.Context, containerID string, options container.StopOptions) error
containerStopFunc func(ctx context.Context, containerID string, options container.StopOptions) error
containerRemoveFunc func(ctx context.Context, containerID string, options client.ContainerRemoveOptions) error
containerRestartFunc func(ctx context.Context, containerID string, options client.ContainerStopOptions) error
containerStopFunc func(ctx context.Context, containerID string, options client.ContainerStopOptions) error
containerKillFunc func(ctx context.Context, containerID, signal string) error
containerPruneFunc func(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error)
containerAttachFunc func(ctx context.Context, containerID string, options container.AttachOptions) (client.HijackedResponse, error)
containerAttachFunc func(ctx context.Context, containerID string, options client.ContainerAttachOptions) (client.HijackedResponse, error)
containerDiffFunc func(ctx context.Context, containerID string) ([]container.FilesystemChange, error)
containerRenameFunc func(ctx context.Context, oldName, newName string) error
containerCommitFunc func(ctx context.Context, container string, options container.CommitOptions) (container.CommitResponse, error)
containerCommitFunc func(ctx context.Context, container string, options client.ContainerCommitOptions) (container.CommitResponse, error)
containerPauseFunc func(ctx context.Context, container string) error
Version string
}
func (f *fakeClient) ContainerList(_ context.Context, options container.ListOptions) ([]container.Summary, error) {
func (f *fakeClient) ContainerList(_ context.Context, options client.ContainerListOptions) ([]container.Summary, error) {
if f.containerListFunc != nil {
return f.containerListFunc(options)
}
@ -91,7 +91,7 @@ func (f *fakeClient) ContainerCreate(
return container.CreateResponse{}, nil
}
func (f *fakeClient) ContainerRemove(ctx context.Context, containerID string, options container.RemoveOptions) error {
func (f *fakeClient) ContainerRemove(ctx context.Context, containerID string, options client.ContainerRemoveOptions) error {
if f.containerRemoveFunc != nil {
return f.containerRemoveFunc(ctx, containerID, options)
}
@ -126,7 +126,7 @@ func (f *fakeClient) CopyFromContainer(_ context.Context, containerID, srcPath s
return nil, container.PathStat{}, nil
}
func (f *fakeClient) ContainerLogs(_ context.Context, containerID string, options container.LogsOptions) (io.ReadCloser, error) {
func (f *fakeClient) ContainerLogs(_ context.Context, containerID string, options client.ContainerLogsOptions) (io.ReadCloser, error) {
if f.logFunc != nil {
return f.logFunc(containerID, options)
}
@ -144,7 +144,7 @@ func (f *fakeClient) ContainerWait(_ context.Context, containerID string, _ cont
return nil, nil
}
func (f *fakeClient) ContainerStart(_ context.Context, containerID string, options container.StartOptions) error {
func (f *fakeClient) ContainerStart(_ context.Context, containerID string, options client.ContainerStartOptions) error {
if f.containerStartFunc != nil {
return f.containerStartFunc(containerID, options)
}
@ -179,21 +179,21 @@ func (f *fakeClient) ContainersPrune(ctx context.Context, pruneFilters filters.A
return container.PruneReport{}, nil
}
func (f *fakeClient) ContainerRestart(ctx context.Context, containerID string, options container.StopOptions) error {
func (f *fakeClient) ContainerRestart(ctx context.Context, containerID string, options client.ContainerStopOptions) error {
if f.containerRestartFunc != nil {
return f.containerRestartFunc(ctx, containerID, options)
}
return nil
}
func (f *fakeClient) ContainerStop(ctx context.Context, containerID string, options container.StopOptions) error {
func (f *fakeClient) ContainerStop(ctx context.Context, containerID string, options client.ContainerStopOptions) error {
if f.containerStopFunc != nil {
return f.containerStopFunc(ctx, containerID, options)
}
return nil
}
func (f *fakeClient) ContainerAttach(ctx context.Context, containerID string, options container.AttachOptions) (client.HijackedResponse, error) {
func (f *fakeClient) ContainerAttach(ctx context.Context, containerID string, options client.ContainerAttachOptions) (client.HijackedResponse, error) {
if f.containerAttachFunc != nil {
return f.containerAttachFunc(ctx, containerID, options)
}
@ -216,7 +216,7 @@ func (f *fakeClient) ContainerRename(ctx context.Context, oldName, newName strin
return nil
}
func (f *fakeClient) ContainerCommit(ctx context.Context, containerID string, options container.CommitOptions) (container.CommitResponse, error) {
func (f *fakeClient) ContainerCommit(ctx context.Context, containerID string, options client.ContainerCommitOptions) (container.CommitResponse, error) {
if f.containerCommitFunc != nil {
return f.containerCommitFunc(ctx, containerID, options)
}

View File

@ -8,7 +8,7 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/opts"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@ -58,7 +58,7 @@ func newCommitCommand(dockerCLI command.Cli) *cobra.Command {
}
func runCommit(ctx context.Context, dockerCli command.Cli, options *commitOptions) error {
response, err := dockerCli.Client().ContainerCommit(ctx, options.container, container.CommitOptions{
response, err := dockerCli.Client().ContainerCommit(ctx, options.container, client.ContainerCommitOptions{
Reference: options.reference,
Comment: options.comment,
Author: options.author,

View File

@ -8,6 +8,7 @@ import (
"github.com/docker/cli/internal/test"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@ -17,7 +18,7 @@ func TestRunCommit(t *testing.T) {
containerCommitFunc: func(
ctx context.Context,
ctr string,
options container.CommitOptions,
options client.ContainerCommitOptions,
) (container.CommitResponse, error) {
assert.Check(t, is.Equal(options.Author, "Author Name <author@name.com>"))
assert.Check(t, is.DeepEqual(options.Changes, []string{"EXPOSE 80"}))
@ -54,7 +55,7 @@ func TestRunCommitClientError(t *testing.T) {
containerCommitFunc: func(
ctx context.Context,
ctr string,
options container.CommitOptions,
options client.ContainerCommitOptions,
) (container.CommitResponse, error) {
return container.CommitResponse{}, clientError
},

View File

@ -7,6 +7,7 @@ import (
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/builders"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/moby/sys/signal"
"github.com/spf13/cobra"
"gotest.tools/v3/assert"
@ -26,7 +27,7 @@ func TestCompleteLinuxCapabilityNames(t *testing.T) {
func TestCompletePid(t *testing.T) {
tests := []struct {
containerListFunc func(container.ListOptions) ([]container.Summary, error)
containerListFunc func(client.ContainerListOptions) ([]container.Summary, error)
toComplete string
expectedCompletions []string
expectedDirective cobra.ShellCompDirective
@ -42,7 +43,7 @@ func TestCompletePid(t *testing.T) {
expectedDirective: cobra.ShellCompDirectiveNoSpace,
},
{
containerListFunc: func(container.ListOptions) ([]container.Summary, error) {
containerListFunc: func(client.ContainerListOptions) ([]container.Summary, error) {
return []container.Summary{
*builders.Container("c1"),
*builders.Container("c2"),

View File

@ -18,7 +18,7 @@ import (
"github.com/docker/cli/cli/streams"
"github.com/docker/go-units"
"github.com/moby/go-archive"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/morikuni/aec"
"github.com/spf13/cobra"
)
@ -398,7 +398,7 @@ func copyToContainer(ctx context.Context, dockerCLI command.Cli, copyConfig cpCo
}
}
options := container.CopyToContainerOptions{
options := client.CopyToContainerOptions{
CopyUIDGID: copyConfig.copyUIDGID,
}

View File

@ -450,7 +450,7 @@ func copyDockerConfigIntoContainer(ctx context.Context, dockerAPI client.APIClie
}
if err := dockerAPI.CopyToContainer(ctx, containerID, "/",
&tarBuf, container.CopyToContainerOptions{}); err != nil {
&tarBuf, client.CopyToContainerOptions{}); err != nil {
return fmt.Errorf("copying config.json into container failed: %w", err)
}

View File

@ -10,7 +10,7 @@ import (
flagsHelper "github.com/docker/cli/cli/flags"
"github.com/docker/cli/opts"
"github.com/docker/cli/templates"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@ -68,8 +68,8 @@ func newListCommand(dockerCLI command.Cli) *cobra.Command {
return &cmd
}
func buildContainerListOptions(options *psOptions) (*container.ListOptions, error) {
listOptions := &container.ListOptions{
func buildContainerListOptions(options *psOptions) (*client.ContainerListOptions, error) {
listOptions := &client.ContainerListOptions{
All: options.all,
Limit: options.last,
Size: options.size,

View File

@ -10,6 +10,7 @@ import (
"github.com/docker/cli/internal/test/builders"
"github.com/docker/cli/opts"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/golden"
@ -128,7 +129,7 @@ func TestContainerListBuildContainerListOptions(t *testing.T) {
func TestContainerListErrors(t *testing.T) {
testCases := []struct {
flags map[string]string
containerListFunc func(container.ListOptions) ([]container.Summary, error)
containerListFunc func(client.ContainerListOptions) ([]container.Summary, error)
expectedError string
}{
{
@ -144,7 +145,7 @@ func TestContainerListErrors(t *testing.T) {
expectedError: `wrong number of args for join`,
},
{
containerListFunc: func(_ container.ListOptions) ([]container.Summary, error) {
containerListFunc: func(_ client.ContainerListOptions) ([]container.Summary, error) {
return nil, errors.New("error listing containers")
},
expectedError: "error listing containers",
@ -168,7 +169,7 @@ func TestContainerListErrors(t *testing.T) {
func TestContainerListWithoutFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ container.ListOptions) ([]container.Summary, error) {
containerListFunc: func(_ client.ContainerListOptions) ([]container.Summary, error) {
return []container.Summary{
*builders.Container("c1"),
*builders.Container("c2", builders.WithName("foo")),
@ -188,7 +189,7 @@ func TestContainerListWithoutFormat(t *testing.T) {
func TestContainerListNoTrunc(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ container.ListOptions) ([]container.Summary, error) {
containerListFunc: func(_ client.ContainerListOptions) ([]container.Summary, error) {
return []container.Summary{
*builders.Container("c1"),
*builders.Container("c2", builders.WithName("foo/bar")),
@ -207,7 +208,7 @@ func TestContainerListNoTrunc(t *testing.T) {
// Test for GitHub issue docker/docker#21772
func TestContainerListNamesMultipleTime(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ container.ListOptions) ([]container.Summary, error) {
containerListFunc: func(_ client.ContainerListOptions) ([]container.Summary, error) {
return []container.Summary{
*builders.Container("c1"),
*builders.Container("c2", builders.WithName("foo/bar")),
@ -226,7 +227,7 @@ func TestContainerListNamesMultipleTime(t *testing.T) {
// Test for GitHub issue docker/docker#30291
func TestContainerListFormatTemplateWithArg(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ container.ListOptions) ([]container.Summary, error) {
containerListFunc: func(_ client.ContainerListOptions) ([]container.Summary, error) {
return []container.Summary{
*builders.Container("c1", builders.WithLabel("some.label", "value")),
*builders.Container("c2", builders.WithName("foo/bar"), builders.WithLabel("foo", "bar")),
@ -279,7 +280,7 @@ func TestContainerListFormatSizeSetsOption(t *testing.T) {
for _, tc := range tests {
t.Run(tc.doc, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(options container.ListOptions) ([]container.Summary, error) {
containerListFunc: func(options client.ContainerListOptions) ([]container.Summary, error) {
assert.Check(t, is.Equal(options.Size, tc.sizeExpected))
return []container.Summary{}, nil
},
@ -299,7 +300,7 @@ func TestContainerListFormatSizeSetsOption(t *testing.T) {
func TestContainerListWithConfigFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ container.ListOptions) ([]container.Summary, error) {
containerListFunc: func(_ client.ContainerListOptions) ([]container.Summary, error) {
return []container.Summary{
*builders.Container("c1", builders.WithLabel("some.label", "value"), builders.WithSize(10700000)),
*builders.Container("c2", builders.WithName("foo/bar"), builders.WithLabel("foo", "bar"), builders.WithSize(3200000)),
@ -319,7 +320,7 @@ func TestContainerListWithConfigFormat(t *testing.T) {
func TestContainerListWithFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ container.ListOptions) ([]container.Summary, error) {
containerListFunc: func(_ client.ContainerListOptions) ([]container.Summary, error) {
return []container.Summary{
*builders.Container("c1", builders.WithLabel("some.label", "value")),
*builders.Container("c2", builders.WithName("foo/bar"), builders.WithLabel("foo", "bar")),

View File

@ -8,7 +8,7 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/moby/moby/api/pkg/stdcopy"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@ -59,7 +59,7 @@ func runLogs(ctx context.Context, dockerCli command.Cli, opts *logsOptions) erro
return err
}
responseBody, err := dockerCli.Client().ContainerLogs(ctx, c.ID, container.LogsOptions{
responseBody, err := dockerCli.Client().ContainerLogs(ctx, c.ID, client.ContainerLogsOptions{
ShowStdout: true,
ShowStderr: true,
Since: opts.since,

View File

@ -8,12 +8,13 @@ import (
"github.com/docker/cli/internal/test"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
var logFn = func(expectedOut string) func(string, container.LogsOptions) (io.ReadCloser, error) {
return func(container string, opts container.LogsOptions) (io.ReadCloser, error) {
var logFn = func(expectedOut string) func(string, client.ContainerLogsOptions) (io.ReadCloser, error) {
return func(container string, opts client.ContainerLogsOptions) (io.ReadCloser, error) {
return io.NopCloser(strings.NewReader(expectedOut)), nil
}
}

View File

@ -8,7 +8,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@ -66,7 +66,7 @@ func runRestart(ctx context.Context, dockerCLI command.Cli, opts *restartOptions
var errs []error
// TODO(thaJeztah): consider using parallelOperation for restart, similar to "stop" and "remove"
for _, name := range opts.containers {
err := apiClient.ContainerRestart(ctx, name, container.StopOptions{
err := apiClient.ContainerRestart(ctx, name, client.ContainerStopOptions{
Signal: opts.signal,
Timeout: timeout,
})

View File

@ -9,7 +9,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@ -19,7 +19,7 @@ func TestRestart(t *testing.T) {
name string
args []string
restarted []string
expectedOpts container.StopOptions
expectedOpts client.ContainerStopOptions
expectedErr string
}{
{
@ -36,19 +36,19 @@ func TestRestart(t *testing.T) {
{
name: "with -t",
args: []string{"-t", "2", "container-1"},
expectedOpts: container.StopOptions{Timeout: func(to int) *int { return &to }(2)},
expectedOpts: client.ContainerStopOptions{Timeout: func(to int) *int { return &to }(2)},
restarted: []string{"container-1"},
},
{
name: "with --timeout",
args: []string{"--timeout", "2", "container-1"},
expectedOpts: container.StopOptions{Timeout: func(to int) *int { return &to }(2)},
expectedOpts: client.ContainerStopOptions{Timeout: func(to int) *int { return &to }(2)},
restarted: []string{"container-1"},
},
{
name: "with --time",
args: []string{"--time", "2", "container-1"},
expectedOpts: container.StopOptions{Timeout: func(to int) *int { return &to }(2)},
expectedOpts: client.ContainerStopOptions{Timeout: func(to int) *int { return &to }(2)},
restarted: []string{"container-1"},
},
{
@ -62,7 +62,7 @@ func TestRestart(t *testing.T) {
mutex := new(sync.Mutex)
cli := test.NewFakeCli(&fakeClient{
containerRestartFunc: func(ctx context.Context, containerID string, options container.StopOptions) error {
containerRestartFunc: func(ctx context.Context, containerID string, options client.ContainerStopOptions) error {
assert.Check(t, is.DeepEqual(options, tc.expectedOpts))
if containerID == "nosuchcontainer" {
return notFound(errors.New("Error: no such container: " + containerID))

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@ -66,7 +67,7 @@ func runRm(ctx context.Context, dockerCLI command.Cli, opts *rmOptions) error {
if ctrID == "" {
return errors.New("container name cannot be empty")
}
return apiClient.ContainerRemove(ctx, ctrID, container.RemoveOptions{
return apiClient.ContainerRemove(ctx, ctrID, client.ContainerRemoveOptions{
RemoveVolumes: opts.rmVolumes,
RemoveLinks: opts.rmLink,
Force: opts.force,

View File

@ -9,7 +9,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
)
@ -27,7 +27,7 @@ func TestRemoveForce(t *testing.T) {
mutex := new(sync.Mutex)
cli := test.NewFakeCli(&fakeClient{
containerRemoveFunc: func(ctx context.Context, container string, options container.RemoveOptions) error {
containerRemoveFunc: func(ctx context.Context, container string, options client.ContainerRemoveOptions) error {
// containerRemoveFunc is called in parallel for each container
// by the remove command so append must be synchronized.
mutex.Lock()

View File

@ -12,6 +12,7 @@ import (
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/opts"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/moby/sys/signal"
"github.com/moby/term"
"github.com/pkg/errors"
@ -176,7 +177,7 @@ func runContainer(ctx context.Context, dockerCli command.Cli, runOpts *runOption
// ctx should not be cancellable here, as this would kill the stream to the container
// and we want to keep the stream open until the process in the container exits or until
// the user forcefully terminates the CLI.
closeFn, err := attachContainer(ctx, dockerCli, containerID, &errCh, config, container.AttachOptions{
closeFn, err := attachContainer(ctx, dockerCli, containerID, &errCh, config, client.ContainerAttachOptions{
Stream: true,
Stdin: config.AttachStdin,
Stdout: config.AttachStdout,
@ -196,7 +197,7 @@ func runContainer(ctx context.Context, dockerCli command.Cli, runOpts *runOption
statusChan := waitExitOrRemoved(statusCtx, apiClient, containerID, copts.autoRemove)
// start the container
if err := apiClient.ContainerStart(ctx, containerID, container.StartOptions{}); err != nil {
if err := apiClient.ContainerStart(ctx, containerID, client.ContainerStartOptions{}); err != nil {
// If we have hijackedIOStreamer, we should notify
// hijackedIOStreamer we are going to exit and wait
// to avoid the terminal are not restored.
@ -259,7 +260,7 @@ func runContainer(ctx context.Context, dockerCli command.Cli, runOpts *runOption
return nil
}
func attachContainer(ctx context.Context, dockerCli command.Cli, containerID string, errCh *chan error, config *container.Config, options container.AttachOptions) (func(), error) {
func attachContainer(ctx context.Context, dockerCli command.Cli, containerID string, errCh *chan error, config *container.Config, options client.ContainerAttachOptions) (func(), error) {
resp, errAttach := dockerCli.Client().ContainerAttach(ctx, containerID, options)
if errAttach != nil {
return nil, errAttach

View File

@ -84,7 +84,7 @@ func TestRunAttach(t *testing.T) {
ID: "id",
}, nil
},
containerAttachFunc: func(ctx context.Context, containerID string, options container.AttachOptions) (client.HijackedResponse, error) {
containerAttachFunc: func(ctx context.Context, containerID string, options client.ContainerAttachOptions) (client.HijackedResponse, error) {
server, clientConn := net.Pipe()
conn = server
t.Cleanup(func() {
@ -161,7 +161,7 @@ func TestRunAttachTermination(t *testing.T) {
}
return nil
},
containerAttachFunc: func(ctx context.Context, containerID string, options container.AttachOptions) (client.HijackedResponse, error) {
containerAttachFunc: func(ctx context.Context, containerID string, options client.ContainerAttachOptions) (client.HijackedResponse, error) {
server, clientConn := net.Pipe()
conn = server
t.Cleanup(func() {
@ -232,7 +232,7 @@ func TestRunPullTermination(t *testing.T) {
) (container.CreateResponse, error) {
return container.CreateResponse{}, errors.New("shouldn't try to create a container")
},
containerAttachFunc: func(ctx context.Context, containerID string, options container.AttachOptions) (client.HijackedResponse, error) {
containerAttachFunc: func(ctx context.Context, containerID string, options client.ContainerAttachOptions) (client.HijackedResponse, error) {
return client.HijackedResponse{}, errors.New("shouldn't try to attach to a container")
},
imageCreateFunc: func(ctx context.Context, parentReference string, options client.ImageCreateOptions) (io.ReadCloser, error) {

View File

@ -10,6 +10,7 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/moby/sys/signal"
"github.com/moby/term"
"github.com/pkg/errors"
@ -97,7 +98,7 @@ func RunStart(ctx context.Context, dockerCli command.Cli, opts *StartOptions) er
detachKeys = opts.DetachKeys
}
options := container.AttachOptions{
options := client.ContainerAttachOptions{
Stream: true,
Stdin: opts.OpenStdin && c.Config.OpenStdin,
Stdout: true,
@ -144,7 +145,7 @@ func RunStart(ctx context.Context, dockerCli command.Cli, opts *StartOptions) er
statusChan := waitExitOrRemoved(ctx, dockerCli.Client(), c.ID, c.HostConfig.AutoRemove)
// 4. Start the container.
err = dockerCli.Client().ContainerStart(ctx, c.ID, container.StartOptions{
err = dockerCli.Client().ContainerStart(ctx, c.ID, client.ContainerStartOptions{
CheckpointID: opts.Checkpoint,
CheckpointDir: opts.CheckpointDir,
})
@ -181,7 +182,7 @@ func RunStart(ctx context.Context, dockerCli command.Cli, opts *StartOptions) er
return errors.New("you cannot restore multiple containers at once")
}
ctr := opts.Containers[0]
return dockerCli.Client().ContainerStart(ctx, ctr, container.StartOptions{
return dockerCli.Client().ContainerStart(ctx, ctr, client.ContainerStartOptions{
CheckpointID: opts.Checkpoint,
CheckpointDir: opts.CheckpointDir,
})
@ -195,7 +196,7 @@ func RunStart(ctx context.Context, dockerCli command.Cli, opts *StartOptions) er
func startContainersWithoutAttachments(ctx context.Context, dockerCli command.Cli, containers []string) error {
var failedContainers []string
for _, ctr := range containers {
if err := dockerCli.Client().ContainerStart(ctx, ctr, container.StartOptions{}); err != nil {
if err := dockerCli.Client().ContainerStart(ctx, ctr, client.ContainerStartOptions{}); err != nil {
fmt.Fprintln(dockerCli.Err(), err)
failedContainers = append(failedContainers, ctr)
continue

View File

@ -15,7 +15,6 @@ import (
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/cli/command/formatter"
flagsHelper "github.com/docker/cli/cli/flags"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/events"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/client"
@ -198,7 +197,7 @@ func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions)
// Fetch the initial list of containers and collect stats for them.
// After the initial list was collected, we start listening for events
// to refresh the list of containers.
cs, err := apiClient.ContainerList(ctx, container.ListOptions{
cs, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
All: options.All,
Filters: *options.Filters,
})

View File

@ -8,7 +8,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/spf13/cobra"
)
@ -64,7 +64,7 @@ func runStop(ctx context.Context, dockerCLI command.Cli, opts *stopOptions) erro
apiClient := dockerCLI.Client()
errChan := parallelOperation(ctx, opts.containers, func(ctx context.Context, id string) error {
return apiClient.ContainerStop(ctx, id, container.StopOptions{
return apiClient.ContainerStop(ctx, id, client.ContainerStopOptions{
Signal: opts.signal,
Timeout: timeout,
})

View File

@ -9,7 +9,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@ -19,7 +19,7 @@ func TestStop(t *testing.T) {
name string
args []string
stopped []string
expectedOpts container.StopOptions
expectedOpts client.ContainerStopOptions
expectedErr string
}{
{
@ -36,19 +36,19 @@ func TestStop(t *testing.T) {
{
name: "with -t",
args: []string{"-t", "2", "container-1"},
expectedOpts: container.StopOptions{Timeout: func(to int) *int { return &to }(2)},
expectedOpts: client.ContainerStopOptions{Timeout: func(to int) *int { return &to }(2)},
stopped: []string{"container-1"},
},
{
name: "with --timeout",
args: []string{"--timeout", "2", "container-1"},
expectedOpts: container.StopOptions{Timeout: func(to int) *int { return &to }(2)},
expectedOpts: client.ContainerStopOptions{Timeout: func(to int) *int { return &to }(2)},
stopped: []string{"container-1"},
},
{
name: "with --time",
args: []string{"--time", "2", "container-1"},
expectedOpts: container.StopOptions{Timeout: func(to int) *int { return &to }(2)},
expectedOpts: client.ContainerStopOptions{Timeout: func(to int) *int { return &to }(2)},
stopped: []string{"container-1"},
},
{
@ -62,7 +62,7 @@ func TestStop(t *testing.T) {
mutex := new(sync.Mutex)
cli := test.NewFakeCli(&fakeClient{
containerStopFunc: func(ctx context.Context, containerID string, options container.StopOptions) error {
containerStopFunc: func(ctx context.Context, containerID string, options client.ContainerStopOptions) error {
assert.Check(t, is.DeepEqual(options, tc.expectedOpts))
if containerID == "nosuchcontainer" {
return notFound(errors.New("Error: no such container: " + containerID))

View File

@ -91,7 +91,7 @@ func legacyWaitExitOrRemoved(ctx context.Context, apiClient client.APIClient, co
// If we are talking to an older daemon, `AutoRemove` is not supported.
// We need to fall back to the old behavior, which is client-side removal
go func() {
removeErr = apiClient.ContainerRemove(ctx, containerID, container.RemoveOptions{RemoveVolumes: true})
removeErr = apiClient.ContainerRemove(ctx, containerID, client.ContainerRemoveOptions{RemoveVolumes: true})
if removeErr != nil {
logrus.Errorf("error removing container: %v", removeErr)
cancel() // cancel the event Q

View File

@ -60,7 +60,7 @@ func TestWaitExitOrRemoved(t *testing.T) {
},
}
apiClient := &fakeClient{waitFunc: waitFn, Version: client.DefaultAPIVersion}
apiClient := &fakeClient{waitFunc: waitFn, Version: client.MaxAPIVersion}
for _, tc := range tests {
t.Run(tc.cid, func(t *testing.T) {
statusC := waitExitOrRemoved(context.Background(), apiClient, tc.cid, true)

View File

@ -25,6 +25,7 @@ import (
buildtypes "github.com/moby/moby/api/types/build"
"github.com/moby/moby/api/types/container"
registrytypes "github.com/moby/moby/api/types/registry"
"github.com/moby/moby/client"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@ -389,9 +390,9 @@ func validateTag(rawRepo string) (string, error) {
return rawRepo, nil
}
func imageBuildOptions(dockerCli command.Cli, options buildOptions) buildtypes.ImageBuildOptions {
func imageBuildOptions(dockerCli command.Cli, options buildOptions) client.ImageBuildOptions {
configFile := dockerCli.ConfigFile()
return buildtypes.ImageBuildOptions{
return client.ImageBuildOptions{
Memory: options.memory.Value(),
MemorySwap: options.memorySwap.Value(),
Tags: options.tags.GetSlice(),

View File

@ -15,7 +15,7 @@ import (
"github.com/docker/cli/internal/test"
"github.com/google/go-cmp/cmp"
"github.com/moby/go-archive/compression"
"github.com/moby/moby/api/types/build"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
"gotest.tools/v3/fs"
"gotest.tools/v3/skip"
@ -25,7 +25,7 @@ func TestRunBuildDockerfileFromStdinWithCompress(t *testing.T) {
t.Setenv("DOCKER_BUILDKIT", "0")
buffer := new(bytes.Buffer)
fakeBuild := newFakeBuild()
fakeImageBuild := func(ctx context.Context, buildContext io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error) {
fakeImageBuild := func(ctx context.Context, buildContext io.Reader, options client.ImageBuildOptions) (client.ImageBuildResponse, error) {
tee := io.TeeReader(buildContext, buffer)
gzipReader, err := gzip.NewReader(tee)
assert.NilError(t, err)
@ -142,8 +142,8 @@ func TestRunBuildFromLocalGitHubDir(t *testing.T) {
err = os.WriteFile(filepath.Join(buildDir, "Dockerfile"), []byte("FROM busybox\n"), 0o644)
assert.NilError(t, err)
client := test.NewFakeCli(&fakeClient{})
cmd := newBuildCommand(client)
fakeCLI := test.NewFakeCli(&fakeClient{})
cmd := newBuildCommand(fakeCLI)
cmd.SetArgs([]string{buildDir})
cmd.SetOut(io.Discard)
err = cmd.Execute()
@ -174,18 +174,18 @@ RUN echo hello world
type fakeBuild struct {
context *tar.Reader
options build.ImageBuildOptions
options client.ImageBuildOptions
}
func newFakeBuild() *fakeBuild {
return &fakeBuild{}
}
func (f *fakeBuild) build(_ context.Context, buildContext io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error) {
func (f *fakeBuild) build(_ context.Context, buildContext io.Reader, options client.ImageBuildOptions) (client.ImageBuildResponse, error) {
f.context = tar.NewReader(buildContext)
f.options = options
body := new(bytes.Buffer)
return build.ImageBuildResponse{Body: io.NopCloser(body)}, nil
return client.ImageBuildResponse{Body: io.NopCloser(body)}, nil
}
func (f *fakeBuild) headers(t *testing.T) []*tar.Header {

View File

@ -6,7 +6,6 @@ import (
"strings"
"time"
"github.com/moby/moby/api/types/build"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/system"
@ -22,12 +21,12 @@ type fakeClient struct {
infoFunc func() (system.Info, error)
imagePullFunc func(ref string, options client.ImagePullOptions) (io.ReadCloser, error)
imagesPruneFunc func(pruneFilter filters.Args) (image.PruneReport, error)
imageLoadFunc func(input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error)
imageLoadFunc func(input io.Reader, options ...client.ImageLoadOption) (client.LoadResponse, error)
imageListFunc func(options client.ImageListOptions) ([]image.Summary, error)
imageInspectFunc func(img string) (image.InspectResponse, error)
imageImportFunc func(source client.ImageImportSource, ref string, options client.ImageImportOptions) (io.ReadCloser, error)
imageHistoryFunc func(img string, options ...client.ImageHistoryOption) ([]image.HistoryResponseItem, error)
imageBuildFunc func(context.Context, io.Reader, build.ImageBuildOptions) (build.ImageBuildResponse, error)
imageBuildFunc func(context.Context, io.Reader, client.ImageBuildOptions) (client.ImageBuildResponse, error)
}
func (cli *fakeClient) ImageTag(_ context.Context, img, ref string) error {
@ -81,11 +80,11 @@ func (cli *fakeClient) ImagesPrune(_ context.Context, pruneFilter filters.Args)
return image.PruneReport{}, nil
}
func (cli *fakeClient) ImageLoad(_ context.Context, input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error) {
func (cli *fakeClient) ImageLoad(_ context.Context, input io.Reader, options ...client.ImageLoadOption) (client.LoadResponse, error) {
if cli.imageLoadFunc != nil {
return cli.imageLoadFunc(input, options...)
}
return image.LoadResponse{}, nil
return client.LoadResponse{}, nil
}
func (cli *fakeClient) ImageList(_ context.Context, options client.ImageListOptions) ([]image.Summary, error) {
@ -118,9 +117,9 @@ func (cli *fakeClient) ImageHistory(_ context.Context, img string, options ...cl
return []image.HistoryResponseItem{{ID: img, Created: time.Now().Unix()}}, nil
}
func (cli *fakeClient) ImageBuild(ctx context.Context, buildContext io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error) {
func (cli *fakeClient) ImageBuild(ctx context.Context, buildContext io.Reader, options client.ImageBuildOptions) (client.ImageBuildResponse, error) {
if cli.imageBuildFunc != nil {
return cli.imageBuildFunc(ctx, buildContext, options)
}
return build.ImageBuildResponse{Body: io.NopCloser(strings.NewReader(""))}, nil
return client.ImageBuildResponse{Body: io.NopCloser(strings.NewReader(""))}, nil
}

View File

@ -8,7 +8,6 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
"gotest.tools/v3/golden"
@ -20,7 +19,7 @@ func TestNewLoadCommandErrors(t *testing.T) {
args []string
isTerminalIn bool
expectedError string
imageLoadFunc func(input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error)
imageLoadFunc func(input io.Reader, options ...client.ImageLoadOption) (client.LoadResponse, error)
}{
{
name: "wrong-args",
@ -37,16 +36,16 @@ func TestNewLoadCommandErrors(t *testing.T) {
name: "pull-error",
args: []string{},
expectedError: "something went wrong",
imageLoadFunc: func(io.Reader, ...client.ImageLoadOption) (image.LoadResponse, error) {
return image.LoadResponse{}, errors.New("something went wrong")
imageLoadFunc: func(io.Reader, ...client.ImageLoadOption) (client.LoadResponse, error) {
return client.LoadResponse{}, errors.New("something went wrong")
},
},
{
name: "invalid platform",
args: []string{"--platform", "<invalid>"},
expectedError: `invalid platform`,
imageLoadFunc: func(io.Reader, ...client.ImageLoadOption) (image.LoadResponse, error) {
return image.LoadResponse{}, nil
imageLoadFunc: func(io.Reader, ...client.ImageLoadOption) (client.LoadResponse, error) {
return client.LoadResponse{}, nil
},
},
}
@ -77,20 +76,20 @@ func TestNewLoadCommandSuccess(t *testing.T) {
testCases := []struct {
name string
args []string
imageLoadFunc func(input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error)
imageLoadFunc func(input io.Reader, options ...client.ImageLoadOption) (client.LoadResponse, error)
}{
{
name: "simple",
args: []string{},
imageLoadFunc: func(io.Reader, ...client.ImageLoadOption) (image.LoadResponse, error) {
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
imageLoadFunc: func(io.Reader, ...client.ImageLoadOption) (client.LoadResponse, error) {
return client.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
},
},
{
name: "json",
args: []string{},
imageLoadFunc: func(io.Reader, ...client.ImageLoadOption) (image.LoadResponse, error) {
return image.LoadResponse{
imageLoadFunc: func(io.Reader, ...client.ImageLoadOption) (client.LoadResponse, error) {
return client.LoadResponse{
Body: io.NopCloser(strings.NewReader(`{"ID": "1"}`)),
JSON: true,
}, nil
@ -99,34 +98,34 @@ func TestNewLoadCommandSuccess(t *testing.T) {
{
name: "input-file",
args: []string{"--input", "testdata/load-command-success.input.txt"},
imageLoadFunc: func(input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error) {
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
imageLoadFunc: func(input io.Reader, options ...client.ImageLoadOption) (client.LoadResponse, error) {
return client.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
},
},
{
name: "with-single-platform",
args: []string{"--platform", "linux/amd64"},
imageLoadFunc: func(input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error) {
imageLoadFunc: func(input io.Reader, options ...client.ImageLoadOption) (client.LoadResponse, error) {
// FIXME(thaJeztah): need to find appropriate way to test the result of "ImageHistoryWithPlatform" being applied
assert.Check(t, len(options) > 0) // can be 1 or two depending on whether a terminal is attached :/
// assert.Check(t, is.Contains(options, client.ImageHistoryWithPlatform(ocispec.Platform{OS: "linux", Architecture: "amd64"})))
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
return client.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
},
},
{
name: "with-comma-separated-platforms",
args: []string{"--platform", "linux/amd64,linux/arm64/v8,linux/riscv64"},
imageLoadFunc: func(input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error) {
imageLoadFunc: func(input io.Reader, options ...client.ImageLoadOption) (client.LoadResponse, error) {
assert.Check(t, len(options) > 0) // can be 1 or two depending on whether a terminal is attached :/
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
return client.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
},
},
{
name: "with-multiple-platform-options",
args: []string{"--platform", "linux/amd64", "--platform", "linux/arm64/v8", "--platform", "linux/riscv64"},
imageLoadFunc: func(input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error) {
imageLoadFunc: func(input io.Reader, options ...client.ImageLoadOption) (client.LoadResponse, error) {
assert.Check(t, len(options) > 0) // can be 1 or two depending on whether a terminal is attached :/
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
return client.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
},
},
}

View File

@ -11,10 +11,6 @@
"Architecture": "",
"Os": "",
"Size": 0,
"GraphDriver": {
"Data": null,
"Name": ""
},
"RootFS": {},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
@ -32,10 +28,6 @@
"Architecture": "",
"Os": "",
"Size": 0,
"GraphDriver": {
"Data": null,
"Name": ""
},
"RootFS": {},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"

View File

@ -11,10 +11,6 @@
"Architecture": "",
"Os": "",
"Size": 0,
"GraphDriver": {
"Data": null,
"Name": ""
},
"RootFS": {},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"

View File

@ -44,7 +44,7 @@ func (c *fakeClient) NetworkList(ctx context.Context, options client.NetworkList
if c.networkListFunc != nil {
return c.networkListFunc(ctx, options)
}
return []network.Inspect{}, nil
return []network.Summary{}, nil
}
func (c *fakeClient) NetworkRemove(ctx context.Context, networkID string) error {

View File

@ -28,39 +28,39 @@ func TestNetworkContext(t *testing.T) {
call func() string
}{
{networkContext{
n: network.Summary{ID: networkID},
n: network.Summary{Network: network.Network{ID: networkID}},
trunc: false,
}, networkID, ctx.ID},
{networkContext{
n: network.Summary{ID: networkID},
n: network.Summary{Network: network.Network{ID: networkID}},
trunc: true,
}, formatter.TruncateID(networkID), ctx.ID},
{networkContext{
n: network.Summary{Name: "network_name"},
n: network.Summary{Network: network.Network{Name: "network_name"}},
}, "network_name", ctx.Name},
{networkContext{
n: network.Summary{Driver: "driver_name"},
n: network.Summary{Network: network.Network{Driver: "driver_name"}},
}, "driver_name", ctx.Driver},
{networkContext{
n: network.Summary{EnableIPv4: true},
n: network.Summary{Network: network.Network{EnableIPv4: true}},
}, "true", ctx.IPv4},
{networkContext{
n: network.Summary{EnableIPv6: true},
n: network.Summary{Network: network.Network{EnableIPv6: true}},
}, "true", ctx.IPv6},
{networkContext{
n: network.Summary{EnableIPv6: false},
n: network.Summary{Network: network.Network{EnableIPv6: false}},
}, "false", ctx.IPv6},
{networkContext{
n: network.Summary{Internal: true},
n: network.Summary{Network: network.Network{Internal: true}},
}, "true", ctx.Internal},
{networkContext{
n: network.Summary{Internal: false},
n: network.Summary{Network: network.Network{Internal: false}},
}, "false", ctx.Internal},
{networkContext{
n: network.Summary{},
}, "", ctx.Labels},
{networkContext{
n: network.Summary{Labels: map[string]string{"label1": "value1", "label2": "value2"}},
n: network.Summary{Network: network.Network{Labels: map[string]string{"label1": "value1", "label2": "value2"}}},
}, "label1=value1,label2=value2", ctx.Labels},
}
@ -158,8 +158,24 @@ foobar_bar 2017-01-01 00:00:00 +0000 UTC
timestamp2, _ := time.Parse("2006-01-02", "2017-01-01")
networks := []network.Summary{
{ID: "networkID1", Name: "foobar_baz", Driver: "foo", Scope: "local", Created: timestamp1},
{ID: "networkID2", Name: "foobar_bar", Driver: "bar", Scope: "local", Created: timestamp2},
{
Network: network.Network{
ID: "networkID1",
Name: "foobar_baz",
Driver: "foo",
Scope: "local",
Created: timestamp1,
},
},
{
Network: network.Network{
ID: "networkID2",
Name: "foobar_bar",
Driver: "bar",
Scope: "local",
Created: timestamp2,
},
},
}
for _, tc := range cases {
@ -178,8 +194,18 @@ foobar_bar 2017-01-01 00:00:00 +0000 UTC
func TestNetworkContextWriteJSON(t *testing.T) {
networks := []network.Summary{
{ID: "networkID1", Name: "foobar_baz"},
{ID: "networkID2", Name: "foobar_bar"},
{
Network: network.Network{
ID: "networkID1",
Name: "foobar_baz",
},
},
{
Network: network.Network{
ID: "networkID2",
Name: "foobar_bar",
},
},
}
expectedJSONs := []map[string]any{
{"Driver": "", "ID": "networkID1", "IPv4": "false", "IPv6": "false", "Internal": "false", "Labels": "", "Name": "foobar_baz", "Scope": "", "CreatedAt": "0001-01-01 00:00:00 +0000 UTC"},
@ -202,8 +228,18 @@ func TestNetworkContextWriteJSON(t *testing.T) {
func TestNetworkContextWriteJSONField(t *testing.T) {
networks := []network.Summary{
{ID: "networkID1", Name: "foobar_baz"},
{ID: "networkID2", Name: "foobar_bar"},
{
Network: network.Network{
ID: "networkID1",
Name: "foobar_baz",
},
},
{
Network: network.Network{
ID: "networkID2",
Name: "foobar_bar",
},
},
}
out := bytes.NewBufferString("")
err := formatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, networks)

View File

@ -113,9 +113,11 @@ func TestNetworkRemovePromptTermination(t *testing.T) {
},
networkInspectFunc: func(ctx context.Context, networkID string, options client.NetworkInspectOptions) (network.Inspect, []byte, error) {
return network.Inspect{
ID: "existing-network",
Name: "existing-network",
Ingress: true,
Network: network.Network{
ID: "existing-network",
Name: "existing-network",
Ingress: true,
},
}, nil, nil
},
})

View File

@ -136,9 +136,11 @@ func formatServiceInspect(t *testing.T, format formatter.Format, now time.Time)
return s, nil, nil
},
func(ref string) (any, []byte, error) {
return network.Inspect{
ID: "5vpyomhb6ievnk0i0o60gcnei",
Name: "mynetwork",
return network.Summary{
Network: network.Network{
ID: "5vpyomhb6ievnk0i0o60gcnei",
Name: "mynetwork",
},
}, nil, nil
},
)

View File

@ -16,7 +16,6 @@ import (
"github.com/docker/cli/cli/command/idresolver"
"github.com/docker/cli/internal/logdetails"
"github.com/moby/moby/api/pkg/stdcopy"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client"
"github.com/pkg/errors"
@ -87,7 +86,7 @@ func runLogs(ctx context.Context, dockerCli command.Cli, opts *logsOptions) erro
tty bool
// logfunc is used to delay the call to logs so that we can do some
// processing before we actually get the logs
logfunc func(context.Context, string, container.LogsOptions) (io.ReadCloser, error)
logfunc func(context.Context, string, client.ContainerLogsOptions) (io.ReadCloser, error)
)
service, _, err := apiClient.ServiceInspectWithRaw(ctx, opts.target, client.ServiceInspectOptions{})
@ -131,7 +130,7 @@ func runLogs(ctx context.Context, dockerCli command.Cli, opts *logsOptions) erro
}
// now get the logs
responseBody, err = logfunc(ctx, opts.target, container.LogsOptions{
responseBody, err = logfunc(ctx, opts.target, client.ContainerLogsOptions{
ShowStdout: true,
ShowStderr: true,
Since: opts.since,

View File

@ -186,9 +186,24 @@ func TestResourceOptionsToResourceRequirements(t *testing.T) {
func TestToServiceNetwork(t *testing.T) {
nws := []network.Inspect{
{Name: "aaa-network", ID: "id555"},
{Name: "mmm-network", ID: "id999"},
{Name: "zzz-network", ID: "id111"},
{
Network: network.Network{
Name: "aaa-network",
ID: "id555",
},
},
{
Network: network.Network{
Name: "mmm-network",
ID: "id999",
},
},
{
Network: network.Network{
Name: "zzz-network",
ID: "id111",
},
},
}
apiClient := &fakeClient{

View File

@ -847,16 +847,31 @@ func TestRemoveGenericResources(t *testing.T) {
func TestUpdateNetworks(t *testing.T) {
ctx := context.Background()
nws := []network.Summary{
{Name: "aaa-network", ID: "id555"},
{Name: "mmm-network", ID: "id999"},
{Name: "zzz-network", ID: "id111"},
{
Network: network.Network{
Name: "aaa-network",
ID: "id555",
},
},
{
Network: network.Network{
Name: "mmm-network",
ID: "id999",
},
},
{
Network: network.Network{
Name: "zzz-network",
ID: "id111",
},
},
}
apiClient := &fakeClient{
networkInspectFunc: func(ctx context.Context, networkID string, options client.NetworkInspectOptions) (network.Inspect, error) {
for _, nw := range nws {
if nw.ID == networkID || nw.Name == networkID {
return nw, nil
return network.Inspect{Network: nw.Network}, nil
}
}
return network.Inspect{}, fmt.Errorf("network not found: %s", networkID)

View File

@ -46,7 +46,7 @@ type fakeClient struct {
func (*fakeClient) ServerVersion(context.Context) (types.Version, error) {
return types.Version{
Version: "docker-dev",
APIVersion: client.DefaultAPIVersion,
APIVersion: client.MaxAPIVersion,
}, nil
}
@ -201,8 +201,10 @@ func serviceFromName(name string) swarm.Service {
func networkFromName(name string) network.Summary {
return network.Summary{
ID: "ID-" + name,
Name: name,
Network: network.Network{
ID: "ID-" + name,
Name: name,
},
}
}

View File

@ -46,7 +46,7 @@ type fakeClient struct {
func (*fakeClient) ServerVersion(context.Context) (types.Version, error) {
return types.Version{
Version: "docker-dev",
APIVersion: client.DefaultAPIVersion,
APIVersion: client.MaxAPIVersion,
}, nil
}
@ -190,8 +190,10 @@ func serviceFromName(name string) swarm.Service {
func networkFromName(name string) network.Summary {
return network.Summary{
ID: "ID-" + name,
Name: name,
Network: network.Network{
ID: "ID-" + name,
Name: name,
},
}
}

View File

@ -44,8 +44,12 @@ func TestValidateExternalNetworks(t *testing.T) {
expectedMsg: "is not in the right scope",
},
{
network: "user",
inspectResponse: networktypes.Inspect{Scope: "swarm"},
network: "user",
inspectResponse: networktypes.Inspect{
Network: networktypes.Network{
Scope: "swarm",
},
},
},
}

View File

@ -19,7 +19,7 @@ type fakeClient struct {
client.Client
version string
containerListFunc func(context.Context, container.ListOptions) ([]container.Summary, error)
containerListFunc func(context.Context, client.ContainerListOptions) ([]container.Summary, error)
containerPruneFunc func(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error)
eventsFn func(context.Context, client.EventsListOptions) (<-chan events.Message, <-chan error)
imageListFunc func(ctx context.Context, options client.ImageListOptions) ([]image.Summary, error)
@ -35,7 +35,7 @@ func (cli *fakeClient) ClientVersion() string {
return cli.version
}
func (cli *fakeClient) ContainerList(ctx context.Context, options container.ListOptions) ([]container.Summary, error) {
func (cli *fakeClient) ContainerList(ctx context.Context, options client.ContainerListOptions) ([]container.Summary, error) {
if cli.containerListFunc != nil {
return cli.containerListFunc(ctx, options)
}

View File

@ -27,7 +27,7 @@ func TestCompleteEventFilter(t *testing.T) {
}{
{
client: &fakeClient{
containerListFunc: func(_ context.Context, _ container.ListOptions) ([]container.Summary, error) {
containerListFunc: func(_ context.Context, _ client.ContainerListOptions) ([]container.Summary, error) {
return []container.Summary{
*builders.Container("c1"),
*builders.Container("c2"),
@ -39,7 +39,7 @@ func TestCompleteEventFilter(t *testing.T) {
},
{
client: &fakeClient{
containerListFunc: func(_ context.Context, _ container.ListOptions) ([]container.Summary, error) {
containerListFunc: func(_ context.Context, _ client.ContainerListOptions) ([]container.Summary, error) {
return nil, errors.New("API error")
},
},

View File

@ -24,6 +24,7 @@ import (
"github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/api/types/system"
"github.com/moby/moby/client"
"github.com/moby/moby/client/pkg/security"
"github.com/spf13/cobra"
)
@ -306,7 +307,7 @@ func prettyPrintServerInfo(streams command.Streams, info *dockerInfo) []error {
fprintln(output, " runc version:", info.RuncCommit.ID)
fprintln(output, " init version:", info.InitCommit.ID)
if len(info.SecurityOptions) != 0 {
if kvs, err := system.DecodeSecurityOptions(info.SecurityOptions); err != nil {
if kvs, err := security.DecodeOptions(info.SecurityOptions); err != nil {
errs = append(errs, err)
} else {
fprintln(output, " Security Options:")

View File

@ -1 +1 @@
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Using metacopy","false"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"IndexConfigs":{"docker.io":{"Mirrors":null,"Name":"docker.io","Official":true,"Secure":true}},"InsecureRegistryCIDRs":["127.0.0.0/8"],"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa"},"SecurityOptions":["foo="],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"FirewallBackend":{"Driver":"nftables+firewalld","Info":[["ReloadedAt","2025-07-16T16:59:14Z"]]},"CDISpecDirs":["/etc/cdi","/var/run/cdi"],"Warnings":null,"ServerErrors":["a server error occurred"],"ClientInfo":{"Debug":false,"Context":"","Plugins":[],"Warnings":null}}
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Using metacopy","false"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa"},"SecurityOptions":["foo="],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"FirewallBackend":{"Driver":"nftables+firewalld","Info":[["ReloadedAt","2025-07-16T16:59:14Z"]]},"CDISpecDirs":["/etc/cdi","/var/run/cdi"],"Warnings":null,"ServerErrors":["a server error occurred"],"ClientInfo":{"Debug":false,"Context":"","Plugins":[],"Warnings":null}}

View File

@ -1 +1 @@
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Using metacopy","false"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"IndexConfigs":{"docker.io":{"Mirrors":null,"Name":"docker.io","Official":true,"Secure":true}},"InsecureRegistryCIDRs":["127.0.0.0/8"],"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"FirewallBackend":{"Driver":"nftables+firewalld","Info":[["ReloadedAt","2025-07-16T16:59:14Z"]]},"CDISpecDirs":["/etc/cdi","/var/run/cdi"],"Warnings":["WARNING: No memory limit support","WARNING: No swap limit support","WARNING: No oom kill disable support","WARNING: No cpu cfs quota support","WARNING: No cpu cfs period support","WARNING: No cpu shares support","WARNING: No cpuset support","WARNING: IPv4 forwarding is disabled"],"ClientInfo":{"Debug":true,"Platform":{"Name":"Docker Engine - Community"},"Version":"24.0.0","Context":"default","Plugins":[],"Warnings":null}}
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Using metacopy","false"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"FirewallBackend":{"Driver":"nftables+firewalld","Info":[["ReloadedAt","2025-07-16T16:59:14Z"]]},"CDISpecDirs":["/etc/cdi","/var/run/cdi"],"Warnings":["WARNING: No memory limit support","WARNING: No swap limit support","WARNING: No oom kill disable support","WARNING: No cpu cfs quota support","WARNING: No cpu cfs period support","WARNING: No cpu shares support","WARNING: No cpuset support","WARNING: IPv4 forwarding is disabled"],"ClientInfo":{"Debug":true,"Platform":{"Name":"Docker Engine - Community"},"Version":"24.0.0","Context":"default","Plugins":[],"Warnings":null}}

View File

@ -1 +1 @@
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Using metacopy","false"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"IndexConfigs":{"docker.io":{"Mirrors":null,"Name":"docker.io","Official":true,"Secure":true}},"InsecureRegistryCIDRs":["127.0.0.0/8"],"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"FirewallBackend":{"Driver":"nftables+firewalld","Info":[["ReloadedAt","2025-07-16T16:59:14Z"]]},"CDISpecDirs":["/etc/cdi","/var/run/cdi"],"Warnings":null,"ClientInfo":{"Debug":true,"Platform":{"Name":"Docker Engine - Community"},"Version":"24.0.0","Context":"default","Plugins":[],"Warnings":null}}
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Using metacopy","false"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"FirewallBackend":{"Driver":"nftables+firewalld","Info":[["ReloadedAt","2025-07-16T16:59:14Z"]]},"CDISpecDirs":["/etc/cdi","/var/run/cdi"],"Warnings":null,"ClientInfo":{"Debug":true,"Platform":{"Name":"Docker Engine - Community"},"Version":"24.0.0","Context":"default","Plugins":[],"Warnings":null}}

View File

@ -1 +1 @@
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Using metacopy","false"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"IndexConfigs":{"docker.io":{"Mirrors":null,"Name":"docker.io","Official":true,"Secure":true}},"InsecureRegistryCIDRs":["127.0.0.0/8"],"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"FirewallBackend":{"Driver":"nftables+firewalld","Info":[["ReloadedAt","2025-07-16T16:59:14Z"]]},"CDISpecDirs":["/etc/cdi","/var/run/cdi"],"Warnings":null,"ClientInfo":{"Debug":false,"Context":"default","Plugins":[{"SchemaVersion":"0.1.0","Vendor":"ACME Corp","Version":"0.1.0","ShortDescription":"unit test is good","Name":"goodplugin","Path":"/path/to/docker-goodplugin"},{"SchemaVersion":"0.1.0","Vendor":"ACME Corp","ShortDescription":"this plugin has no version","Name":"unversionedplugin","Path":"/path/to/docker-unversionedplugin"},{"Name":"badplugin","Path":"/path/to/docker-badplugin","Err":"something wrong"}],"Warnings":null}}
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Using metacopy","false"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"FirewallBackend":{"Driver":"nftables+firewalld","Info":[["ReloadedAt","2025-07-16T16:59:14Z"]]},"CDISpecDirs":["/etc/cdi","/var/run/cdi"],"Warnings":null,"ClientInfo":{"Debug":false,"Context":"default","Plugins":[{"SchemaVersion":"0.1.0","Vendor":"ACME Corp","Version":"0.1.0","ShortDescription":"unit test is good","Name":"goodplugin","Path":"/path/to/docker-goodplugin"},{"SchemaVersion":"0.1.0","Vendor":"ACME Corp","ShortDescription":"this plugin has no version","Name":"unversionedplugin","Path":"/path/to/docker-unversionedplugin"},{"Name":"badplugin","Path":"/path/to/docker-badplugin","Err":"something wrong"}],"Warnings":null}}

View File

@ -1 +1 @@
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Using metacopy","false"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"IndexConfigs":{"docker.io":{"Mirrors":null,"Name":"docker.io","Official":true,"Secure":true}},"InsecureRegistryCIDRs":["127.0.0.0/8"],"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"FirewallBackend":{"Driver":"nftables+firewalld","Info":[["ReloadedAt","2025-07-16T16:59:14Z"]]},"CDISpecDirs":["/etc/cdi","/var/run/cdi"],"DiscoveredDevices":[{"Source":"cdi","ID":"com.example.device1"},{"Source":"cdi","ID":"nvidia.com/gpu=gpu0"}],"Warnings":null}
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Using metacopy","false"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"FirewallBackend":{"Driver":"nftables+firewalld","Info":[["ReloadedAt","2025-07-16T16:59:14Z"]]},"CDISpecDirs":["/etc/cdi","/var/run/cdi"],"DiscoveredDevices":[{"Source":"cdi","ID":"com.example.device1"},{"Source":"cdi","ID":"nvidia.com/gpu=gpu0"}],"Warnings":null}

View File

@ -1 +1 @@
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Using metacopy","false"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"IndexConfigs":{"docker.io":{"Mirrors":null,"Name":"docker.io","Official":true,"Secure":true}},"InsecureRegistryCIDRs":["127.0.0.0/8"],"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"qo2dfdig9mmxqkawulggepdih","NodeAddr":"165.227.107.89","LocalNodeState":"active","ControlAvailable":true,"Error":"","RemoteManagers":[{"NodeID":"qo2dfdig9mmxqkawulggepdih","Addr":"165.227.107.89:2377"}],"Nodes":1,"Managers":1,"Cluster":{"ID":"9vs5ygs0gguyyec4iqf2314c0","Version":{"Index":11},"CreatedAt":"2017-08-24T17:34:19.278062352Z","UpdatedAt":"2017-08-24T17:34:42.398815481Z","Spec":{"Name":"default","Labels":null,"Orchestration":{"TaskHistoryRetentionLimit":5},"Raft":{"SnapshotInterval":10000,"KeepOldSnapshots":0,"LogEntriesForSlowFollowers":500,"ElectionTick":3,"HeartbeatTick":1},"Dispatcher":{"HeartbeatPeriod":5000000000},"CAConfig":{"NodeCertExpiry":7776000000000000},"TaskDefaults":{},"EncryptionConfig":{"AutoLockManagers":true}},"TLSInfo":{"TrustRoot":"\n-----BEGIN CERTIFICATE-----\nMIIBajCCARCgAwIBAgIUaFCW5xsq8eyiJ+Pmcv3MCflMLnMwCgYIKoZIzj0EAwIw\nEzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMTcwODI0MTcyOTAwWhcNMzcwODE5MTcy\nOTAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABDy7NebyUJyUjWJDBUdnZoV6GBxEGKO4TZPNDwnxDxJcUdLVaB7WGa4/DLrW\nUfsVgh1JGik2VTiLuTMA1tLlNPOjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB\nAf8EBTADAQH/MB0GA1UdDgQWBBQl16XFtaaXiUAwEuJptJlDjfKskDAKBggqhkjO\nPQQDAgNIADBFAiEAo9fTQNM5DP9bHVcTJYfl2Cay1bFu1E+lnpmN+EYJfeACIGKH\n1pCUkZ+D0IB6CiEZGWSHyLuXPM1rlP+I5KuS7sB8\n-----END CERTIFICATE-----\n","CertIssuerSubject":"MBMxETAPBgNVBAMTCHN3YXJtLWNh","CertIssuerPublicKey":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPLs15vJQnJSNYkMFR2dmhXoYHEQYo7hNk80PCfEPElxR0tVoHtYZrj8MutZR+xWCHUkaKTZVOIu5MwDW0uU08w=="},"RootRotationInProgress":false,"DefaultAddrPool":null,"SubnetSize":0,"DataPathPort":0}},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"FirewallBackend":{"Driver":"nftables+firewalld","Info":[["ReloadedAt","2025-07-16T16:59:14Z"]]},"CDISpecDirs":["/etc/cdi","/var/run/cdi"],"Warnings":null,"ClientInfo":{"Debug":false,"Context":"default","Plugins":[],"Warnings":null}}
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Using metacopy","false"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"qo2dfdig9mmxqkawulggepdih","NodeAddr":"165.227.107.89","LocalNodeState":"active","ControlAvailable":true,"Error":"","RemoteManagers":[{"NodeID":"qo2dfdig9mmxqkawulggepdih","Addr":"165.227.107.89:2377"}],"Nodes":1,"Managers":1,"Cluster":{"ID":"9vs5ygs0gguyyec4iqf2314c0","Version":{"Index":11},"CreatedAt":"2017-08-24T17:34:19.278062352Z","UpdatedAt":"2017-08-24T17:34:42.398815481Z","Spec":{"Name":"default","Labels":null,"Orchestration":{"TaskHistoryRetentionLimit":5},"Raft":{"SnapshotInterval":10000,"KeepOldSnapshots":0,"LogEntriesForSlowFollowers":500,"ElectionTick":3,"HeartbeatTick":1},"Dispatcher":{"HeartbeatPeriod":5000000000},"CAConfig":{"NodeCertExpiry":7776000000000000},"TaskDefaults":{},"EncryptionConfig":{"AutoLockManagers":true}},"TLSInfo":{"TrustRoot":"\n-----BEGIN CERTIFICATE-----\nMIIBajCCARCgAwIBAgIUaFCW5xsq8eyiJ+Pmcv3MCflMLnMwCgYIKoZIzj0EAwIw\nEzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMTcwODI0MTcyOTAwWhcNMzcwODE5MTcy\nOTAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABDy7NebyUJyUjWJDBUdnZoV6GBxEGKO4TZPNDwnxDxJcUdLVaB7WGa4/DLrW\nUfsVgh1JGik2VTiLuTMA1tLlNPOjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB\nAf8EBTADAQH/MB0GA1UdDgQWBBQl16XFtaaXiUAwEuJptJlDjfKskDAKBggqhkjO\nPQQDAgNIADBFAiEAo9fTQNM5DP9bHVcTJYfl2Cay1bFu1E+lnpmN+EYJfeACIGKH\n1pCUkZ+D0IB6CiEZGWSHyLuXPM1rlP+I5KuS7sB8\n-----END CERTIFICATE-----\n","CertIssuerSubject":"MBMxETAPBgNVBAMTCHN3YXJtLWNh","CertIssuerPublicKey":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPLs15vJQnJSNYkMFR2dmhXoYHEQYo7hNk80PCfEPElxR0tVoHtYZrj8MutZR+xWCHUkaKTZVOIu5MwDW0uU08w=="},"RootRotationInProgress":false,"DefaultAddrPool":null,"SubnetSize":0,"DataPathPort":0}},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"FirewallBackend":{"Driver":"nftables+firewalld","Info":[["ReloadedAt","2025-07-16T16:59:14Z"]]},"CDISpecDirs":["/etc/cdi","/var/run/cdi"],"Warnings":null,"ClientInfo":{"Debug":false,"Context":"default","Plugins":[],"Warnings":null}}

View File

@ -91,7 +91,7 @@ type clientVersion struct {
func newClientVersion(contextName string, dockerCli command.Cli) clientVersion {
v := clientVersion{
Version: version.Version,
DefaultAPIVersion: client.DefaultAPIVersion,
DefaultAPIVersion: client.MaxAPIVersion,
GoVersion: runtime.Version(),
GitCommit: version.GitCommit,
BuildTime: reformatDate(version.BuildTime),

View File

@ -105,7 +105,7 @@ func (c *FakeCli) Client() client.APIClient {
// CurrentVersion returns the API version used by FakeCli.
func (*FakeCli) CurrentVersion() string {
return client.DefaultAPIVersion
return client.MaxAPIVersion
}
// Out returns the output stream (stdout) the cli should write on

View File

@ -28,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 v1.52.0-alpha.1.0.20250827142737-8ac1bfa6c554 // master
github.com/moby/moby/client v0.1.0-alpha.0.0.20250827142737-8ac1bfa6c554 // master
github.com/moby/moby/api v1.52.0-beta.1
github.com/moby/moby/client v0.1.0-beta.0
github.com/moby/patternmatcher v0.6.0
github.com/moby/swarmkit/v2 v2.0.0
github.com/moby/sys/atomicwriter v0.1.0

View File

@ -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 v1.52.0-alpha.1.0.20250827142737-8ac1bfa6c554 h1:N6U77C4Lro2uqDeBGP4Zz3UIHjaQst8E45P9vOeUY7E=
github.com/moby/moby/api v1.52.0-alpha.1.0.20250827142737-8ac1bfa6c554/go.mod h1:8sBV0soUREiudtow4vqJGOxa4GyHI5vLQmvgKdHq5Ok=
github.com/moby/moby/client v0.1.0-alpha.0.0.20250827142737-8ac1bfa6c554 h1:8Vd0p/2rVqjnyQxUbcaox9uVhbgxr9axxfSWdpq1KXc=
github.com/moby/moby/client v0.1.0-alpha.0.0.20250827142737-8ac1bfa6c554/go.mod h1:7pOYrEHdG7I0dNZEC+yqk/p8ZOxGMR1KgoexzCEDe0w=
github.com/moby/moby/api v1.52.0-beta.1 h1:r5U4U72E7xSHh4zX72ndY1mA/FOGiAPiGiz2a8rBW+w=
github.com/moby/moby/api v1.52.0-beta.1/go.mod h1:8sBV0soUREiudtow4vqJGOxa4GyHI5vLQmvgKdHq5Ok=
github.com/moby/moby/client v0.1.0-beta.0 h1:eXzrwi0YkzLvezOBKHafvAWNmH1B9HFh4n13yb2QgFE=
github.com/moby/moby/client v0.1.0-beta.0/go.mod h1:irAv8jRi4yKKBeND96Y+3AM9ers+KaJYk9Vmcm7loxs=
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=

View File

@ -1,12 +1,5 @@
package build
import (
"io"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/registry"
)
// BuilderVersion sets the version of underlying builder to use
type BuilderVersion string
@ -21,71 +14,3 @@ const (
type Result struct {
ID string
}
// ImageBuildOptions holds the information
// necessary to build images.
type ImageBuildOptions struct {
Tags []string
SuppressOutput bool
RemoteContext string
NoCache bool
Remove bool
ForceRemove bool
PullParent bool
Isolation container.Isolation
CPUSetCPUs string
CPUSetMems string
CPUShares int64
CPUQuota int64
CPUPeriod int64
Memory int64
MemorySwap int64
CgroupParent string
NetworkMode string
ShmSize int64
Dockerfile string
Ulimits []*container.Ulimit
// BuildArgs needs to be a *string instead of just a string so that
// we can tell the difference between "" (empty string) and no value
// at all (nil). See the parsing of buildArgs in
// api/server/router/build/build_routes.go for even more info.
BuildArgs map[string]*string
AuthConfigs map[string]registry.AuthConfig
Context io.Reader
Labels map[string]string
// squash the resulting image's layers to the parent
// preserves the original image and creates a new one from the parent with all
// the changes applied to a single layer
Squash bool
// CacheFrom specifies images that are used for matching cache. Images
// specified here do not need to have a valid parent chain to match cache.
CacheFrom []string
SecurityOpt []string
ExtraHosts []string // List of extra hosts
Target string
SessionID string
Platform string
// Version specifies the version of the underlying builder to use
Version BuilderVersion
// BuildID is an optional identifier that can be passed together with the
// build request. The same identifier can be used to gracefully cancel the
// build with the cancel request.
BuildID string
// Outputs defines configurations for exporting build results. Only supported
// in BuildKit mode
Outputs []ImageBuildOutput
}
// ImageBuildOutput defines configuration for exporting a build result
type ImageBuildOutput struct {
Type string
Attrs map[string]string
}
// ImageBuildResponse holds information
// returned by a server after building
// an image.
type ImageBuildResponse struct {
Body io.ReadCloser
OSType string
}

View File

@ -2,8 +2,6 @@ package build
import (
"time"
"github.com/moby/moby/api/types/filters"
)
// CacheRecord contains information about a build cache record.
@ -33,17 +31,6 @@ type CacheRecord struct {
UsageCount int
}
// CachePruneOptions hold parameters to prune the build cache.
type CachePruneOptions struct {
All bool
ReservedSpace int64
MaxUsedSpace int64
MinFreeSpace int64
Filters filters.Args
KeepStorage int64 // Deprecated: deprecated in API 1.48.
}
// CachePruneReport contains the response for Engine API:
// POST "/build/prune"
type CachePruneReport struct {

View File

@ -0,0 +1,8 @@
package checkpoint
// CreateRequest holds parameters to create a checkpoint from a container.
type CreateRequest struct {
CheckpointID string
CheckpointDir string
Exit bool
}

View File

@ -1,19 +0,0 @@
package checkpoint
// CreateOptions holds parameters to create a checkpoint from a container.
type CreateOptions struct {
CheckpointID string
CheckpointDir string
Exit bool
}
// ListOptions holds parameters to list checkpoints for a container.
type ListOptions struct {
CheckpointDir string
}
// DeleteOptions holds parameters to delete a checkpoint from a container.
type DeleteOptions struct {
CheckpointID string
CheckpointDir string
}

View File

@ -12,24 +12,6 @@ import (
// Docker interprets it as 3 nanoseconds.
const MinimumDuration = 1 * time.Millisecond
// StopOptions holds the options to stop or restart a container.
type StopOptions struct {
// Signal (optional) is the signal to send to the container to (gracefully)
// stop it before forcibly terminating the container with SIGKILL after the
// timeout expires. If not value is set, the default (SIGTERM) is used.
Signal string `json:",omitempty"`
// Timeout (optional) is the timeout (in seconds) to wait for the container
// to stop gracefully before forcibly terminating it with SIGKILL.
//
// - Use nil to use the default timeout (10 seconds).
// - Use '-1' to wait indefinitely.
// - Use '0' to not wait for the container to exit gracefully, and
// immediately proceeds to forcibly terminating the container.
// - Other positive values are used as timeout (in seconds).
Timeout *int `json:",omitempty"`
}
// HealthConfig holds configuration settings for the HEALTHCHECK feature.
type HealthConfig = dockerspec.HealthcheckConfig

View File

@ -27,13 +27,6 @@ type PathStat struct {
LinkTarget string `json:"linkTarget"`
}
// CopyToContainerOptions holds information
// about files to copy into a container
type CopyToContainerOptions struct {
AllowOverwriteDirWithFile bool
CopyUIDGID bool
}
// MountPoint represents a mount point configuration inside the container.
// This is used for reporting the mountpoints in use by a container.
type MountPoint struct {

View File

@ -12,8 +12,11 @@ type NetworkSettings struct {
}
// NetworkSettingsBase holds networking state for a container when inspecting it.
//
// Deprecated: Most fields in NetworkSettingsBase are deprecated. Fields which aren't deprecated will move to
// NetworkSettings in v29.0, and this struct will be removed.
type NetworkSettingsBase struct {
Bridge string // Bridge contains the name of the default bridge interface iff it was set through the daemon --bridge flag.
Bridge string // Deprecated: This field is only set when the daemon is started with the --bridge flag specified.
SandboxID string // SandboxID uniquely represents a container's network stack
SandboxKey string // SandboxKey identifies the sandbox
Ports PortMap // Ports is a collection of PortBinding indexed by Port
@ -34,18 +37,44 @@ type NetworkSettingsBase struct {
SecondaryIPv6Addresses []network.Address // Deprecated: This field is never set and will be removed in a future release.
}
// DefaultNetworkSettings holds network information
// during the 2 release deprecation period.
// It will be removed in Docker 1.11.
// DefaultNetworkSettings holds the networking state for the default bridge, if the container is connected to that
// network.
//
// Deprecated: this struct is deprecated since Docker v1.11 and will be removed in v29. You should look for the default
// network in NetworkSettings.Networks instead.
type DefaultNetworkSettings struct {
EndpointID string // EndpointID uniquely represents a service endpoint in a Sandbox
Gateway string // Gateway holds the gateway address for the network
GlobalIPv6Address string // GlobalIPv6Address holds network's global IPv6 address
GlobalIPv6PrefixLen int // GlobalIPv6PrefixLen represents mask length of network's global IPv6 address
IPAddress string // IPAddress holds the IPv4 address for the network
IPPrefixLen int // IPPrefixLen represents mask length of network's IPv4 address
IPv6Gateway string // IPv6Gateway holds gateway address specific for IPv6
MacAddress string // MacAddress holds the MAC address for the network
// EndpointID uniquely represents a service endpoint in a Sandbox
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
EndpointID string
// Gateway holds the gateway address for the network
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
Gateway string
// GlobalIPv6Address holds network's global IPv6 address
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
GlobalIPv6Address string
// GlobalIPv6PrefixLen represents mask length of network's global IPv6 address
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
GlobalIPv6PrefixLen int
// IPAddress holds the IPv4 address for the network
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
IPAddress string
// IPPrefixLen represents mask length of network's IPv4 address
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
IPPrefixLen int
// IPv6Gateway holds gateway address specific for IPv6
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
IPv6Gateway string
// MacAddress holds the MAC address for the network
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
MacAddress string
}
// NetworkSettingsSummary provides a summary of container's networks

View File

@ -1,59 +0,0 @@
package container
import "github.com/moby/moby/api/types/filters"
// AttachOptions holds parameters to attach to a container.
type AttachOptions struct {
Stream bool
Stdin bool
Stdout bool
Stderr bool
DetachKeys string
Logs bool
}
// CommitOptions holds parameters to commit changes into a container.
type CommitOptions struct {
Reference string
Comment string
Author string
Changes []string
Pause bool
Config *Config
}
// RemoveOptions holds parameters to remove containers.
type RemoveOptions struct {
RemoveVolumes bool
RemoveLinks bool
Force bool
}
// StartOptions holds parameters to start containers.
type StartOptions struct {
CheckpointID string
CheckpointDir string
}
// ListOptions holds parameters to list containers with.
type ListOptions struct {
Size bool
All bool
Latest bool
Since string
Before string
Limit int
Filters filters.Args
}
// LogsOptions holds parameters to filter logs with.
type LogsOptions struct {
ShowStdout bool
ShowStderr bool
Since string
Until string
Timestamps bool
Follow bool
Tail string
Details bool
}

View File

@ -1,7 +1,6 @@
package image
import (
"io"
"time"
)
@ -17,31 +16,3 @@ type PruneReport struct {
ImagesDeleted []DeleteResponse
SpaceReclaimed uint64
}
// LoadResponse returns information to the client about a load process.
//
// TODO(thaJeztah): remove this type, and just use an io.ReadCloser
//
// This type was added in https://github.com/moby/moby/pull/18878, related
// to https://github.com/moby/moby/issues/19177;
//
// Make docker load to output json when the response content type is json
// Swarm hijacks the response from docker load and returns JSON rather
// than plain text like the Engine does. This makes the API library to return
// information to figure that out.
//
// However the "load" endpoint unconditionally returns JSON;
// https://github.com/moby/moby/blob/7b9d2ef6e5518a3d3f3cc418459f8df786cfbbd1/api/server/router/image/image_routes.go#L248-L255
//
// PR https://github.com/moby/moby/pull/21959 made the response-type depend
// on whether "quiet" was set, but this logic got changed in a follow-up
// https://github.com/moby/moby/pull/25557, which made the JSON response-type
// unconditionally, but the output produced depend on whether"quiet" was set.
//
// We should deprecated the "quiet" option, as it's really a client
// responsibility.
type LoadResponse struct {
// Body must be closed to avoid a resource leak
Body io.ReadCloser
JSON bool
}

View File

@ -111,7 +111,7 @@ type InspectResponse struct {
// GraphDriver holds information about the storage driver used to store the
// container's and image's filesystem.
GraphDriver storage.DriverData
GraphDriver *storage.DriverData `json:"GraphDriver,omitempty"`
// RootFS contains information about the image's RootFS, including the
// layer IDs.

View File

@ -0,0 +1,20 @@
// Code generated by go-swagger; DO NOT EDIT.
package network
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// ConfigReference The config-only network source to provide the configuration for
// this network.
//
// swagger:model ConfigReference
type ConfigReference struct {
// The name of the config-only network that provides the network's
// configuration. The specified network must be an existing config-only
// network. Only network names are allowed, not network IDs.
//
// Example: config_only_network_01
Network string `json:"Network"`
}

View File

@ -0,0 +1,31 @@
// Code generated by go-swagger; DO NOT EDIT.
package network
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// EndpointResource contains network resources allocated and used for a container in a network.
//
// swagger:model EndpointResource
type EndpointResource struct {
// name
// Example: container_1
Name string `json:"Name"`
// endpoint ID
// Example: 628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a
EndpointID string `json:"EndpointID"`
// mac address
// Example: 02:42:ac:13:00:02
MacAddress string `json:"MacAddress"`
// IPv4 address
// Example: 172.19.0.2/16
IPv4Address string `json:"IPv4Address"`
// IPv6 address
IPv6Address string `json:"IPv6Address"`
}

View File

@ -0,0 +1,23 @@
// Code generated by go-swagger; DO NOT EDIT.
package network
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// Inspect The body of the "get network" http response message.
//
// swagger:model Inspect
type Inspect struct {
Network
// Contains endpoints attached to the network.
//
// Example: {"19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c":{"EndpointID":"628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a","IPv4Address":"172.19.0.2/16","IPv6Address":"","MacAddress":"02:42:ac:13:00:02","Name":"test"}}
Containers map[string]EndpointResource `json:"Containers"`
// List of services using the network. This field is only present for
// swarm scope networks, and omitted for local scope networks.
//
Services map[string]ServiceInfo `json:"Services,omitempty"`
}

View File

@ -1,138 +1,100 @@
// Code generated by go-swagger; DO NOT EDIT.
package network
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"time"
"github.com/moby/moby/api/types/filters"
timeext "time"
)
const (
// NetworkDefault is a platform-independent alias to choose the platform-specific default network stack.
NetworkDefault = "default"
// NetworkHost is the name of the predefined network used when the NetworkMode host is selected (only available on Linux)
NetworkHost = "host"
// NetworkNone is the name of the predefined network used when the NetworkMode none is selected (available on both Linux and Windows)
NetworkNone = "none"
// NetworkBridge is the name of the default network on Linux
NetworkBridge = "bridge"
// NetworkNat is the name of the default network on Windows
NetworkNat = "nat"
)
// Network network
//
// swagger:model Network
type Network struct {
// CreateRequest is the request message sent to the server for network create call.
type CreateRequest struct {
Name string // Name is the requested name of the network.
Driver string // Driver is the driver-name used to create the network (e.g. `bridge`, `overlay`)
Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level).
EnableIPv4 *bool `json:",omitempty"` // EnableIPv4 represents whether to enable IPv4.
EnableIPv6 *bool `json:",omitempty"` // EnableIPv6 represents whether to enable IPv6.
IPAM *IPAM // IPAM is the network's IP Address Management.
Internal bool // Internal represents if the network is used internal only.
Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
Ingress bool // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
ConfigOnly bool // ConfigOnly creates a config-only network. Config-only networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
ConfigFrom *ConfigReference // ConfigFrom specifies the source which will provide the configuration for this network. The specified network must be a config-only network; see [CreateOptions.ConfigOnly].
Options map[string]string // Options specifies the network-specific options to use for when creating the network.
Labels map[string]string // Labels holds metadata specific to the network being created.
// Name of the network.
//
// Example: my_network
Name string `json:"Name"`
// Deprecated: CheckDuplicate is deprecated since API v1.44, but it defaults to true when sent by the client
// package to older daemons.
CheckDuplicate *bool `json:",omitempty"`
}
// Inspect is the body of the "get network" http response message.
type Inspect struct {
Name string // Name is the name of the network
ID string `json:"Id"` // ID uniquely identifies a network on a single machine
Created time.Time // Created is the time the network created
Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level)
Driver string // Driver is the Driver name used to create the network (e.g. `bridge`, `overlay`)
EnableIPv4 bool // EnableIPv4 represents whether IPv4 is enabled
EnableIPv6 bool // EnableIPv6 represents whether IPv6 is enabled
IPAM IPAM // IPAM is the network's IP Address Management
Internal bool // Internal represents if the network is used internal only
Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
Ingress bool // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
ConfigFrom ConfigReference // ConfigFrom specifies the source which will provide the configuration for this network.
ConfigOnly bool // ConfigOnly networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
Containers map[string]EndpointResource // Containers contains endpoints belonging to the network
Options map[string]string // Options holds the network specific options to use for when creating the network
Labels map[string]string // Labels holds metadata specific to the network being created
Peers []PeerInfo `json:",omitempty"` // List of peer nodes for an overlay network
Services map[string]ServiceInfo `json:",omitempty"`
}
// Summary is used as response when listing networks. It currently is an alias
// for [Inspect], but may diverge in the future, as not all information may
// be included when listing networks.
type Summary = Inspect
// Address represents an IP address
type Address struct {
Addr string
PrefixLen int
}
// PeerInfo represents one peer of an overlay network
type PeerInfo struct {
Name string
IP string
}
// Task carries the information about one backend task
type Task struct {
Name string
EndpointID string
EndpointIP string
Info map[string]string
}
// ServiceInfo represents service parameters with the list of service's tasks
type ServiceInfo struct {
VIP string
Ports []string
LocalLBIndex int
Tasks []Task
}
// EndpointResource contains network resources allocated and used for a
// container in a network.
type EndpointResource struct {
Name string
EndpointID string
MacAddress string
IPv4Address string
IPv6Address string
}
// NetworkingConfig represents the container's networking configuration for each of its interfaces
// Carries the networking configs specified in the `docker run` and `docker network connect` commands
type NetworkingConfig struct {
EndpointsConfig map[string]*EndpointSettings // Endpoint configs for each connecting network
}
// ConfigReference specifies the source which provides a network's configuration
type ConfigReference struct {
Network string
}
var acceptedFilters = map[string]bool{
"dangling": true,
"driver": true,
"id": true,
"label": true,
"name": true,
"scope": true,
"type": true,
}
// ValidateFilters validates the list of filter args with the available filters.
func ValidateFilters(filter filters.Args) error {
return filter.Validate(acceptedFilters)
}
// PruneReport contains the response for Engine API:
// POST "/networks/prune"
type PruneReport struct {
NetworksDeleted []string
// ID that uniquely identifies a network on a single machine.
//
// Example: 7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99
ID string `json:"Id"`
// Date and time at which the network was created in
// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
//
// Example: 2016-10-19T04:33:30.360899459Z
Created timeext.Time `json:"Created"`
// The level at which the network exists (e.g. `swarm` for cluster-wide
// or `local` for machine level)
//
// Example: local
Scope string `json:"Scope"`
// The name of the driver used to create the network (e.g. `bridge`,
// `overlay`).
//
// Example: overlay
Driver string `json:"Driver"`
// Whether the network was created with IPv4 enabled.
//
// Example: true
EnableIPv4 bool `json:"EnableIPv4"`
// Whether the network was created with IPv6 enabled.
//
// Example: false
EnableIPv6 bool `json:"EnableIPv6"`
// The network's IP Address Management.
//
IPAM IPAM `json:"IPAM"`
// Whether the network is created to only allow internal networking
// connectivity.
//
// Example: false
Internal bool `json:"Internal"`
// Whether a global / swarm scope network is manually attachable by regular
// containers from workers in swarm mode.
//
// Example: false
Attachable bool `json:"Attachable"`
// Whether the network is providing the routing-mesh for the swarm cluster.
//
// Example: false
Ingress bool `json:"Ingress"`
// config from
ConfigFrom ConfigReference `json:"ConfigFrom"`
// Whether the network is a config-only network. Config-only networks are
// placeholder networks for network configurations to be used by other
// networks. Config-only networks cannot be used directly to run containers
// or services.
//
ConfigOnly bool `json:"ConfigOnly"`
// Network-specific options uses when creating the network.
//
// Example: {"com.docker.network.bridge.default_bridge":"true","com.docker.network.bridge.enable_icc":"true","com.docker.network.bridge.enable_ip_masquerade":"true","com.docker.network.bridge.host_binding_ipv4":"0.0.0.0","com.docker.network.bridge.name":"docker0","com.docker.network.driver.mtu":"1500"}
Options map[string]string `json:"Options"`
// Metadata specific to the network being created.
//
// Example: {"com.example.some-label":"some-value","com.example.some-other-label":"some-other-value"}
Labels map[string]string `json:"Labels"`
// List of peer nodes for an overlay network. This field is only present
// for overlay networks, and omitted for other network types.
//
Peers []PeerInfo `json:"Peers,omitempty"`
}

View File

@ -0,0 +1,61 @@
package network
const (
// NetworkDefault is a platform-independent alias to choose the platform-specific default network stack.
NetworkDefault = "default"
// NetworkHost is the name of the predefined network used when the NetworkMode host is selected (only available on Linux)
NetworkHost = "host"
// NetworkNone is the name of the predefined network used when the NetworkMode none is selected (available on both Linux and Windows)
NetworkNone = "none"
// NetworkBridge is the name of the default network on Linux
NetworkBridge = "bridge"
// NetworkNat is the name of the default network on Windows
NetworkNat = "nat"
)
// CreateRequest is the request message sent to the server for network create call.
type CreateRequest struct {
Name string // Name is the requested name of the network.
Driver string // Driver is the driver-name used to create the network (e.g. `bridge`, `overlay`)
Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level).
EnableIPv4 *bool `json:",omitempty"` // EnableIPv4 represents whether to enable IPv4.
EnableIPv6 *bool `json:",omitempty"` // EnableIPv6 represents whether to enable IPv6.
IPAM *IPAM // IPAM is the network's IP Address Management.
Internal bool // Internal represents if the network is used internal only.
Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
Ingress bool // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
ConfigOnly bool // ConfigOnly creates a config-only network. Config-only networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
ConfigFrom *ConfigReference // ConfigFrom specifies the source which will provide the configuration for this network. The specified network must be a config-only network; see [CreateOptions.ConfigOnly].
Options map[string]string // Options specifies the network-specific options to use for when creating the network.
Labels map[string]string // Labels holds metadata specific to the network being created.
// Deprecated: CheckDuplicate is deprecated since API v1.44, but it defaults to true when sent by the client
// package to older daemons.
CheckDuplicate *bool `json:",omitempty"`
}
// Address represents an IP address
type Address struct {
Addr string
PrefixLen int
}
// ServiceInfo represents service parameters with the list of service's tasks
type ServiceInfo struct {
VIP string
Ports []string
LocalLBIndex int
Tasks []Task
}
// NetworkingConfig represents the container's networking configuration for each of its interfaces
// Carries the networking configs specified in the `docker run` and `docker network connect` commands
type NetworkingConfig struct {
EndpointsConfig map[string]*EndpointSettings // Endpoint configs for each connecting network
}
// PruneReport contains the response for Engine API:
// POST "/networks/prune"
type PruneReport struct {
NetworksDeleted []string
}

View File

@ -0,0 +1,20 @@
// Code generated by go-swagger; DO NOT EDIT.
package network
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// PeerInfo represents one peer of an overlay network.
//
// swagger:model PeerInfo
type PeerInfo struct {
// ID of the peer-node in the Swarm cluster.
// Example: 6869d7c1732b
Name string `json:"Name"`
// IP-address of the peer-node in the Swarm cluster.
// Example: 10.133.77.91
IP string `json:"IP"`
}

View File

@ -0,0 +1,13 @@
// Code generated by go-swagger; DO NOT EDIT.
package network
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// Summary Network list response item
//
// swagger:model Summary
type Summary struct {
Network
}

24
vendor/github.com/moby/moby/api/types/network/task.go generated vendored Normal file
View File

@ -0,0 +1,24 @@
// Code generated by go-swagger; DO NOT EDIT.
package network
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// Task carries the information about one backend task
//
// swagger:model Task
type Task struct {
// name
Name string `json:"Name"`
// endpoint ID
EndpointID string `json:"EndpointID"`
// endpoint IP
EndpointIP string `json:"EndpointIP"`
// info
Info map[string]string `json:"Info"`
}

View File

@ -17,23 +17,6 @@ type ServiceConfig struct {
ExtraFields map[string]any `json:"-"`
}
// MarshalJSON implements a custom marshaler to include legacy fields
// in API responses.
func (sc *ServiceConfig) MarshalJSON() ([]byte, error) {
type tmp ServiceConfig
base, err := json.Marshal((*tmp)(sc))
if err != nil {
return nil, err
}
var merged map[string]any
_ = json.Unmarshal(base, &merged)
for k, v := range sc.ExtraFields {
merged[k] = v
}
return json.Marshal(merged)
}
// NetIPNet is the net.IPNet type, which can be marshalled and
// unmarshalled to JSON
type NetIPNet net.IPNet

View File

@ -19,7 +19,6 @@ import (
"context"
"fmt"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
)
@ -30,7 +29,7 @@ func main() {
}
defer apiClient.Close()
containers, err := apiClient.ContainerList(context.Background(), container.ListOptions{All: true})
containers, err := apiClient.ContainerList(context.Background(), client.ContainerListOptions{All: true})
if err != nil {
panic(err)
}

View File

@ -9,10 +9,20 @@ import (
"github.com/moby/moby/api/types/build"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/versions"
)
// BuildCachePruneOptions hold parameters to prune the build cache.
type BuildCachePruneOptions struct {
All bool
ReservedSpace int64
MaxUsedSpace int64
MinFreeSpace int64
Filters filters.Args
}
// BuildCachePrune requests the daemon to delete unused cache data.
func (cli *Client) BuildCachePrune(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error) {
func (cli *Client) BuildCachePrune(ctx context.Context, opts BuildCachePruneOptions) (*build.CachePruneReport, error) {
if err := cli.NewVersionError(ctx, "1.31", "build prune"); err != nil {
return nil, err
}
@ -22,11 +32,14 @@ func (cli *Client) BuildCachePrune(ctx context.Context, opts build.CachePruneOpt
query.Set("all", "1")
}
if opts.KeepStorage != 0 {
query.Set("keep-storage", strconv.Itoa(int(opts.KeepStorage)))
}
if opts.ReservedSpace != 0 {
query.Set("reserved-space", strconv.Itoa(int(opts.ReservedSpace)))
// Prior to API v1.48, 'keep-storage' was used to set the reserved space for the build cache.
// TODO(austinvazquez): remove once API v1.47 is no longer supported. See https://github.com/moby/moby/issues/50902
if versions.LessThanOrEqualTo(cli.version, "1.47") {
query.Set("keep-storage", strconv.Itoa(int(opts.ReservedSpace)))
} else {
query.Set("reserved-space", strconv.Itoa(int(opts.ReservedSpace)))
}
}
if opts.MaxUsedSpace != 0 {
query.Set("max-used-space", strconv.Itoa(int(opts.MaxUsedSpace)))

View File

@ -12,7 +12,7 @@ import (
// and only available if the daemon is running with experimental features
// enabled.
type CheckpointAPIClient interface {
CheckpointCreate(ctx context.Context, container string, options checkpoint.CreateOptions) error
CheckpointDelete(ctx context.Context, container string, options checkpoint.DeleteOptions) error
CheckpointList(ctx context.Context, container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error)
CheckpointCreate(ctx context.Context, container string, options CheckpointCreateOptions) error
CheckpointDelete(ctx context.Context, container string, options CheckpointDeleteOptions) error
CheckpointList(ctx context.Context, container string, options CheckpointListOptions) ([]checkpoint.Summary, error)
}

View File

@ -6,14 +6,26 @@ import (
"github.com/moby/moby/api/types/checkpoint"
)
// CheckpointCreateOptions holds parameters to create a checkpoint from a container.
type CheckpointCreateOptions struct {
CheckpointID string
CheckpointDir string
Exit bool
}
// CheckpointCreate creates a checkpoint from the given container.
func (cli *Client) CheckpointCreate(ctx context.Context, containerID string, options checkpoint.CreateOptions) error {
func (cli *Client) CheckpointCreate(ctx context.Context, containerID string, options CheckpointCreateOptions) error {
containerID, err := trimID("container", containerID)
if err != nil {
return err
}
requestBody := checkpoint.CreateRequest{
CheckpointID: options.CheckpointID,
CheckpointDir: options.CheckpointDir,
Exit: options.Exit,
}
resp, err := cli.post(ctx, "/containers/"+containerID+"/checkpoints", nil, options, nil)
resp, err := cli.post(ctx, "/containers/"+containerID+"/checkpoints", nil, requestBody, nil)
defer ensureReaderClosed(resp)
return err
}

View File

@ -3,12 +3,16 @@ package client
import (
"context"
"net/url"
"github.com/moby/moby/api/types/checkpoint"
)
// CheckpointDeleteOptions holds parameters to delete a checkpoint from a container.
type CheckpointDeleteOptions struct {
CheckpointID string
CheckpointDir string
}
// 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 {
func (cli *Client) CheckpointDelete(ctx context.Context, containerID string, options CheckpointDeleteOptions) error {
containerID, err := trimID("container", containerID)
if err != nil {
return err

View File

@ -8,8 +8,13 @@ import (
"github.com/moby/moby/api/types/checkpoint"
)
// CheckpointListOptions holds parameters to list checkpoints for a container.
type CheckpointListOptions struct {
CheckpointDir string
}
// 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) {
func (cli *Client) CheckpointList(ctx context.Context, container string, options CheckpointListOptions) ([]checkpoint.Summary, error) {
var checkpoints []checkpoint.Summary
query := url.Values{}

View File

@ -19,7 +19,6 @@ For example, to list running containers (the equivalent of "docker ps"):
"context"
"fmt"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
)
@ -29,7 +28,7 @@ For example, to list running containers (the equivalent of "docker ps"):
panic(err)
}
containers, err := cli.ContainerList(context.Background(), container.ListOptions{})
containers, err := cli.ContainerList(context.Background(), client.ContainerListOptions{})
if err != nil {
panic(err)
}
@ -91,15 +90,14 @@ import (
// [Go stdlib]: https://github.com/golang/go/blob/6244b1946bc2101b01955468f1be502dbadd6807/src/net/http/transport.go#L558-L569
const DummyHost = "api.moby.localhost"
// DefaultAPIVersion is the highest REST API version supported by the client.
// MaxAPIVersion is the highest REST API version supported by the client.
// If API-version negotiation is enabled (see [WithAPIVersionNegotiation],
// [Client.NegotiateAPIVersion]), the client may downgrade its API version.
// Similarly, the [WithVersion] and [WithVersionFromEnv] allow overriding
// the version.
//
// This version may be lower than the [api.DefaultVersion], which is the default
// (and highest supported) version of the api library module used.
const DefaultAPIVersion = "1.52"
// This version may be lower than the version of the api library module used.
const MaxAPIVersion = "1.52"
// fallbackAPIVersion is the version to fallback to if API-version negotiation
// fails. This version is the highest version of the API before API-version
@ -114,35 +112,7 @@ var _ APIClient = &Client{}
// Client is the API client that performs all operations
// against a docker server.
type Client struct {
// scheme sets the scheme for the client
scheme string
// host holds the server address to connect to
host string
// proto holds the client protocol i.e. unix.
proto string
// addr holds the client address.
addr string
// basePath holds the path to prepend to the requests.
basePath string
// client used to send and receive http requests.
client *http.Client
// version of the server to talk to.
version string
// userAgent is the User-Agent header to use for HTTP requests. It takes
// precedence over User-Agent headers set in customHTTPHeaders, and other
// header variables. When set to an empty string, the User-Agent header
// is removed, and no header is sent.
userAgent *string
// custom HTTP headers configured by users.
customHTTPHeaders map[string]string
// manualOverride is set to true when the version was set by users.
manualOverride bool
// negotiateVersion indicates if the client should automatically negotiate
// the API version to use when making requests. API version negotiation is
// performed on the first request, after which negotiated is set to "true"
// so that subsequent requests do not re-negotiate.
negotiateVersion bool
clientConfig
// negotiated indicates that API version negotiation took place
negotiated atomic.Bool
@ -150,8 +120,6 @@ type Client struct {
// negotiateLock is used to single-flight the version negotiation process
negotiateLock sync.Mutex
traceOpts []otelhttp.Option
// When the client transport is an *http.Transport (default) we need to do some extra things (like closing idle connections).
// Store the original transport as the http.Client transport will be wrapped with tracing libs.
baseTransport *http.Transport
@ -207,21 +175,23 @@ func NewClientWithOpts(ops ...Opt) (*Client, error) {
return nil, err
}
c := &Client{
host: DefaultDockerHost,
version: DefaultAPIVersion,
client: client,
proto: hostURL.Scheme,
addr: hostURL.Host,
traceOpts: []otelhttp.Option{
otelhttp.WithSpanNameFormatter(func(_ string, req *http.Request) string {
return req.Method + " " + req.URL.Path
}),
clientConfig: clientConfig{
host: DefaultDockerHost,
version: MaxAPIVersion,
client: client,
proto: hostURL.Scheme,
addr: hostURL.Host,
traceOpts: []otelhttp.Option{
otelhttp.WithSpanNameFormatter(func(_ string, req *http.Request) string {
return req.Method + " " + req.URL.Path
}),
},
},
}
cfg := &c.clientConfig
for _, op := range ops {
if err := op(c); err != nil {
if err := op(cfg); err != nil {
return nil, err
}
}
@ -391,7 +361,7 @@ func (cli *Client) negotiateAPIVersionPing(pingResponse types.Ping) {
// if the client is not initialized with a version, start with the latest supported version
if cli.version == "" {
cli.version = DefaultAPIVersion
cli.version = MaxAPIVersion
}
// if server version is lower than the client version, downgrade
@ -484,3 +454,11 @@ func (cli *Client) dialer() func(context.Context) (net.Conn, error) {
}
}
}
// transportFunc allows us to inject a mock transport for testing. We define it
// here so we can detect the tlsconfig and return nil for only this type.
type transportFunc func(*http.Request) (*http.Response, error)
func (tf transportFunc) RoundTrip(req *http.Request) (*http.Response, error) {
return tf(req)
}

View File

@ -65,8 +65,8 @@ type HijackDialer interface {
// ContainerAPIClient defines API client methods for the containers
type ContainerAPIClient interface {
ContainerAttach(ctx context.Context, container string, options container.AttachOptions) (HijackedResponse, error)
ContainerCommit(ctx context.Context, container string, options container.CommitOptions) (container.CommitResponse, error)
ContainerAttach(ctx context.Context, container string, options ContainerAttachOptions) (HijackedResponse, error)
ContainerCommit(ctx context.Context, container string, options ContainerCommitOptions) (container.CommitResponse, error)
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error)
ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error)
ContainerExecAttach(ctx context.Context, execID string, options container.ExecAttachOptions) (HijackedResponse, error)
@ -78,24 +78,24 @@ type ContainerAPIClient interface {
ContainerInspect(ctx context.Context, container string) (container.InspectResponse, error)
ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (container.InspectResponse, []byte, error)
ContainerKill(ctx context.Context, container, signal string) error
ContainerList(ctx context.Context, options container.ListOptions) ([]container.Summary, error)
ContainerLogs(ctx context.Context, container string, options container.LogsOptions) (io.ReadCloser, error)
ContainerList(ctx context.Context, options ContainerListOptions) ([]container.Summary, error)
ContainerLogs(ctx context.Context, container string, options ContainerLogsOptions) (io.ReadCloser, error)
ContainerPause(ctx context.Context, container string) error
ContainerRemove(ctx context.Context, container string, options container.RemoveOptions) error
ContainerRemove(ctx context.Context, container string, options ContainerRemoveOptions) error
ContainerRename(ctx context.Context, container, newContainerName string) error
ContainerResize(ctx context.Context, container string, options ContainerResizeOptions) error
ContainerRestart(ctx context.Context, container string, options container.StopOptions) error
ContainerRestart(ctx context.Context, container string, options ContainerStopOptions) error
ContainerStatPath(ctx context.Context, container, path string) (container.PathStat, error)
ContainerStats(ctx context.Context, container string, stream bool) (StatsResponseReader, error)
ContainerStatsOneShot(ctx context.Context, container string) (StatsResponseReader, error)
ContainerStart(ctx context.Context, container string, options container.StartOptions) error
ContainerStop(ctx context.Context, container string, options container.StopOptions) error
ContainerStart(ctx context.Context, container string, options ContainerStartOptions) error
ContainerStop(ctx context.Context, container string, options ContainerStopOptions) error
ContainerTop(ctx context.Context, container string, arguments []string) (container.TopResponse, error)
ContainerUnpause(ctx context.Context, container string) error
ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) (container.UpdateResponse, error)
ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error)
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error)
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options container.CopyToContainerOptions) error
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options CopyToContainerOptions) error
ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error)
}
@ -106,8 +106,8 @@ type DistributionAPIClient interface {
// ImageAPIClient defines API client methods for the images
type ImageAPIClient interface {
ImageBuild(ctx context.Context, context io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error)
BuildCachePrune(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error)
ImageBuild(ctx context.Context, context io.Reader, options ImageBuildOptions) (ImageBuildResponse, error)
BuildCachePrune(ctx context.Context, opts BuildCachePruneOptions) (*build.CachePruneReport, error)
BuildCancel(ctx context.Context, id string) error
ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (io.ReadCloser, error)
ImageImport(ctx context.Context, source ImageImportSource, ref string, options ImageImportOptions) (io.ReadCloser, error)
@ -122,7 +122,7 @@ type ImageAPIClient interface {
ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (image.InspectResponse, error)
ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) ([]image.HistoryResponseItem, error)
ImageLoad(ctx context.Context, input io.Reader, _ ...ImageLoadOption) (image.LoadResponse, error)
ImageLoad(ctx context.Context, input io.Reader, _ ...ImageLoadOption) (LoadResponse, error)
ImageSave(ctx context.Context, images []string, _ ...ImageSaveOption) (io.ReadCloser, error)
}
@ -167,8 +167,8 @@ type ServiceAPIClient interface {
ServiceList(ctx context.Context, options ServiceListOptions) ([]swarm.Service, error)
ServiceRemove(ctx context.Context, serviceID string) error
ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
ServiceLogs(ctx context.Context, serviceID string, options container.LogsOptions) (io.ReadCloser, error)
TaskLogs(ctx context.Context, taskID string, options container.LogsOptions) (io.ReadCloser, error)
ServiceLogs(ctx context.Context, serviceID string, options ContainerLogsOptions) (io.ReadCloser, error)
TaskLogs(ctx context.Context, taskID string, options ContainerLogsOptions) (io.ReadCloser, error)
TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error)
TaskList(ctx context.Context, options TaskListOptions) ([]swarm.Task, error)
}

View File

@ -4,10 +4,18 @@ import (
"context"
"net/http"
"net/url"
"github.com/moby/moby/api/types/container"
)
// ContainerAttachOptions holds parameters to attach to a container.
type ContainerAttachOptions struct {
Stream bool
Stdin bool
Stdout bool
Stderr bool
DetachKeys string
Logs bool
}
// ContainerAttach attaches a connection to a container in the server.
// It returns a [HijackedResponse] with the hijacked connection
// and a reader to get output. It's up to the called to close
@ -36,7 +44,7 @@ import (
// [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) {
func (cli *Client) ContainerAttach(ctx context.Context, containerID string, options ContainerAttachOptions) (HijackedResponse, error) {
containerID, err := trimID("container", containerID)
if err != nil {
return HijackedResponse{}, err

View File

@ -10,8 +10,18 @@ import (
"github.com/moby/moby/api/types/container"
)
// ContainerCommitOptions holds parameters to commit changes into a container.
type ContainerCommitOptions struct {
Reference string
Comment string
Author string
Changes []string
Pause bool
Config *container.Config
}
// ContainerCommit applies changes to a container and creates a new tagged image.
func (cli *Client) ContainerCommit(ctx context.Context, containerID string, options container.CommitOptions) (container.CommitResponse, error) {
func (cli *Client) ContainerCommit(ctx context.Context, containerID string, options ContainerCommitOptions) (container.CommitResponse, error) {
containerID, err := trimID("container", containerID)
if err != nil {
return container.CommitResponse{}, err

View File

@ -32,9 +32,16 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri
return getContainerPathStatFromHeader(resp.Header)
}
// CopyToContainerOptions holds information
// about files to copy into a container
type CopyToContainerOptions struct {
AllowOverwriteDirWithFile bool
CopyUIDGID bool
}
// CopyToContainer copies content into the container filesystem.
// Note that `content` must be a Reader for a TAR archive
func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options container.CopyToContainerOptions) error {
func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options CopyToContainerOptions) error {
containerID, err := trimID("container", containerID)
if err != nil {
return err

View File

@ -11,8 +11,19 @@ import (
"github.com/moby/moby/api/types/versions"
)
// ContainerListOptions holds parameters to list containers with.
type ContainerListOptions struct {
Size bool
All bool
Latest bool
Since string
Before string
Limit int
Filters filters.Args
}
// ContainerList returns the list of containers in the docker host.
func (cli *Client) ContainerList(ctx context.Context, options container.ListOptions) ([]container.Summary, error) {
func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptions) ([]container.Summary, error) {
query := url.Values{}
if options.All {

View File

@ -7,10 +7,21 @@ import (
"net/url"
"time"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client/internal/timestamp"
)
// ContainerLogsOptions holds parameters to filter logs with.
type ContainerLogsOptions struct {
ShowStdout bool
ShowStderr bool
Since string
Until string
Timestamps bool
Follow bool
Tail string
Details bool
}
// ContainerLogs returns the logs generated by a container in an [io.ReadCloser].
// It's up to the caller to close the stream.
//
@ -37,7 +48,7 @@ import (
// [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) {
func (cli *Client) ContainerLogs(ctx context.Context, containerID string, options ContainerLogsOptions) (io.ReadCloser, error) {
containerID, err := trimID("container", containerID)
if err != nil {
return nil, err

View File

@ -3,12 +3,17 @@ package client
import (
"context"
"net/url"
"github.com/moby/moby/api/types/container"
)
// ContainerRemoveOptions holds parameters to remove containers.
type ContainerRemoveOptions struct {
RemoveVolumes bool
RemoveLinks bool
Force bool
}
// ContainerRemove kills and removes a container from the docker host.
func (cli *Client) ContainerRemove(ctx context.Context, containerID string, options container.RemoveOptions) error {
func (cli *Client) ContainerRemove(ctx context.Context, containerID string, options ContainerRemoveOptions) error {
containerID, err := trimID("container", containerID)
if err != nil {
return err

View File

@ -5,14 +5,13 @@ import (
"net/url"
"strconv"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/versions"
)
// 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 {
func (cli *Client) ContainerRestart(ctx context.Context, containerID string, options ContainerStopOptions) error {
containerID, err := trimID("container", containerID)
if err != nil {
return err

Some files were not shown because too many files have changed in this diff Show More