Merge pull request #5134 from thaJeztah/bump_engine

vendor: github.com/docker/docker a736d0701c41 (master, v27.0.0-dev)
This commit is contained in:
Paweł Gronowski 2024-06-10 18:03:45 +02:00 committed by GitHub
commit cba002eb5e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
53 changed files with 904 additions and 575 deletions

View File

@ -17,8 +17,8 @@ import (
type fakeClient struct { type fakeClient struct {
client.Client client.Client
inspectFunc func(string) (types.ContainerJSON, error) inspectFunc func(string) (types.ContainerJSON, error)
execInspectFunc func(execID string) (types.ContainerExecInspect, error) execInspectFunc func(execID string) (container.ExecInspect, error)
execCreateFunc func(containerID string, config types.ExecConfig) (types.IDResponse, error) execCreateFunc func(containerID string, options container.ExecOptions) (types.IDResponse, error)
createContainerFunc func(config *container.Config, createContainerFunc func(config *container.Config,
hostConfig *container.HostConfig, hostConfig *container.HostConfig,
networkingConfig *network.NetworkingConfig, networkingConfig *network.NetworkingConfig,
@ -27,8 +27,8 @@ type fakeClient struct {
containerStartFunc func(containerID string, options container.StartOptions) error containerStartFunc func(containerID string, options container.StartOptions) error
imageCreateFunc func(parentReference string, options image.CreateOptions) (io.ReadCloser, error) imageCreateFunc func(parentReference string, options image.CreateOptions) (io.ReadCloser, error)
infoFunc func() (system.Info, error) infoFunc func() (system.Info, error)
containerStatPathFunc func(containerID, path string) (types.ContainerPathStat, error) containerStatPathFunc func(containerID, path string) (container.PathStat, error)
containerCopyFromFunc func(containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) containerCopyFromFunc func(containerID, srcPath string) (io.ReadCloser, container.PathStat, error)
logFunc func(string, container.LogsOptions) (io.ReadCloser, error) logFunc func(string, container.LogsOptions) (io.ReadCloser, error)
waitFunc func(string) (<-chan container.WaitResponse, <-chan error) waitFunc func(string) (<-chan container.WaitResponse, <-chan error)
containerListFunc func(container.ListOptions) ([]types.Container, error) containerListFunc func(container.ListOptions) ([]types.Container, error)
@ -36,7 +36,7 @@ type fakeClient struct {
containerExecResizeFunc func(id string, options container.ResizeOptions) error containerExecResizeFunc func(id string, options container.ResizeOptions) error
containerRemoveFunc func(ctx context.Context, containerID string, options container.RemoveOptions) error containerRemoveFunc func(ctx context.Context, containerID string, options container.RemoveOptions) error
containerKillFunc func(ctx context.Context, containerID, signal string) error containerKillFunc func(ctx context.Context, containerID, signal string) error
containerPruneFunc func(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) containerPruneFunc func(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error)
containerAttachFunc func(ctx context.Context, containerID string, options container.AttachOptions) (types.HijackedResponse, error) containerAttachFunc func(ctx context.Context, containerID string, options container.AttachOptions) (types.HijackedResponse, error)
Version string Version string
} }
@ -55,21 +55,21 @@ func (f *fakeClient) ContainerInspect(_ context.Context, containerID string) (ty
return types.ContainerJSON{}, nil return types.ContainerJSON{}, nil
} }
func (f *fakeClient) ContainerExecCreate(_ context.Context, containerID string, config types.ExecConfig) (types.IDResponse, error) { func (f *fakeClient) ContainerExecCreate(_ context.Context, containerID string, config container.ExecOptions) (types.IDResponse, error) {
if f.execCreateFunc != nil { if f.execCreateFunc != nil {
return f.execCreateFunc(containerID, config) return f.execCreateFunc(containerID, config)
} }
return types.IDResponse{}, nil return types.IDResponse{}, nil
} }
func (f *fakeClient) ContainerExecInspect(_ context.Context, execID string) (types.ContainerExecInspect, error) { func (f *fakeClient) ContainerExecInspect(_ context.Context, execID string) (container.ExecInspect, error) {
if f.execInspectFunc != nil { if f.execInspectFunc != nil {
return f.execInspectFunc(execID) return f.execInspectFunc(execID)
} }
return types.ContainerExecInspect{}, nil return container.ExecInspect{}, nil
} }
func (f *fakeClient) ContainerExecStart(context.Context, string, types.ExecStartCheck) error { func (f *fakeClient) ContainerExecStart(context.Context, string, container.ExecStartOptions) error {
return nil return nil
} }
@ -108,18 +108,18 @@ func (f *fakeClient) Info(_ context.Context) (system.Info, error) {
return system.Info{}, nil return system.Info{}, nil
} }
func (f *fakeClient) ContainerStatPath(_ context.Context, containerID, path string) (types.ContainerPathStat, error) { func (f *fakeClient) ContainerStatPath(_ context.Context, containerID, path string) (container.PathStat, error) {
if f.containerStatPathFunc != nil { if f.containerStatPathFunc != nil {
return f.containerStatPathFunc(containerID, path) return f.containerStatPathFunc(containerID, path)
} }
return types.ContainerPathStat{}, nil return container.PathStat{}, nil
} }
func (f *fakeClient) CopyFromContainer(_ context.Context, containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { func (f *fakeClient) CopyFromContainer(_ context.Context, containerID, srcPath string) (io.ReadCloser, container.PathStat, error) {
if f.containerCopyFromFunc != nil { if f.containerCopyFromFunc != nil {
return f.containerCopyFromFunc(containerID, srcPath) return f.containerCopyFromFunc(containerID, srcPath)
} }
return nil, types.ContainerPathStat{}, nil 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 container.LogsOptions) (io.ReadCloser, error) {
@ -168,11 +168,11 @@ func (f *fakeClient) ContainerKill(ctx context.Context, containerID, signal stri
return nil return nil
} }
func (f *fakeClient) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) { func (f *fakeClient) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) {
if f.containerPruneFunc != nil { if f.containerPruneFunc != nil {
return f.containerPruneFunc(ctx, pruneFilters) return f.containerPruneFunc(ctx, pruneFilters)
} }
return types.ContainersPruneReport{}, nil return container.PruneReport{}, nil
} }
func (f *fakeClient) ContainerAttach(ctx context.Context, containerID string, options container.AttachOptions) (types.HijackedResponse, error) { func (f *fakeClient) ContainerAttach(ctx context.Context, containerID string, options container.AttachOptions) (types.HijackedResponse, error) {

View File

@ -15,7 +15,7 @@ import (
"github.com/docker/cli/cli" "github.com/docker/cli/cli"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/streams" "github.com/docker/cli/cli/streams"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/system"
units "github.com/docker/go-units" units "github.com/docker/go-units"
@ -397,7 +397,7 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpCo
} }
} }
options := types.CopyToContainerOptions{ options := container.CopyToContainerOptions{
AllowOverwriteDirWithFile: false, AllowOverwriteDirWithFile: false,
CopyUIDGID: copyConfig.copyUIDGID, CopyUIDGID: copyConfig.copyUIDGID,
} }
@ -433,18 +433,18 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpCo
// so we have to check for a `/` or `.` prefix. Also, in the case of a Windows // so we have to check for a `/` or `.` prefix. Also, in the case of a Windows
// client, a `:` could be part of an absolute Windows path, in which case it // client, a `:` could be part of an absolute Windows path, in which case it
// is immediately proceeded by a backslash. // is immediately proceeded by a backslash.
func splitCpArg(arg string) (container, path string) { func splitCpArg(arg string) (ctr, path string) {
if system.IsAbs(arg) { if system.IsAbs(arg) {
// Explicit local absolute path, e.g., `C:\foo` or `/foo`. // Explicit local absolute path, e.g., `C:\foo` or `/foo`.
return "", arg return "", arg
} }
container, path, ok := strings.Cut(arg, ":") ctr, path, ok := strings.Cut(arg, ":")
if !ok || strings.HasPrefix(container, ".") { if !ok || strings.HasPrefix(ctr, ".") {
// Either there's no `:` in the arg // Either there's no `:` in the arg
// OR it's an explicit local relative path like `./file:name.txt`. // OR it's an explicit local relative path like `./file:name.txt`.
return "", arg return "", arg
} }
return container, path return ctr, path
} }

View File

@ -9,7 +9,7 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/archive"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@ -51,15 +51,16 @@ func TestRunCopyWithInvalidArguments(t *testing.T) {
func TestRunCopyFromContainerToStdout(t *testing.T) { func TestRunCopyFromContainerToStdout(t *testing.T) {
tarContent := "the tar content" tarContent := "the tar content"
fakeClient := &fakeClient{ cli := test.NewFakeCli(&fakeClient{
containerCopyFromFunc: func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { containerCopyFromFunc: func(ctr, srcPath string) (io.ReadCloser, container.PathStat, error) {
assert.Check(t, is.Equal("container", container)) assert.Check(t, is.Equal("container", ctr))
return io.NopCloser(strings.NewReader(tarContent)), types.ContainerPathStat{}, nil return io.NopCloser(strings.NewReader(tarContent)), container.PathStat{}, nil
}, },
} })
options := copyOptions{source: "container:/path", destination: "-"} err := runCopy(context.TODO(), cli, copyOptions{
cli := test.NewFakeCli(fakeClient) source: "container:/path",
err := runCopy(context.TODO(), cli, options) destination: "-",
})
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Equal(tarContent, cli.OutBuffer().String())) assert.Check(t, is.Equal(tarContent, cli.OutBuffer().String()))
assert.Check(t, is.Equal("", cli.ErrBuffer().String())) assert.Check(t, is.Equal("", cli.ErrBuffer().String()))
@ -70,16 +71,18 @@ func TestRunCopyFromContainerToFilesystem(t *testing.T) {
fs.WithFile("file1", "content\n")) fs.WithFile("file1", "content\n"))
defer destDir.Remove() defer destDir.Remove()
fakeClient := &fakeClient{ cli := test.NewFakeCli(&fakeClient{
containerCopyFromFunc: func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { containerCopyFromFunc: func(ctr, srcPath string) (io.ReadCloser, container.PathStat, error) {
assert.Check(t, is.Equal("container", container)) assert.Check(t, is.Equal("container", ctr))
readCloser, err := archive.TarWithOptions(destDir.Path(), &archive.TarOptions{}) readCloser, err := archive.TarWithOptions(destDir.Path(), &archive.TarOptions{})
return readCloser, types.ContainerPathStat{}, err return readCloser, container.PathStat{}, err
}, },
} })
options := copyOptions{source: "container:/path", destination: destDir.Path(), quiet: true} err := runCopy(context.TODO(), cli, copyOptions{
cli := test.NewFakeCli(fakeClient) source: "container:/path",
err := runCopy(context.TODO(), cli, options) destination: destDir.Path(),
quiet: true,
})
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Equal("", cli.OutBuffer().String())) assert.Check(t, is.Equal("", cli.OutBuffer().String()))
assert.Check(t, is.Equal("", cli.ErrBuffer().String())) assert.Check(t, is.Equal("", cli.ErrBuffer().String()))
@ -94,20 +97,17 @@ func TestRunCopyFromContainerToFilesystemMissingDestinationDirectory(t *testing.
fs.WithFile("file1", "content\n")) fs.WithFile("file1", "content\n"))
defer destDir.Remove() defer destDir.Remove()
fakeClient := &fakeClient{ cli := test.NewFakeCli(&fakeClient{
containerCopyFromFunc: func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { containerCopyFromFunc: func(ctr, srcPath string) (io.ReadCloser, container.PathStat, error) {
assert.Check(t, is.Equal("container", container)) assert.Check(t, is.Equal("container", ctr))
readCloser, err := archive.TarWithOptions(destDir.Path(), &archive.TarOptions{}) readCloser, err := archive.TarWithOptions(destDir.Path(), &archive.TarOptions{})
return readCloser, types.ContainerPathStat{}, err return readCloser, container.PathStat{}, err
}, },
} })
err := runCopy(context.TODO(), cli, copyOptions{
options := copyOptions{
source: "container:/path", source: "container:/path",
destination: destDir.Join("missing", "foo"), destination: destDir.Join("missing", "foo"),
} })
cli := test.NewFakeCli(fakeClient)
err := runCopy(context.TODO(), cli, options)
assert.ErrorContains(t, err, destDir.Join("missing")) assert.ErrorContains(t, err, destDir.Join("missing"))
} }
@ -115,12 +115,11 @@ func TestRunCopyToContainerFromFileWithTrailingSlash(t *testing.T) {
srcFile := fs.NewFile(t, t.Name()) srcFile := fs.NewFile(t, t.Name())
defer srcFile.Remove() defer srcFile.Remove()
options := copyOptions{ cli := test.NewFakeCli(&fakeClient{})
err := runCopy(context.TODO(), cli, copyOptions{
source: srcFile.Path() + string(os.PathSeparator), source: srcFile.Path() + string(os.PathSeparator),
destination: "container:/path", destination: "container:/path",
} })
cli := test.NewFakeCli(&fakeClient{})
err := runCopy(context.TODO(), cli, options)
expectedError := "not a directory" expectedError := "not a directory"
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
@ -130,12 +129,11 @@ func TestRunCopyToContainerFromFileWithTrailingSlash(t *testing.T) {
} }
func TestRunCopyToContainerSourceDoesNotExist(t *testing.T) { func TestRunCopyToContainerSourceDoesNotExist(t *testing.T) {
options := copyOptions{ cli := test.NewFakeCli(&fakeClient{})
err := runCopy(context.TODO(), cli, copyOptions{
source: "/does/not/exist", source: "/does/not/exist",
destination: "container:/path", destination: "container:/path",
} })
cli := test.NewFakeCli(&fakeClient{})
err := runCopy(context.TODO(), cli, options)
expected := "no such file or directory" expected := "no such file or directory"
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
expected = "cannot find the file specified" expected = "cannot find the file specified"
@ -184,17 +182,19 @@ func TestSplitCpArg(t *testing.T) {
t.Run(testcase.doc, func(t *testing.T) { t.Run(testcase.doc, func(t *testing.T) {
skip.If(t, testcase.os != "" && testcase.os != runtime.GOOS) skip.If(t, testcase.os != "" && testcase.os != runtime.GOOS)
container, path := splitCpArg(testcase.path) ctr, path := splitCpArg(testcase.path)
assert.Check(t, is.Equal(testcase.expectedContainer, container)) assert.Check(t, is.Equal(testcase.expectedContainer, ctr))
assert.Check(t, is.Equal(testcase.expectedPath, path)) assert.Check(t, is.Equal(testcase.expectedPath, path))
}) })
} }
} }
func TestRunCopyFromContainerToFilesystemIrregularDestination(t *testing.T) { func TestRunCopyFromContainerToFilesystemIrregularDestination(t *testing.T) {
options := copyOptions{source: "container:/dev/null", destination: "/dev/random"}
cli := test.NewFakeCli(nil) cli := test.NewFakeCli(nil)
err := runCopy(context.TODO(), cli, options) err := runCopy(context.TODO(), cli, copyOptions{
source: "container:/dev/null",
destination: "/dev/random",
})
assert.Assert(t, err != nil) assert.Assert(t, err != nil)
expected := `"/dev/random" must be a directory or a regular file` expected := `"/dev/random" must be a directory or a regular file`
assert.ErrorContains(t, err, expected) assert.ErrorContains(t, err, expected)

View File

@ -12,7 +12,8 @@ import (
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/opts" "github.com/docker/cli/opts"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
apiclient "github.com/docker/docker/client" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -43,19 +44,18 @@ func NewExecOptions() ExecOptions {
// NewExecCommand creates a new cobra.Command for `docker exec` // NewExecCommand creates a new cobra.Command for `docker exec`
func NewExecCommand(dockerCli command.Cli) *cobra.Command { func NewExecCommand(dockerCli command.Cli) *cobra.Command {
options := NewExecOptions() options := NewExecOptions()
var container string
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "exec [OPTIONS] CONTAINER COMMAND [ARG...]", Use: "exec [OPTIONS] CONTAINER COMMAND [ARG...]",
Short: "Execute a command in a running container", Short: "Execute a command in a running container",
Args: cli.RequiresMinArgs(2), Args: cli.RequiresMinArgs(2),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
container = args[0] containerIDorName := args[0]
options.Command = args[1:] options.Command = args[1:]
return RunExec(cmd.Context(), dockerCli, container, options) return RunExec(cmd.Context(), dockerCli, containerIDorName, options)
}, },
ValidArgsFunction: completion.ContainerNames(dockerCli, false, func(container types.Container) bool { ValidArgsFunction: completion.ContainerNames(dockerCli, false, func(ctr types.Container) bool {
return container.State != "paused" return ctr.State != "paused"
}), }),
Annotations: map[string]string{ Annotations: map[string]string{
"category-top": "2", "category-top": "2",
@ -79,47 +79,41 @@ func NewExecCommand(dockerCli command.Cli) *cobra.Command {
flags.StringVarP(&options.Workdir, "workdir", "w", "", "Working directory inside the container") flags.StringVarP(&options.Workdir, "workdir", "w", "", "Working directory inside the container")
flags.SetAnnotation("workdir", "version", []string{"1.35"}) flags.SetAnnotation("workdir", "version", []string{"1.35"})
cmd.RegisterFlagCompletionFunc( _ = cmd.RegisterFlagCompletionFunc("env", func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
"env",
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return os.Environ(), cobra.ShellCompDirectiveNoFileComp return os.Environ(), cobra.ShellCompDirectiveNoFileComp
}, })
) _ = cmd.RegisterFlagCompletionFunc("env-file", func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
cmd.RegisterFlagCompletionFunc(
"env-file",
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveDefault // _filedir return nil, cobra.ShellCompDirectiveDefault // _filedir
}, })
)
return cmd return cmd
} }
// RunExec executes an `exec` command // RunExec executes an `exec` command
func RunExec(ctx context.Context, dockerCli command.Cli, container string, options ExecOptions) error { func RunExec(ctx context.Context, dockerCli command.Cli, containerIDorName string, options ExecOptions) error {
execConfig, err := parseExec(options, dockerCli.ConfigFile()) execOptions, err := parseExec(options, dockerCli.ConfigFile())
if err != nil { if err != nil {
return err return err
} }
client := dockerCli.Client() apiClient := dockerCli.Client()
// We need to check the tty _before_ we do the ContainerExecCreate, because // We need to check the tty _before_ we do the ContainerExecCreate, because
// otherwise if we error out we will leak execIDs on the server (and // otherwise if we error out we will leak execIDs on the server (and
// there's no easy way to clean those up). But also in order to make "not // there's no easy way to clean those up). But also in order to make "not
// exist" errors take precedence we do a dummy inspect first. // exist" errors take precedence we do a dummy inspect first.
if _, err := client.ContainerInspect(ctx, container); err != nil { if _, err := apiClient.ContainerInspect(ctx, containerIDorName); err != nil {
return err return err
} }
if !execConfig.Detach { if !execOptions.Detach {
if err := dockerCli.In().CheckTty(execConfig.AttachStdin, execConfig.Tty); err != nil { if err := dockerCli.In().CheckTty(execOptions.AttachStdin, execOptions.Tty); err != nil {
return err return err
} }
} }
fillConsoleSize(execConfig, dockerCli) fillConsoleSize(execOptions, dockerCli)
response, err := client.ContainerExecCreate(ctx, container, *execConfig) response, err := apiClient.ContainerExecCreate(ctx, containerIDorName, *execOptions)
if err != nil { if err != nil {
return err return err
} }
@ -129,52 +123,50 @@ func RunExec(ctx context.Context, dockerCli command.Cli, container string, optio
return errors.New("exec ID empty") return errors.New("exec ID empty")
} }
if execConfig.Detach { if execOptions.Detach {
execStartCheck := types.ExecStartCheck{ return apiClient.ContainerExecStart(ctx, execID, container.ExecStartOptions{
Detach: execConfig.Detach, Detach: execOptions.Detach,
Tty: execConfig.Tty, Tty: execOptions.Tty,
ConsoleSize: execConfig.ConsoleSize, ConsoleSize: execOptions.ConsoleSize,
})
} }
return client.ContainerExecStart(ctx, execID, execStartCheck) return interactiveExec(ctx, dockerCli, execOptions, execID)
}
return interactiveExec(ctx, dockerCli, execConfig, execID)
} }
func fillConsoleSize(execConfig *types.ExecConfig, dockerCli command.Cli) { func fillConsoleSize(execOptions *container.ExecOptions, dockerCli command.Cli) {
if execConfig.Tty { if execOptions.Tty {
height, width := dockerCli.Out().GetTtySize() height, width := dockerCli.Out().GetTtySize()
execConfig.ConsoleSize = &[2]uint{height, width} execOptions.ConsoleSize = &[2]uint{height, width}
} }
} }
func interactiveExec(ctx context.Context, dockerCli command.Cli, execConfig *types.ExecConfig, execID string) error { func interactiveExec(ctx context.Context, dockerCli command.Cli, execOptions *container.ExecOptions, execID string) error {
// Interactive exec requested. // Interactive exec requested.
var ( var (
out, stderr io.Writer out, stderr io.Writer
in io.ReadCloser in io.ReadCloser
) )
if execConfig.AttachStdin { if execOptions.AttachStdin {
in = dockerCli.In() in = dockerCli.In()
} }
if execConfig.AttachStdout { if execOptions.AttachStdout {
out = dockerCli.Out() out = dockerCli.Out()
} }
if execConfig.AttachStderr { if execOptions.AttachStderr {
if execConfig.Tty { if execOptions.Tty {
stderr = dockerCli.Out() stderr = dockerCli.Out()
} else { } else {
stderr = dockerCli.Err() stderr = dockerCli.Err()
} }
} }
fillConsoleSize(execConfig, dockerCli) fillConsoleSize(execOptions, dockerCli)
client := dockerCli.Client() apiClient := dockerCli.Client()
execStartCheck := types.ExecStartCheck{ resp, err := apiClient.ContainerExecAttach(ctx, execID, container.ExecAttachOptions{
Tty: execConfig.Tty, Tty: execOptions.Tty,
ConsoleSize: execConfig.ConsoleSize, ConsoleSize: execOptions.ConsoleSize,
} })
resp, err := client.ContainerExecAttach(ctx, execID, execStartCheck)
if err != nil { if err != nil {
return err return err
} }
@ -191,17 +183,17 @@ func interactiveExec(ctx context.Context, dockerCli command.Cli, execConfig *typ
outputStream: out, outputStream: out,
errorStream: stderr, errorStream: stderr,
resp: resp, resp: resp,
tty: execConfig.Tty, tty: execOptions.Tty,
detachKeys: execConfig.DetachKeys, detachKeys: execOptions.DetachKeys,
} }
return streamer.stream(ctx) return streamer.stream(ctx)
}() }()
}() }()
if execConfig.Tty && dockerCli.In().IsTerminal() { if execOptions.Tty && dockerCli.In().IsTerminal() {
if err := MonitorTtySize(ctx, dockerCli, execID, true); err != nil { if err := MonitorTtySize(ctx, dockerCli, execID, true); err != nil {
fmt.Fprintln(dockerCli.Err(), "Error monitoring TTY size:", err) _, _ = fmt.Fprintln(dockerCli.Err(), "Error monitoring TTY size:", err)
} }
} }
@ -210,14 +202,14 @@ func interactiveExec(ctx context.Context, dockerCli command.Cli, execConfig *typ
return err return err
} }
return getExecExitStatus(ctx, client, execID) return getExecExitStatus(ctx, apiClient, execID)
} }
func getExecExitStatus(ctx context.Context, client apiclient.ContainerAPIClient, execID string) error { func getExecExitStatus(ctx context.Context, apiClient client.ContainerAPIClient, execID string) error {
resp, err := client.ContainerExecInspect(ctx, execID) resp, err := apiClient.ContainerExecInspect(ctx, execID)
if err != nil { if err != nil {
// If we can't connect, then the daemon probably died. // If we can't connect, then the daemon probably died.
if !apiclient.IsErrConnectionFailed(err) { if !client.IsErrConnectionFailed(err) {
return err return err
} }
return cli.StatusError{StatusCode: -1} return cli.StatusError{StatusCode: -1}
@ -231,8 +223,8 @@ func getExecExitStatus(ctx context.Context, client apiclient.ContainerAPIClient,
// parseExec parses the specified args for the specified command and generates // parseExec parses the specified args for the specified command and generates
// an ExecConfig from it. // an ExecConfig from it.
func parseExec(execOpts ExecOptions, configFile *configfile.ConfigFile) (*types.ExecConfig, error) { func parseExec(execOpts ExecOptions, configFile *configfile.ConfigFile) (*container.ExecOptions, error) {
execConfig := &types.ExecConfig{ execOptions := &container.ExecOptions{
User: execOpts.User, User: execOpts.User,
Privileged: execOpts.Privileged, Privileged: execOpts.Privileged,
Tty: execOpts.TTY, Tty: execOpts.TTY,
@ -243,23 +235,23 @@ func parseExec(execOpts ExecOptions, configFile *configfile.ConfigFile) (*types.
// collect all the environment variables for the container // collect all the environment variables for the container
var err error var err error
if execConfig.Env, err = opts.ReadKVEnvStrings(execOpts.EnvFile.GetAll(), execOpts.Env.GetAll()); err != nil { if execOptions.Env, err = opts.ReadKVEnvStrings(execOpts.EnvFile.GetAll(), execOpts.Env.GetAll()); err != nil {
return nil, err return nil, err
} }
// If -d is not set, attach to everything by default // If -d is not set, attach to everything by default
if !execOpts.Detach { if !execOpts.Detach {
execConfig.AttachStdout = true execOptions.AttachStdout = true
execConfig.AttachStderr = true execOptions.AttachStderr = true
if execOpts.Interactive { if execOpts.Interactive {
execConfig.AttachStdin = true execOptions.AttachStdin = true
} }
} }
if execOpts.DetachKeys != "" { if execOpts.DetachKeys != "" {
execConfig.DetachKeys = execOpts.DetachKeys execOptions.DetachKeys = execOpts.DetachKeys
} else { } else {
execConfig.DetachKeys = configFile.DetachKeys execOptions.DetachKeys = configFile.DetachKeys
} }
return execConfig, nil return execOptions, nil
} }

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/cli/opts" "github.com/docker/cli/opts"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@ -37,10 +38,10 @@ TWO=2
testcases := []struct { testcases := []struct {
options ExecOptions options ExecOptions
configFile configfile.ConfigFile configFile configfile.ConfigFile
expected types.ExecConfig expected container.ExecOptions
}{ }{
{ {
expected: types.ExecConfig{ expected: container.ExecOptions{
Cmd: []string{"command"}, Cmd: []string{"command"},
AttachStdout: true, AttachStdout: true,
AttachStderr: true, AttachStderr: true,
@ -48,7 +49,7 @@ TWO=2
options: withDefaultOpts(ExecOptions{}), options: withDefaultOpts(ExecOptions{}),
}, },
{ {
expected: types.ExecConfig{ expected: container.ExecOptions{
Cmd: []string{"command1", "command2"}, Cmd: []string{"command1", "command2"},
AttachStdout: true, AttachStdout: true,
AttachStderr: true, AttachStderr: true,
@ -63,7 +64,7 @@ TWO=2
TTY: true, TTY: true,
User: "uid", User: "uid",
}), }),
expected: types.ExecConfig{ expected: container.ExecOptions{
User: "uid", User: "uid",
AttachStdin: true, AttachStdin: true,
AttachStdout: true, AttachStdout: true,
@ -74,7 +75,7 @@ TWO=2
}, },
{ {
options: withDefaultOpts(ExecOptions{Detach: true}), options: withDefaultOpts(ExecOptions{Detach: true}),
expected: types.ExecConfig{ expected: container.ExecOptions{
Detach: true, Detach: true,
Cmd: []string{"command"}, Cmd: []string{"command"},
}, },
@ -85,7 +86,7 @@ TWO=2
Interactive: true, Interactive: true,
Detach: true, Detach: true,
}), }),
expected: types.ExecConfig{ expected: container.ExecOptions{
Detach: true, Detach: true,
Tty: true, Tty: true,
Cmd: []string{"command"}, Cmd: []string{"command"},
@ -94,7 +95,7 @@ TWO=2
{ {
options: withDefaultOpts(ExecOptions{Detach: true}), options: withDefaultOpts(ExecOptions{Detach: true}),
configFile: configfile.ConfigFile{DetachKeys: "de"}, configFile: configfile.ConfigFile{DetachKeys: "de"},
expected: types.ExecConfig{ expected: container.ExecOptions{
Cmd: []string{"command"}, Cmd: []string{"command"},
DetachKeys: "de", DetachKeys: "de",
Detach: true, Detach: true,
@ -106,14 +107,14 @@ TWO=2
DetachKeys: "ab", DetachKeys: "ab",
}), }),
configFile: configfile.ConfigFile{DetachKeys: "de"}, configFile: configfile.ConfigFile{DetachKeys: "de"},
expected: types.ExecConfig{ expected: container.ExecOptions{
Cmd: []string{"command"}, Cmd: []string{"command"},
DetachKeys: "ab", DetachKeys: "ab",
Detach: true, Detach: true,
}, },
}, },
{ {
expected: types.ExecConfig{ expected: container.ExecOptions{
Cmd: []string{"command"}, Cmd: []string{"command"},
AttachStdout: true, AttachStdout: true,
AttachStderr: true, AttachStderr: true,
@ -126,7 +127,7 @@ TWO=2
}(), }(),
}, },
{ {
expected: types.ExecConfig{ expected: container.ExecOptions{
Cmd: []string{"command"}, Cmd: []string{"command"},
AttachStdout: true, AttachStdout: true,
AttachStderr: true, AttachStderr: true,
@ -206,7 +207,7 @@ func TestRunExec(t *testing.T) {
} }
} }
func execCreateWithID(_ string, _ types.ExecConfig) (types.IDResponse, error) { func execCreateWithID(_ string, _ container.ExecOptions) (types.IDResponse, error) {
return types.IDResponse{ID: "execid"}, nil return types.IDResponse{ID: "execid"}, nil
} }
@ -235,9 +236,9 @@ func TestGetExecExitStatus(t *testing.T) {
for _, testcase := range testcases { for _, testcase := range testcases {
client := &fakeClient{ client := &fakeClient{
execInspectFunc: func(id string) (types.ContainerExecInspect, error) { execInspectFunc: func(id string) (container.ExecInspect, error) {
assert.Check(t, is.Equal(execID, id)) assert.Check(t, is.Equal(execID, id))
return types.ContainerExecInspect{ExitCode: testcase.exitCode}, testcase.inspectError return container.ExecInspect{ExitCode: testcase.exitCode}, testcase.inspectError
}, },
} }
err := getExecExitStatus(context.Background(), client, execID) err := getExecExitStatus(context.Background(), client, execID)

View File

@ -5,7 +5,7 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -15,8 +15,8 @@ func TestContainerPrunePromptTermination(t *testing.T) {
t.Cleanup(cancel) t.Cleanup(cancel)
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
containerPruneFunc: func(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) { containerPruneFunc: func(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) {
return types.ContainersPruneReport{}, errors.New("fakeClient containerPruneFunc should not be called") return container.PruneReport{}, errors.New("fakeClient containerPruneFunc should not be called")
}, },
}) })
cmd := NewPruneCommand(cli) cmd := NewPruneCommand(cli)

View File

@ -13,7 +13,6 @@ import (
"github.com/docker/cli/cli/command/completion" "github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/command/formatter"
flagsHelper "github.com/docker/cli/cli/flags" flagsHelper "github.com/docker/cli/cli/flags"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
@ -164,7 +163,7 @@ func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions)
// is not valid for filtering containers. // is not valid for filtering containers.
f := options.Filters.Clone() f := options.Filters.Clone()
f.Add("type", string(events.ContainerEventType)) f.Add("type", string(events.ContainerEventType))
eventChan, errChan := apiClient.Events(ctx, types.EventsOptions{ eventChan, errChan := apiClient.Events(ctx, events.ListOptions{
Filters: f, Filters: f,
}) })

View File

@ -5,7 +5,6 @@ import (
"errors" "errors"
"strconv" "strconv"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
@ -68,11 +67,11 @@ func legacyWaitExitOrRemoved(ctx context.Context, apiClient client.APIClient, co
f := filters.NewArgs() f := filters.NewArgs()
f.Add("type", "container") f.Add("type", "container")
f.Add("container", containerID) f.Add("container", containerID)
options := types.EventsOptions{
Filters: f,
}
eventCtx, cancel := context.WithCancel(ctx) eventCtx, cancel := context.WithCancel(ctx)
eventq, errq := apiClient.Events(eventCtx, options) eventq, errq := apiClient.Events(eventCtx, events.ListOptions{
Filters: f,
})
eventProcessor := func(e events.Message) bool { eventProcessor := func(e events.Message) bool {
stopProcessing := false stopProcessing := false

View File

@ -21,11 +21,11 @@ type fakeClient struct {
imagePushFunc func(ref string, options image.PushOptions) (io.ReadCloser, error) imagePushFunc func(ref string, options image.PushOptions) (io.ReadCloser, error)
infoFunc func() (system.Info, error) infoFunc func() (system.Info, error)
imagePullFunc func(ref string, options image.PullOptions) (io.ReadCloser, error) imagePullFunc func(ref string, options image.PullOptions) (io.ReadCloser, error)
imagesPruneFunc func(pruneFilter filters.Args) (types.ImagesPruneReport, error) imagesPruneFunc func(pruneFilter filters.Args) (image.PruneReport, error)
imageLoadFunc func(input io.Reader, quiet bool) (types.ImageLoadResponse, error) imageLoadFunc func(input io.Reader, quiet bool) (image.LoadResponse, error)
imageListFunc func(options image.ListOptions) ([]image.Summary, error) imageListFunc func(options image.ListOptions) ([]image.Summary, error)
imageInspectFunc func(image string) (types.ImageInspect, []byte, error) imageInspectFunc func(image string) (types.ImageInspect, []byte, error)
imageImportFunc func(source types.ImageImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) imageImportFunc func(source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error)
imageHistoryFunc func(image string) ([]image.HistoryResponseItem, error) imageHistoryFunc func(image string) ([]image.HistoryResponseItem, error)
imageBuildFunc func(context.Context, io.Reader, types.ImageBuildOptions) (types.ImageBuildResponse, error) imageBuildFunc func(context.Context, io.Reader, types.ImageBuildOptions) (types.ImageBuildResponse, error)
} }
@ -74,18 +74,18 @@ func (cli *fakeClient) ImagePull(_ context.Context, ref string, options image.Pu
return io.NopCloser(strings.NewReader("")), nil return io.NopCloser(strings.NewReader("")), nil
} }
func (cli *fakeClient) ImagesPrune(_ context.Context, pruneFilter filters.Args) (types.ImagesPruneReport, error) { func (cli *fakeClient) ImagesPrune(_ context.Context, pruneFilter filters.Args) (image.PruneReport, error) {
if cli.imagesPruneFunc != nil { if cli.imagesPruneFunc != nil {
return cli.imagesPruneFunc(pruneFilter) return cli.imagesPruneFunc(pruneFilter)
} }
return types.ImagesPruneReport{}, nil return image.PruneReport{}, nil
} }
func (cli *fakeClient) ImageLoad(_ context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error) { func (cli *fakeClient) ImageLoad(_ context.Context, input io.Reader, quiet bool) (image.LoadResponse, error) {
if cli.imageLoadFunc != nil { if cli.imageLoadFunc != nil {
return cli.imageLoadFunc(input, quiet) return cli.imageLoadFunc(input, quiet)
} }
return types.ImageLoadResponse{}, nil return image.LoadResponse{}, nil
} }
func (cli *fakeClient) ImageList(_ context.Context, options image.ListOptions) ([]image.Summary, error) { func (cli *fakeClient) ImageList(_ context.Context, options image.ListOptions) ([]image.Summary, error) {
@ -102,7 +102,7 @@ func (cli *fakeClient) ImageInspectWithRaw(_ context.Context, img string) (types
return types.ImageInspect{}, nil, nil return types.ImageInspect{}, nil, nil
} }
func (cli *fakeClient) ImageImport(_ context.Context, source types.ImageImportSource, ref string, func (cli *fakeClient) ImageImport(_ context.Context, source image.ImportSource, ref string,
options image.ImportOptions, options image.ImportOptions,
) (io.ReadCloser, error) { ) (io.ReadCloser, error) {
if cli.imageImportFunc != nil { if cli.imageImportFunc != nil {

View File

@ -8,7 +8,6 @@ import (
"github.com/docker/cli/cli" "github.com/docker/cli/cli"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
dockeropts "github.com/docker/cli/opts" dockeropts "github.com/docker/cli/opts"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/jsonmessage"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -53,17 +52,17 @@ func NewImportCommand(dockerCli command.Cli) *cobra.Command {
} }
func runImport(ctx context.Context, dockerCli command.Cli, options importOptions) error { func runImport(ctx context.Context, dockerCli command.Cli, options importOptions) error {
var source types.ImageImportSource var source image.ImportSource
switch { switch {
case options.source == "-": case options.source == "-":
// import from STDIN // import from STDIN
source = types.ImageImportSource{ source = image.ImportSource{
Source: dockerCli.In(), Source: dockerCli.In(),
SourceName: options.source, SourceName: options.source,
} }
case strings.HasPrefix(options.source, "https://"), strings.HasPrefix(options.source, "http://"): case strings.HasPrefix(options.source, "https://"), strings.HasPrefix(options.source, "http://"):
// import from a remote source (handled by the daemon) // import from a remote source (handled by the daemon)
source = types.ImageImportSource{ source = image.ImportSource{
SourceName: options.source, SourceName: options.source,
} }
default: default:
@ -73,7 +72,7 @@ func runImport(ctx context.Context, dockerCli command.Cli, options importOptions
return err return err
} }
defer file.Close() defer file.Close()
source = types.ImageImportSource{ source = image.ImportSource{
Source: file, Source: file,
SourceName: "-", SourceName: "-",
} }

View File

@ -6,7 +6,6 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
@ -18,7 +17,7 @@ func TestNewImportCommandErrors(t *testing.T) {
name string name string
args []string args []string
expectedError string expectedError string
imageImportFunc func(source types.ImageImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) imageImportFunc func(source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error)
}{ }{
{ {
name: "wrong-args", name: "wrong-args",
@ -29,7 +28,7 @@ func TestNewImportCommandErrors(t *testing.T) {
name: "import-failed", name: "import-failed",
args: []string{"testdata/import-command-success.input.txt"}, args: []string{"testdata/import-command-success.input.txt"},
expectedError: "something went wrong", expectedError: "something went wrong",
imageImportFunc: func(source types.ImageImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) { imageImportFunc: func(source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) {
return nil, errors.Errorf("something went wrong") return nil, errors.Errorf("something went wrong")
}, },
}, },
@ -53,7 +52,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
args []string args []string
imageImportFunc func(source types.ImageImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) imageImportFunc func(source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error)
}{ }{
{ {
name: "simple", name: "simple",
@ -66,7 +65,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
{ {
name: "double", name: "double",
args: []string{"-", "image:local"}, args: []string{"-", "image:local"},
imageImportFunc: func(source types.ImageImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) { imageImportFunc: func(source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) {
assert.Check(t, is.Equal("image:local", ref)) assert.Check(t, is.Equal("image:local", ref))
return io.NopCloser(strings.NewReader("")), nil return io.NopCloser(strings.NewReader("")), nil
}, },
@ -74,7 +73,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
{ {
name: "message", name: "message",
args: []string{"--message", "test message", "-"}, args: []string{"--message", "test message", "-"},
imageImportFunc: func(source types.ImageImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) { imageImportFunc: func(source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) {
assert.Check(t, is.Equal("test message", options.Message)) assert.Check(t, is.Equal("test message", options.Message))
return io.NopCloser(strings.NewReader("")), nil return io.NopCloser(strings.NewReader("")), nil
}, },
@ -82,7 +81,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
{ {
name: "change", name: "change",
args: []string{"--change", "ENV DEBUG=true", "-"}, args: []string{"--change", "ENV DEBUG=true", "-"},
imageImportFunc: func(source types.ImageImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) { imageImportFunc: func(source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) {
assert.Check(t, is.Equal("ENV DEBUG=true", options.Changes[0])) assert.Check(t, is.Equal("ENV DEBUG=true", options.Changes[0]))
return io.NopCloser(strings.NewReader("")), nil return io.NopCloser(strings.NewReader("")), nil
}, },
@ -90,7 +89,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
{ {
name: "change legacy syntax", name: "change legacy syntax",
args: []string{"--change", "ENV DEBUG true", "-"}, args: []string{"--change", "ENV DEBUG true", "-"},
imageImportFunc: func(source types.ImageImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) { imageImportFunc: func(source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) {
assert.Check(t, is.Equal("ENV DEBUG true", options.Changes[0])) assert.Check(t, is.Equal("ENV DEBUG true", options.Changes[0]))
return io.NopCloser(strings.NewReader("")), nil return io.NopCloser(strings.NewReader("")), nil
}, },

View File

@ -7,7 +7,7 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/image"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
"gotest.tools/v3/golden" "gotest.tools/v3/golden"
@ -19,7 +19,7 @@ func TestNewLoadCommandErrors(t *testing.T) {
args []string args []string
isTerminalIn bool isTerminalIn bool
expectedError string expectedError string
imageLoadFunc func(input io.Reader, quiet bool) (types.ImageLoadResponse, error) imageLoadFunc func(input io.Reader, quiet bool) (image.LoadResponse, error)
}{ }{
{ {
name: "wrong-args", name: "wrong-args",
@ -34,8 +34,8 @@ func TestNewLoadCommandErrors(t *testing.T) {
{ {
name: "pull-error", name: "pull-error",
expectedError: "something went wrong", expectedError: "something went wrong",
imageLoadFunc: func(input io.Reader, quiet bool) (types.ImageLoadResponse, error) { imageLoadFunc: func(input io.Reader, quiet bool) (image.LoadResponse, error) {
return types.ImageLoadResponse{}, errors.Errorf("something went wrong") return image.LoadResponse{}, errors.Errorf("something went wrong")
}, },
}, },
} }
@ -62,19 +62,19 @@ func TestNewLoadCommandSuccess(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
args []string args []string
imageLoadFunc func(input io.Reader, quiet bool) (types.ImageLoadResponse, error) imageLoadFunc func(input io.Reader, quiet bool) (image.LoadResponse, error)
}{ }{
{ {
name: "simple", name: "simple",
imageLoadFunc: func(input io.Reader, quiet bool) (types.ImageLoadResponse, error) { imageLoadFunc: func(input io.Reader, quiet bool) (image.LoadResponse, error) {
return types.ImageLoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
}, },
}, },
{ {
name: "json", name: "json",
imageLoadFunc: func(input io.Reader, quiet bool) (types.ImageLoadResponse, error) { imageLoadFunc: func(input io.Reader, quiet bool) (image.LoadResponse, error) {
json := "{\"ID\": \"1\"}" json := "{\"ID\": \"1\"}"
return types.ImageLoadResponse{ return image.LoadResponse{
Body: io.NopCloser(strings.NewReader(json)), Body: io.NopCloser(strings.NewReader(json)),
JSON: true, JSON: true,
}, nil }, nil
@ -83,8 +83,8 @@ func TestNewLoadCommandSuccess(t *testing.T) {
{ {
name: "input-file", name: "input-file",
args: []string{"--input", "testdata/load-command-success.input.txt"}, args: []string{"--input", "testdata/load-command-success.input.txt"},
imageLoadFunc: func(input io.Reader, quiet bool) (types.ImageLoadResponse, error) { imageLoadFunc: func(input io.Reader, quiet bool) (image.LoadResponse, error) {
return types.ImageLoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
}, },
}, },
} }

View File

@ -9,7 +9,6 @@ import (
"github.com/docker/cli/cli/streams" "github.com/docker/cli/cli/streams"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -23,7 +22,7 @@ func TestNewPruneCommandErrors(t *testing.T) {
name string name string
args []string args []string
expectedError string expectedError string
imagesPruneFunc func(pruneFilter filters.Args) (types.ImagesPruneReport, error) imagesPruneFunc func(pruneFilter filters.Args) (image.PruneReport, error)
}{ }{
{ {
name: "wrong-args", name: "wrong-args",
@ -34,8 +33,8 @@ func TestNewPruneCommandErrors(t *testing.T) {
name: "prune-error", name: "prune-error",
args: []string{"--force"}, args: []string{"--force"},
expectedError: "something went wrong", expectedError: "something went wrong",
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) { imagesPruneFunc: func(pruneFilter filters.Args) (image.PruneReport, error) {
return types.ImagesPruneReport{}, errors.Errorf("something went wrong") return image.PruneReport{}, errors.Errorf("something went wrong")
}, },
}, },
} }
@ -53,22 +52,22 @@ func TestNewPruneCommandSuccess(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
args []string args []string
imagesPruneFunc func(pruneFilter filters.Args) (types.ImagesPruneReport, error) imagesPruneFunc func(pruneFilter filters.Args) (image.PruneReport, error)
}{ }{
{ {
name: "all", name: "all",
args: []string{"--all"}, args: []string{"--all"},
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) { imagesPruneFunc: func(pruneFilter filters.Args) (image.PruneReport, error) {
assert.Check(t, is.Equal("false", pruneFilter.Get("dangling")[0])) assert.Check(t, is.Equal("false", pruneFilter.Get("dangling")[0]))
return types.ImagesPruneReport{}, nil return image.PruneReport{}, nil
}, },
}, },
{ {
name: "force-deleted", name: "force-deleted",
args: []string{"--force"}, args: []string{"--force"},
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) { imagesPruneFunc: func(pruneFilter filters.Args) (image.PruneReport, error) {
assert.Check(t, is.Equal("true", pruneFilter.Get("dangling")[0])) assert.Check(t, is.Equal("true", pruneFilter.Get("dangling")[0]))
return types.ImagesPruneReport{ return image.PruneReport{
ImagesDeleted: []image.DeleteResponse{{Deleted: "image1"}}, ImagesDeleted: []image.DeleteResponse{{Deleted: "image1"}},
SpaceReclaimed: 1, SpaceReclaimed: 1,
}, nil }, nil
@ -77,17 +76,17 @@ func TestNewPruneCommandSuccess(t *testing.T) {
{ {
name: "label-filter", name: "label-filter",
args: []string{"--force", "--filter", "label=foobar"}, args: []string{"--force", "--filter", "label=foobar"},
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) { imagesPruneFunc: func(pruneFilter filters.Args) (image.PruneReport, error) {
assert.Check(t, is.Equal("foobar", pruneFilter.Get("label")[0])) assert.Check(t, is.Equal("foobar", pruneFilter.Get("label")[0]))
return types.ImagesPruneReport{}, nil return image.PruneReport{}, nil
}, },
}, },
{ {
name: "force-untagged", name: "force-untagged",
args: []string{"--force"}, args: []string{"--force"},
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) { imagesPruneFunc: func(pruneFilter filters.Args) (image.PruneReport, error) {
assert.Check(t, is.Equal("true", pruneFilter.Get("dangling")[0])) assert.Check(t, is.Equal("true", pruneFilter.Get("dangling")[0]))
return types.ImagesPruneReport{ return image.PruneReport{
ImagesDeleted: []image.DeleteResponse{{Untagged: "image1"}}, ImagesDeleted: []image.DeleteResponse{{Untagged: "image1"}},
SpaceReclaimed: 2, SpaceReclaimed: 2,
}, nil }, nil
@ -115,8 +114,8 @@ func TestPrunePromptTermination(t *testing.T) {
t.Cleanup(cancel) t.Cleanup(cancel)
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) { imagesPruneFunc: func(pruneFilter filters.Args) (image.PruneReport, error) {
return types.ImagesPruneReport{}, errors.New("fakeClient imagesPruneFunc should not be called") return image.PruneReport{}, errors.New("fakeClient imagesPruneFunc should not be called")
}, },
}) })
cmd := NewPruneCommand(cli) cmd := NewPruneCommand(cli)

View File

@ -7,7 +7,7 @@ import (
"github.com/docker/cli/cli" "github.com/docker/cli/cli"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
apiclient "github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -38,9 +38,9 @@ func NewNodeCommand(dockerCli command.Cli) *cobra.Command {
// Reference returns the reference of a node. The special value "self" for a node // Reference returns the reference of a node. The special value "self" for a node
// reference is mapped to the current node, hence the node ID is retrieved using // reference is mapped to the current node, hence the node ID is retrieved using
// the `/info` endpoint. // the `/info` endpoint.
func Reference(ctx context.Context, client apiclient.APIClient, ref string) (string, error) { func Reference(ctx context.Context, apiClient client.APIClient, ref string) (string, error) {
if ref == "self" { if ref == "self" {
info, err := client.Info(ctx) info, err := apiClient.Info(ctx)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -48,7 +48,7 @@ func Reference(ctx context.Context, client apiclient.APIClient, ref string) (str
// If there's no node ID in /info, the node probably // If there's no node ID in /info, the node probably
// isn't a manager. Call a swarm-specific endpoint to // isn't a manager. Call a swarm-specific endpoint to
// get a more specific error message. // get a more specific error message.
_, err = client.NodeList(ctx, types.NodeListOptions{}) _, err = apiClient.NodeList(ctx, types.NodeListOptions{})
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -8,7 +8,6 @@ import (
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/command/formatter"
"github.com/docker/cli/opts" "github.com/docker/cli/opts"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry" registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -65,7 +64,7 @@ func runSearch(ctx context.Context, dockerCli command.Cli, options searchOptions
} }
requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(dockerCli, indexInfo, "search") requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(dockerCli, indexInfo, "search")
results, err := dockerCli.Client().ImageSearch(ctx, options.term, types.ImageSearchOptions{ results, err := dockerCli.Client().ImageSearch(ctx, options.term, registrytypes.SearchOptions{
RegistryAuth: encodedAuth, RegistryAuth: encodedAuth,
PrivilegeFunc: requestPrivilege, PrivilegeFunc: requestPrivilege,
Filters: options.filter.Value(), Filters: options.filter.Value(),

View File

@ -14,7 +14,7 @@ import (
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
apiclient "github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/docker/docker/errdefs" "github.com/docker/docker/errdefs"
) )
@ -89,14 +89,14 @@ func getServicesDeclaredNetworks(serviceConfigs []composetypes.ServiceConfig) ma
return serviceNetworks return serviceNetworks
} }
func validateExternalNetworks(ctx context.Context, client apiclient.NetworkAPIClient, externalNetworks []string) error { func validateExternalNetworks(ctx context.Context, apiClient client.NetworkAPIClient, externalNetworks []string) error {
for _, networkName := range externalNetworks { for _, networkName := range externalNetworks {
if !container.NetworkMode(networkName).IsUserDefined() { if !container.NetworkMode(networkName).IsUserDefined() {
// Networks that are not user defined always exist on all nodes as // Networks that are not user defined always exist on all nodes as
// local-scoped networks, so there's no need to inspect them. // local-scoped networks, so there's no need to inspect them.
continue continue
} }
nw, err := client.NetworkInspect(ctx, networkName, network.InspectOptions{}) nw, err := apiClient.NetworkInspect(ctx, networkName, network.InspectOptions{})
switch { switch {
case errdefs.IsNotFound(err): case errdefs.IsNotFound(err):
return fmt.Errorf("network %q is declared as external, but could not be found. You need to create a swarm-scoped network before the stack is deployed", networkName) return fmt.Errorf("network %q is declared as external, but could not be found. You need to create a swarm-scoped network before the stack is deployed", networkName)
@ -110,20 +110,20 @@ func validateExternalNetworks(ctx context.Context, client apiclient.NetworkAPICl
} }
func createSecrets(ctx context.Context, dockerCli command.Cli, secrets []swarm.SecretSpec) error { func createSecrets(ctx context.Context, dockerCli command.Cli, secrets []swarm.SecretSpec) error {
client := dockerCli.Client() apiClient := dockerCli.Client()
for _, secretSpec := range secrets { for _, secretSpec := range secrets {
secret, _, err := client.SecretInspectWithRaw(ctx, secretSpec.Name) secret, _, err := apiClient.SecretInspectWithRaw(ctx, secretSpec.Name)
switch { switch {
case err == nil: case err == nil:
// secret already exists, then we update that // secret already exists, then we update that
if err := client.SecretUpdate(ctx, secret.ID, secret.Meta.Version, secretSpec); err != nil { if err := apiClient.SecretUpdate(ctx, secret.ID, secret.Meta.Version, secretSpec); err != nil {
return fmt.Errorf("failed to update secret %s: %w", secretSpec.Name, err) return fmt.Errorf("failed to update secret %s: %w", secretSpec.Name, err)
} }
case errdefs.IsNotFound(err): case errdefs.IsNotFound(err):
// secret does not exist, then we create a new one. // secret does not exist, then we create a new one.
fmt.Fprintf(dockerCli.Out(), "Creating secret %s\n", secretSpec.Name) fmt.Fprintf(dockerCli.Out(), "Creating secret %s\n", secretSpec.Name)
if _, err := client.SecretCreate(ctx, secretSpec); err != nil { if _, err := apiClient.SecretCreate(ctx, secretSpec); err != nil {
return fmt.Errorf("failed to create secret %s: %w", secretSpec.Name, err) return fmt.Errorf("failed to create secret %s: %w", secretSpec.Name, err)
} }
default: default:
@ -134,20 +134,20 @@ func createSecrets(ctx context.Context, dockerCli command.Cli, secrets []swarm.S
} }
func createConfigs(ctx context.Context, dockerCli command.Cli, configs []swarm.ConfigSpec) error { func createConfigs(ctx context.Context, dockerCli command.Cli, configs []swarm.ConfigSpec) error {
client := dockerCli.Client() apiClient := dockerCli.Client()
for _, configSpec := range configs { for _, configSpec := range configs {
config, _, err := client.ConfigInspectWithRaw(ctx, configSpec.Name) config, _, err := apiClient.ConfigInspectWithRaw(ctx, configSpec.Name)
switch { switch {
case err == nil: case err == nil:
// config already exists, then we update that // config already exists, then we update that
if err := client.ConfigUpdate(ctx, config.ID, config.Meta.Version, configSpec); err != nil { if err := apiClient.ConfigUpdate(ctx, config.ID, config.Meta.Version, configSpec); err != nil {
return fmt.Errorf("failed to update config %s: %w", configSpec.Name, err) return fmt.Errorf("failed to update config %s: %w", configSpec.Name, err)
} }
case errdefs.IsNotFound(err): case errdefs.IsNotFound(err):
// config does not exist, then we create a new one. // config does not exist, then we create a new one.
fmt.Fprintf(dockerCli.Out(), "Creating config %s\n", configSpec.Name) fmt.Fprintf(dockerCli.Out(), "Creating config %s\n", configSpec.Name)
if _, err := client.ConfigCreate(ctx, configSpec); err != nil { if _, err := apiClient.ConfigCreate(ctx, configSpec); err != nil {
return fmt.Errorf("failed to create config %s: %w", configSpec.Name, err) return fmt.Errorf("failed to create config %s: %w", configSpec.Name, err)
} }
default: default:
@ -158,9 +158,9 @@ func createConfigs(ctx context.Context, dockerCli command.Cli, configs []swarm.C
} }
func createNetworks(ctx context.Context, dockerCli command.Cli, namespace convert.Namespace, networks map[string]network.CreateOptions) error { func createNetworks(ctx context.Context, dockerCli command.Cli, namespace convert.Namespace, networks map[string]network.CreateOptions) error {
client := dockerCli.Client() apiClient := dockerCli.Client()
existingNetworks, err := getStackNetworks(ctx, client, namespace.Name()) existingNetworks, err := getStackNetworks(ctx, apiClient, namespace.Name())
if err != nil { if err != nil {
return err return err
} }
@ -180,7 +180,7 @@ func createNetworks(ctx context.Context, dockerCli command.Cli, namespace conver
} }
fmt.Fprintf(dockerCli.Out(), "Creating network %s\n", name) fmt.Fprintf(dockerCli.Out(), "Creating network %s\n", name)
if _, err := client.NetworkCreate(ctx, name, createOpts); err != nil { if _, err := apiClient.NetworkCreate(ctx, name, createOpts); err != nil {
return fmt.Errorf("failed to create network %s: %w", name, err) return fmt.Errorf("failed to create network %s: %w", name, err)
} }
} }

View File

@ -11,37 +11,37 @@ import (
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
apiclient "github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// RunRemove is the swarm implementation of docker stack remove // RunRemove is the swarm implementation of docker stack remove
func RunRemove(ctx context.Context, dockerCli command.Cli, opts options.Remove) error { func RunRemove(ctx context.Context, dockerCli command.Cli, opts options.Remove) error {
client := dockerCli.Client() apiClient := dockerCli.Client()
var errs []string var errs []string
for _, namespace := range opts.Namespaces { for _, namespace := range opts.Namespaces {
services, err := getStackServices(ctx, client, namespace) services, err := getStackServices(ctx, apiClient, namespace)
if err != nil { if err != nil {
return err return err
} }
networks, err := getStackNetworks(ctx, client, namespace) networks, err := getStackNetworks(ctx, apiClient, namespace)
if err != nil { if err != nil {
return err return err
} }
var secrets []swarm.Secret var secrets []swarm.Secret
if versions.GreaterThanOrEqualTo(client.ClientVersion(), "1.25") { if versions.GreaterThanOrEqualTo(apiClient.ClientVersion(), "1.25") {
secrets, err = getStackSecrets(ctx, client, namespace) secrets, err = getStackSecrets(ctx, apiClient, namespace)
if err != nil { if err != nil {
return err return err
} }
} }
var configs []swarm.Config var configs []swarm.Config
if versions.GreaterThanOrEqualTo(client.ClientVersion(), "1.30") { if versions.GreaterThanOrEqualTo(apiClient.ClientVersion(), "1.30") {
configs, err = getStackConfigs(ctx, client, namespace) configs, err = getStackConfigs(ctx, apiClient, namespace)
if err != nil { if err != nil {
return err return err
} }
@ -63,7 +63,7 @@ func RunRemove(ctx context.Context, dockerCli command.Cli, opts options.Remove)
} }
if !opts.Detach { if !opts.Detach {
err = waitOnTasks(ctx, client, namespace) err = waitOnTasks(ctx, apiClient, namespace)
if err != nil { if err != nil {
errs = append(errs, fmt.Sprintf("Failed to wait on tasks of stack: %s: %s", namespace, err)) errs = append(errs, fmt.Sprintf("Failed to wait on tasks of stack: %s: %s", namespace, err))
} }
@ -82,11 +82,7 @@ func sortServiceByName(services []swarm.Service) func(i, j int) bool {
} }
} }
func removeServices( func removeServices(ctx context.Context, dockerCli command.Cli, services []swarm.Service) bool {
ctx context.Context,
dockerCli command.Cli,
services []swarm.Service,
) bool {
var hasError bool var hasError bool
sort.Slice(services, sortServiceByName(services)) sort.Slice(services, sortServiceByName(services))
for _, service := range services { for _, service := range services {
@ -99,11 +95,7 @@ func removeServices(
return hasError return hasError
} }
func removeNetworks( func removeNetworks(ctx context.Context, dockerCli command.Cli, networks []network.Summary) bool {
ctx context.Context,
dockerCli command.Cli,
networks []network.Summary,
) bool {
var hasError bool var hasError bool
for _, nw := range networks { for _, nw := range networks {
fmt.Fprintf(dockerCli.Out(), "Removing network %s\n", nw.Name) fmt.Fprintf(dockerCli.Out(), "Removing network %s\n", nw.Name)
@ -115,11 +107,7 @@ func removeNetworks(
return hasError return hasError
} }
func removeSecrets( func removeSecrets(ctx context.Context, dockerCli command.Cli, secrets []swarm.Secret) bool {
ctx context.Context,
dockerCli command.Cli,
secrets []swarm.Secret,
) bool {
var hasError bool var hasError bool
for _, secret := range secrets { for _, secret := range secrets {
fmt.Fprintf(dockerCli.Out(), "Removing secret %s\n", secret.Spec.Name) fmt.Fprintf(dockerCli.Out(), "Removing secret %s\n", secret.Spec.Name)
@ -131,11 +119,7 @@ func removeSecrets(
return hasError return hasError
} }
func removeConfigs( func removeConfigs(ctx context.Context, dockerCli command.Cli, configs []swarm.Config) bool {
ctx context.Context,
dockerCli command.Cli,
configs []swarm.Config,
) bool {
var hasError bool var hasError bool
for _, config := range configs { for _, config := range configs {
fmt.Fprintf(dockerCli.Out(), "Removing config %s\n", config.Spec.Name) fmt.Fprintf(dockerCli.Out(), "Removing config %s\n", config.Spec.Name)
@ -167,10 +151,10 @@ func terminalState(state swarm.TaskState) bool {
return numberedStates[state] > numberedStates[swarm.TaskStateRunning] return numberedStates[state] > numberedStates[swarm.TaskStateRunning]
} }
func waitOnTasks(ctx context.Context, client apiclient.APIClient, namespace string) error { func waitOnTasks(ctx context.Context, apiClient client.APIClient, namespace string) error {
terminalStatesReached := 0 terminalStatesReached := 0
for { for {
tasks, err := getStackTasks(ctx, client, namespace) tasks, err := getStackTasks(ctx, apiClient, namespace)
if err != nil { if err != nil {
return fmt.Errorf("failed to get tasks: %w", err) return fmt.Errorf("failed to get tasks: %w", err)
} }

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
@ -15,8 +16,8 @@ type fakeClient struct {
version string version string
serverVersion func(ctx context.Context) (types.Version, error) serverVersion func(ctx context.Context) (types.Version, error)
eventsFn func(context.Context, types.EventsOptions) (<-chan events.Message, <-chan error) eventsFn func(context.Context, events.ListOptions) (<-chan events.Message, <-chan error)
containerPruneFunc func(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) containerPruneFunc func(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error)
networkPruneFunc func(ctx context.Context, pruneFilter filters.Args) (network.PruneReport, error) networkPruneFunc func(ctx context.Context, pruneFilter filters.Args) (network.PruneReport, error)
} }
@ -28,15 +29,15 @@ func (cli *fakeClient) ClientVersion() string {
return cli.version return cli.version
} }
func (cli *fakeClient) Events(ctx context.Context, opts types.EventsOptions) (<-chan events.Message, <-chan error) { func (cli *fakeClient) Events(ctx context.Context, opts events.ListOptions) (<-chan events.Message, <-chan error) {
return cli.eventsFn(ctx, opts) return cli.eventsFn(ctx, opts)
} }
func (cli *fakeClient) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) { func (cli *fakeClient) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) {
if cli.containerPruneFunc != nil { if cli.containerPruneFunc != nil {
return cli.containerPruneFunc(ctx, pruneFilters) return cli.containerPruneFunc(ctx, pruneFilters)
} }
return types.ContainersPruneReport{}, nil return container.PruneReport{}, nil
} }
func (cli *fakeClient) NetworksPrune(ctx context.Context, pruneFilter filters.Args) (network.PruneReport, error) { func (cli *fakeClient) NetworksPrune(ctx context.Context, pruneFilter filters.Args) (network.PruneReport, error) {

View File

@ -16,7 +16,6 @@ import (
flagsHelper "github.com/docker/cli/cli/flags" flagsHelper "github.com/docker/cli/cli/flags"
"github.com/docker/cli/opts" "github.com/docker/cli/opts"
"github.com/docker/cli/templates" "github.com/docker/cli/templates"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/events"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -63,7 +62,7 @@ func runEvents(ctx context.Context, dockerCli command.Cli, options *eventsOption
} }
} }
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
evts, errs := dockerCli.Client().Events(ctx, types.EventsOptions{ evts, errs := dockerCli.Client().Events(ctx, events.ListOptions{
Since: options.since, Since: options.since,
Until: options.until, Until: options.until,
Filters: options.filter.Value(), Filters: options.filter.Value(),

View File

@ -9,7 +9,6 @@ import (
"time" "time"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/events"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
"gotest.tools/v3/golden" "gotest.tools/v3/golden"
@ -59,7 +58,7 @@ func TestEventsFormat(t *testing.T) {
// Set to UTC timezone as timestamps in output are // Set to UTC timezone as timestamps in output are
// printed in the current timezone // printed in the current timezone
t.Setenv("TZ", "UTC") t.Setenv("TZ", "UTC")
cli := test.NewFakeCli(&fakeClient{eventsFn: func(context.Context, types.EventsOptions) (<-chan events.Message, <-chan error) { cli := test.NewFakeCli(&fakeClient{eventsFn: func(context.Context, events.ListOptions) (<-chan events.Message, <-chan error) {
messages := make(chan events.Message) messages := make(chan events.Message)
errs := make(chan error, 1) errs := make(chan error, 1)
go func() { go func() {

View File

@ -6,7 +6,7 @@ import (
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -60,8 +60,8 @@ func TestSystemPrunePromptTermination(t *testing.T) {
t.Cleanup(cancel) t.Cleanup(cancel)
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
containerPruneFunc: func(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) { containerPruneFunc: func(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) {
return types.ContainersPruneReport{}, errors.New("fakeClient containerPruneFunc should not be called") return container.PruneReport{}, errors.New("fakeClient containerPruneFunc should not be called")
}, },
networkPruneFunc: func(ctx context.Context, pruneFilters filters.Args) (network.PruneReport, error) { networkPruneFunc: func(ctx context.Context, pruneFilters filters.Args) (network.PruneReport, error) {
return network.PruneReport{}, errors.New("fakeClient networkPruneFunc should not be called") return network.PruneReport{}, errors.New("fakeClient networkPruneFunc should not be called")

View File

@ -13,9 +13,9 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/system" "github.com/docker/docker/api/types/system"
apiclient "github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/theupdateframework/notary" "github.com/theupdateframework/notary"
"github.com/theupdateframework/notary/client" notaryclient "github.com/theupdateframework/notary/client"
"github.com/theupdateframework/notary/tuf/data" "github.com/theupdateframework/notary/tuf/data"
"github.com/theupdateframework/notary/tuf/utils" "github.com/theupdateframework/notary/tuf/utils"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
@ -26,7 +26,7 @@ import (
// TODO(n4ss): remove common tests with the regular inspect command // TODO(n4ss): remove common tests with the regular inspect command
type fakeClient struct { type fakeClient struct {
apiclient.Client client.Client
} }
func (c *fakeClient) Info(context.Context) (system.Info, error) { func (c *fakeClient) Info(context.Context) (system.Info, error) {
@ -212,7 +212,7 @@ func mockDelegationRoleWithName(name string) data.DelegationRole {
func TestMatchEmptySignatures(t *testing.T) { func TestMatchEmptySignatures(t *testing.T) {
// first try empty targets // first try empty targets
emptyTgts := []client.TargetSignedStruct{} emptyTgts := []notaryclient.TargetSignedStruct{}
matchedSigRows := matchReleasedSignatures(emptyTgts) matchedSigRows := matchReleasedSignatures(emptyTgts)
assert.Check(t, is.Len(matchedSigRows, 0)) assert.Check(t, is.Len(matchedSigRows, 0))
@ -220,11 +220,11 @@ func TestMatchEmptySignatures(t *testing.T) {
func TestMatchUnreleasedSignatures(t *testing.T) { func TestMatchUnreleasedSignatures(t *testing.T) {
// try an "unreleased" target with 3 signatures, 0 rows will appear // try an "unreleased" target with 3 signatures, 0 rows will appear
unreleasedTgts := []client.TargetSignedStruct{} unreleasedTgts := []notaryclient.TargetSignedStruct{}
tgt := client.Target{Name: "unreleased", Hashes: data.Hashes{notary.SHA256: []byte("hash")}} tgt := notaryclient.Target{Name: "unreleased", Hashes: data.Hashes{notary.SHA256: []byte("hash")}}
for _, unreleasedRole := range []string{"targets/a", "targets/b", "targets/c"} { for _, unreleasedRole := range []string{"targets/a", "targets/b", "targets/c"} {
unreleasedTgts = append(unreleasedTgts, client.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: tgt}) unreleasedTgts = append(unreleasedTgts, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: tgt})
} }
matchedSigRows := matchReleasedSignatures(unreleasedTgts) matchedSigRows := matchReleasedSignatures(unreleasedTgts)
@ -233,16 +233,16 @@ func TestMatchUnreleasedSignatures(t *testing.T) {
func TestMatchOneReleasedSingleSignature(t *testing.T) { func TestMatchOneReleasedSingleSignature(t *testing.T) {
// now try only 1 "released" target with no additional sigs, 1 row will appear with 0 signers // now try only 1 "released" target with no additional sigs, 1 row will appear with 0 signers
oneReleasedTgt := []client.TargetSignedStruct{} oneReleasedTgt := []notaryclient.TargetSignedStruct{}
// make and append the "released" target to our mock input // make and append the "released" target to our mock input
releasedTgt := client.Target{Name: "released", Hashes: data.Hashes{notary.SHA256: []byte("released-hash")}} releasedTgt := notaryclient.Target{Name: "released", Hashes: data.Hashes{notary.SHA256: []byte("released-hash")}}
oneReleasedTgt = append(oneReleasedTgt, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: releasedTgt}) oneReleasedTgt = append(oneReleasedTgt, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: releasedTgt})
// make and append 3 non-released signatures on the "unreleased" target // make and append 3 non-released signatures on the "unreleased" target
unreleasedTgt := client.Target{Name: "unreleased", Hashes: data.Hashes{notary.SHA256: []byte("hash")}} unreleasedTgt := notaryclient.Target{Name: "unreleased", Hashes: data.Hashes{notary.SHA256: []byte("hash")}}
for _, unreleasedRole := range []string{"targets/a", "targets/b", "targets/c"} { for _, unreleasedRole := range []string{"targets/a", "targets/b", "targets/c"} {
oneReleasedTgt = append(oneReleasedTgt, client.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: unreleasedTgt}) oneReleasedTgt = append(oneReleasedTgt, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: unreleasedTgt})
} }
matchedSigRows := matchReleasedSignatures(oneReleasedTgt) matchedSigRows := matchReleasedSignatures(oneReleasedTgt)
@ -257,17 +257,17 @@ func TestMatchOneReleasedSingleSignature(t *testing.T) {
func TestMatchOneReleasedMultiSignature(t *testing.T) { func TestMatchOneReleasedMultiSignature(t *testing.T) {
// now try only 1 "released" target with 3 additional sigs, 1 row will appear with 3 signers // now try only 1 "released" target with 3 additional sigs, 1 row will appear with 3 signers
oneReleasedTgt := []client.TargetSignedStruct{} oneReleasedTgt := []notaryclient.TargetSignedStruct{}
// make and append the "released" target to our mock input // make and append the "released" target to our mock input
releasedTgt := client.Target{Name: "released", Hashes: data.Hashes{notary.SHA256: []byte("released-hash")}} releasedTgt := notaryclient.Target{Name: "released", Hashes: data.Hashes{notary.SHA256: []byte("released-hash")}}
oneReleasedTgt = append(oneReleasedTgt, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: releasedTgt}) oneReleasedTgt = append(oneReleasedTgt, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: releasedTgt})
// make and append 3 non-released signatures on both the "released" and "unreleased" targets // make and append 3 non-released signatures on both the "released" and "unreleased" targets
unreleasedTgt := client.Target{Name: "unreleased", Hashes: data.Hashes{notary.SHA256: []byte("hash")}} unreleasedTgt := notaryclient.Target{Name: "unreleased", Hashes: data.Hashes{notary.SHA256: []byte("hash")}}
for _, unreleasedRole := range []string{"targets/a", "targets/b", "targets/c"} { for _, unreleasedRole := range []string{"targets/a", "targets/b", "targets/c"} {
oneReleasedTgt = append(oneReleasedTgt, client.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: unreleasedTgt}) oneReleasedTgt = append(oneReleasedTgt, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: unreleasedTgt})
oneReleasedTgt = append(oneReleasedTgt, client.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: releasedTgt}) oneReleasedTgt = append(oneReleasedTgt, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: releasedTgt})
} }
matchedSigRows := matchReleasedSignatures(oneReleasedTgt) matchedSigRows := matchReleasedSignatures(oneReleasedTgt)
@ -285,29 +285,29 @@ func TestMatchMultiReleasedMultiSignature(t *testing.T) {
// target-a is signed by targets/releases and targets/a - a will be the signer // target-a is signed by targets/releases and targets/a - a will be the signer
// target-b is signed by targets/releases, targets/a, targets/b - a and b will be the signers // target-b is signed by targets/releases, targets/a, targets/b - a and b will be the signers
// target-c is signed by targets/releases, targets/a, targets/b, targets/c - a, b, and c will be the signers // target-c is signed by targets/releases, targets/a, targets/b, targets/c - a, b, and c will be the signers
multiReleasedTgts := []client.TargetSignedStruct{} multiReleasedTgts := []notaryclient.TargetSignedStruct{}
// make target-a, target-b, and target-c // make target-a, target-b, and target-c
targetA := client.Target{Name: "target-a", Hashes: data.Hashes{notary.SHA256: []byte("target-a-hash")}} targetA := notaryclient.Target{Name: "target-a", Hashes: data.Hashes{notary.SHA256: []byte("target-a-hash")}}
targetB := client.Target{Name: "target-b", Hashes: data.Hashes{notary.SHA256: []byte("target-b-hash")}} targetB := notaryclient.Target{Name: "target-b", Hashes: data.Hashes{notary.SHA256: []byte("target-b-hash")}}
targetC := client.Target{Name: "target-c", Hashes: data.Hashes{notary.SHA256: []byte("target-c-hash")}} targetC := notaryclient.Target{Name: "target-c", Hashes: data.Hashes{notary.SHA256: []byte("target-c-hash")}}
// have targets/releases "sign" on all of these targets so they are released // have targets/releases "sign" on all of these targets so they are released
multiReleasedTgts = append(multiReleasedTgts, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: targetA}) multiReleasedTgts = append(multiReleasedTgts, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: targetA})
multiReleasedTgts = append(multiReleasedTgts, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: targetB}) multiReleasedTgts = append(multiReleasedTgts, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: targetB})
multiReleasedTgts = append(multiReleasedTgts, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: targetC}) multiReleasedTgts = append(multiReleasedTgts, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: targetC})
// targets/a signs off on all three targets (target-a, target-b, target-c): // targets/a signs off on all three targets (target-a, target-b, target-c):
for _, tgt := range []client.Target{targetA, targetB, targetC} { for _, tgt := range []notaryclient.Target{targetA, targetB, targetC} {
multiReleasedTgts = append(multiReleasedTgts, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/a"), Target: tgt}) multiReleasedTgts = append(multiReleasedTgts, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/a"), Target: tgt})
} }
// targets/b signs off on the final two targets (target-b, target-c): // targets/b signs off on the final two targets (target-b, target-c):
for _, tgt := range []client.Target{targetB, targetC} { for _, tgt := range []notaryclient.Target{targetB, targetC} {
multiReleasedTgts = append(multiReleasedTgts, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/b"), Target: tgt}) multiReleasedTgts = append(multiReleasedTgts, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/b"), Target: tgt})
} }
// targets/c only signs off on the last target (target-c): // targets/c only signs off on the last target (target-c):
multiReleasedTgts = append(multiReleasedTgts, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/c"), Target: targetC}) multiReleasedTgts = append(multiReleasedTgts, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/c"), Target: targetC})
matchedSigRows := matchReleasedSignatures(multiReleasedTgts) matchedSigRows := matchReleasedSignatures(multiReleasedTgts)
assert.Check(t, is.Len(matchedSigRows, 3)) assert.Check(t, is.Len(matchedSigRows, 3))
@ -331,10 +331,10 @@ func TestMatchMultiReleasedMultiSignature(t *testing.T) {
func TestMatchReleasedSignatureFromTargets(t *testing.T) { func TestMatchReleasedSignatureFromTargets(t *testing.T) {
// now try only 1 "released" target with no additional sigs, one rows will appear // now try only 1 "released" target with no additional sigs, one rows will appear
oneReleasedTgt := []client.TargetSignedStruct{} oneReleasedTgt := []notaryclient.TargetSignedStruct{}
// make and append the "released" target to our mock input // make and append the "released" target to our mock input
releasedTgt := client.Target{Name: "released", Hashes: data.Hashes{notary.SHA256: []byte("released-hash")}} releasedTgt := notaryclient.Target{Name: "released", Hashes: data.Hashes{notary.SHA256: []byte("released-hash")}}
oneReleasedTgt = append(oneReleasedTgt, client.TargetSignedStruct{Role: mockDelegationRoleWithName(data.CanonicalTargetsRole.String()), Target: releasedTgt}) oneReleasedTgt = append(oneReleasedTgt, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName(data.CanonicalTargetsRole.String()), Target: releasedTgt})
matchedSigRows := matchReleasedSignatures(oneReleasedTgt) matchedSigRows := matchReleasedSignatures(oneReleasedTgt)
assert.Check(t, is.Len(matchedSigRows, 1)) assert.Check(t, is.Len(matchedSigRows, 1))
outputRow := matchedSigRows[0] outputRow := matchedSigRows[0]
@ -405,7 +405,7 @@ func TestFormatAdminRole(t *testing.T) {
}, },
Name: "targets/alice", Name: "targets/alice",
} }
aliceRoleWithSigs := client.RoleWithSignatures{Role: aliceRole, Signatures: nil} aliceRoleWithSigs := notaryclient.RoleWithSignatures{Role: aliceRole, Signatures: nil}
assert.Check(t, is.Equal("", formatAdminRole(aliceRoleWithSigs))) assert.Check(t, is.Equal("", formatAdminRole(aliceRoleWithSigs)))
releasesRole := data.Role{ releasesRole := data.Role{
@ -414,7 +414,7 @@ func TestFormatAdminRole(t *testing.T) {
}, },
Name: "targets/releases", Name: "targets/releases",
} }
releasesRoleWithSigs := client.RoleWithSignatures{Role: releasesRole, Signatures: nil} releasesRoleWithSigs := notaryclient.RoleWithSignatures{Role: releasesRole, Signatures: nil}
assert.Check(t, is.Equal("", formatAdminRole(releasesRoleWithSigs))) assert.Check(t, is.Equal("", formatAdminRole(releasesRoleWithSigs)))
timestampRole := data.Role{ timestampRole := data.Role{
@ -423,7 +423,7 @@ func TestFormatAdminRole(t *testing.T) {
}, },
Name: data.CanonicalTimestampRole, Name: data.CanonicalTimestampRole,
} }
timestampRoleWithSigs := client.RoleWithSignatures{Role: timestampRole, Signatures: nil} timestampRoleWithSigs := notaryclient.RoleWithSignatures{Role: timestampRole, Signatures: nil}
assert.Check(t, is.Equal("", formatAdminRole(timestampRoleWithSigs))) assert.Check(t, is.Equal("", formatAdminRole(timestampRoleWithSigs)))
snapshotRole := data.Role{ snapshotRole := data.Role{
@ -432,7 +432,7 @@ func TestFormatAdminRole(t *testing.T) {
}, },
Name: data.CanonicalSnapshotRole, Name: data.CanonicalSnapshotRole,
} }
snapshotRoleWithSigs := client.RoleWithSignatures{Role: snapshotRole, Signatures: nil} snapshotRoleWithSigs := notaryclient.RoleWithSignatures{Role: snapshotRole, Signatures: nil}
assert.Check(t, is.Equal("", formatAdminRole(snapshotRoleWithSigs))) assert.Check(t, is.Equal("", formatAdminRole(snapshotRoleWithSigs)))
rootRole := data.Role{ rootRole := data.Role{
@ -441,7 +441,7 @@ func TestFormatAdminRole(t *testing.T) {
}, },
Name: data.CanonicalRootRole, Name: data.CanonicalRootRole,
} }
rootRoleWithSigs := client.RoleWithSignatures{Role: rootRole, Signatures: nil} rootRoleWithSigs := notaryclient.RoleWithSignatures{Role: rootRole, Signatures: nil}
assert.Check(t, is.Equal("Root Key:\tkey11\n", formatAdminRole(rootRoleWithSigs))) assert.Check(t, is.Equal("Root Key:\tkey11\n", formatAdminRole(rootRoleWithSigs)))
targetsRole := data.Role{ targetsRole := data.Role{
@ -450,7 +450,7 @@ func TestFormatAdminRole(t *testing.T) {
}, },
Name: data.CanonicalTargetsRole, Name: data.CanonicalTargetsRole,
} }
targetsRoleWithSigs := client.RoleWithSignatures{Role: targetsRole, Signatures: nil} targetsRoleWithSigs := notaryclient.RoleWithSignatures{Role: targetsRole, Signatures: nil}
assert.Check(t, is.Equal("Repository Key:\tabc, key11, key99\n", formatAdminRole(targetsRoleWithSigs))) assert.Check(t, is.Equal("Repository Key:\tabc, key11, key99\n", formatAdminRole(targetsRoleWithSigs)))
} }

View File

@ -14,10 +14,10 @@ import (
"github.com/docker/cli/cli/trust" "github.com/docker/cli/cli/trust"
imagetypes "github.com/docker/docker/api/types/image" imagetypes "github.com/docker/docker/api/types/image"
registrytypes "github.com/docker/docker/api/types/registry" registrytypes "github.com/docker/docker/api/types/registry"
apiclient "github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/theupdateframework/notary/client" notaryclient "github.com/theupdateframework/notary/client"
"github.com/theupdateframework/notary/tuf/data" "github.com/theupdateframework/notary/tuf/data"
) )
@ -64,7 +64,7 @@ func runSignImage(ctx context.Context, dockerCLI command.Cli, options signOption
// get the latest repository metadata so we can figure out which roles to sign // get the latest repository metadata so we can figure out which roles to sign
if _, err = notaryRepo.ListTargets(); err != nil { if _, err = notaryRepo.ListTargets(); err != nil {
switch err.(type) { switch err.(type) {
case client.ErrRepoNotInitialized, client.ErrRepositoryNotExist: case notaryclient.ErrRepoNotInitialized, notaryclient.ErrRepositoryNotExist:
// before initializing a new repo, check that the image exists locally: // before initializing a new repo, check that the image exists locally:
if err := checkLocalImageExistence(ctx, dockerCLI.Client(), imageName); err != nil { if err := checkLocalImageExistence(ctx, dockerCLI.Client(), imageName); err != nil {
return err return err
@ -86,7 +86,7 @@ func runSignImage(ctx context.Context, dockerCLI command.Cli, options signOption
if err != nil || options.local { if err != nil || options.local {
switch err := err.(type) { switch err := err.(type) {
// If the error is nil then the local flag is set // If the error is nil then the local flag is set
case client.ErrNoSuchTarget, client.ErrRepositoryNotExist, nil: case notaryclient.ErrNoSuchTarget, notaryclient.ErrRepositoryNotExist, nil:
// Fail fast if the image doesn't exist locally // Fail fast if the image doesn't exist locally
if err := checkLocalImageExistence(ctx, dockerCLI.Client(), imageName); err != nil { if err := checkLocalImageExistence(ctx, dockerCLI.Client(), imageName); err != nil {
return err return err
@ -110,7 +110,7 @@ func runSignImage(ctx context.Context, dockerCLI command.Cli, options signOption
return signAndPublishToTarget(dockerCLI.Out(), imgRefAndAuth, notaryRepo, target) return signAndPublishToTarget(dockerCLI.Out(), imgRefAndAuth, notaryRepo, target)
} }
func signAndPublishToTarget(out io.Writer, imgRefAndAuth trust.ImageRefAndAuth, notaryRepo client.Repository, target client.Target) error { func signAndPublishToTarget(out io.Writer, imgRefAndAuth trust.ImageRefAndAuth, notaryRepo notaryclient.Repository, target notaryclient.Target) error {
tag := imgRefAndAuth.Tag() tag := imgRefAndAuth.Tag()
fmt.Fprintf(out, "Signing and pushing trust metadata for %s\n", imgRefAndAuth.Name()) fmt.Fprintf(out, "Signing and pushing trust metadata for %s\n", imgRefAndAuth.Name())
existingSigInfo, err := getExistingSignatureInfoForReleasedTag(notaryRepo, tag) existingSigInfo, err := getExistingSignatureInfoForReleasedTag(notaryRepo, tag)
@ -140,13 +140,13 @@ func validateTag(imgRefAndAuth trust.ImageRefAndAuth) error {
return nil return nil
} }
func checkLocalImageExistence(ctx context.Context, apiClient apiclient.APIClient, imageName string) error { func checkLocalImageExistence(ctx context.Context, apiClient client.APIClient, imageName string) error {
_, _, err := apiClient.ImageInspectWithRaw(ctx, imageName) _, _, err := apiClient.ImageInspectWithRaw(ctx, imageName)
return err return err
} }
func createTarget(notaryRepo client.Repository, tag string) (client.Target, error) { func createTarget(notaryRepo notaryclient.Repository, tag string) (notaryclient.Target, error) {
target := &client.Target{} target := &notaryclient.Target{}
var err error var err error
if tag == "" { if tag == "" {
return *target, errors.New("no tag specified") return *target, errors.New("no tag specified")
@ -156,7 +156,7 @@ func createTarget(notaryRepo client.Repository, tag string) (client.Target, erro
return *target, err return *target, err
} }
func getSignedManifestHashAndSize(notaryRepo client.Repository, tag string) (data.Hashes, int64, error) { func getSignedManifestHashAndSize(notaryRepo notaryclient.Repository, tag string) (data.Hashes, int64, error) {
targets, err := notaryRepo.GetAllTargetMetadataByName(tag) targets, err := notaryRepo.GetAllTargetMetadataByName(tag)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
@ -164,16 +164,16 @@ func getSignedManifestHashAndSize(notaryRepo client.Repository, tag string) (dat
return getReleasedTargetHashAndSize(targets, tag) return getReleasedTargetHashAndSize(targets, tag)
} }
func getReleasedTargetHashAndSize(targets []client.TargetSignedStruct, tag string) (data.Hashes, int64, error) { func getReleasedTargetHashAndSize(targets []notaryclient.TargetSignedStruct, tag string) (data.Hashes, int64, error) {
for _, tgt := range targets { for _, tgt := range targets {
if isReleasedTarget(tgt.Role.Name) { if isReleasedTarget(tgt.Role.Name) {
return tgt.Target.Hashes, tgt.Target.Length, nil return tgt.Target.Hashes, tgt.Target.Length, nil
} }
} }
return nil, 0, client.ErrNoSuchTarget(tag) return nil, 0, notaryclient.ErrNoSuchTarget(tag)
} }
func getExistingSignatureInfoForReleasedTag(notaryRepo client.Repository, tag string) (trustTagRow, error) { func getExistingSignatureInfoForReleasedTag(notaryRepo notaryclient.Repository, tag string) (trustTagRow, error) {
targets, err := notaryRepo.GetAllTargetMetadataByName(tag) targets, err := notaryRepo.GetAllTargetMetadataByName(tag)
if err != nil { if err != nil {
return trustTagRow{}, err return trustTagRow{}, err
@ -191,7 +191,7 @@ func prettyPrintExistingSignatureInfo(out io.Writer, existingSigInfo trustTagRow
fmt.Fprintf(out, "Existing signatures for tag %s digest %s from:\n%s\n", existingSigInfo.SignedTag, existingSigInfo.Digest, joinedSigners) fmt.Fprintf(out, "Existing signatures for tag %s digest %s from:\n%s\n", existingSigInfo.SignedTag, existingSigInfo.Digest, joinedSigners)
} }
func initNotaryRepoWithSigners(notaryRepo client.Repository, newSigner data.RoleName) error { func initNotaryRepoWithSigners(notaryRepo notaryclient.Repository, newSigner data.RoleName) error {
rootKey, err := getOrGenerateNotaryKey(notaryRepo, data.CanonicalRootRole) rootKey, err := getOrGenerateNotaryKey(notaryRepo, data.CanonicalRootRole)
if err != nil { if err != nil {
return err return err
@ -215,7 +215,7 @@ func initNotaryRepoWithSigners(notaryRepo client.Repository, newSigner data.Role
} }
// generates an ECDSA key without a GUN for the specified role // generates an ECDSA key without a GUN for the specified role
func getOrGenerateNotaryKey(notaryRepo client.Repository, role data.RoleName) (data.PublicKey, error) { func getOrGenerateNotaryKey(notaryRepo notaryclient.Repository, role data.RoleName) (data.PublicKey, error) {
// use the signer name in the PEM headers if this is a delegation key // use the signer name in the PEM headers if this is a delegation key
if data.IsDelegation(role) { if data.IsDelegation(role) {
role = data.RoleName(notaryRoleToSigner(role)) role = data.RoleName(notaryRoleToSigner(role))
@ -242,7 +242,7 @@ func getOrGenerateNotaryKey(notaryRepo client.Repository, role data.RoleName) (d
} }
// stages changes to add a signer with the specified name and key(s). Adds to targets/<name> and targets/releases // stages changes to add a signer with the specified name and key(s). Adds to targets/<name> and targets/releases
func addStagedSigner(notaryRepo client.Repository, newSigner data.RoleName, signerKeys []data.PublicKey) error { func addStagedSigner(notaryRepo notaryclient.Repository, newSigner data.RoleName, signerKeys []data.PublicKey) error {
// create targets/<username> // create targets/<username>
if err := notaryRepo.AddDelegationRoleAndKeys(newSigner, signerKeys); err != nil { if err := notaryRepo.AddDelegationRoleAndKeys(newSigner, signerKeys); err != nil {
return err return err

View File

@ -3,7 +3,6 @@ package volume
import ( import (
"context" "context"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/volume" "github.com/docker/docker/api/types/volume"
"github.com/docker/docker/client" "github.com/docker/docker/client"
@ -15,7 +14,7 @@ type fakeClient struct {
volumeInspectFunc func(volumeID string) (volume.Volume, error) volumeInspectFunc func(volumeID string) (volume.Volume, error)
volumeListFunc func(filter filters.Args) (volume.ListResponse, error) volumeListFunc func(filter filters.Args) (volume.ListResponse, error)
volumeRemoveFunc func(volumeID string, force bool) error volumeRemoveFunc func(volumeID string, force bool) error
volumePruneFunc func(filter filters.Args) (types.VolumesPruneReport, error) volumePruneFunc func(filter filters.Args) (volume.PruneReport, error)
} }
func (c *fakeClient) VolumeCreate(_ context.Context, options volume.CreateOptions) (volume.Volume, error) { func (c *fakeClient) VolumeCreate(_ context.Context, options volume.CreateOptions) (volume.Volume, error) {
@ -39,11 +38,11 @@ func (c *fakeClient) VolumeList(_ context.Context, options volume.ListOptions) (
return volume.ListResponse{}, nil return volume.ListResponse{}, nil
} }
func (c *fakeClient) VolumesPrune(_ context.Context, filter filters.Args) (types.VolumesPruneReport, error) { func (c *fakeClient) VolumesPrune(_ context.Context, filter filters.Args) (volume.PruneReport, error) {
if c.volumePruneFunc != nil { if c.volumePruneFunc != nil {
return c.volumePruneFunc(filter) return c.volumePruneFunc(filter)
} }
return types.VolumesPruneReport{}, nil return volume.PruneReport{}, nil
} }
func (c *fakeClient) VolumeRemove(_ context.Context, volumeID string, force bool) error { func (c *fakeClient) VolumeRemove(_ context.Context, volumeID string, force bool) error {

View File

@ -10,8 +10,8 @@ import (
"github.com/docker/cli/cli/streams" "github.com/docker/cli/cli/streams"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/volume"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@ -24,7 +24,7 @@ func TestVolumePruneErrors(t *testing.T) {
name string name string
args []string args []string
flags map[string]string flags map[string]string
volumePruneFunc func(args filters.Args) (types.VolumesPruneReport, error) volumePruneFunc func(args filters.Args) (volume.PruneReport, error)
expectedError string expectedError string
}{ }{
{ {
@ -37,8 +37,8 @@ func TestVolumePruneErrors(t *testing.T) {
flags: map[string]string{ flags: map[string]string{
"force": "true", "force": "true",
}, },
volumePruneFunc: func(args filters.Args) (types.VolumesPruneReport, error) { volumePruneFunc: func(args filters.Args) (volume.PruneReport, error) {
return types.VolumesPruneReport{}, errors.Errorf("error pruning volumes") return volume.PruneReport{}, errors.Errorf("error pruning volumes")
}, },
expectedError: "error pruning volumes", expectedError: "error pruning volumes",
}, },
@ -75,31 +75,31 @@ func TestVolumePruneSuccess(t *testing.T) {
name string name string
args []string args []string
input string input string
volumePruneFunc func(args filters.Args) (types.VolumesPruneReport, error) volumePruneFunc func(args filters.Args) (volume.PruneReport, error)
}{ }{
{ {
name: "all", name: "all",
args: []string{"--all"}, args: []string{"--all"},
input: "y", input: "y",
volumePruneFunc: func(pruneFilter filters.Args) (types.VolumesPruneReport, error) { volumePruneFunc: func(pruneFilter filters.Args) (volume.PruneReport, error) {
assert.Check(t, is.DeepEqual([]string{"true"}, pruneFilter.Get("all"))) assert.Check(t, is.DeepEqual([]string{"true"}, pruneFilter.Get("all")))
return types.VolumesPruneReport{}, nil return volume.PruneReport{}, nil
}, },
}, },
{ {
name: "all-forced", name: "all-forced",
args: []string{"--all", "--force"}, args: []string{"--all", "--force"},
volumePruneFunc: func(pruneFilter filters.Args) (types.VolumesPruneReport, error) { volumePruneFunc: func(pruneFilter filters.Args) (volume.PruneReport, error) {
return types.VolumesPruneReport{}, nil return volume.PruneReport{}, nil
}, },
}, },
{ {
name: "label-filter", name: "label-filter",
args: []string{"--filter", "label=foobar"}, args: []string{"--filter", "label=foobar"},
input: "y", input: "y",
volumePruneFunc: func(pruneFilter filters.Args) (types.VolumesPruneReport, error) { volumePruneFunc: func(pruneFilter filters.Args) (volume.PruneReport, error) {
assert.Check(t, is.DeepEqual([]string{"foobar"}, pruneFilter.Get("label"))) assert.Check(t, is.DeepEqual([]string{"foobar"}, pruneFilter.Get("label")))
return types.VolumesPruneReport{}, nil return volume.PruneReport{}, nil
}, },
}, },
} }
@ -123,7 +123,7 @@ func TestVolumePruneSuccess(t *testing.T) {
func TestVolumePruneForce(t *testing.T) { func TestVolumePruneForce(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
volumePruneFunc func(args filters.Args) (types.VolumesPruneReport, error) volumePruneFunc func(args filters.Args) (volume.PruneReport, error)
}{ }{
{ {
name: "empty", name: "empty",
@ -178,8 +178,8 @@ func TestVolumePrunePromptNo(t *testing.T) {
} }
} }
func simplePruneFunc(filters.Args) (types.VolumesPruneReport, error) { func simplePruneFunc(filters.Args) (volume.PruneReport, error) {
return types.VolumesPruneReport{ return volume.PruneReport{
VolumesDeleted: []string{ VolumesDeleted: []string{
"foo", "bar", "baz", "foo", "bar", "baz",
}, },
@ -192,8 +192,8 @@ func TestVolumePrunePromptTerminate(t *testing.T) {
t.Cleanup(cancel) t.Cleanup(cancel)
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
volumePruneFunc: func(filter filters.Args) (types.VolumesPruneReport, error) { volumePruneFunc: func(filter filters.Args) (volume.PruneReport, error) {
return types.VolumesPruneReport{}, errors.New("fakeClient volumePruneFunc should not be called") return volume.PruneReport{}, errors.New("fakeClient volumePruneFunc should not be called")
}, },
}) })

View File

@ -12,7 +12,7 @@ require (
github.com/creack/pty v1.1.21 github.com/creack/pty v1.1.21
github.com/distribution/reference v0.6.0 github.com/distribution/reference v0.6.0
github.com/docker/distribution v2.8.3+incompatible github.com/docker/distribution v2.8.3+incompatible
github.com/docker/docker v26.1.1-0.20240607121412-59996a493cfc+incompatible // master (v27.0.0-dev) github.com/docker/docker v26.1.1-0.20240610145149-a736d0701c41+incompatible // master (v27.0.0-dev)
github.com/docker/docker-credential-helpers v0.8.2 github.com/docker/docker-credential-helpers v0.8.2
github.com/docker/go-connections v0.5.0 github.com/docker/go-connections v0.5.0
github.com/docker/go-units v0.5.0 github.com/docker/go-units v0.5.0

View File

@ -59,8 +59,8 @@ github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v26.1.1-0.20240607121412-59996a493cfc+incompatible h1:MQR7fZxS7agfjACehtep/M6Bvz7/pFvbOcFvtTmvKlg= github.com/docker/docker v26.1.1-0.20240610145149-a736d0701c41+incompatible h1:Kraon288jb3POkrmM5w6Xo979z2rrCtFzHycAjafRes=
github.com/docker/docker v26.1.1-0.20240607121412-59996a493cfc+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v26.1.1-0.20240610145149-a736d0701c41+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=

View File

@ -1198,13 +1198,6 @@ definitions:
ContainerConfig: ContainerConfig:
description: | description: |
Configuration for a container that is portable between hosts. Configuration for a container that is portable between hosts.
When used as `ContainerConfig` field in an image, `ContainerConfig` is an
optional field containing the configuration of the container that was last
committed when creating the image.
Previous versions of Docker builder used this field to store build cache,
and it is not in active use anymore.
type: "object" type: "object"
properties: properties:
Hostname: Hostname:
@ -1363,6 +1356,277 @@ definitions:
type: "string" type: "string"
example: ["/bin/sh", "-c"] example: ["/bin/sh", "-c"]
ImageConfig:
description: |
Configuration of the image. These fields are used as defaults
when starting a container from the image.
type: "object"
properties:
Hostname:
description: |
The hostname to use for the container, as a valid RFC 1123 hostname.
<p><br /></p>
> **Note**: this field is always empty and must not be used.
type: "string"
example: ""
Domainname:
description: |
The domain name to use for the container.
<p><br /></p>
> **Note**: this field is always empty and must not be used.
type: "string"
example: ""
User:
description: "The user that commands are run as inside the container."
type: "string"
example: "web:web"
AttachStdin:
description: |
Whether to attach to `stdin`.
<p><br /></p>
> **Note**: this field is always false and must not be used.
type: "boolean"
default: false
example: false
AttachStdout:
description: |
Whether to attach to `stdout`.
<p><br /></p>
> **Note**: this field is always false and must not be used.
type: "boolean"
default: false
example: false
AttachStderr:
description: |
Whether to attach to `stderr`.
<p><br /></p>
> **Note**: this field is always false and must not be used.
type: "boolean"
default: false
example: false
ExposedPorts:
description: |
An object mapping ports to an empty object in the form:
`{"<port>/<tcp|udp|sctp>": {}}`
type: "object"
x-nullable: true
additionalProperties:
type: "object"
enum:
- {}
default: {}
example: {
"80/tcp": {},
"443/tcp": {}
}
Tty:
description: |
Attach standard streams to a TTY, including `stdin` if it is not closed.
<p><br /></p>
> **Note**: this field is always false and must not be used.
type: "boolean"
default: false
example: false
OpenStdin:
description: |
Open `stdin`
<p><br /></p>
> **Note**: this field is always false and must not be used.
type: "boolean"
default: false
example: false
StdinOnce:
description: |
Close `stdin` after one attached client disconnects.
<p><br /></p>
> **Note**: this field is always false and must not be used.
type: "boolean"
default: false
example: false
Env:
description: |
A list of environment variables to set inside the container in the
form `["VAR=value", ...]`. A variable without `=` is removed from the
environment, rather than to have an empty value.
type: "array"
items:
type: "string"
example:
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Cmd:
description: |
Command to run specified as a string or an array of strings.
type: "array"
items:
type: "string"
example: ["/bin/sh"]
Healthcheck:
$ref: "#/definitions/HealthConfig"
ArgsEscaped:
description: "Command is already escaped (Windows only)"
type: "boolean"
default: false
example: false
x-nullable: true
Image:
description: |
The name (or reference) of the image to use when creating the container,
or which was used when the container was created.
<p><br /></p>
> **Note**: this field is always empty and must not be used.
type: "string"
default: ""
example: ""
Volumes:
description: |
An object mapping mount point paths inside the container to empty
objects.
type: "object"
additionalProperties:
type: "object"
enum:
- {}
default: {}
example:
"/app/data": {}
"/app/config": {}
WorkingDir:
description: "The working directory for commands to run in."
type: "string"
example: "/public/"
Entrypoint:
description: |
The entry point for the container as a string or an array of strings.
If the array consists of exactly one empty string (`[""]`) then the
entry point is reset to system default (i.e., the entry point used by
docker when there is no `ENTRYPOINT` instruction in the `Dockerfile`).
type: "array"
items:
type: "string"
example: []
NetworkDisabled:
description: |
Disable networking for the container.
<p><br /></p>
> **Note**: this field is always omitted and must not be used.
type: "boolean"
default: false
example: false
x-nullable: true
MacAddress:
description: |
MAC address of the container.
<p><br /></p>
> **Deprecated**: this field is deprecated in API v1.44 and up. It is always omitted.
type: "string"
default: ""
example: ""
x-nullable: true
OnBuild:
description: |
`ONBUILD` metadata that were defined in the image's `Dockerfile`.
type: "array"
x-nullable: true
items:
type: "string"
example: []
Labels:
description: "User-defined key/value metadata."
type: "object"
additionalProperties:
type: "string"
example:
com.example.some-label: "some-value"
com.example.some-other-label: "some-other-value"
StopSignal:
description: |
Signal to stop a container as a string or unsigned integer.
type: "string"
example: "SIGTERM"
x-nullable: true
StopTimeout:
description: |
Timeout to stop a container in seconds.
<p><br /></p>
> **Note**: this field is always omitted and must not be used.
type: "integer"
default: 10
x-nullable: true
Shell:
description: |
Shell for when `RUN`, `CMD`, and `ENTRYPOINT` uses a shell.
type: "array"
x-nullable: true
items:
type: "string"
example: ["/bin/sh", "-c"]
# FIXME(thaJeztah): temporarily using a full example to remove some "omitempty" fields. Remove once the fields are removed.
example:
"Hostname": ""
"Domainname": ""
"User": "web:web"
"AttachStdin": false
"AttachStdout": false
"AttachStderr": false
"ExposedPorts": {
"80/tcp": {},
"443/tcp": {}
}
"Tty": false
"OpenStdin": false
"StdinOnce": false
"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"]
"Cmd": ["/bin/sh"]
"Healthcheck": {
"Test": ["string"],
"Interval": 0,
"Timeout": 0,
"Retries": 0,
"StartPeriod": 0,
"StartInterval": 0
}
"ArgsEscaped": true
"Image": ""
"Volumes": {
"/app/data": {},
"/app/config": {}
}
"WorkingDir": "/public/"
"Entrypoint": []
"OnBuild": []
"Labels": {
"com.example.some-label": "some-value",
"com.example.some-other-label": "some-other-value"
}
"StopSignal": "SIGTERM"
"Shell": ["/bin/sh", "-c"]
NetworkingConfig: NetworkingConfig:
description: | description: |
NetworkingConfig represents the container's networking configuration for NetworkingConfig represents the container's networking configuration for
@ -1758,21 +2022,6 @@ definitions:
format: "dateTime" format: "dateTime"
x-nullable: true x-nullable: true
example: "2022-02-04T21:20:12.497794809Z" example: "2022-02-04T21:20:12.497794809Z"
Container:
description: |
The ID of the container that was used to create the image.
Depending on how the image was created, this field may be empty.
**Deprecated**: this field is kept for backward compatibility, but
will be removed in API v1.45.
type: "string"
example: "65974bc86f1770ae4bff79f651ebdbce166ae9aada632ee3fa9af3a264911735"
ContainerConfig:
description: |
**Deprecated**: this field is kept for backward compatibility, but
will be removed in API v1.45.
$ref: "#/definitions/ContainerConfig"
DockerVersion: DockerVersion:
description: | description: |
The version of Docker that was used to build the image. The version of Docker that was used to build the image.
@ -1789,7 +2038,7 @@ definitions:
x-nullable: false x-nullable: false
example: "" example: ""
Config: Config:
$ref: "#/definitions/ContainerConfig" $ref: "#/definitions/ImageConfig"
Architecture: Architecture:
description: | description: |
Hardware CPU architecture that the image runs on. Hardware CPU architecture that the image runs on.

View File

@ -12,29 +12,6 @@ import (
units "github.com/docker/go-units" units "github.com/docker/go-units"
) )
// ContainerExecInspect holds information returned by exec inspect.
type ContainerExecInspect struct {
ExecID string `json:"ID"`
ContainerID string
Running bool
ExitCode int
Pid int
}
// CopyToContainerOptions holds information
// about files to copy into a container
type CopyToContainerOptions struct {
AllowOverwriteDirWithFile bool
CopyUIDGID bool
}
// EventsOptions holds parameters to filter events with.
type EventsOptions struct {
Since string
Until string
Filters filters.Args
}
// NewHijackedResponse intializes a HijackedResponse type // NewHijackedResponse intializes a HijackedResponse type
func NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse { func NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse {
return HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType} return HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType}
@ -153,19 +130,6 @@ type ImageBuildResponse struct {
OSType string OSType string
} }
// ImageImportSource holds source information for ImageImport
type ImageImportSource struct {
Source io.Reader // Source is the data to send to the server to create this image from. You must set SourceName to "-" to leverage this.
SourceName string // SourceName is the name of the image to pull. Set to "-" to leverage the Source attribute.
}
// ImageLoadResponse returns information to the client about a load process.
type ImageLoadResponse struct {
// Body must be closed to avoid a resource leak
Body io.ReadCloser
JSON bool
}
// RequestPrivilegeFunc is a function interface that // RequestPrivilegeFunc is a function interface that
// clients can supply to retry operations after // clients can supply to retry operations after
// getting an authorization error. // getting an authorization error.
@ -174,14 +138,6 @@ type ImageLoadResponse struct {
// if the privilege request fails. // if the privilege request fails.
type RequestPrivilegeFunc func(context.Context) (string, error) type RequestPrivilegeFunc func(context.Context) (string, error)
// ImageSearchOptions holds parameters to search images with.
type ImageSearchOptions struct {
RegistryAuth string
PrivilegeFunc RequestPrivilegeFunc
Filters filters.Args
Limit int
}
// NodeListOptions holds parameters to list nodes with. // NodeListOptions holds parameters to list nodes with.
type NodeListOptions struct { type NodeListOptions struct {
Filters filters.Args Filters filters.Args

View File

@ -1,18 +0,0 @@
package types // import "github.com/docker/docker/api/types"
// ExecConfig is a small subset of the Config struct that holds the configuration
// for the exec feature of docker.
type ExecConfig struct {
User string // User that will run the command
Privileged bool // Is the container in privileged mode
Tty bool // Attach standard streams to a tty.
ConsoleSize *[2]uint `json:",omitempty"` // Initial console size [height, width]
AttachStdin bool // Attach the standard input, makes possible user interaction
AttachStderr bool // Attach the standard error
AttachStdout bool // Attach the standard output
Detach bool // Execute in detach mode
DetachKeys string // Escape keys for detach
Env []string // Environment variables
WorkingDir string // Working directory
Cmd []string // Execution commands and args
}

View File

@ -1,7 +1,6 @@
package container // import "github.com/docker/docker/api/types/container" package container // import "github.com/docker/docker/api/types/container"
import ( import (
"io"
"time" "time"
"github.com/docker/docker/api/types/strslice" "github.com/docker/docker/api/types/strslice"
@ -36,14 +35,6 @@ type StopOptions struct {
// HealthConfig holds configuration settings for the HEALTHCHECK feature. // HealthConfig holds configuration settings for the HEALTHCHECK feature.
type HealthConfig = dockerspec.HealthcheckConfig type HealthConfig = dockerspec.HealthcheckConfig
// ExecStartOptions holds the options to start container's exec.
type ExecStartOptions struct {
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
ConsoleSize *[2]uint `json:",omitempty"`
}
// Config contains the configuration data about a container. // Config contains the configuration data about a container.
// It should hold only portable information about the container. // It should hold only portable information about the container.
// Here, "portable" means "independent from the host we are running on". // Here, "portable" means "independent from the host we are running on".

View File

@ -0,0 +1,39 @@
package container
import (
"io"
"os"
"time"
)
// PruneReport contains the response for Engine API:
// POST "/containers/prune"
type PruneReport struct {
ContainersDeleted []string
SpaceReclaimed uint64
}
// PathStat is used to encode the header from
// GET "/containers/{name:.*}/archive"
// "Name" is the file or directory name.
type PathStat struct {
Name string `json:"name"`
Size int64 `json:"size"`
Mode os.FileMode `json:"mode"`
Mtime time.Time `json:"mtime"`
LinkTarget string `json:"linkTarget"`
}
// CopyToContainerOptions holds information
// about files to copy into a container
type CopyToContainerOptions struct {
AllowOverwriteDirWithFile bool
CopyUIDGID bool
}
// StatsResponse contains response of Engine API:
// GET "/stats"
type StatsResponse struct {
Body io.ReadCloser `json:"body"`
OSType string `json:"ostype"`
}

View File

@ -0,0 +1,43 @@
package container
// ExecOptions is a small subset of the Config struct that holds the configuration
// for the exec feature of docker.
type ExecOptions struct {
User string // User that will run the command
Privileged bool // Is the container in privileged mode
Tty bool // Attach standard streams to a tty.
ConsoleSize *[2]uint `json:",omitempty"` // Initial console size [height, width]
AttachStdin bool // Attach the standard input, makes possible user interaction
AttachStderr bool // Attach the standard error
AttachStdout bool // Attach the standard output
Detach bool // Execute in detach mode
DetachKeys string // Escape keys for detach
Env []string // Environment variables
WorkingDir string // Working directory
Cmd []string // Execution commands and args
}
// ExecStartOptions is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package
type ExecStartOptions struct {
// ExecStart will first check if it's detached
Detach bool
// Check if there's a tty
Tty bool
// Terminal size [height, width], unused if Tty == false
ConsoleSize *[2]uint `json:",omitempty"`
}
// ExecAttachOptions is a temp struct used by execAttach.
//
// TODO(thaJeztah): make this a separate type; ContainerExecAttach does not use the Detach option, and cannot run detached.
type ExecAttachOptions = ExecStartOptions
// ExecInspect holds information returned by exec inspect.
type ExecInspect struct {
ExecID string `json:"ID"`
ContainerID string
Running bool
ExitCode int
Pid int
}

View File

@ -1,4 +1,5 @@
package events // import "github.com/docker/docker/api/types/events" package events // import "github.com/docker/docker/api/types/events"
import "github.com/docker/docker/api/types/filters"
// Type is used for event-types. // Type is used for event-types.
type Type string type Type string
@ -125,3 +126,10 @@ type Message struct {
Time int64 `json:"time,omitempty"` Time int64 `json:"time,omitempty"`
TimeNano int64 `json:"timeNano,omitempty"` TimeNano int64 `json:"timeNano,omitempty"`
} }
// ListOptions holds parameters to filter events with.
type ListOptions struct {
Since string
Until string
Filters filters.Args
}

View File

@ -1,9 +1,47 @@
package image package image
import "time" import (
"io"
"time"
)
// Metadata contains engine-local data about the image. // Metadata contains engine-local data about the image.
type Metadata struct { type Metadata struct {
// LastTagTime is the date and time at which the image was last tagged. // LastTagTime is the date and time at which the image was last tagged.
LastTagTime time.Time `json:",omitempty"` LastTagTime time.Time `json:",omitempty"`
} }
// PruneReport contains the response for Engine API:
// POST "/images/prune"
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

@ -2,10 +2,17 @@ package image
import ( import (
"context" "context"
"io"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
) )
// ImportSource holds source information for ImageImport
type ImportSource struct {
Source io.Reader // Source is the data to send to the server to create this image from. You must set SourceName to "-" to leverage this.
SourceName string // SourceName is the name of the image to pull. Set to "-" to leverage the Source attribute.
}
// ImportOptions holds information to import images from the client host. // ImportOptions holds information to import images from the client host.
type ImportOptions struct { type ImportOptions struct {
Tag string // Tag is the name to tag this image with. This attribute is deprecated. Tag string // Tag is the name to tag this image with. This attribute is deprecated.

View File

@ -84,32 +84,6 @@ type IndexInfo struct {
Official bool Official bool
} }
// SearchResult describes a search result returned from a registry
type SearchResult struct {
// StarCount indicates the number of stars this repository has
StarCount int `json:"star_count"`
// IsOfficial is true if the result is from an official repository.
IsOfficial bool `json:"is_official"`
// Name is the name of the repository
Name string `json:"name"`
// IsAutomated indicates whether the result is automated.
//
// Deprecated: the "is_automated" field is deprecated and will always be "false".
IsAutomated bool `json:"is_automated"`
// Description is a textual description of the repository
Description string `json:"description"`
}
// SearchResults lists a collection search results returned from a registry
type SearchResults struct {
// Query contains the query string that generated the search results
Query string `json:"query"`
// NumResults indicates the number of results the query returned
NumResults int `json:"num_results"`
// Results is a slice containing the actual results for the search
Results []SearchResult `json:"results"`
}
// DistributionInspect describes the result obtained from contacting the // DistributionInspect describes the result obtained from contacting the
// registry to retrieve image metadata // registry to retrieve image metadata
type DistributionInspect struct { type DistributionInspect struct {

View File

@ -0,0 +1,47 @@
package registry
import (
"context"
"github.com/docker/docker/api/types/filters"
)
// SearchOptions holds parameters to search images with.
type SearchOptions struct {
RegistryAuth string
// PrivilegeFunc is a [types.RequestPrivilegeFunc] the client can
// supply to retry operations after getting an authorization error.
//
// It must return the registry authentication header value in base64
// format, or an error if the privilege request fails.
PrivilegeFunc func(context.Context) (string, error)
Filters filters.Args
Limit int
}
// SearchResult describes a search result returned from a registry
type SearchResult struct {
// StarCount indicates the number of stars this repository has
StarCount int `json:"star_count"`
// IsOfficial is true if the result is from an official repository.
IsOfficial bool `json:"is_official"`
// Name is the name of the repository
Name string `json:"name"`
// IsAutomated indicates whether the result is automated.
//
// Deprecated: the "is_automated" field is deprecated and will always be "false".
IsAutomated bool `json:"is_automated"`
// Description is a textual description of the repository
Description string `json:"description"`
}
// SearchResults lists a collection search results returned from a registry
type SearchResults struct {
// Query contains the query string that generated the search results
Query string `json:"query"`
// NumResults indicates the number of results the query returned
NumResults int `json:"num_results"`
// Results is a slice containing the actual results for the search
Results []SearchResult `json:"results"`
}

View File

@ -1,8 +1,6 @@
package types // import "github.com/docker/docker/api/types" package types // import "github.com/docker/docker/api/types"
import ( import (
"io"
"os"
"time" "time"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
@ -162,30 +160,6 @@ type Container struct {
Mounts []MountPoint Mounts []MountPoint
} }
// CopyConfig contains request body of Engine API:
// POST "/containers/"+containerID+"/copy"
type CopyConfig struct {
Resource string
}
// ContainerPathStat is used to encode the header from
// GET "/containers/{name:.*}/archive"
// "Name" is the file or directory name.
type ContainerPathStat struct {
Name string `json:"name"`
Size int64 `json:"size"`
Mode os.FileMode `json:"mode"`
Mtime time.Time `json:"mtime"`
LinkTarget string `json:"linkTarget"`
}
// ContainerStats contains response of Engine API:
// GET "/stats"
type ContainerStats struct {
Body io.ReadCloser `json:"body"`
OSType string `json:"ostype"`
}
// Ping contains response of Engine API: // Ping contains response of Engine API:
// GET "/_ping" // GET "/_ping"
type Ping struct { type Ping struct {
@ -231,17 +205,6 @@ type Version struct {
BuildTime string `json:",omitempty"` BuildTime string `json:",omitempty"`
} }
// ExecStartCheck is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package
type ExecStartCheck struct {
// ExecStart will first check if it's detached
Detach bool
// Check if there's a tty
Tty bool
// Terminal size [height, width], unused if Tty == false
ConsoleSize *[2]uint `json:",omitempty"`
}
// HealthcheckResult stores information about a single run of a healthcheck probe // HealthcheckResult stores information about a single run of a healthcheck probe
type HealthcheckResult struct { type HealthcheckResult struct {
Start time.Time // Start is the time this check started Start time.Time // Start is the time this check started
@ -456,27 +419,6 @@ type DiskUsage struct {
BuilderSize int64 `json:",omitempty"` // Deprecated: deprecated in API 1.38, and no longer used since API 1.40. BuilderSize int64 `json:",omitempty"` // Deprecated: deprecated in API 1.38, and no longer used since API 1.40.
} }
// ContainersPruneReport contains the response for Engine API:
// POST "/containers/prune"
type ContainersPruneReport struct {
ContainersDeleted []string
SpaceReclaimed uint64
}
// VolumesPruneReport contains the response for Engine API:
// POST "/volumes/prune"
type VolumesPruneReport struct {
VolumesDeleted []string
SpaceReclaimed uint64
}
// ImagesPruneReport contains the response for Engine API:
// POST "/images/prune"
type ImagesPruneReport struct {
ImagesDeleted []image.DeleteResponse
SpaceReclaimed uint64
}
// BuildCachePruneReport contains the response for Engine API: // BuildCachePruneReport contains the response for Engine API:
// POST "/build/prune" // POST "/build/prune"
type BuildCachePruneReport struct { type BuildCachePruneReport struct {

View File

@ -1,9 +1,26 @@
package types package types
import ( import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/volume"
) )
// ImagesPruneReport contains the response for Engine API:
// POST "/images/prune"
//
// Deprecated: use [image.PruneReport].
type ImagesPruneReport = image.PruneReport
// VolumesPruneReport contains the response for Engine API:
// POST "/volumes/prune".
//
// Deprecated: use [volume.PruneReport].
type VolumesPruneReport = volume.PruneReport
// NetworkCreateRequest is the request message sent to the server for network create call. // NetworkCreateRequest is the request message sent to the server for network create call.
// //
// Deprecated: use [network.CreateRequest]. // Deprecated: use [network.CreateRequest].
@ -54,3 +71,65 @@ type NetworkResource = network.Inspect
// //
// Deprecated: use [network.PruneReport]. // Deprecated: use [network.PruneReport].
type NetworksPruneReport = network.PruneReport type NetworksPruneReport = network.PruneReport
// ExecConfig is a small subset of the Config struct that holds the configuration
// for the exec feature of docker.
//
// Deprecated: use [container.ExecOptions].
type ExecConfig = container.ExecOptions
// ExecStartCheck is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package
//
// Deprecated: use [container.ExecStartOptions] or [container.ExecAttachOptions].
type ExecStartCheck = container.ExecStartOptions
// ContainerExecInspect holds information returned by exec inspect.
//
// Deprecated: use [container.ExecInspect].
type ContainerExecInspect = container.ExecInspect
// ContainersPruneReport contains the response for Engine API:
// POST "/containers/prune"
//
// Deprecated: use [container.PruneReport].
type ContainersPruneReport = container.PruneReport
// ContainerPathStat is used to encode the header from
// GET "/containers/{name:.*}/archive"
// "Name" is the file or directory name.
//
// Deprecated: use [container.PathStat].
type ContainerPathStat = container.PathStat
// CopyToContainerOptions holds information
// about files to copy into a container.
//
// Deprecated: use [container.CopyToContainerOptions],
type CopyToContainerOptions = container.CopyToContainerOptions
// ContainerStats contains response of Engine API:
// GET "/stats"
//
// Deprecated: use [container.StatsResponse].
type ContainerStats = container.StatsResponse
// EventsOptions holds parameters to filter events with.
//
// Deprecated: use [events.ListOptions].
type EventsOptions = events.ListOptions
// ImageSearchOptions holds parameters to search images with.
//
// Deprecated: use [registry.SearchOptions].
type ImageSearchOptions = registry.SearchOptions
// ImageImportSource holds source information for ImageImport
//
// Deprecated: use [image.ImportSource].
type ImageImportSource image.ImportSource
// ImageLoadResponse returns information to the client about a load process.
//
// Deprecated: use [image.LoadResponse].
type ImageLoadResponse = image.LoadResponse

View File

@ -6,3 +6,10 @@ import "github.com/docker/docker/api/types/filters"
type ListOptions struct { type ListOptions struct {
Filters filters.Args Filters filters.Args
} }
// PruneReport contains the response for Engine API:
// POST "/volumes/prune"
type PruneReport struct {
VolumesDeleted []string
SpaceReclaimed uint64
}

View File

@ -11,11 +11,11 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container"
) )
// ContainerStatPath returns stat information about a path inside the container filesystem. // ContainerStatPath returns stat information about a path inside the container filesystem.
func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path string) (types.ContainerPathStat, error) { func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path string) (container.PathStat, error) {
query := url.Values{} query := url.Values{}
query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API. query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API.
@ -23,14 +23,14 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri
response, err := cli.head(ctx, urlStr, query, nil) response, err := cli.head(ctx, urlStr, query, nil)
defer ensureReaderClosed(response) defer ensureReaderClosed(response)
if err != nil { if err != nil {
return types.ContainerPathStat{}, err return container.PathStat{}, err
} }
return getContainerPathStatFromHeader(response.header) return getContainerPathStatFromHeader(response.header)
} }
// CopyToContainer copies content into the container filesystem. // CopyToContainer copies content into the container filesystem.
// Note that `content` must be a Reader for a TAR archive // 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 types.CopyToContainerOptions) error { func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options container.CopyToContainerOptions) error {
query := url.Values{} query := url.Values{}
query.Set("path", filepath.ToSlash(dstPath)) // Normalize the paths used in the API. query.Set("path", filepath.ToSlash(dstPath)) // Normalize the paths used in the API.
// Do not allow for an existing directory to be overwritten by a non-directory and vice versa. // Do not allow for an existing directory to be overwritten by a non-directory and vice versa.
@ -55,14 +55,14 @@ func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath str
// CopyFromContainer gets the content from the container and returns it as a Reader // CopyFromContainer gets the content from the container and returns it as a Reader
// for a TAR archive to manipulate it in the host. It's up to the caller to close the reader. // for a TAR archive to manipulate it in the host. It's up to the caller to close the reader.
func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, container.PathStat, error) {
query := make(url.Values, 1) query := make(url.Values, 1)
query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API. query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API.
apiPath := "/containers/" + containerID + "/archive" apiPath := "/containers/" + containerID + "/archive"
response, err := cli.get(ctx, apiPath, query, nil) response, err := cli.get(ctx, apiPath, query, nil)
if err != nil { if err != nil {
return nil, types.ContainerPathStat{}, err return nil, container.PathStat{}, err
} }
// In order to get the copy behavior right, we need to know information // In order to get the copy behavior right, we need to know information
@ -78,8 +78,8 @@ func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath s
return response.body, stat, err return response.body, stat, err
} }
func getContainerPathStatFromHeader(header http.Header) (types.ContainerPathStat, error) { func getContainerPathStatFromHeader(header http.Header) (container.PathStat, error) {
var stat types.ContainerPathStat var stat container.PathStat
encodedStat := header.Get("X-Docker-Container-Path-Stat") encodedStat := header.Get("X-Docker-Container-Path-Stat")
statDecoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(encodedStat)) statDecoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(encodedStat))

View File

@ -6,11 +6,12 @@ import (
"net/http" "net/http"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
) )
// ContainerExecCreate creates a new exec configuration to run an exec process. // ContainerExecCreate creates a new exec configuration to run an exec process.
func (cli *Client) ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error) { func (cli *Client) ContainerExecCreate(ctx context.Context, container string, options container.ExecOptions) (types.IDResponse, error) {
var response types.IDResponse var response types.IDResponse
// Make sure we negotiated (if the client is configured to do so), // Make sure we negotiated (if the client is configured to do so),
@ -22,14 +23,14 @@ func (cli *Client) ContainerExecCreate(ctx context.Context, container string, co
return response, err return response, err
} }
if err := cli.NewVersionError(ctx, "1.25", "env"); len(config.Env) != 0 && err != nil { if err := cli.NewVersionError(ctx, "1.25", "env"); len(options.Env) != 0 && err != nil {
return response, err return response, err
} }
if versions.LessThan(cli.ClientVersion(), "1.42") { if versions.LessThan(cli.ClientVersion(), "1.42") {
config.ConsoleSize = nil options.ConsoleSize = nil
} }
resp, err := cli.post(ctx, "/containers/"+container+"/exec", nil, config, nil) resp, err := cli.post(ctx, "/containers/"+container+"/exec", nil, options, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {
return response, err return response, err
@ -39,7 +40,7 @@ func (cli *Client) ContainerExecCreate(ctx context.Context, container string, co
} }
// ContainerExecStart starts an exec process already created in the docker host. // ContainerExecStart starts an exec process already created in the docker host.
func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error { func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config container.ExecStartOptions) error {
if versions.LessThan(cli.ClientVersion(), "1.42") { if versions.LessThan(cli.ClientVersion(), "1.42") {
config.ConsoleSize = nil config.ConsoleSize = nil
} }
@ -52,7 +53,7 @@ func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config
// It returns a types.HijackedConnection with the hijacked connection // It returns a types.HijackedConnection with the hijacked connection
// and the a reader to get output. It's up to the called to close // and the a reader to get output. It's up to the called to close
// the hijacked connection by calling types.HijackedResponse.Close. // the hijacked connection by calling types.HijackedResponse.Close.
func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error) { func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config container.ExecAttachOptions) (types.HijackedResponse, error) {
if versions.LessThan(cli.ClientVersion(), "1.42") { if versions.LessThan(cli.ClientVersion(), "1.42") {
config.ConsoleSize = nil config.ConsoleSize = nil
} }
@ -62,8 +63,8 @@ func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, confi
} }
// ContainerExecInspect returns information about a specific exec process on the docker host. // ContainerExecInspect returns information about a specific exec process on the docker host.
func (cli *Client) ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) { func (cli *Client) ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error) {
var response types.ContainerExecInspect var response container.ExecInspect
resp, err := cli.get(ctx, "/exec/"+execID+"/json", nil, nil) resp, err := cli.get(ctx, "/exec/"+execID+"/json", nil, nil)
if err != nil { if err != nil {
return response, err return response, err

View File

@ -5,13 +5,13 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
) )
// ContainersPrune requests the daemon to delete unused data // ContainersPrune requests the daemon to delete unused data
func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) { func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) {
var report types.ContainersPruneReport var report container.PruneReport
if err := cli.NewVersionError(ctx, "1.25", "container prune"); err != nil { if err := cli.NewVersionError(ctx, "1.25", "container prune"); err != nil {
return report, err return report, err

View File

@ -4,12 +4,12 @@ import (
"context" "context"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container"
) )
// ContainerStats returns near realtime stats for a given container. // ContainerStats returns near realtime stats for a given container.
// It's up to the caller to close the io.ReadCloser returned. // It's up to the caller to close the io.ReadCloser returned.
func (cli *Client) ContainerStats(ctx context.Context, containerID string, stream bool) (types.ContainerStats, error) { func (cli *Client) ContainerStats(ctx context.Context, containerID string, stream bool) (container.StatsResponse, error) {
query := url.Values{} query := url.Values{}
query.Set("stream", "0") query.Set("stream", "0")
if stream { if stream {
@ -18,10 +18,10 @@ func (cli *Client) ContainerStats(ctx context.Context, containerID string, strea
resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil) resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil)
if err != nil { if err != nil {
return types.ContainerStats{}, err return container.StatsResponse{}, err
} }
return types.ContainerStats{ return container.StatsResponse{
Body: resp.body, Body: resp.body,
OSType: getDockerOS(resp.header.Get("Server")), OSType: getDockerOS(resp.header.Get("Server")),
}, nil }, nil
@ -29,17 +29,17 @@ func (cli *Client) ContainerStats(ctx context.Context, containerID string, strea
// ContainerStatsOneShot gets a single stat entry from a container. // ContainerStatsOneShot gets a single stat entry from a container.
// It differs from `ContainerStats` in that the API should not wait to prime the stats // It differs from `ContainerStats` in that the API should not wait to prime the stats
func (cli *Client) ContainerStatsOneShot(ctx context.Context, containerID string) (types.ContainerStats, error) { func (cli *Client) ContainerStatsOneShot(ctx context.Context, containerID string) (container.StatsResponse, error) {
query := url.Values{} query := url.Values{}
query.Set("stream", "0") query.Set("stream", "0")
query.Set("one-shot", "1") query.Set("one-shot", "1")
resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil) resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil)
if err != nil { if err != nil {
return types.ContainerStats{}, err return container.StatsResponse{}, err
} }
return types.ContainerStats{ return container.StatsResponse{
Body: resp.body, Body: resp.body,
OSType: getDockerOS(resp.header.Get("Server")), OSType: getDockerOS(resp.header.Get("Server")),
}, nil }, nil

View File

@ -6,7 +6,6 @@ import (
"net/url" "net/url"
"time" "time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
timetypes "github.com/docker/docker/api/types/time" timetypes "github.com/docker/docker/api/types/time"
@ -16,7 +15,7 @@ import (
// by cancelling the context. Once the stream has been completely read an io.EOF error will // by cancelling the context. Once the stream has been completely read an io.EOF error will
// be sent over the error channel. If an error is sent all processing will be stopped. It's up // be sent over the error channel. If an error is sent all processing will be stopped. It's up
// to the caller to reopen the stream in the event of an error by reinvoking this method. // to the caller to reopen the stream in the event of an error by reinvoking this method.
func (cli *Client) Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error) { func (cli *Client) Events(ctx context.Context, options events.ListOptions) (<-chan events.Message, <-chan error) {
messages := make(chan events.Message) messages := make(chan events.Message)
errs := make(chan error, 1) errs := make(chan error, 1)
@ -68,7 +67,7 @@ func (cli *Client) Events(ctx context.Context, options types.EventsOptions) (<-c
return messages, errs return messages, errs
} }
func buildEventsQueryParams(cliVersion string, options types.EventsOptions) (url.Values, error) { func buildEventsQueryParams(cliVersion string, options events.ListOptions) (url.Values, error) {
query := url.Values{} query := url.Values{}
ref := time.Now() ref := time.Now()

View File

@ -7,13 +7,12 @@ import (
"strings" "strings"
"github.com/distribution/reference" "github.com/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
) )
// ImageImport creates a new image based on the source options. // ImageImport creates a new image based on the source options.
// It returns the JSON content in the response body. // It returns the JSON content in the response body.
func (cli *Client) ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) { func (cli *Client) ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) {
if ref != "" { if ref != "" {
// Check if the given image name can be resolved // Check if the given image name can be resolved
if _, err := reference.ParseNormalizedNamed(ref); err != nil { if _, err := reference.ParseNormalizedNamed(ref); err != nil {

View File

@ -6,13 +6,13 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/image"
) )
// ImageLoad loads an image in the docker host from the client host. // ImageLoad loads an image in the docker host from the client host.
// It's up to the caller to close the io.ReadCloser in the // It's up to the caller to close the io.ReadCloser in the
// ImageLoadResponse returned by this function. // ImageLoadResponse returned by this function.
func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error) { func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (image.LoadResponse, error) {
v := url.Values{} v := url.Values{}
v.Set("quiet", "0") v.Set("quiet", "0")
if quiet { if quiet {
@ -22,9 +22,9 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (
"Content-Type": {"application/x-tar"}, "Content-Type": {"application/x-tar"},
}) })
if err != nil { if err != nil {
return types.ImageLoadResponse{}, err return image.LoadResponse{}, err
} }
return types.ImageLoadResponse{ return image.LoadResponse{
Body: resp.body, Body: resp.body,
JSON: resp.header.Get("Content-Type") == "application/json", JSON: resp.header.Get("Content-Type") == "application/json",
}, nil }, nil

View File

@ -5,13 +5,13 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
) )
// ImagesPrune requests the daemon to delete unused data // ImagesPrune requests the daemon to delete unused data
func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (types.ImagesPruneReport, error) { func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (image.PruneReport, error) {
var report types.ImagesPruneReport var report image.PruneReport
if err := cli.NewVersionError(ctx, "1.25", "image prune"); err != nil { if err := cli.NewVersionError(ctx, "1.25", "image prune"); err != nil {
return report, err return report, err

View File

@ -7,7 +7,6 @@ import (
"net/url" "net/url"
"strconv" "strconv"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs" "github.com/docker/docker/errdefs"
@ -15,7 +14,7 @@ import (
// ImageSearch makes the docker host search by a term in a remote registry. // ImageSearch makes the docker host search by a term in a remote registry.
// The list of results is not sorted in any fashion. // The list of results is not sorted in any fashion.
func (cli *Client) ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) { func (cli *Client) ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error) {
var results []registry.SearchResult var results []registry.SearchResult
query := url.Values{} query := url.Values{}
query.Set("term", term) query.Set("term", term)

View File

@ -50,11 +50,11 @@ type ContainerAPIClient interface {
ContainerCommit(ctx context.Context, container string, options container.CommitOptions) (types.IDResponse, error) ContainerCommit(ctx context.Context, container string, options container.CommitOptions) (types.IDResponse, error)
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, 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) ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error)
ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error) ContainerExecAttach(ctx context.Context, execID string, options container.ExecAttachOptions) (types.HijackedResponse, error)
ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error) ContainerExecCreate(ctx context.Context, container string, options container.ExecOptions) (types.IDResponse, error)
ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error)
ContainerExecResize(ctx context.Context, execID string, options container.ResizeOptions) error ContainerExecResize(ctx context.Context, execID string, options container.ResizeOptions) error
ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error ContainerExecStart(ctx context.Context, execID string, options container.ExecStartOptions) error
ContainerExport(ctx context.Context, container string) (io.ReadCloser, error) ContainerExport(ctx context.Context, container string) (io.ReadCloser, error)
ContainerInspect(ctx context.Context, container string) (types.ContainerJSON, error) ContainerInspect(ctx context.Context, container string) (types.ContainerJSON, error)
ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (types.ContainerJSON, []byte, error) ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (types.ContainerJSON, []byte, error)
@ -66,18 +66,18 @@ type ContainerAPIClient interface {
ContainerRename(ctx context.Context, container, newContainerName string) error ContainerRename(ctx context.Context, container, newContainerName string) error
ContainerResize(ctx context.Context, container string, options container.ResizeOptions) error ContainerResize(ctx context.Context, container string, options container.ResizeOptions) error
ContainerRestart(ctx context.Context, container string, options container.StopOptions) error ContainerRestart(ctx context.Context, container string, options container.StopOptions) error
ContainerStatPath(ctx context.Context, container, path string) (types.ContainerPathStat, error) ContainerStatPath(ctx context.Context, container, path string) (container.PathStat, error)
ContainerStats(ctx context.Context, container string, stream bool) (types.ContainerStats, error) ContainerStats(ctx context.Context, container string, stream bool) (container.StatsResponse, error)
ContainerStatsOneShot(ctx context.Context, container string) (types.ContainerStats, error) ContainerStatsOneShot(ctx context.Context, container string) (container.StatsResponse, error)
ContainerStart(ctx context.Context, container string, options container.StartOptions) error ContainerStart(ctx context.Context, container string, options container.StartOptions) error
ContainerStop(ctx context.Context, container string, options container.StopOptions) error ContainerStop(ctx context.Context, container string, options container.StopOptions) error
ContainerTop(ctx context.Context, container string, arguments []string) (container.ContainerTopOKBody, error) ContainerTop(ctx context.Context, container string, arguments []string) (container.ContainerTopOKBody, error)
ContainerUnpause(ctx context.Context, container string) error ContainerUnpause(ctx context.Context, container string) error
ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) (container.ContainerUpdateOKBody, error) ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) (container.ContainerUpdateOKBody, error)
ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error)
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error)
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error CopyToContainer(ctx context.Context, container, path string, content io.Reader, options container.CopyToContainerOptions) error
ContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error)
} }
// DistributionAPIClient defines API client methods for the registry // DistributionAPIClient defines API client methods for the registry
@ -92,17 +92,17 @@ type ImageAPIClient interface {
BuildCancel(ctx context.Context, id string) error BuildCancel(ctx context.Context, id string) error
ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error) ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error)
ImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, error) ImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, error)
ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error)
ImageInspectWithRaw(ctx context.Context, image string) (types.ImageInspect, []byte, error) ImageInspectWithRaw(ctx context.Context, image string) (types.ImageInspect, []byte, error)
ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error) ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error)
ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (image.LoadResponse, error)
ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error) ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error)
ImagePush(ctx context.Context, ref string, options image.PushOptions) (io.ReadCloser, error) ImagePush(ctx context.Context, ref string, options image.PushOptions) (io.ReadCloser, error)
ImageRemove(ctx context.Context, image string, options image.RemoveOptions) ([]image.DeleteResponse, error) ImageRemove(ctx context.Context, image string, options image.RemoveOptions) ([]image.DeleteResponse, error)
ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error)
ImageSave(ctx context.Context, images []string) (io.ReadCloser, error) ImageSave(ctx context.Context, images []string) (io.ReadCloser, error)
ImageTag(ctx context.Context, image, ref string) error ImageTag(ctx context.Context, image, ref string) error
ImagesPrune(ctx context.Context, pruneFilter filters.Args) (types.ImagesPruneReport, error) ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error)
} }
// NetworkAPIClient defines API client methods for the networks // NetworkAPIClient defines API client methods for the networks
@ -165,7 +165,7 @@ type SwarmAPIClient interface {
// SystemAPIClient defines API client methods for the system // SystemAPIClient defines API client methods for the system
type SystemAPIClient interface { type SystemAPIClient interface {
Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error) Events(ctx context.Context, options events.ListOptions) (<-chan events.Message, <-chan error)
Info(ctx context.Context) (system.Info, error) Info(ctx context.Context) (system.Info, error)
RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error) RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error)
DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error) DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error)
@ -179,7 +179,7 @@ type VolumeAPIClient interface {
VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error) VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error)
VolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error) VolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error)
VolumeRemove(ctx context.Context, volumeID string, force bool) error VolumeRemove(ctx context.Context, volumeID string, force bool) error
VolumesPrune(ctx context.Context, pruneFilter filters.Args) (types.VolumesPruneReport, error) VolumesPrune(ctx context.Context, pruneFilter filters.Args) (volume.PruneReport, error)
VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error
} }

View File

@ -5,13 +5,13 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/volume"
) )
// VolumesPrune requests the daemon to delete unused data // VolumesPrune requests the daemon to delete unused data
func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters filters.Args) (types.VolumesPruneReport, error) { func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters filters.Args) (volume.PruneReport, error) {
var report types.VolumesPruneReport var report volume.PruneReport
if err := cli.NewVersionError(ctx, "1.25", "volume prune"); err != nil { if err := cli.NewVersionError(ctx, "1.25", "volume prune"); err != nil {
return report, err return report, err

2
vendor/modules.txt vendored
View File

@ -56,7 +56,7 @@ github.com/docker/distribution/registry/client/transport
github.com/docker/distribution/registry/storage/cache github.com/docker/distribution/registry/storage/cache
github.com/docker/distribution/registry/storage/cache/memory github.com/docker/distribution/registry/storage/cache/memory
github.com/docker/distribution/uuid github.com/docker/distribution/uuid
# github.com/docker/docker v26.1.1-0.20240607121412-59996a493cfc+incompatible # github.com/docker/docker v26.1.1-0.20240610145149-a736d0701c41+incompatible
## explicit ## explicit
github.com/docker/docker/api github.com/docker/docker/api
github.com/docker/docker/api/types github.com/docker/docker/api/types