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

View File

@ -15,7 +15,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"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/system"
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,
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
// client, a `:` could be part of an absolute Windows path, in which case it
// is immediately proceeded by a backslash.
func splitCpArg(arg string) (container, path string) {
func splitCpArg(arg string) (ctr, path string) {
if system.IsAbs(arg) {
// Explicit local absolute path, e.g., `C:\foo` or `/foo`.
return "", arg
}
container, path, ok := strings.Cut(arg, ":")
if !ok || strings.HasPrefix(container, ".") {
ctr, path, ok := strings.Cut(arg, ":")
if !ok || strings.HasPrefix(ctr, ".") {
// Either there's no `:` in the arg
// OR it's an explicit local relative path like `./file:name.txt`.
return "", arg
}
return container, path
return ctr, path
}

View File

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

View File

@ -12,7 +12,8 @@ import (
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/opts"
"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/sirupsen/logrus"
"github.com/spf13/cobra"
@ -43,19 +44,18 @@ func NewExecOptions() ExecOptions {
// NewExecCommand creates a new cobra.Command for `docker exec`
func NewExecCommand(dockerCli command.Cli) *cobra.Command {
options := NewExecOptions()
var container string
cmd := &cobra.Command{
Use: "exec [OPTIONS] CONTAINER COMMAND [ARG...]",
Short: "Execute a command in a running container",
Args: cli.RequiresMinArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
container = args[0]
containerIDorName := args[0]
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 {
return container.State != "paused"
ValidArgsFunction: completion.ContainerNames(dockerCli, false, func(ctr types.Container) bool {
return ctr.State != "paused"
}),
Annotations: map[string]string{
"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.SetAnnotation("workdir", "version", []string{"1.35"})
cmd.RegisterFlagCompletionFunc(
"env",
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return os.Environ(), cobra.ShellCompDirectiveNoFileComp
},
)
cmd.RegisterFlagCompletionFunc(
"env-file",
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveDefault // _filedir
},
)
_ = cmd.RegisterFlagCompletionFunc("env", func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
return os.Environ(), cobra.ShellCompDirectiveNoFileComp
})
_ = cmd.RegisterFlagCompletionFunc("env-file", func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveDefault // _filedir
})
return cmd
}
// RunExec executes an `exec` command
func RunExec(ctx context.Context, dockerCli command.Cli, container string, options ExecOptions) error {
execConfig, err := parseExec(options, dockerCli.ConfigFile())
func RunExec(ctx context.Context, dockerCli command.Cli, containerIDorName string, options ExecOptions) error {
execOptions, err := parseExec(options, dockerCli.ConfigFile())
if err != nil {
return err
}
client := dockerCli.Client()
apiClient := dockerCli.Client()
// 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
// 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.
if _, err := client.ContainerInspect(ctx, container); err != nil {
if _, err := apiClient.ContainerInspect(ctx, containerIDorName); err != nil {
return err
}
if !execConfig.Detach {
if err := dockerCli.In().CheckTty(execConfig.AttachStdin, execConfig.Tty); err != nil {
if !execOptions.Detach {
if err := dockerCli.In().CheckTty(execOptions.AttachStdin, execOptions.Tty); err != nil {
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 {
return err
}
@ -129,52 +123,50 @@ func RunExec(ctx context.Context, dockerCli command.Cli, container string, optio
return errors.New("exec ID empty")
}
if execConfig.Detach {
execStartCheck := types.ExecStartCheck{
Detach: execConfig.Detach,
Tty: execConfig.Tty,
ConsoleSize: execConfig.ConsoleSize,
}
return client.ContainerExecStart(ctx, execID, execStartCheck)
if execOptions.Detach {
return apiClient.ContainerExecStart(ctx, execID, container.ExecStartOptions{
Detach: execOptions.Detach,
Tty: execOptions.Tty,
ConsoleSize: execOptions.ConsoleSize,
})
}
return interactiveExec(ctx, dockerCli, execConfig, execID)
return interactiveExec(ctx, dockerCli, execOptions, execID)
}
func fillConsoleSize(execConfig *types.ExecConfig, dockerCli command.Cli) {
if execConfig.Tty {
func fillConsoleSize(execOptions *container.ExecOptions, dockerCli command.Cli) {
if execOptions.Tty {
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.
var (
out, stderr io.Writer
in io.ReadCloser
)
if execConfig.AttachStdin {
if execOptions.AttachStdin {
in = dockerCli.In()
}
if execConfig.AttachStdout {
if execOptions.AttachStdout {
out = dockerCli.Out()
}
if execConfig.AttachStderr {
if execConfig.Tty {
if execOptions.AttachStderr {
if execOptions.Tty {
stderr = dockerCli.Out()
} else {
stderr = dockerCli.Err()
}
}
fillConsoleSize(execConfig, dockerCli)
fillConsoleSize(execOptions, dockerCli)
client := dockerCli.Client()
execStartCheck := types.ExecStartCheck{
Tty: execConfig.Tty,
ConsoleSize: execConfig.ConsoleSize,
}
resp, err := client.ContainerExecAttach(ctx, execID, execStartCheck)
apiClient := dockerCli.Client()
resp, err := apiClient.ContainerExecAttach(ctx, execID, container.ExecAttachOptions{
Tty: execOptions.Tty,
ConsoleSize: execOptions.ConsoleSize,
})
if err != nil {
return err
}
@ -191,17 +183,17 @@ func interactiveExec(ctx context.Context, dockerCli command.Cli, execConfig *typ
outputStream: out,
errorStream: stderr,
resp: resp,
tty: execConfig.Tty,
detachKeys: execConfig.DetachKeys,
tty: execOptions.Tty,
detachKeys: execOptions.DetachKeys,
}
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 {
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 getExecExitStatus(ctx, client, execID)
return getExecExitStatus(ctx, apiClient, execID)
}
func getExecExitStatus(ctx context.Context, client apiclient.ContainerAPIClient, execID string) error {
resp, err := client.ContainerExecInspect(ctx, execID)
func getExecExitStatus(ctx context.Context, apiClient client.ContainerAPIClient, execID string) error {
resp, err := apiClient.ContainerExecInspect(ctx, execID)
if err != nil {
// If we can't connect, then the daemon probably died.
if !apiclient.IsErrConnectionFailed(err) {
if !client.IsErrConnectionFailed(err) {
return err
}
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
// an ExecConfig from it.
func parseExec(execOpts ExecOptions, configFile *configfile.ConfigFile) (*types.ExecConfig, error) {
execConfig := &types.ExecConfig{
func parseExec(execOpts ExecOptions, configFile *configfile.ConfigFile) (*container.ExecOptions, error) {
execOptions := &container.ExecOptions{
User: execOpts.User,
Privileged: execOpts.Privileged,
Tty: execOpts.TTY,
@ -243,23 +235,23 @@ func parseExec(execOpts ExecOptions, configFile *configfile.ConfigFile) (*types.
// collect all the environment variables for the container
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
}
// If -d is not set, attach to everything by default
if !execOpts.Detach {
execConfig.AttachStdout = true
execConfig.AttachStderr = true
execOptions.AttachStdout = true
execOptions.AttachStderr = true
if execOpts.Interactive {
execConfig.AttachStdin = true
execOptions.AttachStdin = true
}
}
if execOpts.DetachKeys != "" {
execConfig.DetachKeys = execOpts.DetachKeys
execOptions.DetachKeys = execOpts.DetachKeys
} 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/opts"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@ -37,10 +38,10 @@ TWO=2
testcases := []struct {
options ExecOptions
configFile configfile.ConfigFile
expected types.ExecConfig
expected container.ExecOptions
}{
{
expected: types.ExecConfig{
expected: container.ExecOptions{
Cmd: []string{"command"},
AttachStdout: true,
AttachStderr: true,
@ -48,7 +49,7 @@ TWO=2
options: withDefaultOpts(ExecOptions{}),
},
{
expected: types.ExecConfig{
expected: container.ExecOptions{
Cmd: []string{"command1", "command2"},
AttachStdout: true,
AttachStderr: true,
@ -63,7 +64,7 @@ TWO=2
TTY: true,
User: "uid",
}),
expected: types.ExecConfig{
expected: container.ExecOptions{
User: "uid",
AttachStdin: true,
AttachStdout: true,
@ -74,7 +75,7 @@ TWO=2
},
{
options: withDefaultOpts(ExecOptions{Detach: true}),
expected: types.ExecConfig{
expected: container.ExecOptions{
Detach: true,
Cmd: []string{"command"},
},
@ -85,7 +86,7 @@ TWO=2
Interactive: true,
Detach: true,
}),
expected: types.ExecConfig{
expected: container.ExecOptions{
Detach: true,
Tty: true,
Cmd: []string{"command"},
@ -94,7 +95,7 @@ TWO=2
{
options: withDefaultOpts(ExecOptions{Detach: true}),
configFile: configfile.ConfigFile{DetachKeys: "de"},
expected: types.ExecConfig{
expected: container.ExecOptions{
Cmd: []string{"command"},
DetachKeys: "de",
Detach: true,
@ -106,14 +107,14 @@ TWO=2
DetachKeys: "ab",
}),
configFile: configfile.ConfigFile{DetachKeys: "de"},
expected: types.ExecConfig{
expected: container.ExecOptions{
Cmd: []string{"command"},
DetachKeys: "ab",
Detach: true,
},
},
{
expected: types.ExecConfig{
expected: container.ExecOptions{
Cmd: []string{"command"},
AttachStdout: true,
AttachStderr: true,
@ -126,7 +127,7 @@ TWO=2
}(),
},
{
expected: types.ExecConfig{
expected: container.ExecOptions{
Cmd: []string{"command"},
AttachStdout: 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
}
@ -235,9 +236,9 @@ func TestGetExecExitStatus(t *testing.T) {
for _, testcase := range testcases {
client := &fakeClient{
execInspectFunc: func(id string) (types.ContainerExecInspect, error) {
execInspectFunc: func(id string) (container.ExecInspect, error) {
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)

View File

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

View File

@ -13,7 +13,6 @@ import (
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/cli/command/formatter"
flagsHelper "github.com/docker/cli/cli/flags"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"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.
f := options.Filters.Clone()
f.Add("type", string(events.ContainerEventType))
eventChan, errChan := apiClient.Events(ctx, types.EventsOptions{
eventChan, errChan := apiClient.Events(ctx, events.ListOptions{
Filters: f,
})

View File

@ -5,7 +5,6 @@ import (
"errors"
"strconv"
"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/filters"
@ -68,11 +67,11 @@ func legacyWaitExitOrRemoved(ctx context.Context, apiClient client.APIClient, co
f := filters.NewArgs()
f.Add("type", "container")
f.Add("container", containerID)
options := types.EventsOptions{
Filters: f,
}
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 {
stopProcessing := false

View File

@ -21,11 +21,11 @@ type fakeClient struct {
imagePushFunc func(ref string, options image.PushOptions) (io.ReadCloser, error)
infoFunc func() (system.Info, error)
imagePullFunc func(ref string, options image.PullOptions) (io.ReadCloser, error)
imagesPruneFunc func(pruneFilter filters.Args) (types.ImagesPruneReport, error)
imageLoadFunc func(input io.Reader, quiet bool) (types.ImageLoadResponse, error)
imagesPruneFunc func(pruneFilter filters.Args) (image.PruneReport, error)
imageLoadFunc func(input io.Reader, quiet bool) (image.LoadResponse, error)
imageListFunc func(options image.ListOptions) ([]image.Summary, 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)
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
}
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 {
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 {
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) {
@ -102,7 +102,7 @@ func (cli *fakeClient) ImageInspectWithRaw(_ context.Context, img string) (types
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,
) (io.ReadCloser, error) {
if cli.imageImportFunc != nil {

View File

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

View File

@ -6,7 +6,6 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/image"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
@ -18,7 +17,7 @@ func TestNewImportCommandErrors(t *testing.T) {
name string
args []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",
@ -29,7 +28,7 @@ func TestNewImportCommandErrors(t *testing.T) {
name: "import-failed",
args: []string{"testdata/import-command-success.input.txt"},
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")
},
},
@ -53,7 +52,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
testCases := []struct {
name 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",
@ -66,7 +65,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
{
name: "double",
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))
return io.NopCloser(strings.NewReader("")), nil
},
@ -74,7 +73,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
{
name: "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))
return io.NopCloser(strings.NewReader("")), nil
},
@ -82,7 +81,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
{
name: "change",
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]))
return io.NopCloser(strings.NewReader("")), nil
},
@ -90,7 +89,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
{
name: "change legacy syntax",
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]))
return io.NopCloser(strings.NewReader("")), nil
},

View File

@ -7,7 +7,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/image"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
"gotest.tools/v3/golden"
@ -19,7 +19,7 @@ func TestNewLoadCommandErrors(t *testing.T) {
args []string
isTerminalIn bool
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",
@ -34,8 +34,8 @@ func TestNewLoadCommandErrors(t *testing.T) {
{
name: "pull-error",
expectedError: "something went wrong",
imageLoadFunc: func(input io.Reader, quiet bool) (types.ImageLoadResponse, error) {
return types.ImageLoadResponse{}, errors.Errorf("something went wrong")
imageLoadFunc: func(input io.Reader, quiet bool) (image.LoadResponse, error) {
return image.LoadResponse{}, errors.Errorf("something went wrong")
},
},
}
@ -62,19 +62,19 @@ func TestNewLoadCommandSuccess(t *testing.T) {
testCases := []struct {
name 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",
imageLoadFunc: func(input io.Reader, quiet bool) (types.ImageLoadResponse, error) {
return types.ImageLoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
imageLoadFunc: func(input io.Reader, quiet bool) (image.LoadResponse, error) {
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
},
},
{
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\"}"
return types.ImageLoadResponse{
return image.LoadResponse{
Body: io.NopCloser(strings.NewReader(json)),
JSON: true,
}, nil
@ -83,8 +83,8 @@ func TestNewLoadCommandSuccess(t *testing.T) {
{
name: "input-file",
args: []string{"--input", "testdata/load-command-success.input.txt"},
imageLoadFunc: func(input io.Reader, quiet bool) (types.ImageLoadResponse, error) {
return types.ImageLoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
imageLoadFunc: func(input io.Reader, quiet bool) (image.LoadResponse, error) {
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/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
"github.com/pkg/errors"
@ -23,7 +22,7 @@ func TestNewPruneCommandErrors(t *testing.T) {
name string
args []string
expectedError string
imagesPruneFunc func(pruneFilter filters.Args) (types.ImagesPruneReport, error)
imagesPruneFunc func(pruneFilter filters.Args) (image.PruneReport, error)
}{
{
name: "wrong-args",
@ -34,8 +33,8 @@ func TestNewPruneCommandErrors(t *testing.T) {
name: "prune-error",
args: []string{"--force"},
expectedError: "something went wrong",
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) {
return types.ImagesPruneReport{}, errors.Errorf("something went wrong")
imagesPruneFunc: func(pruneFilter filters.Args) (image.PruneReport, error) {
return image.PruneReport{}, errors.Errorf("something went wrong")
},
},
}
@ -53,22 +52,22 @@ func TestNewPruneCommandSuccess(t *testing.T) {
testCases := []struct {
name string
args []string
imagesPruneFunc func(pruneFilter filters.Args) (types.ImagesPruneReport, error)
imagesPruneFunc func(pruneFilter filters.Args) (image.PruneReport, error)
}{
{
name: "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]))
return types.ImagesPruneReport{}, nil
return image.PruneReport{}, nil
},
},
{
name: "force-deleted",
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]))
return types.ImagesPruneReport{
return image.PruneReport{
ImagesDeleted: []image.DeleteResponse{{Deleted: "image1"}},
SpaceReclaimed: 1,
}, nil
@ -77,17 +76,17 @@ func TestNewPruneCommandSuccess(t *testing.T) {
{
name: "label-filter",
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]))
return types.ImagesPruneReport{}, nil
return image.PruneReport{}, nil
},
},
{
name: "force-untagged",
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]))
return types.ImagesPruneReport{
return image.PruneReport{
ImagesDeleted: []image.DeleteResponse{{Untagged: "image1"}},
SpaceReclaimed: 2,
}, nil
@ -115,8 +114,8 @@ func TestPrunePromptTermination(t *testing.T) {
t.Cleanup(cancel)
cli := test.NewFakeCli(&fakeClient{
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) {
return types.ImagesPruneReport{}, errors.New("fakeClient imagesPruneFunc should not be called")
imagesPruneFunc: func(pruneFilter filters.Args) (image.PruneReport, error) {
return image.PruneReport{}, errors.New("fakeClient imagesPruneFunc should not be called")
},
})
cmd := NewPruneCommand(cli)

View File

@ -7,7 +7,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types"
apiclient "github.com/docker/docker/client"
"github.com/docker/docker/client"
"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 is mapped to the current node, hence the node ID is retrieved using
// 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" {
info, err := client.Info(ctx)
info, err := apiClient.Info(ctx)
if err != nil {
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
// isn't a manager. Call a swarm-specific endpoint to
// get a more specific error message.
_, err = client.NodeList(ctx, types.NodeListOptions{})
_, err = apiClient.NodeList(ctx, types.NodeListOptions{})
if err != nil {
return "", err
}

View File

@ -8,7 +8,6 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/registry"
"github.com/spf13/cobra"
@ -65,7 +64,7 @@ func runSearch(ctx context.Context, dockerCli command.Cli, options searchOptions
}
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,
PrivilegeFunc: requestPrivilege,
Filters: options.filter.Value(),

View File

@ -14,7 +14,7 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/swarm"
apiclient "github.com/docker/docker/client"
"github.com/docker/docker/client"
"github.com/docker/docker/errdefs"
)
@ -89,14 +89,14 @@ func getServicesDeclaredNetworks(serviceConfigs []composetypes.ServiceConfig) ma
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 {
if !container.NetworkMode(networkName).IsUserDefined() {
// Networks that are not user defined always exist on all nodes as
// local-scoped networks, so there's no need to inspect them.
continue
}
nw, err := client.NetworkInspect(ctx, networkName, network.InspectOptions{})
nw, err := apiClient.NetworkInspect(ctx, networkName, network.InspectOptions{})
switch {
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)
@ -110,20 +110,20 @@ func validateExternalNetworks(ctx context.Context, client apiclient.NetworkAPICl
}
func createSecrets(ctx context.Context, dockerCli command.Cli, secrets []swarm.SecretSpec) error {
client := dockerCli.Client()
apiClient := dockerCli.Client()
for _, secretSpec := range secrets {
secret, _, err := client.SecretInspectWithRaw(ctx, secretSpec.Name)
secret, _, err := apiClient.SecretInspectWithRaw(ctx, secretSpec.Name)
switch {
case err == nil:
// 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)
}
case errdefs.IsNotFound(err):
// secret does not exist, then we create a new one.
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)
}
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 {
client := dockerCli.Client()
apiClient := dockerCli.Client()
for _, configSpec := range configs {
config, _, err := client.ConfigInspectWithRaw(ctx, configSpec.Name)
config, _, err := apiClient.ConfigInspectWithRaw(ctx, configSpec.Name)
switch {
case err == nil:
// 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)
}
case errdefs.IsNotFound(err):
// config does not exist, then we create a new one.
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)
}
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 {
client := dockerCli.Client()
apiClient := dockerCli.Client()
existingNetworks, err := getStackNetworks(ctx, client, namespace.Name())
existingNetworks, err := getStackNetworks(ctx, apiClient, namespace.Name())
if err != nil {
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)
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)
}
}

View File

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

View File

@ -4,6 +4,7 @@ import (
"context"
"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/filters"
"github.com/docker/docker/api/types/network"
@ -15,8 +16,8 @@ type fakeClient struct {
version string
serverVersion func(ctx context.Context) (types.Version, error)
eventsFn func(context.Context, types.EventsOptions) (<-chan events.Message, <-chan error)
containerPruneFunc func(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error)
eventsFn func(context.Context, events.ListOptions) (<-chan events.Message, <-chan error)
containerPruneFunc func(ctx context.Context, pruneFilters filters.Args) (container.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
}
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)
}
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 {
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) {

View File

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

View File

@ -9,7 +9,6 @@ import (
"time"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events"
"gotest.tools/v3/assert"
"gotest.tools/v3/golden"
@ -59,7 +58,7 @@ func TestEventsFormat(t *testing.T) {
// Set to UTC timezone as timestamps in output are
// printed in the current timezone
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)
errs := make(chan error, 1)
go func() {

View File

@ -6,7 +6,7 @@ import (
"github.com/docker/cli/cli/config/configfile"
"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/network"
"github.com/pkg/errors"
@ -60,8 +60,8 @@ func TestSystemPrunePromptTermination(t *testing.T) {
t.Cleanup(cancel)
cli := test.NewFakeCli(&fakeClient{
containerPruneFunc: func(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) {
return types.ContainersPruneReport{}, errors.New("fakeClient containerPruneFunc should not be called")
containerPruneFunc: func(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) {
return container.PruneReport{}, errors.New("fakeClient containerPruneFunc should not be called")
},
networkPruneFunc: func(ctx context.Context, pruneFilters filters.Args) (network.PruneReport, error) {
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/image"
"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/client"
notaryclient "github.com/theupdateframework/notary/client"
"github.com/theupdateframework/notary/tuf/data"
"github.com/theupdateframework/notary/tuf/utils"
"gotest.tools/v3/assert"
@ -26,7 +26,7 @@ import (
// TODO(n4ss): remove common tests with the regular inspect command
type fakeClient struct {
apiclient.Client
client.Client
}
func (c *fakeClient) Info(context.Context) (system.Info, error) {
@ -212,7 +212,7 @@ func mockDelegationRoleWithName(name string) data.DelegationRole {
func TestMatchEmptySignatures(t *testing.T) {
// first try empty targets
emptyTgts := []client.TargetSignedStruct{}
emptyTgts := []notaryclient.TargetSignedStruct{}
matchedSigRows := matchReleasedSignatures(emptyTgts)
assert.Check(t, is.Len(matchedSigRows, 0))
@ -220,11 +220,11 @@ func TestMatchEmptySignatures(t *testing.T) {
func TestMatchUnreleasedSignatures(t *testing.T) {
// 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"} {
unreleasedTgts = append(unreleasedTgts, client.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: tgt})
unreleasedTgts = append(unreleasedTgts, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: tgt})
}
matchedSigRows := matchReleasedSignatures(unreleasedTgts)
@ -233,16 +233,16 @@ func TestMatchUnreleasedSignatures(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
oneReleasedTgt := []client.TargetSignedStruct{}
oneReleasedTgt := []notaryclient.TargetSignedStruct{}
// make and append the "released" target to our mock input
releasedTgt := client.Target{Name: "released", Hashes: data.Hashes{notary.SHA256: []byte("released-hash")}}
oneReleasedTgt = append(oneReleasedTgt, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: releasedTgt})
releasedTgt := notaryclient.Target{Name: "released", Hashes: data.Hashes{notary.SHA256: []byte("released-hash")}}
oneReleasedTgt = append(oneReleasedTgt, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: releasedTgt})
// 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"} {
oneReleasedTgt = append(oneReleasedTgt, client.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: unreleasedTgt})
oneReleasedTgt = append(oneReleasedTgt, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: unreleasedTgt})
}
matchedSigRows := matchReleasedSignatures(oneReleasedTgt)
@ -257,17 +257,17 @@ func TestMatchOneReleasedSingleSignature(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
oneReleasedTgt := []client.TargetSignedStruct{}
oneReleasedTgt := []notaryclient.TargetSignedStruct{}
// make and append the "released" target to our mock input
releasedTgt := client.Target{Name: "released", Hashes: data.Hashes{notary.SHA256: []byte("released-hash")}}
oneReleasedTgt = append(oneReleasedTgt, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: releasedTgt})
releasedTgt := notaryclient.Target{Name: "released", Hashes: data.Hashes{notary.SHA256: []byte("released-hash")}}
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
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"} {
oneReleasedTgt = append(oneReleasedTgt, client.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: unreleasedTgt})
oneReleasedTgt = append(oneReleasedTgt, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName(unreleasedRole), Target: releasedTgt})
}
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-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
multiReleasedTgts := []client.TargetSignedStruct{}
multiReleasedTgts := []notaryclient.TargetSignedStruct{}
// make target-a, target-b, and target-c
targetA := client.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")}}
targetC := client.Target{Name: "target-c", Hashes: data.Hashes{notary.SHA256: []byte("target-c-hash")}}
targetA := notaryclient.Target{Name: "target-a", Hashes: data.Hashes{notary.SHA256: []byte("target-a-hash")}}
targetB := notaryclient.Target{Name: "target-b", Hashes: data.Hashes{notary.SHA256: []byte("target-b-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
multiReleasedTgts = append(multiReleasedTgts, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: targetA})
multiReleasedTgts = append(multiReleasedTgts, client.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: targetA})
multiReleasedTgts = append(multiReleasedTgts, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/releases"), Target: targetB})
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):
for _, tgt := range []client.Target{targetA, targetB, targetC} {
multiReleasedTgts = append(multiReleasedTgts, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/a"), Target: tgt})
for _, tgt := range []notaryclient.Target{targetA, targetB, targetC} {
multiReleasedTgts = append(multiReleasedTgts, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/a"), Target: tgt})
}
// targets/b signs off on the final two targets (target-b, target-c):
for _, tgt := range []client.Target{targetB, targetC} {
multiReleasedTgts = append(multiReleasedTgts, client.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/b"), Target: tgt})
for _, tgt := range []notaryclient.Target{targetB, targetC} {
multiReleasedTgts = append(multiReleasedTgts, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName("targets/b"), Target: tgt})
}
// 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)
assert.Check(t, is.Len(matchedSigRows, 3))
@ -331,10 +331,10 @@ func TestMatchMultiReleasedMultiSignature(t *testing.T) {
func TestMatchReleasedSignatureFromTargets(t *testing.T) {
// 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
releasedTgt := client.Target{Name: "released", Hashes: data.Hashes{notary.SHA256: []byte("released-hash")}}
oneReleasedTgt = append(oneReleasedTgt, client.TargetSignedStruct{Role: mockDelegationRoleWithName(data.CanonicalTargetsRole.String()), Target: releasedTgt})
releasedTgt := notaryclient.Target{Name: "released", Hashes: data.Hashes{notary.SHA256: []byte("released-hash")}}
oneReleasedTgt = append(oneReleasedTgt, notaryclient.TargetSignedStruct{Role: mockDelegationRoleWithName(data.CanonicalTargetsRole.String()), Target: releasedTgt})
matchedSigRows := matchReleasedSignatures(oneReleasedTgt)
assert.Check(t, is.Len(matchedSigRows, 1))
outputRow := matchedSigRows[0]
@ -405,7 +405,7 @@ func TestFormatAdminRole(t *testing.T) {
},
Name: "targets/alice",
}
aliceRoleWithSigs := client.RoleWithSignatures{Role: aliceRole, Signatures: nil}
aliceRoleWithSigs := notaryclient.RoleWithSignatures{Role: aliceRole, Signatures: nil}
assert.Check(t, is.Equal("", formatAdminRole(aliceRoleWithSigs)))
releasesRole := data.Role{
@ -414,7 +414,7 @@ func TestFormatAdminRole(t *testing.T) {
},
Name: "targets/releases",
}
releasesRoleWithSigs := client.RoleWithSignatures{Role: releasesRole, Signatures: nil}
releasesRoleWithSigs := notaryclient.RoleWithSignatures{Role: releasesRole, Signatures: nil}
assert.Check(t, is.Equal("", formatAdminRole(releasesRoleWithSigs)))
timestampRole := data.Role{
@ -423,7 +423,7 @@ func TestFormatAdminRole(t *testing.T) {
},
Name: data.CanonicalTimestampRole,
}
timestampRoleWithSigs := client.RoleWithSignatures{Role: timestampRole, Signatures: nil}
timestampRoleWithSigs := notaryclient.RoleWithSignatures{Role: timestampRole, Signatures: nil}
assert.Check(t, is.Equal("", formatAdminRole(timestampRoleWithSigs)))
snapshotRole := data.Role{
@ -432,7 +432,7 @@ func TestFormatAdminRole(t *testing.T) {
},
Name: data.CanonicalSnapshotRole,
}
snapshotRoleWithSigs := client.RoleWithSignatures{Role: snapshotRole, Signatures: nil}
snapshotRoleWithSigs := notaryclient.RoleWithSignatures{Role: snapshotRole, Signatures: nil}
assert.Check(t, is.Equal("", formatAdminRole(snapshotRoleWithSigs)))
rootRole := data.Role{
@ -441,7 +441,7 @@ func TestFormatAdminRole(t *testing.T) {
},
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)))
targetsRole := data.Role{
@ -450,7 +450,7 @@ func TestFormatAdminRole(t *testing.T) {
},
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)))
}

View File

@ -14,10 +14,10 @@ import (
"github.com/docker/cli/cli/trust"
imagetypes "github.com/docker/docker/api/types/image"
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/spf13/cobra"
"github.com/theupdateframework/notary/client"
notaryclient "github.com/theupdateframework/notary/client"
"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
if _, err = notaryRepo.ListTargets(); err != nil {
switch err.(type) {
case client.ErrRepoNotInitialized, client.ErrRepositoryNotExist:
case notaryclient.ErrRepoNotInitialized, notaryclient.ErrRepositoryNotExist:
// before initializing a new repo, check that the image exists locally:
if err := checkLocalImageExistence(ctx, dockerCLI.Client(), imageName); err != nil {
return err
@ -86,7 +86,7 @@ func runSignImage(ctx context.Context, dockerCLI command.Cli, options signOption
if err != nil || options.local {
switch err := err.(type) {
// 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
if err := checkLocalImageExistence(ctx, dockerCLI.Client(), imageName); err != nil {
return err
@ -110,7 +110,7 @@ func runSignImage(ctx context.Context, dockerCLI command.Cli, options signOption
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()
fmt.Fprintf(out, "Signing and pushing trust metadata for %s\n", imgRefAndAuth.Name())
existingSigInfo, err := getExistingSignatureInfoForReleasedTag(notaryRepo, tag)
@ -140,13 +140,13 @@ func validateTag(imgRefAndAuth trust.ImageRefAndAuth) error {
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)
return err
}
func createTarget(notaryRepo client.Repository, tag string) (client.Target, error) {
target := &client.Target{}
func createTarget(notaryRepo notaryclient.Repository, tag string) (notaryclient.Target, error) {
target := &notaryclient.Target{}
var err error
if tag == "" {
return *target, errors.New("no tag specified")
@ -156,7 +156,7 @@ func createTarget(notaryRepo client.Repository, tag string) (client.Target, erro
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)
if err != nil {
return nil, 0, err
@ -164,16 +164,16 @@ func getSignedManifestHashAndSize(notaryRepo client.Repository, tag string) (dat
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 {
if isReleasedTarget(tgt.Role.Name) {
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)
if err != nil {
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)
}
func initNotaryRepoWithSigners(notaryRepo client.Repository, newSigner data.RoleName) error {
func initNotaryRepoWithSigners(notaryRepo notaryclient.Repository, newSigner data.RoleName) error {
rootKey, err := getOrGenerateNotaryKey(notaryRepo, data.CanonicalRootRole)
if err != nil {
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
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
if data.IsDelegation(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
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>
if err := notaryRepo.AddDelegationRoleAndKeys(newSigner, signerKeys); err != nil {
return err

View File

@ -3,7 +3,6 @@ package volume
import (
"context"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/volume"
"github.com/docker/docker/client"
@ -15,7 +14,7 @@ type fakeClient struct {
volumeInspectFunc func(volumeID string) (volume.Volume, error)
volumeListFunc func(filter filters.Args) (volume.ListResponse, 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) {
@ -39,11 +38,11 @@ func (c *fakeClient) VolumeList(_ context.Context, options volume.ListOptions) (
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 {
return c.volumePruneFunc(filter)
}
return types.VolumesPruneReport{}, nil
return volume.PruneReport{}, nil
}
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/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/volume"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@ -24,7 +24,7 @@ func TestVolumePruneErrors(t *testing.T) {
name string
args []string
flags map[string]string
volumePruneFunc func(args filters.Args) (types.VolumesPruneReport, error)
volumePruneFunc func(args filters.Args) (volume.PruneReport, error)
expectedError string
}{
{
@ -37,8 +37,8 @@ func TestVolumePruneErrors(t *testing.T) {
flags: map[string]string{
"force": "true",
},
volumePruneFunc: func(args filters.Args) (types.VolumesPruneReport, error) {
return types.VolumesPruneReport{}, errors.Errorf("error pruning volumes")
volumePruneFunc: func(args filters.Args) (volume.PruneReport, error) {
return volume.PruneReport{}, errors.Errorf("error pruning volumes")
},
expectedError: "error pruning volumes",
},
@ -75,31 +75,31 @@ func TestVolumePruneSuccess(t *testing.T) {
name string
args []string
input string
volumePruneFunc func(args filters.Args) (types.VolumesPruneReport, error)
volumePruneFunc func(args filters.Args) (volume.PruneReport, error)
}{
{
name: "all",
args: []string{"--all"},
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")))
return types.VolumesPruneReport{}, nil
return volume.PruneReport{}, nil
},
},
{
name: "all-forced",
args: []string{"--all", "--force"},
volumePruneFunc: func(pruneFilter filters.Args) (types.VolumesPruneReport, error) {
return types.VolumesPruneReport{}, nil
volumePruneFunc: func(pruneFilter filters.Args) (volume.PruneReport, error) {
return volume.PruneReport{}, nil
},
},
{
name: "label-filter",
args: []string{"--filter", "label=foobar"},
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")))
return types.VolumesPruneReport{}, nil
return volume.PruneReport{}, nil
},
},
}
@ -123,7 +123,7 @@ func TestVolumePruneSuccess(t *testing.T) {
func TestVolumePruneForce(t *testing.T) {
testCases := []struct {
name string
volumePruneFunc func(args filters.Args) (types.VolumesPruneReport, error)
volumePruneFunc func(args filters.Args) (volume.PruneReport, error)
}{
{
name: "empty",
@ -178,8 +178,8 @@ func TestVolumePrunePromptNo(t *testing.T) {
}
}
func simplePruneFunc(filters.Args) (types.VolumesPruneReport, error) {
return types.VolumesPruneReport{
func simplePruneFunc(filters.Args) (volume.PruneReport, error) {
return volume.PruneReport{
VolumesDeleted: []string{
"foo", "bar", "baz",
},
@ -192,8 +192,8 @@ func TestVolumePrunePromptTerminate(t *testing.T) {
t.Cleanup(cancel)
cli := test.NewFakeCli(&fakeClient{
volumePruneFunc: func(filter filters.Args) (types.VolumesPruneReport, error) {
return types.VolumesPruneReport{}, errors.New("fakeClient volumePruneFunc should not be called")
volumePruneFunc: func(filter filters.Args) (volume.PruneReport, error) {
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/distribution/reference v0.6.0
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/go-connections 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.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/docker v26.1.1-0.20240607121412-59996a493cfc+incompatible h1:MQR7fZxS7agfjACehtep/M6Bvz7/pFvbOcFvtTmvKlg=
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 h1:Kraon288jb3POkrmM5w6Xo979z2rrCtFzHycAjafRes=
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/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=

View File

@ -1198,13 +1198,6 @@ definitions:
ContainerConfig:
description: |
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"
properties:
Hostname:
@ -1363,6 +1356,277 @@ definitions:
type: "string"
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:
description: |
NetworkingConfig represents the container's networking configuration for
@ -1758,21 +2022,6 @@ definitions:
format: "dateTime"
x-nullable: true
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:
description: |
The version of Docker that was used to build the image.
@ -1789,7 +2038,7 @@ definitions:
x-nullable: false
example: ""
Config:
$ref: "#/definitions/ContainerConfig"
$ref: "#/definitions/ImageConfig"
Architecture:
description: |
Hardware CPU architecture that the image runs on.

View File

@ -12,29 +12,6 @@ import (
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
func NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse {
return HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType}
@ -153,19 +130,6 @@ type ImageBuildResponse struct {
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
// clients can supply to retry operations after
// getting an authorization error.
@ -174,14 +138,6 @@ type ImageLoadResponse struct {
// if the privilege request fails.
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.
type NodeListOptions struct {
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"
import (
"io"
"time"
"github.com/docker/docker/api/types/strslice"
@ -36,14 +35,6 @@ type StopOptions struct {
// HealthConfig holds configuration settings for the HEALTHCHECK feature.
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.
// It should hold only portable information about the container.
// 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"
import "github.com/docker/docker/api/types/filters"
// Type is used for event-types.
type Type string
@ -125,3 +126,10 @@ type Message struct {
Time int64 `json:"time,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
import "time"
import (
"io"
"time"
)
// Metadata contains engine-local data about the image.
type Metadata struct {
// LastTagTime is the date and time at which the image was last tagged.
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 (
"context"
"io"
"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.
type ImportOptions struct {
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
}
// 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
// registry to retrieve image metadata
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"
import (
"io"
"os"
"time"
"github.com/docker/docker/api/types/container"
@ -162,30 +160,6 @@ type Container struct {
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:
// GET "/_ping"
type Ping struct {
@ -231,17 +205,6 @@ type Version struct {
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
type HealthcheckResult struct {
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.
}
// 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:
// POST "/build/prune"
type BuildCachePruneReport struct {

View File

@ -1,9 +1,26 @@
package types
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/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.
//
// Deprecated: use [network.CreateRequest].
@ -54,3 +71,65 @@ type NetworkResource = network.Inspect
//
// Deprecated: use [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 {
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"
"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.
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.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)
defer ensureReaderClosed(response)
if err != nil {
return types.ContainerPathStat{}, err
return container.PathStat{}, err
}
return getContainerPathStatFromHeader(response.header)
}
// CopyToContainer copies content into the container filesystem.
// Note that `content` must be a Reader for a TAR archive
func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options types.CopyToContainerOptions) error {
func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options container.CopyToContainerOptions) error {
query := url.Values{}
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.
@ -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
// 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.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API.
apiPath := "/containers/" + containerID + "/archive"
response, err := cli.get(ctx, apiPath, query, 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
@ -78,8 +78,8 @@ func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath s
return response.body, stat, err
}
func getContainerPathStatFromHeader(header http.Header) (types.ContainerPathStat, error) {
var stat types.ContainerPathStat
func getContainerPathStatFromHeader(header http.Header) (container.PathStat, error) {
var stat container.PathStat
encodedStat := header.Get("X-Docker-Container-Path-Stat")
statDecoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(encodedStat))

View File

@ -6,11 +6,12 @@ import (
"net/http"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/versions"
)
// 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
// 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
}
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
}
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)
if err != nil {
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.
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") {
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
// and the a reader to get output. It's up to the called to 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") {
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.
func (cli *Client) ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) {
var response types.ContainerExecInspect
func (cli *Client) ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error) {
var response container.ExecInspect
resp, err := cli.get(ctx, "/exec/"+execID+"/json", nil, nil)
if err != nil {
return response, err

View File

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

View File

@ -4,12 +4,12 @@ import (
"context"
"net/url"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
)
// ContainerStats returns near realtime stats for a given container.
// 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.Set("stream", "0")
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)
if err != nil {
return types.ContainerStats{}, err
return container.StatsResponse{}, err
}
return types.ContainerStats{
return container.StatsResponse{
Body: resp.body,
OSType: getDockerOS(resp.header.Get("Server")),
}, nil
@ -29,17 +29,17 @@ func (cli *Client) ContainerStats(ctx context.Context, containerID string, strea
// ContainerStatsOneShot gets a single stat entry from a container.
// 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.Set("stream", "0")
query.Set("one-shot", "1")
resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil)
if err != nil {
return types.ContainerStats{}, err
return container.StatsResponse{}, err
}
return types.ContainerStats{
return container.StatsResponse{
Body: resp.body,
OSType: getDockerOS(resp.header.Get("Server")),
}, nil

View File

@ -6,7 +6,6 @@ import (
"net/url"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
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
// 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.
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)
errs := make(chan error, 1)
@ -68,7 +67,7 @@ func (cli *Client) Events(ctx context.Context, options types.EventsOptions) (<-c
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{}
ref := time.Now()

View File

@ -7,13 +7,12 @@ import (
"strings"
"github.com/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/image"
)
// ImageImport creates a new image based on the source options.
// 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 != "" {
// Check if the given image name can be resolved
if _, err := reference.ParseNormalizedNamed(ref); err != nil {

View File

@ -6,13 +6,13 @@ import (
"net/http"
"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.
// It's up to the caller to close the io.ReadCloser in the
// 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.Set("quiet", "0")
if quiet {
@ -22,9 +22,9 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (
"Content-Type": {"application/x-tar"},
})
if err != nil {
return types.ImageLoadResponse{}, err
return image.LoadResponse{}, err
}
return types.ImageLoadResponse{
return image.LoadResponse{
Body: resp.body,
JSON: resp.header.Get("Content-Type") == "application/json",
}, nil

View File

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

View File

@ -7,7 +7,6 @@ import (
"net/url"
"strconv"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
@ -15,7 +14,7 @@ import (
// ImageSearch makes the docker host search by a term in a remote registry.
// 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
query := url.Values{}
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)
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error)
ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error)
ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error)
ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error)
ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error)
ContainerExecAttach(ctx context.Context, execID string, options container.ExecAttachOptions) (types.HijackedResponse, error)
ContainerExecCreate(ctx context.Context, container string, options container.ExecOptions) (types.IDResponse, error)
ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, 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)
ContainerInspect(ctx context.Context, container string) (types.ContainerJSON, 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
ContainerResize(ctx context.Context, container string, options container.ResizeOptions) error
ContainerRestart(ctx context.Context, container string, options container.StopOptions) error
ContainerStatPath(ctx context.Context, container, path string) (types.ContainerPathStat, error)
ContainerStats(ctx context.Context, container string, stream bool) (types.ContainerStats, error)
ContainerStatsOneShot(ctx context.Context, container string) (types.ContainerStats, error)
ContainerStatPath(ctx context.Context, container, path string) (container.PathStat, error)
ContainerStats(ctx context.Context, container string, stream bool) (container.StatsResponse, error)
ContainerStatsOneShot(ctx context.Context, container string) (container.StatsResponse, error)
ContainerStart(ctx context.Context, container string, options container.StartOptions) error
ContainerStop(ctx context.Context, container string, options container.StopOptions) error
ContainerTop(ctx context.Context, container string, arguments []string) (container.ContainerTopOKBody, error)
ContainerUnpause(ctx context.Context, container string) 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)
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error)
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error
ContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error)
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error)
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options container.CopyToContainerOptions) error
ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error)
}
// DistributionAPIClient defines API client methods for the registry
@ -92,17 +92,17 @@ type ImageAPIClient interface {
BuildCancel(ctx context.Context, id string) error
ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, 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)
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)
ImagePush(ctx context.Context, ref string, options image.PushOptions) (io.ReadCloser, 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)
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
@ -165,7 +165,7 @@ type SwarmAPIClient interface {
// SystemAPIClient defines API client methods for the system
type SystemAPIClient interface {
Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error)
Events(ctx context.Context, options events.ListOptions) (<-chan events.Message, <-chan error)
Info(ctx context.Context) (system.Info, error)
RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error)
DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error)
@ -179,7 +179,7 @@ type VolumeAPIClient interface {
VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error)
VolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, 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
}

View File

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