mirror of https://github.com/docker/cli.git
Merge pull request #5134 from thaJeztah/bump_engine
vendor: github.com/docker/docker a736d0701c41 (master, v27.0.0-dev)
This commit is contained in:
commit
cba002eb5e
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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: "-",
|
||||
}
|
||||
|
|
|
@ -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
|
||||
},
|
||||
|
|
|
@ -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
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
|
||||
|
|
|
@ -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 := ¬aryclient.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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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")
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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=
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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".
|
||||
|
|
|
@ -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"`
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"`
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue