Compare commits
65 Commits
v28.2.0-rc
...
v28.2.2
| Author | SHA1 | Date | |
|---|---|---|---|
| e6534b4eb7 | |||
| 5c3128e95e | |||
| 879ac3f88f | |||
| 92fa1e1fc9 | |||
| 4bec3a6795 | |||
| a007d1ae24 | |||
| bbfbd54f4d | |||
| 2d21e1f7a5 | |||
| bc9be0bdea | |||
| 3fe7dc5cb4 | |||
| 9eae2a8976 | |||
| a29e53dab7 | |||
| da0c976fb0 | |||
| 17dc2880fa | |||
| bb0ca9f9ef | |||
| f567263802 | |||
| 7775f01caa | |||
| 908ff04d6e | |||
| 519bc2daa1 | |||
| b2c4452acb | |||
| 3e287df661 | |||
| f1fb3e3011 | |||
| 9c8666c106 | |||
| 21d0466ff1 | |||
| 1d3b933ac3 | |||
| 649d088ddf | |||
| e135563c1f | |||
| 026ae7a11f | |||
| 681c705be6 | |||
| bdd994b79a | |||
| 1015d15621 | |||
| ae922ec177 | |||
| 881c68f690 | |||
| 761285bfee | |||
| f23ec25a12 | |||
| 565b0a2822 | |||
| 4be9afb801 | |||
| f05025caf9 | |||
| 32a8f4c420 | |||
| 68ef98d801 | |||
| 63f2984336 | |||
| 0ee20b8543 | |||
| c07cd8aaad | |||
| bf2eea31b5 | |||
| 6e4315f599 | |||
| 97e060e7b1 | |||
| 67c0be4b05 | |||
| 7aa6c79c0a | |||
| af090512a6 | |||
| 067587bf15 | |||
| ed5d9757c9 | |||
| 89f38282fd | |||
| 9d027dff40 | |||
| d1e9946ab8 | |||
| 615ffee13b | |||
| c1313a92a0 | |||
| 18e911c958 | |||
| d65f0c9bbf | |||
| b64d9b3b19 | |||
| 062ad57ce2 | |||
| 915b3fe992 | |||
| 2ef9ab4494 | |||
| d14b7e8d09 | |||
| 6c2d023d87 | |||
| a0385bf042 |
@ -26,39 +26,49 @@ formatters:
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- asasalint # Detects "[]any" used as argument for variadic "func(...any)".
|
||||
- bodyclose
|
||||
- copyloopvar # Detects places where loop variables are copied.
|
||||
- copyloopvar # Detects places where loop variables are copied.
|
||||
- depguard
|
||||
- dogsled
|
||||
- dupword # Detects duplicate words.
|
||||
- durationcheck
|
||||
- dogsled # Detects assignments with too many blank identifiers.
|
||||
- dupword # Detects duplicate words.
|
||||
- durationcheck # Detect cases where two time.Duration values are being multiplied in possibly erroneous ways.
|
||||
- errcheck
|
||||
- errchkjson
|
||||
- errchkjson # Detects unsupported types passed to json encoding functions and reports if checks for the returned error can be omitted.
|
||||
- exhaustive # Detects missing options in enum switch statements.
|
||||
- exptostd # Detects functions from golang.org/x/exp/ that can be replaced by std functions.
|
||||
- fatcontext # Detects nested contexts in loops and function literals.
|
||||
- forbidigo
|
||||
- gocritic # Metalinter; detects bugs, performance, and styling issues.
|
||||
- gocheckcompilerdirectives # Detects invalid go compiler directive comments (//go:).
|
||||
- gocritic # Metalinter; detects bugs, performance, and styling issues.
|
||||
- gocyclo
|
||||
- gosec # Detects security problems.
|
||||
- gosec # Detects security problems.
|
||||
- govet
|
||||
- iface # Detects incorrect use of interfaces. Currently only used for "identical" interfaces in the same package.
|
||||
- importas # Enforces consistent import aliases.
|
||||
- ineffassign
|
||||
- importas # Enforces consistent import aliases.
|
||||
- misspell # Detects commonly misspelled English words in comments.
|
||||
- nakedret # Detects uses of naked returns.
|
||||
- nilerr # Detects code that returns nil even if it checks that the error is not nil.
|
||||
- nolintlint # Detects ill-formed or insufficient nolint directives.
|
||||
- perfsprint # Detects fmt.Sprintf uses that can be replaced with a faster alternative.
|
||||
- prealloc # Detects slice declarations that could potentially be pre-allocated.
|
||||
- predeclared # Detects code that shadows one of Go's predeclared identifiers
|
||||
- reassign
|
||||
- revive # Metalinter; drop-in replacement for golint.
|
||||
- makezero # Finds slice declarations with non-zero initial length.
|
||||
- mirror # Detects wrong mirror patterns of bytes/strings usage.
|
||||
- misspell # Detects commonly misspelled English words in comments.
|
||||
- nakedret # Detects uses of naked returns.
|
||||
- nilnesserr # Detects returning nil errors. It combines the features of nilness and nilerr,
|
||||
- nosprintfhostport # Detects misuse of Sprintf to construct a host with port in a URL.
|
||||
- nolintlint # Detects ill-formed or insufficient nolint directives.
|
||||
- perfsprint # Detects fmt.Sprintf uses that can be replaced with a faster alternative.
|
||||
- prealloc # Detects slice declarations that could potentially be pre-allocated.
|
||||
- predeclared # Detects code that shadows one of Go's predeclared identifiers
|
||||
- reassign # Detects reassigning a top-level variable in another package.
|
||||
- revive # Metalinter; drop-in replacement for golint.
|
||||
- spancheck # Detects mistakes with OpenTelemetry/Census spans.
|
||||
- staticcheck
|
||||
- thelper # Detects test helpers without t.Helper().
|
||||
- tparallel # Detects inappropriate usage of t.Parallel().
|
||||
- unconvert # Detects unnecessary type conversions.
|
||||
- thelper # Detects test helpers without t.Helper().
|
||||
- tparallel # Detects inappropriate usage of t.Parallel().
|
||||
- unconvert # Detects unnecessary type conversions.
|
||||
- unparam
|
||||
- unused
|
||||
- usestdlibvars
|
||||
- usetesting # Reports uses of functions with replacement inside the testing package.
|
||||
- wastedassign
|
||||
- usestdlibvars # Detects the possibility to use variables/constants from the Go standard library.
|
||||
- usetesting # Reports uses of functions with replacement inside the testing package.
|
||||
- wastedassign # Detects wasted assignment statements.
|
||||
|
||||
disable:
|
||||
- errcheck
|
||||
@ -132,9 +142,7 @@ linters:
|
||||
staticcheck:
|
||||
checks:
|
||||
- all
|
||||
- -QF1008 # Omit embedded fields from selector expression
|
||||
- -ST1020 # The documentation of an exported function should start with the function’s name
|
||||
- -ST1022 # The documentation of an exported variable or constant should start with variable’s name
|
||||
- -QF1008 # Omit embedded fields from selector expression; https://staticcheck.dev/docs/checks/#QF1008
|
||||
|
||||
revive:
|
||||
rules:
|
||||
@ -159,8 +167,8 @@ linters:
|
||||
# (unlike the "include" option), the "exclude" option does not take exclusion
|
||||
# ID's.
|
||||
#
|
||||
# These exclusion patterns are copied from the default excluses at:
|
||||
# https://github.com/golangci/golangci-lint/blob/v1.44.0/pkg/config/issues.go#L10-L104
|
||||
# These exclusion patterns are copied from the default excludes at:
|
||||
# https://github.com/golangci/golangci-lint/blob/v1.61.0/pkg/config/issues.go#L11-L104
|
||||
#
|
||||
# The default list of exclusions can be found at:
|
||||
# https://golangci-lint.run/usage/false-positives/#default-exclusions
|
||||
@ -207,6 +215,12 @@ linters:
|
||||
linters:
|
||||
- govet
|
||||
|
||||
# Ignore for cli/command/formatter/tabwriter, which is forked from go stdlib, so we want to align with it.
|
||||
- text: '^(ST1020|ST1022): comment on exported'
|
||||
path: "cli/command/formatter/tabwriter"
|
||||
linters:
|
||||
- staticcheck
|
||||
|
||||
# Log a warning if an exclusion rule is unused.
|
||||
# Default: false
|
||||
warn-unused: true
|
||||
|
||||
@ -12,8 +12,8 @@ ARG GOTESTSUM_VERSION=v1.12.0
|
||||
# BUILDX_VERSION sets the version of buildx to use for the e2e tests.
|
||||
# It must be a tag in the docker.io/docker/buildx-bin image repository
|
||||
# on Docker Hub.
|
||||
ARG BUILDX_VERSION=0.23.0
|
||||
ARG COMPOSE_VERSION=v2.35.1
|
||||
ARG BUILDX_VERSION=0.24.0
|
||||
ARG COMPOSE_VERSION=v2.36.2
|
||||
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ func addPluginCandidatesFromDir(res map[string][]string, d string) {
|
||||
return
|
||||
}
|
||||
for _, dentry := range dentries {
|
||||
switch dentry.Type() & os.ModeType {
|
||||
switch dentry.Type() & os.ModeType { //nolint:exhaustive,nolintlint // no need to include all possible file-modes in this list
|
||||
case 0, os.ModeSymlink:
|
||||
// Regular file or symlink, keep going
|
||||
default:
|
||||
|
||||
@ -148,7 +148,7 @@ container2 -- --
|
||||
`,
|
||||
},
|
||||
}
|
||||
stats := []StatsEntry{
|
||||
entries := []StatsEntry{
|
||||
{
|
||||
Container: "container1",
|
||||
CPUPercentage: 20,
|
||||
@ -181,7 +181,7 @@ container2 -- --
|
||||
t.Run(string(tc.context.Format), func(t *testing.T) {
|
||||
var out bytes.Buffer
|
||||
tc.context.Output = &out
|
||||
err := statsFormatWrite(tc.context, stats, "windows", false)
|
||||
err := statsFormatWrite(tc.context, entries, "windows", false)
|
||||
if err != nil {
|
||||
assert.Error(t, err, tc.expected)
|
||||
} else {
|
||||
@ -273,45 +273,46 @@ func TestContainerStatsContextWriteWithNoStatsWindows(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestContainerStatsContextWriteTrunc(t *testing.T) {
|
||||
var out bytes.Buffer
|
||||
|
||||
contexts := []struct {
|
||||
tests := []struct {
|
||||
doc string
|
||||
context formatter.Context
|
||||
trunc bool
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
formatter.Context{
|
||||
doc: "non-truncated",
|
||||
context: formatter.Context{
|
||||
Format: "{{.ID}}",
|
||||
Output: &out,
|
||||
},
|
||||
false,
|
||||
"b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc\n",
|
||||
expected: "b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc\n",
|
||||
},
|
||||
{
|
||||
formatter.Context{
|
||||
doc: "truncated",
|
||||
context: formatter.Context{
|
||||
Format: "{{.ID}}",
|
||||
Output: &out,
|
||||
},
|
||||
true,
|
||||
"b95a83497c91\n",
|
||||
trunc: true,
|
||||
expected: "b95a83497c91\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, context := range contexts {
|
||||
statsFormatWrite(context.context, []StatsEntry{{ID: "b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc"}}, "linux", context.trunc)
|
||||
assert.Check(t, is.Equal(context.expected, out.String()))
|
||||
// Clean buffer
|
||||
out.Reset()
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.doc, func(t *testing.T) {
|
||||
var out bytes.Buffer
|
||||
tc.context.Output = &out
|
||||
err := statsFormatWrite(tc.context, []StatsEntry{{ID: "b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc"}}, "linux", tc.trunc)
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(tc.expected, out.String()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStatsFormat(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
stats := genStats()
|
||||
entries := genStats()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
for _, s := range stats {
|
||||
for _, s := range entries {
|
||||
_ = s.CPUPerc()
|
||||
_ = s.MemUsage()
|
||||
_ = s.MemPerc()
|
||||
@ -334,9 +335,9 @@ func genStats() []statsContext {
|
||||
NetworkTx: 987.654321,
|
||||
PidsCurrent: 123456789,
|
||||
}}
|
||||
stats := make([]statsContext, 100)
|
||||
for i := 0; i < 100; i++ {
|
||||
stats = append(stats, entry)
|
||||
entries := make([]statsContext, 0, 100)
|
||||
for range 100 {
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
return stats
|
||||
return entries
|
||||
}
|
||||
|
||||
@ -84,12 +84,9 @@ func (h *hijackedIOStreamer) setupInput() (restore func(), err error) {
|
||||
|
||||
// Use sync.Once so we may call restore multiple times but ensure we
|
||||
// only restore the terminal once.
|
||||
var restoreOnce sync.Once
|
||||
restore = func() {
|
||||
restoreOnce.Do(func() {
|
||||
_ = restoreTerminal(h.streams, h.inputStream)
|
||||
})
|
||||
}
|
||||
restore = sync.OnceFunc(func() {
|
||||
_ = restoreTerminal(h.streams, h.inputStream)
|
||||
})
|
||||
|
||||
// Wrap the input to detect detach escape sequence.
|
||||
// Use default escape keys if an invalid sequence is given.
|
||||
|
||||
@ -375,7 +375,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
|
||||
|
||||
if parsed.Type == string(mounttypes.TypeBind) {
|
||||
if hostPart, targetPath, ok := strings.Cut(bind, ":"); ok {
|
||||
if strings.HasPrefix(hostPart, "."+string(filepath.Separator)) || hostPart == "." {
|
||||
if !filepath.IsAbs(hostPart) && strings.HasPrefix(hostPart, ".") {
|
||||
if absHostPart, err := filepath.Abs(hostPart); err == nil {
|
||||
hostPart = absHostPart
|
||||
}
|
||||
|
||||
@ -11,10 +11,12 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/platforms"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/go-units"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -26,8 +28,18 @@ const (
|
||||
mountsHeader = "MOUNTS"
|
||||
localVolumes = "LOCAL VOLUMES"
|
||||
networksHeader = "NETWORKS"
|
||||
platformHeader = "PLATFORM"
|
||||
)
|
||||
|
||||
// Platform wraps a [ocispec.Platform] to implement the stringer interface.
|
||||
type Platform struct {
|
||||
ocispec.Platform
|
||||
}
|
||||
|
||||
func (p Platform) String() string {
|
||||
return platforms.FormatAll(p.Platform)
|
||||
}
|
||||
|
||||
// NewContainerFormat returns a Format for rendering using a Context
|
||||
func NewContainerFormat(source string, quiet bool, size bool) Format {
|
||||
switch source {
|
||||
@ -109,6 +121,7 @@ func NewContainerContext() *ContainerContext {
|
||||
"Mounts": mountsHeader,
|
||||
"LocalVolumes": localVolumes,
|
||||
"Networks": networksHeader,
|
||||
"Platform": platformHeader,
|
||||
}
|
||||
return &containerCtx
|
||||
}
|
||||
@ -208,6 +221,16 @@ func (c *ContainerContext) RunningFor() string {
|
||||
return units.HumanDuration(time.Now().UTC().Sub(createdAt)) + " ago"
|
||||
}
|
||||
|
||||
// Platform returns a human-readable representation of the container's
|
||||
// platform if it is available.
|
||||
func (c *ContainerContext) Platform() *Platform {
|
||||
p := c.c.ImageManifestDescriptor
|
||||
if p == nil || p.Platform == nil {
|
||||
return nil
|
||||
}
|
||||
return &Platform{*p.Platform}
|
||||
}
|
||||
|
||||
// Ports returns a comma-separated string representing open ports of the container
|
||||
// e.g. "0.0.0.0:80->9090/tcp, 9988/tcp"
|
||||
// it's used by command 'docker ps'
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/golden"
|
||||
@ -425,13 +426,36 @@ func TestContainerContextWriteWithNoContainers(t *testing.T) {
|
||||
func TestContainerContextWriteJSON(t *testing.T) {
|
||||
unix := time.Now().Add(-65 * time.Second).Unix()
|
||||
containers := []container.Summary{
|
||||
{ID: "containerID1", Names: []string{"/foobar_baz"}, Image: "ubuntu", Created: unix, State: container.StateRunning},
|
||||
{ID: "containerID2", Names: []string{"/foobar_bar"}, Image: "ubuntu", Created: unix, State: container.StateRunning},
|
||||
{
|
||||
ID: "containerID1",
|
||||
Names: []string{"/foobar_baz"},
|
||||
Image: "ubuntu",
|
||||
Created: unix,
|
||||
State: container.StateRunning,
|
||||
},
|
||||
{
|
||||
ID: "containerID2",
|
||||
Names: []string{"/foobar_bar"},
|
||||
Image: "ubuntu",
|
||||
Created: unix,
|
||||
State: container.StateRunning,
|
||||
|
||||
ImageManifestDescriptor: &ocispec.Descriptor{Platform: &ocispec.Platform{Architecture: "amd64", OS: "linux"}},
|
||||
},
|
||||
{
|
||||
ID: "containerID3",
|
||||
Names: []string{"/foobar_bar"},
|
||||
Image: "ubuntu",
|
||||
Created: unix,
|
||||
State: container.StateRunning,
|
||||
|
||||
ImageManifestDescriptor: &ocispec.Descriptor{Platform: &ocispec.Platform{}},
|
||||
},
|
||||
}
|
||||
expectedCreated := time.Unix(unix, 0).String()
|
||||
expectedJSONs := []map[string]any{
|
||||
{
|
||||
"Command": "\"\"",
|
||||
"Command": `""`,
|
||||
"CreatedAt": expectedCreated,
|
||||
"ID": "containerID1",
|
||||
"Image": "ubuntu",
|
||||
@ -440,6 +464,7 @@ func TestContainerContextWriteJSON(t *testing.T) {
|
||||
"Mounts": "",
|
||||
"Names": "foobar_baz",
|
||||
"Networks": "",
|
||||
"Platform": nil,
|
||||
"Ports": "",
|
||||
"RunningFor": "About a minute ago",
|
||||
"Size": "0B",
|
||||
@ -447,7 +472,7 @@ func TestContainerContextWriteJSON(t *testing.T) {
|
||||
"Status": "",
|
||||
},
|
||||
{
|
||||
"Command": "\"\"",
|
||||
"Command": `""`,
|
||||
"CreatedAt": expectedCreated,
|
||||
"ID": "containerID2",
|
||||
"Image": "ubuntu",
|
||||
@ -456,6 +481,24 @@ func TestContainerContextWriteJSON(t *testing.T) {
|
||||
"Mounts": "",
|
||||
"Names": "foobar_bar",
|
||||
"Networks": "",
|
||||
"Platform": map[string]any{"architecture": "amd64", "os": "linux"},
|
||||
"Ports": "",
|
||||
"RunningFor": "About a minute ago",
|
||||
"Size": "0B",
|
||||
"State": "running",
|
||||
"Status": "",
|
||||
},
|
||||
{
|
||||
"Command": `""`,
|
||||
"CreatedAt": expectedCreated,
|
||||
"ID": "containerID3",
|
||||
"Image": "ubuntu",
|
||||
"Labels": "",
|
||||
"LocalVolumes": "0",
|
||||
"Mounts": "",
|
||||
"Names": "foobar_bar",
|
||||
"Networks": "",
|
||||
"Platform": map[string]any{"architecture": "", "os": ""},
|
||||
"Ports": "",
|
||||
"RunningFor": "About a minute ago",
|
||||
"Size": "0B",
|
||||
|
||||
@ -20,6 +20,8 @@ func charWidth(r rune) int {
|
||||
switch width.LookupRune(r).Kind() {
|
||||
case width.EastAsianWide, width.EastAsianFullwidth:
|
||||
return 2
|
||||
case width.Neutral, width.EastAsianAmbiguous, width.EastAsianNarrow, width.EastAsianHalfwidth:
|
||||
return 1
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ package idresolver
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
)
|
||||
@ -21,7 +20,7 @@ func (cli *fakeClient) NodeInspectWithRaw(_ context.Context, nodeID string) (swa
|
||||
return swarm.Node{}, []byte{}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) ServiceInspectWithRaw(_ context.Context, serviceID string, _ types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
func (cli *fakeClient) ServiceInspectWithRaw(_ context.Context, serviceID string, _ swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
if cli.serviceInspectFunc != nil {
|
||||
return cli.serviceInspectFunc(serviceID)
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ package idresolver
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/pkg/errors"
|
||||
@ -44,7 +43,7 @@ func (r *IDResolver) get(ctx context.Context, t any, id string) (string, error)
|
||||
}
|
||||
return id, nil
|
||||
case swarm.Service:
|
||||
service, _, err := r.client.ServiceInspectWithRaw(ctx, id, types.ServiceInspectOptions{})
|
||||
service, _, err := r.client.ServiceInspectWithRaw(ctx, id, swarm.ServiceInspectOptions{})
|
||||
if err != nil {
|
||||
// TODO(thaJeztah): should error-handling be more specific, or is it ok to ignore any error?
|
||||
return id, nil //nolint:nilerr // ignore nil-error being returned, as this is a best-effort.
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/platforms"
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
@ -14,22 +15,23 @@ import (
|
||||
)
|
||||
|
||||
type removeOptions struct {
|
||||
force bool
|
||||
noPrune bool
|
||||
force bool
|
||||
noPrune bool
|
||||
platforms []string
|
||||
}
|
||||
|
||||
// NewRemoveCommand creates a new `docker remove` command
|
||||
func NewRemoveCommand(dockerCli command.Cli) *cobra.Command {
|
||||
var opts removeOptions
|
||||
func NewRemoveCommand(dockerCLI command.Cli) *cobra.Command {
|
||||
var options removeOptions
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "rmi [OPTIONS] IMAGE [IMAGE...]",
|
||||
Short: "Remove one or more images",
|
||||
Args: cli.RequiresMinArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runRemove(cmd.Context(), dockerCli, opts, args)
|
||||
return runRemove(cmd.Context(), dockerCLI, options, args)
|
||||
},
|
||||
ValidArgsFunction: completion.ImageNames(dockerCli, -1),
|
||||
ValidArgsFunction: completion.ImageNames(dockerCLI, -1),
|
||||
Annotations: map[string]string{
|
||||
"aliases": "docker image rm, docker image remove, docker rmi",
|
||||
},
|
||||
@ -37,9 +39,14 @@ func NewRemoveCommand(dockerCli command.Cli) *cobra.Command {
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
||||
flags.BoolVarP(&opts.force, "force", "f", false, "Force removal of the image")
|
||||
flags.BoolVar(&opts.noPrune, "no-prune", false, "Do not delete untagged parents")
|
||||
flags.BoolVarP(&options.force, "force", "f", false, "Force removal of the image")
|
||||
flags.BoolVar(&options.noPrune, "no-prune", false, "Do not delete untagged parents")
|
||||
|
||||
// TODO(thaJeztah): create a "platforms" option for this (including validation / parsing).
|
||||
flags.StringSliceVar(&options.platforms, "platform", nil, `Remove only the given platform variant. Formatted as "os[/arch[/variant]]" (e.g., "linux/amd64")`)
|
||||
_ = flags.SetAnnotation("platform", "version", []string{"1.50"})
|
||||
|
||||
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@ -58,6 +65,14 @@ func runRemove(ctx context.Context, dockerCLI command.Cli, opts removeOptions, i
|
||||
PruneChildren: !opts.noPrune,
|
||||
}
|
||||
|
||||
for _, v := range opts.platforms {
|
||||
p, err := platforms.Parse(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options.Platforms = append(options.Platforms, p)
|
||||
}
|
||||
|
||||
// TODO(thaJeztah): this logic can likely be simplified: do we want to print "not found" errors at all when using "force"?
|
||||
fatalErr := false
|
||||
var errs []error
|
||||
|
||||
@ -3,7 +3,6 @@ package node
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/system"
|
||||
"github.com/docker/docker/client"
|
||||
@ -17,8 +16,8 @@ type fakeClient struct {
|
||||
nodeRemoveFunc func() error
|
||||
nodeUpdateFunc func(nodeID string, version swarm.Version, node swarm.NodeSpec) error
|
||||
taskInspectFunc func(taskID string) (swarm.Task, []byte, error)
|
||||
taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error)
|
||||
serviceInspectFunc func(ctx context.Context, serviceID string, opts types.ServiceInspectOptions) (swarm.Service, []byte, error)
|
||||
taskListFunc func(options swarm.TaskListOptions) ([]swarm.Task, error)
|
||||
serviceInspectFunc func(ctx context.Context, serviceID string, opts swarm.ServiceInspectOptions) (swarm.Service, []byte, error)
|
||||
}
|
||||
|
||||
func (cli *fakeClient) NodeInspectWithRaw(context.Context, string) (swarm.Node, []byte, error) {
|
||||
@ -28,14 +27,14 @@ func (cli *fakeClient) NodeInspectWithRaw(context.Context, string) (swarm.Node,
|
||||
return swarm.Node{}, []byte{}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) NodeList(context.Context, types.NodeListOptions) ([]swarm.Node, error) {
|
||||
func (cli *fakeClient) NodeList(context.Context, swarm.NodeListOptions) ([]swarm.Node, error) {
|
||||
if cli.nodeListFunc != nil {
|
||||
return cli.nodeListFunc()
|
||||
}
|
||||
return []swarm.Node{}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) NodeRemove(context.Context, string, types.NodeRemoveOptions) error {
|
||||
func (cli *fakeClient) NodeRemove(context.Context, string, swarm.NodeRemoveOptions) error {
|
||||
if cli.nodeRemoveFunc != nil {
|
||||
return cli.nodeRemoveFunc()
|
||||
}
|
||||
@ -63,14 +62,14 @@ func (cli *fakeClient) TaskInspectWithRaw(_ context.Context, taskID string) (swa
|
||||
return swarm.Task{}, []byte{}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) TaskList(_ context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
func (cli *fakeClient) TaskList(_ context.Context, options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
if cli.taskListFunc != nil {
|
||||
return cli.taskListFunc(options)
|
||||
}
|
||||
return []swarm.Task{}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) ServiceInspectWithRaw(ctx context.Context, serviceID string, opts types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
func (cli *fakeClient) ServiceInspectWithRaw(ctx context.Context, serviceID string, opts swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
if cli.serviceInspectFunc != nil {
|
||||
return cli.serviceInspectFunc(ctx, serviceID, opts)
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@ -48,7 +48,7 @@ func Reference(ctx context.Context, apiClient client.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 = apiClient.NodeList(ctx, types.NodeListOptions{})
|
||||
_, err = apiClient.NodeList(ctx, swarm.NodeListOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@ -17,7 +17,7 @@ func completeNodeNames(dockerCLI completion.APIClientProvider) cobra.CompletionF
|
||||
// https://github.com/docker/cli/blob/f9ced58158d5e0b358052432244b483774a1983d/contrib/completion/bash/docker#L41-L43
|
||||
showIDs := os.Getenv("DOCKER_COMPLETION_SHOW_NODE_IDS") == "yes"
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
list, err := dockerCLI.Client().NodeList(cmd.Context(), types.NodeListOptions{})
|
||||
list, err := dockerCLI.Client().NodeList(cmd.Context(), swarm.NodeListOptions{})
|
||||
if err != nil {
|
||||
return nil, cobra.ShellCompDirectiveError
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import (
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
flagsHelper "github.com/docker/cli/cli/flags"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/system"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
@ -55,7 +55,7 @@ func runList(ctx context.Context, dockerCli command.Cli, options listOptions) er
|
||||
|
||||
nodes, err := client.NodeList(
|
||||
ctx,
|
||||
types.NodeListOptions{Filters: options.filter.Value()})
|
||||
swarm.NodeListOptions{Filters: options.filter.Value()})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -10,7 +10,6 @@ import (
|
||||
"github.com/docker/cli/cli/command/idresolver"
|
||||
"github.com/docker/cli/cli/command/task"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
@ -84,7 +83,7 @@ func runPs(ctx context.Context, dockerCli command.Cli, options psOptions) error
|
||||
filter := options.filter.Value()
|
||||
filter.Add("node", node.ID)
|
||||
|
||||
nodeTasks, err := client.TaskList(ctx, types.TaskListOptions{Filters: filter})
|
||||
nodeTasks, err := client.TaskList(ctx, swarm.TaskListOptions{Filters: filter})
|
||||
if err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
continue
|
||||
|
||||
@ -10,7 +10,6 @@ import (
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/builders"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/system"
|
||||
"gotest.tools/v3/assert"
|
||||
@ -23,7 +22,7 @@ func TestNodePsErrors(t *testing.T) {
|
||||
flags map[string]string
|
||||
infoFunc func() (system.Info, error)
|
||||
nodeInspectFunc func() (swarm.Node, []byte, error)
|
||||
taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error)
|
||||
taskListFunc func(options swarm.TaskListOptions) ([]swarm.Task, error)
|
||||
taskInspectFunc func(taskID string) (swarm.Task, []byte, error)
|
||||
expectedError string
|
||||
}{
|
||||
@ -42,7 +41,7 @@ func TestNodePsErrors(t *testing.T) {
|
||||
},
|
||||
{
|
||||
args: []string{"nodeID"},
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return []swarm.Task{}, errors.New("error returning the task list")
|
||||
},
|
||||
expectedError: "error returning the task list",
|
||||
@ -73,9 +72,9 @@ func TestNodePs(t *testing.T) {
|
||||
flags map[string]string
|
||||
infoFunc func() (system.Info, error)
|
||||
nodeInspectFunc func() (swarm.Node, []byte, error)
|
||||
taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error)
|
||||
taskListFunc func(options swarm.TaskListOptions) ([]swarm.Task, error)
|
||||
taskInspectFunc func(taskID string) (swarm.Task, []byte, error)
|
||||
serviceInspectFunc func(ctx context.Context, serviceID string, opts types.ServiceInspectOptions) (swarm.Service, []byte, error)
|
||||
serviceInspectFunc func(ctx context.Context, serviceID string, opts swarm.ServiceInspectOptions) (swarm.Service, []byte, error)
|
||||
}{
|
||||
{
|
||||
name: "simple",
|
||||
@ -83,7 +82,7 @@ func TestNodePs(t *testing.T) {
|
||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||
return *builders.Node(), []byte{}, nil
|
||||
},
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return []swarm.Task{
|
||||
*builders.Task(builders.WithStatus(builders.Timestamp(time.Now().Add(-2*time.Hour)), builders.PortStatus([]swarm.PortConfig{
|
||||
{
|
||||
@ -94,7 +93,7 @@ func TestNodePs(t *testing.T) {
|
||||
}))),
|
||||
}, nil
|
||||
},
|
||||
serviceInspectFunc: func(ctx context.Context, serviceID string, opts types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
serviceInspectFunc: func(ctx context.Context, serviceID string, opts swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
return swarm.Service{
|
||||
ID: serviceID,
|
||||
Spec: swarm.ServiceSpec{
|
||||
@ -111,7 +110,7 @@ func TestNodePs(t *testing.T) {
|
||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||
return *builders.Node(), []byte{}, nil
|
||||
},
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return []swarm.Task{
|
||||
*builders.Task(builders.TaskID("taskID1"), builders.TaskServiceID("failure"),
|
||||
builders.WithStatus(builders.Timestamp(time.Now().Add(-2*time.Hour)), builders.StatusErr("a task error"))),
|
||||
@ -121,7 +120,7 @@ func TestNodePs(t *testing.T) {
|
||||
builders.WithStatus(builders.Timestamp(time.Now().Add(-4*time.Hour)), builders.StatusErr("a task error"))),
|
||||
}, nil
|
||||
},
|
||||
serviceInspectFunc: func(ctx context.Context, serviceID string, opts types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
serviceInspectFunc: func(ctx context.Context, serviceID string, opts swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
return swarm.Service{
|
||||
ID: serviceID,
|
||||
Spec: swarm.ServiceSpec{
|
||||
|
||||
@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@ -38,7 +38,7 @@ func runRemove(ctx context.Context, dockerCLI command.Cli, nodeIDs []string, opt
|
||||
|
||||
var errs []error
|
||||
for _, id := range nodeIDs {
|
||||
if err := apiClient.NodeRemove(ctx, id, types.NodeRemoveOptions{Force: opts.force}); err != nil {
|
||||
if err := apiClient.NodeRemove(ctx, id, swarm.NodeRemoveOptions{Force: opts.force}); err != nil {
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -42,7 +42,6 @@ func SearchWrite(ctx formatter.Context, results []registrytypes.SearchResult) er
|
||||
"Description": formatter.DescriptionHeader,
|
||||
"StarCount": starsHeader,
|
||||
"IsOfficial": officialHeader,
|
||||
"IsAutomated": automatedHeader,
|
||||
}
|
||||
return ctx.Write(&searchCtx, render)
|
||||
}
|
||||
@ -92,10 +91,3 @@ func (c *searchContext) formatBool(value bool) string {
|
||||
func (c *searchContext) IsOfficial() string {
|
||||
return c.formatBool(c.s.IsOfficial)
|
||||
}
|
||||
|
||||
// IsAutomated formats the IsAutomated field for printing.
|
||||
//
|
||||
// Deprecated: the "is_automated" field is deprecated and will always be "false" in the future.
|
||||
func (c *searchContext) IsAutomated() string {
|
||||
return c.formatBool(c.s.IsAutomated) //nolint:nolintlint,staticcheck // ignore SA1019 (IsAutomated is deprecated).
|
||||
}
|
||||
|
||||
@ -45,19 +45,6 @@ func TestSearchContext(t *testing.T) {
|
||||
},
|
||||
call: ctx.IsOfficial,
|
||||
},
|
||||
{
|
||||
searchCtx: searchContext{
|
||||
s: registrytypes.SearchResult{IsAutomated: true}, //nolint:nolintlint,staticcheck // ignore SA1019 (IsAutomated is deprecated).
|
||||
},
|
||||
expValue: "[OK]",
|
||||
call: ctx.IsAutomated, //nolint:nolintlint,staticcheck // ignore SA1019 (IsAutomated is deprecated).
|
||||
},
|
||||
{
|
||||
searchCtx: searchContext{
|
||||
s: registrytypes.SearchResult{},
|
||||
},
|
||||
call: ctx.IsAutomated, //nolint:nolintlint,staticcheck // ignore SA1019 (IsAutomated is deprecated).
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
@ -157,8 +144,8 @@ func TestSearchContextWrite(t *testing.T) {
|
||||
{
|
||||
doc: "JSON format",
|
||||
format: "{{json .}}",
|
||||
expected: `{"Description":"Official build","IsAutomated":"false","IsOfficial":"true","Name":"result1","StarCount":"5000"}
|
||||
{"Description":"Not official","IsAutomated":"true","IsOfficial":"false","Name":"result2","StarCount":"5"}
|
||||
expected: `{"Description":"Official build","IsOfficial":"true","Name":"result1","StarCount":"5000"}
|
||||
{"Description":"Not official","IsOfficial":"false","Name":"result2","StarCount":"5"}
|
||||
`,
|
||||
},
|
||||
{
|
||||
@ -199,7 +186,7 @@ result2 5
|
||||
|
||||
results := []registrytypes.SearchResult{
|
||||
{Name: "result1", Description: "Official build", StarCount: 5000, IsOfficial: true},
|
||||
{Name: "result2", Description: "Not official", StarCount: 5, IsAutomated: true},
|
||||
{Name: "result2", Description: "Not official", StarCount: 5},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
|
||||
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/cli/internal/test/builders"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/system"
|
||||
@ -13,30 +12,30 @@ import (
|
||||
|
||||
type fakeClient struct {
|
||||
client.Client
|
||||
serviceInspectWithRawFunc func(ctx context.Context, serviceID string, options types.ServiceInspectOptions) (swarm.Service, []byte, error)
|
||||
serviceUpdateFunc func(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
|
||||
serviceListFunc func(context.Context, types.ServiceListOptions) ([]swarm.Service, error)
|
||||
taskListFunc func(context.Context, types.TaskListOptions) ([]swarm.Task, error)
|
||||
serviceInspectWithRawFunc func(ctx context.Context, serviceID string, options swarm.ServiceInspectOptions) (swarm.Service, []byte, error)
|
||||
serviceUpdateFunc func(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
|
||||
serviceListFunc func(context.Context, swarm.ServiceListOptions) ([]swarm.Service, error)
|
||||
taskListFunc func(context.Context, swarm.TaskListOptions) ([]swarm.Task, error)
|
||||
infoFunc func(ctx context.Context) (system.Info, error)
|
||||
networkInspectFunc func(ctx context.Context, networkID string, options network.InspectOptions) (network.Inspect, error)
|
||||
nodeListFunc func(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error)
|
||||
nodeListFunc func(ctx context.Context, options swarm.NodeListOptions) ([]swarm.Node, error)
|
||||
}
|
||||
|
||||
func (f *fakeClient) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
|
||||
func (f *fakeClient) NodeList(ctx context.Context, options swarm.NodeListOptions) ([]swarm.Node, error) {
|
||||
if f.nodeListFunc != nil {
|
||||
return f.nodeListFunc(ctx, options)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (f *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
func (f *fakeClient) TaskList(ctx context.Context, options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
if f.taskListFunc != nil {
|
||||
return f.taskListFunc(ctx, options)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (f *fakeClient) ServiceInspectWithRaw(ctx context.Context, serviceID string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
func (f *fakeClient) ServiceInspectWithRaw(ctx context.Context, serviceID string, options swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
if f.serviceInspectWithRawFunc != nil {
|
||||
return f.serviceInspectWithRawFunc(ctx, serviceID, options)
|
||||
}
|
||||
@ -44,7 +43,7 @@ func (f *fakeClient) ServiceInspectWithRaw(ctx context.Context, serviceID string
|
||||
return *builders.Service(builders.ServiceID(serviceID)), []byte{}, nil
|
||||
}
|
||||
|
||||
func (f *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
func (f *fakeClient) ServiceList(ctx context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
if f.serviceListFunc != nil {
|
||||
return f.serviceListFunc(ctx, options)
|
||||
}
|
||||
@ -52,7 +51,7 @@ func (f *fakeClient) ServiceList(ctx context.Context, options types.ServiceListO
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (f *fakeClient) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
func (f *fakeClient) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
if f.serviceUpdateFunc != nil {
|
||||
return f.serviceUpdateFunc(ctx, serviceID, version, service, options)
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@ -15,7 +15,7 @@ func completeServiceNames(dockerCLI completion.APIClientProvider) cobra.Completi
|
||||
// https://github.com/docker/cli/blob/f9ced58158d5e0b358052432244b483774a1983d/contrib/completion/bash/docker#L41-L43
|
||||
showIDs := os.Getenv("DOCKER_COMPLETION_SHOW_SERVICE_IDS") == "yes"
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
list, err := dockerCLI.Client().ServiceList(cmd.Context(), types.ServiceListOptions{})
|
||||
list, err := dockerCLI.Client().ServiceList(cmd.Context(), swarm.ServiceListOptions{})
|
||||
if err != nil {
|
||||
return nil, cobra.ShellCompDirectiveError
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ import (
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
cliopts "github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/client"
|
||||
@ -102,7 +101,7 @@ func newCreateCommand(dockerCLI command.Cli) *cobra.Command {
|
||||
|
||||
func runCreate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet, opts *serviceOptions) error {
|
||||
apiClient := dockerCLI.Client()
|
||||
createOpts := types.ServiceCreateOptions{}
|
||||
createOpts := swarm.ServiceCreateOptions{}
|
||||
|
||||
service, err := opts.ToService(ctx, apiClient, flags)
|
||||
if err != nil {
|
||||
|
||||
@ -13,8 +13,8 @@ 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/network"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
@ -66,7 +66,7 @@ func runInspect(ctx context.Context, dockerCli command.Cli, opts inspectOptions)
|
||||
|
||||
getRef := func(ref string) (any, []byte, error) {
|
||||
// Service inspect shows defaults values in empty fields.
|
||||
service, _, err := client.ServiceInspectWithRaw(ctx, ref, types.ServiceInspectOptions{InsertDefaults: true})
|
||||
service, _, err := client.ServiceInspectWithRaw(ctx, ref, swarm.ServiceInspectOptions{InsertDefaults: true})
|
||||
if err == nil || !cerrdefs.IsNotFound(err) {
|
||||
return service, nil, err
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
flagsHelper "github.com/docker/cli/cli/flags"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
@ -57,7 +56,7 @@ func runList(ctx context.Context, dockerCLI command.Cli, options listOptions) er
|
||||
err error
|
||||
)
|
||||
|
||||
listOpts := types.ServiceListOptions{
|
||||
listOpts := swarm.ServiceListOptions{
|
||||
Filters: options.filter.Value(),
|
||||
// When not running "quiet", also get service status (number of running
|
||||
// and desired tasks). Note that this is only supported on API v1.41 and
|
||||
@ -147,7 +146,7 @@ func AppendServiceStatus(ctx context.Context, c client.APIClient, services []swa
|
||||
return services, nil
|
||||
}
|
||||
|
||||
tasks, err := c.TaskList(ctx, types.TaskListOptions{Filters: taskFilter})
|
||||
tasks, err := c.TaskList(ctx, swarm.TaskListOptions{Filters: taskFilter})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -184,7 +183,7 @@ func AppendServiceStatus(ctx context.Context, c client.APIClient, services []swa
|
||||
}
|
||||
|
||||
func getActiveNodes(ctx context.Context, c client.NodeAPIClient) (map[string]struct{}, error) {
|
||||
nodes, err := c.NodeList(ctx, types.NodeListOptions{})
|
||||
nodes, err := c.NodeList(ctx, swarm.NodeListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/builders"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"gotest.tools/v3/assert"
|
||||
@ -19,7 +18,7 @@ import (
|
||||
|
||||
func TestServiceListOrder(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{
|
||||
serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(ctx context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{
|
||||
newService("a57dbe8", "service-1-foo"),
|
||||
newService("a57dbdd", "service-10-foo"),
|
||||
@ -173,7 +172,7 @@ func TestServiceListServiceStatus(t *testing.T) {
|
||||
tc.cluster = generateCluster(t, tc.opts)
|
||||
}
|
||||
cli := test.NewFakeCli(&fakeClient{
|
||||
serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(ctx context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
if !options.Status || versions.LessThan(tc.opts.apiVersion, "1.41") {
|
||||
// Don't return "ServiceStatus" if not requested, or on older API versions
|
||||
for i := range tc.cluster.services {
|
||||
@ -182,10 +181,10 @@ func TestServiceListServiceStatus(t *testing.T) {
|
||||
}
|
||||
return tc.cluster.services, nil
|
||||
},
|
||||
taskListFunc: func(context.Context, types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(context.Context, swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return tc.cluster.tasks, nil
|
||||
},
|
||||
nodeListFunc: func(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
|
||||
nodeListFunc: func(ctx context.Context, options swarm.NodeListOptions) ([]swarm.Node, error) {
|
||||
return tc.cluster.nodes, nil
|
||||
},
|
||||
})
|
||||
|
||||
@ -15,7 +15,6 @@ import (
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/cli/cli/command/idresolver"
|
||||
"github.com/docker/cli/internal/logdetails"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
@ -91,7 +90,7 @@ func runLogs(ctx context.Context, dockerCli command.Cli, opts *logsOptions) erro
|
||||
logfunc func(context.Context, string, container.LogsOptions) (io.ReadCloser, error)
|
||||
)
|
||||
|
||||
service, _, err := apiClient.ServiceInspectWithRaw(ctx, opts.target, types.ServiceInspectOptions{})
|
||||
service, _, err := apiClient.ServiceInspectWithRaw(ctx, opts.target, swarm.ServiceInspectOptions{})
|
||||
if err != nil {
|
||||
// if it's any error other than service not found, it's Real
|
||||
if !cerrdefs.IsNotFound(err) {
|
||||
|
||||
@ -11,7 +11,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
@ -89,7 +88,7 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
|
||||
)
|
||||
|
||||
for {
|
||||
service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
|
||||
service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID, swarm.ServiceInspectOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -143,7 +142,7 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
|
||||
return nil
|
||||
}
|
||||
|
||||
tasks, err := apiClient.TaskList(ctx, types.TaskListOptions{Filters: filters.NewArgs(
|
||||
tasks, err := apiClient.TaskList(ctx, swarm.TaskListOptions{Filters: filters.NewArgs(
|
||||
filters.KeyValuePair{Key: "service", Value: service.ID},
|
||||
filters.KeyValuePair{Key: "_up-to-date", Value: "true"},
|
||||
)})
|
||||
@ -217,7 +216,7 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
|
||||
//
|
||||
// TODO(thaJeztah): this should really be a filter on [apiClient.NodeList] instead of being filtered on the client side.
|
||||
func getActiveNodes(ctx context.Context, apiClient client.NodeAPIClient) (map[string]struct{}, error) {
|
||||
nodes, err := apiClient.NodeList(ctx, types.NodeListOptions{})
|
||||
nodes, err := apiClient.NodeList(ctx, swarm.NodeListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -11,8 +11,8 @@ import (
|
||||
"github.com/docker/cli/cli/command/node"
|
||||
"github.com/docker/cli/cli/command/task"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
@ -68,7 +68,7 @@ func runPS(ctx context.Context, dockerCli command.Cli, options psOptions) error
|
||||
return err
|
||||
}
|
||||
|
||||
tasks, err := apiClient.TaskList(ctx, types.TaskListOptions{Filters: filter})
|
||||
tasks, err := apiClient.TaskList(ctx, swarm.TaskListOptions{Filters: filter})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -98,11 +98,11 @@ func createFilter(ctx context.Context, apiClient client.APIClient, options psOpt
|
||||
serviceIDFilter.Add("id", service)
|
||||
serviceNameFilter.Add("name", service)
|
||||
}
|
||||
serviceByIDList, err := apiClient.ServiceList(ctx, types.ServiceListOptions{Filters: serviceIDFilter})
|
||||
serviceByIDList, err := apiClient.ServiceList(ctx, swarm.ServiceListOptions{Filters: serviceIDFilter})
|
||||
if err != nil {
|
||||
return filter, nil, err
|
||||
}
|
||||
serviceByNameList, err := apiClient.ServiceList(ctx, types.ServiceListOptions{Filters: serviceNameFilter})
|
||||
serviceByNameList, err := apiClient.ServiceList(ctx, swarm.ServiceListOptions{Filters: serviceNameFilter})
|
||||
if err != nil {
|
||||
return filter, nil, err
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/system"
|
||||
@ -17,7 +16,7 @@ import (
|
||||
|
||||
func TestCreateFilter(t *testing.T) {
|
||||
client := &fakeClient{
|
||||
serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(ctx context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{
|
||||
{ID: "idmatch"},
|
||||
{ID: "idprefixmatch"},
|
||||
@ -49,7 +48,7 @@ func TestCreateFilter(t *testing.T) {
|
||||
|
||||
func TestCreateFilterWithAmbiguousIDPrefixError(t *testing.T) {
|
||||
client := &fakeClient{
|
||||
serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(ctx context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{
|
||||
{ID: "aaaone"},
|
||||
{ID: "aaatwo"},
|
||||
@ -76,7 +75,7 @@ func TestCreateFilterNoneFound(t *testing.T) {
|
||||
|
||||
func TestRunPSWarnsOnNotFound(t *testing.T) {
|
||||
client := &fakeClient{
|
||||
serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(ctx context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{
|
||||
{ID: "foo"},
|
||||
}, nil
|
||||
@ -97,10 +96,10 @@ func TestRunPSWarnsOnNotFound(t *testing.T) {
|
||||
|
||||
func TestRunPSQuiet(t *testing.T) {
|
||||
client := &fakeClient{
|
||||
serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(ctx context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{{ID: "foo"}}, nil
|
||||
},
|
||||
taskListFunc: func(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(ctx context.Context, options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return []swarm.Task{{ID: "sxabyp0obqokwekpun4rjo0b3"}}, nil
|
||||
},
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import (
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
@ -43,12 +43,12 @@ func newRollbackCommand(dockerCli command.Cli) *cobra.Command {
|
||||
func runRollback(ctx context.Context, dockerCLI command.Cli, options *serviceOptions, serviceID string) error {
|
||||
apiClient := dockerCLI.Client()
|
||||
|
||||
service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
|
||||
service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID, swarm.ServiceInspectOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
response, err := apiClient.ServiceUpdate(ctx, service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{
|
||||
response, err := apiClient.ServiceUpdate(ctx, service.ID, service.Version, service.Spec, swarm.ServiceUpdateOptions{
|
||||
Rollback: "previous", // TODO(thaJeztah): this should have a const defined
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@ -8,7 +8,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
@ -18,7 +17,7 @@ func TestRollback(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
serviceUpdateFunc func(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
|
||||
serviceUpdateFunc func(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
|
||||
expectedDockerCliErr string
|
||||
}{
|
||||
{
|
||||
@ -28,7 +27,7 @@ func TestRollback(t *testing.T) {
|
||||
{
|
||||
name: "rollback-service-with-warnings",
|
||||
args: []string{"service-id"},
|
||||
serviceUpdateFunc: func(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
serviceUpdateFunc: func(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
response := swarm.ServiceUpdateResponse{}
|
||||
|
||||
response.Warnings = []string{
|
||||
@ -59,8 +58,8 @@ func TestRollbackWithErrors(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
serviceInspectWithRawFunc func(ctx context.Context, serviceID string, options types.ServiceInspectOptions) (swarm.Service, []byte, error)
|
||||
serviceUpdateFunc func(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
|
||||
serviceInspectWithRawFunc func(ctx context.Context, serviceID string, options swarm.ServiceInspectOptions) (swarm.Service, []byte, error)
|
||||
serviceUpdateFunc func(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
@ -75,7 +74,7 @@ func TestRollbackWithErrors(t *testing.T) {
|
||||
{
|
||||
name: "service-does-not-exists",
|
||||
args: []string{"service-id"},
|
||||
serviceInspectWithRawFunc: func(ctx context.Context, serviceID string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
serviceInspectWithRawFunc: func(ctx context.Context, serviceID string, options swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
return swarm.Service{}, []byte{}, fmt.Errorf("no such services: %s", serviceID)
|
||||
},
|
||||
expectedError: "no such services: service-id",
|
||||
@ -83,7 +82,7 @@ func TestRollbackWithErrors(t *testing.T) {
|
||||
{
|
||||
name: "service-update-failed",
|
||||
args: []string{"service-id"},
|
||||
serviceUpdateFunc: func(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
serviceUpdateFunc: func(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
return swarm.ServiceUpdateResponse{}, fmt.Errorf("no such services: %s", serviceID)
|
||||
},
|
||||
expectedError: "no such services: service-id",
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/spf13/cobra"
|
||||
@ -94,7 +94,7 @@ func runScale(ctx context.Context, dockerCLI command.Cli, options *scaleOptions,
|
||||
}
|
||||
|
||||
func runServiceScale(ctx context.Context, apiClient client.ServiceAPIClient, serviceID string, scale uint64) (warnings []string, _ error) {
|
||||
service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
|
||||
service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID, swarm.ServiceInspectOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -109,7 +109,7 @@ func runServiceScale(ctx context.Context, apiClient client.ServiceAPIClient, ser
|
||||
return nil, errors.New("scale can only be used with replicated or replicated-job mode")
|
||||
}
|
||||
|
||||
response, err := apiClient.ServiceUpdate(ctx, service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{})
|
||||
response, err := apiClient.ServiceUpdate(ctx, service.ID, service.Version, service.Spec, swarm.ServiceUpdateOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -12,7 +12,6 @@ import (
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/cli/opts/swarmopts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
mounttypes "github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
@ -156,7 +155,7 @@ func newListOptsVarWithValidator(validator opts.ValidatorFctType) *opts.ListOpts
|
||||
func runUpdate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet, options *serviceOptions, serviceID string) error {
|
||||
apiClient := dockerCLI.Client()
|
||||
|
||||
service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
|
||||
service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID, swarm.ServiceInspectOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -201,7 +200,7 @@ func runUpdate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet,
|
||||
}
|
||||
}
|
||||
|
||||
updateOpts := types.ServiceUpdateOptions{}
|
||||
updateOpts := swarm.ServiceUpdateOptions{}
|
||||
if serverSideRollback {
|
||||
updateOpts.Rollback = "previous"
|
||||
}
|
||||
@ -255,9 +254,9 @@ func runUpdate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet,
|
||||
}
|
||||
updateOpts.EncodedRegistryAuth = encodedAuth
|
||||
case clientSideRollback:
|
||||
updateOpts.RegistryAuthFrom = types.RegistryAuthFromPreviousSpec
|
||||
updateOpts.RegistryAuthFrom = swarm.RegistryAuthFromPreviousSpec
|
||||
default:
|
||||
updateOpts.RegistryAuthFrom = types.RegistryAuthFromSpec
|
||||
updateOpts.RegistryAuthFrom = swarm.RegistryAuthFromSpec
|
||||
}
|
||||
|
||||
response, err := apiClient.ServiceUpdate(ctx, service.ID, service.Version, *spec, updateOpts)
|
||||
|
||||
@ -28,15 +28,15 @@ type fakeClient struct {
|
||||
removedSecrets []string
|
||||
removedConfigs []string
|
||||
|
||||
serviceListFunc func(options types.ServiceListOptions) ([]swarm.Service, error)
|
||||
serviceListFunc func(options swarm.ServiceListOptions) ([]swarm.Service, error)
|
||||
networkListFunc func(options network.ListOptions) ([]network.Summary, error)
|
||||
secretListFunc func(options swarm.SecretListOptions) ([]swarm.Secret, error)
|
||||
configListFunc func(options swarm.ConfigListOptions) ([]swarm.Config, error)
|
||||
nodeListFunc func(options types.NodeListOptions) ([]swarm.Node, error)
|
||||
taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error)
|
||||
nodeListFunc func(options swarm.NodeListOptions) ([]swarm.Node, error)
|
||||
taskListFunc func(options swarm.TaskListOptions) ([]swarm.Task, error)
|
||||
nodeInspectWithRaw func(ref string) (swarm.Node, []byte, error)
|
||||
|
||||
serviceUpdateFunc func(serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
|
||||
serviceUpdateFunc func(serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
|
||||
|
||||
serviceRemoveFunc func(serviceID string) error
|
||||
networkRemoveFunc func(networkID string) error
|
||||
@ -55,7 +55,7 @@ func (cli *fakeClient) ClientVersion() string {
|
||||
return cli.version
|
||||
}
|
||||
|
||||
func (cli *fakeClient) ServiceList(_ context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
func (cli *fakeClient) ServiceList(_ context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
if cli.serviceListFunc != nil {
|
||||
return cli.serviceListFunc(options)
|
||||
}
|
||||
@ -115,14 +115,14 @@ func (cli *fakeClient) ConfigList(_ context.Context, options swarm.ConfigListOpt
|
||||
return configsList, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) TaskList(_ context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
func (cli *fakeClient) TaskList(_ context.Context, options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
if cli.taskListFunc != nil {
|
||||
return cli.taskListFunc(options)
|
||||
}
|
||||
return []swarm.Task{}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) NodeList(_ context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
|
||||
func (cli *fakeClient) NodeList(_ context.Context, options swarm.NodeListOptions) ([]swarm.Node, error) {
|
||||
if cli.nodeListFunc != nil {
|
||||
return cli.nodeListFunc(options)
|
||||
}
|
||||
@ -136,7 +136,7 @@ func (cli *fakeClient) NodeInspectWithRaw(_ context.Context, ref string) (swarm.
|
||||
return swarm.Node{}, nil, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) ServiceUpdate(_ context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
func (cli *fakeClient) ServiceUpdate(_ context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
if cli.serviceUpdateFunc != nil {
|
||||
return cli.serviceUpdateFunc(serviceID, version, service, options)
|
||||
}
|
||||
@ -180,7 +180,7 @@ func (cli *fakeClient) ConfigRemove(_ context.Context, configID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*fakeClient) ServiceInspectWithRaw(_ context.Context, serviceID string, _ types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
func (*fakeClient) ServiceInspectWithRaw(_ context.Context, serviceID string, _ swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
return swarm.Service{
|
||||
ID: serviceID,
|
||||
Spec: swarm.ServiceSpec{
|
||||
|
||||
@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/builders"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/golden"
|
||||
@ -17,7 +16,7 @@ func TestListErrors(t *testing.T) {
|
||||
testCases := []struct {
|
||||
args []string
|
||||
flags map[string]string
|
||||
serviceListFunc func(options types.ServiceListOptions) ([]swarm.Service, error)
|
||||
serviceListFunc func(options swarm.ServiceListOptions) ([]swarm.Service, error)
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
@ -33,14 +32,14 @@ func TestListErrors(t *testing.T) {
|
||||
},
|
||||
{
|
||||
args: []string{},
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{}, errors.New("error getting services")
|
||||
},
|
||||
expectedError: "error getting services",
|
||||
},
|
||||
{
|
||||
args: []string{},
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{*builders.Service()}, nil
|
||||
},
|
||||
expectedError: "cannot get label",
|
||||
@ -115,7 +114,7 @@ func TestStackList(t *testing.T) {
|
||||
)
|
||||
}
|
||||
cli := test.NewFakeCli(&fakeClient{
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return services, nil
|
||||
},
|
||||
})
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/builders"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
@ -19,7 +18,7 @@ import (
|
||||
func TestStackPsErrors(t *testing.T) {
|
||||
testCases := []struct {
|
||||
args []string
|
||||
taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error)
|
||||
taskListFunc func(options swarm.TaskListOptions) ([]swarm.Task, error)
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
@ -32,7 +31,7 @@ func TestStackPsErrors(t *testing.T) {
|
||||
},
|
||||
{
|
||||
args: []string{"foo"},
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return nil, errors.New("error getting tasks")
|
||||
},
|
||||
expectedError: "error getting tasks",
|
||||
@ -55,7 +54,7 @@ func TestStackPsErrors(t *testing.T) {
|
||||
func TestStackPs(t *testing.T) {
|
||||
testCases := []struct {
|
||||
doc string
|
||||
taskListFunc func(types.TaskListOptions) ([]swarm.Task, error)
|
||||
taskListFunc func(swarm.TaskListOptions) ([]swarm.Task, error)
|
||||
nodeInspectWithRaw func(string) (swarm.Node, []byte, error)
|
||||
config configfile.ConfigFile
|
||||
args []string
|
||||
@ -70,7 +69,7 @@ func TestStackPs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
doc: "WithEmptyStack",
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return []swarm.Task{}, nil
|
||||
},
|
||||
args: []string{"foo"},
|
||||
@ -78,7 +77,7 @@ func TestStackPs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
doc: "WithQuietOption",
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return []swarm.Task{*builders.Task(builders.TaskID("id-foo"))}, nil
|
||||
},
|
||||
args: []string{"foo"},
|
||||
@ -89,7 +88,7 @@ func TestStackPs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
doc: "WithNoTruncOption",
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return []swarm.Task{*builders.Task(builders.TaskID("xn4cypcov06f2w8gsbaf2lst3"))}, nil
|
||||
},
|
||||
args: []string{"foo"},
|
||||
@ -101,7 +100,7 @@ func TestStackPs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
doc: "WithNoResolveOption",
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return []swarm.Task{*builders.Task(
|
||||
builders.TaskNodeID("id-node-foo"),
|
||||
)}, nil
|
||||
@ -118,7 +117,7 @@ func TestStackPs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
doc: "WithFormat",
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return []swarm.Task{*builders.Task(builders.TaskServiceID("service-id-foo"))}, nil
|
||||
},
|
||||
args: []string{"foo"},
|
||||
@ -129,7 +128,7 @@ func TestStackPs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
doc: "WithConfigFormat",
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return []swarm.Task{*builders.Task(builders.TaskServiceID("service-id-foo"))}, nil
|
||||
},
|
||||
config: configfile.ConfigFile{
|
||||
@ -140,7 +139,7 @@ func TestStackPs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
doc: "WithoutFormat",
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return []swarm.Task{*builders.Task(
|
||||
builders.TaskID("id-foo"),
|
||||
builders.TaskServiceID("service-id-foo"),
|
||||
|
||||
@ -8,7 +8,6 @@ import (
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/builders"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
@ -19,37 +18,37 @@ func TestStackServicesErrors(t *testing.T) {
|
||||
testCases := []struct {
|
||||
args []string
|
||||
flags map[string]string
|
||||
serviceListFunc func(options types.ServiceListOptions) ([]swarm.Service, error)
|
||||
nodeListFunc func(options types.NodeListOptions) ([]swarm.Node, error)
|
||||
taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error)
|
||||
serviceListFunc func(options swarm.ServiceListOptions) ([]swarm.Service, error)
|
||||
nodeListFunc func(options swarm.NodeListOptions) ([]swarm.Node, error)
|
||||
taskListFunc func(options swarm.TaskListOptions) ([]swarm.Task, error)
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
args: []string{"foo"},
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return nil, errors.New("error getting services")
|
||||
},
|
||||
expectedError: "error getting services",
|
||||
},
|
||||
{
|
||||
args: []string{"foo"},
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{*builders.Service(builders.GlobalService())}, nil
|
||||
},
|
||||
nodeListFunc: func(options types.NodeListOptions) ([]swarm.Node, error) {
|
||||
nodeListFunc: func(options swarm.NodeListOptions) ([]swarm.Node, error) {
|
||||
return nil, errors.New("error getting nodes")
|
||||
},
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return []swarm.Task{*builders.Task()}, nil
|
||||
},
|
||||
expectedError: "error getting nodes",
|
||||
},
|
||||
{
|
||||
args: []string{"foo"},
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{*builders.Service(builders.GlobalService())}, nil
|
||||
},
|
||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
taskListFunc: func(options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
return nil, errors.New("error getting tasks")
|
||||
},
|
||||
expectedError: "error getting tasks",
|
||||
@ -59,7 +58,7 @@ func TestStackServicesErrors(t *testing.T) {
|
||||
flags: map[string]string{
|
||||
"format": "{{invalid format}}",
|
||||
},
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{*builders.Service()}, nil
|
||||
},
|
||||
expectedError: "template parsing error",
|
||||
@ -96,7 +95,7 @@ func TestRunServicesWithEmptyName(t *testing.T) {
|
||||
|
||||
func TestStackServicesEmptyServiceList(t *testing.T) {
|
||||
fakeCli := test.NewFakeCli(&fakeClient{
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{}, nil
|
||||
},
|
||||
})
|
||||
@ -109,7 +108,7 @@ func TestStackServicesEmptyServiceList(t *testing.T) {
|
||||
|
||||
func TestStackServicesWithQuietOption(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{*builders.Service(builders.ServiceID("id-foo"))}, nil
|
||||
},
|
||||
})
|
||||
@ -122,7 +121,7 @@ func TestStackServicesWithQuietOption(t *testing.T) {
|
||||
|
||||
func TestStackServicesWithFormat(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{
|
||||
*builders.Service(builders.ServiceName("service-name-foo")),
|
||||
}, nil
|
||||
@ -137,7 +136,7 @@ func TestStackServicesWithFormat(t *testing.T) {
|
||||
|
||||
func TestStackServicesWithConfigFormat(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{
|
||||
*builders.Service(builders.ServiceName("service-name-foo")),
|
||||
}, nil
|
||||
@ -154,7 +153,7 @@ func TestStackServicesWithConfigFormat(t *testing.T) {
|
||||
|
||||
func TestStackServicesWithoutFormat(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{*builders.Service(
|
||||
builders.ServiceName("name-foo"),
|
||||
builders.ServiceID("id-foo"),
|
||||
|
||||
@ -28,15 +28,15 @@ type fakeClient struct {
|
||||
removedSecrets []string
|
||||
removedConfigs []string
|
||||
|
||||
serviceListFunc func(options types.ServiceListOptions) ([]swarm.Service, error)
|
||||
serviceListFunc func(options swarm.ServiceListOptions) ([]swarm.Service, error)
|
||||
networkListFunc func(options network.ListOptions) ([]network.Summary, error)
|
||||
secretListFunc func(options swarm.SecretListOptions) ([]swarm.Secret, error)
|
||||
configListFunc func(options swarm.ConfigListOptions) ([]swarm.Config, error)
|
||||
nodeListFunc func(options types.NodeListOptions) ([]swarm.Node, error)
|
||||
taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error)
|
||||
nodeListFunc func(options swarm.NodeListOptions) ([]swarm.Node, error)
|
||||
taskListFunc func(options swarm.TaskListOptions) ([]swarm.Task, error)
|
||||
nodeInspectWithRaw func(ref string) (swarm.Node, []byte, error)
|
||||
|
||||
serviceUpdateFunc func(serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
|
||||
serviceUpdateFunc func(serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
|
||||
|
||||
serviceRemoveFunc func(serviceID string) error
|
||||
networkRemoveFunc func(networkID string) error
|
||||
@ -55,7 +55,7 @@ func (cli *fakeClient) ClientVersion() string {
|
||||
return cli.version
|
||||
}
|
||||
|
||||
func (cli *fakeClient) ServiceList(_ context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
func (cli *fakeClient) ServiceList(_ context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
if cli.serviceListFunc != nil {
|
||||
return cli.serviceListFunc(options)
|
||||
}
|
||||
@ -115,14 +115,14 @@ func (cli *fakeClient) ConfigList(_ context.Context, options swarm.ConfigListOpt
|
||||
return configsList, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) TaskList(_ context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
|
||||
func (cli *fakeClient) TaskList(_ context.Context, options swarm.TaskListOptions) ([]swarm.Task, error) {
|
||||
if cli.taskListFunc != nil {
|
||||
return cli.taskListFunc(options)
|
||||
}
|
||||
return []swarm.Task{}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) NodeList(_ context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
|
||||
func (cli *fakeClient) NodeList(_ context.Context, options swarm.NodeListOptions) ([]swarm.Node, error) {
|
||||
if cli.nodeListFunc != nil {
|
||||
return cli.nodeListFunc(options)
|
||||
}
|
||||
@ -136,7 +136,7 @@ func (cli *fakeClient) NodeInspectWithRaw(_ context.Context, ref string) (swarm.
|
||||
return swarm.Node{}, nil, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) ServiceUpdate(_ context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
func (cli *fakeClient) ServiceUpdate(_ context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
if cli.serviceUpdateFunc != nil {
|
||||
return cli.serviceUpdateFunc(serviceID, version, service, options)
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli/compose/convert"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
@ -31,7 +30,7 @@ func getAllStacksFilter() filters.Args {
|
||||
}
|
||||
|
||||
func getStackServices(ctx context.Context, apiclient client.APIClient, namespace string) ([]swarm.Service, error) {
|
||||
return apiclient.ServiceList(ctx, types.ServiceListOptions{Filters: getStackFilter(namespace)})
|
||||
return apiclient.ServiceList(ctx, swarm.ServiceListOptions{Filters: getStackFilter(namespace)})
|
||||
}
|
||||
|
||||
func getStackNetworks(ctx context.Context, apiclient client.APIClient, namespace string) ([]network.Summary, error) {
|
||||
@ -47,5 +46,5 @@ func getStackConfigs(ctx context.Context, apiclient client.APIClient, namespace
|
||||
}
|
||||
|
||||
func getStackTasks(ctx context.Context, apiclient client.APIClient, namespace string) ([]swarm.Task, error) {
|
||||
return apiclient.TaskList(ctx, types.TaskListOptions{Filters: getStackFilter(namespace)})
|
||||
return apiclient.TaskList(ctx, swarm.TaskListOptions{Filters: getStackFilter(namespace)})
|
||||
}
|
||||
|
||||
@ -11,7 +11,6 @@ import (
|
||||
"github.com/docker/cli/cli/command/stack/options"
|
||||
"github.com/docker/cli/cli/compose/convert"
|
||||
composetypes "github.com/docker/cli/cli/compose/types"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
@ -221,7 +220,7 @@ func deployServices(ctx context.Context, dockerCLI command.Cli, services map[str
|
||||
if service, exists := existingServiceMap[name]; exists {
|
||||
_, _ = fmt.Fprintf(out, "Updating service %s (id: %s)\n", name, service.ID)
|
||||
|
||||
updateOpts := types.ServiceUpdateOptions{EncodedRegistryAuth: encodedAuth}
|
||||
updateOpts := swarm.ServiceUpdateOptions{EncodedRegistryAuth: encodedAuth}
|
||||
|
||||
switch resolveImage {
|
||||
case ResolveImageAlways:
|
||||
@ -266,7 +265,7 @@ func deployServices(ctx context.Context, dockerCLI command.Cli, services map[str
|
||||
} else {
|
||||
_, _ = fmt.Fprintln(out, "Creating service", name)
|
||||
|
||||
createOpts := types.ServiceCreateOptions{EncodedRegistryAuth: encodedAuth}
|
||||
createOpts := swarm.ServiceCreateOptions{EncodedRegistryAuth: encodedAuth}
|
||||
|
||||
// query registry if flag disabling it was not set
|
||||
if resolveImage == ResolveImageAlways || resolveImage == ResolveImageChanged {
|
||||
|
||||
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli/compose/convert"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
@ -33,12 +32,12 @@ func TestServiceUpdateResolveImageChanged(t *testing.T) {
|
||||
namespace := convert.NewNamespace("mystack")
|
||||
|
||||
var (
|
||||
receivedOptions types.ServiceUpdateOptions
|
||||
receivedOptions swarm.ServiceUpdateOptions
|
||||
receivedService swarm.ServiceSpec
|
||||
)
|
||||
|
||||
client := test.NewFakeCli(&fakeClient{
|
||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
serviceListFunc: func(options swarm.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return []swarm.Service{
|
||||
{
|
||||
Spec: swarm.ServiceSpec{
|
||||
@ -56,7 +55,7 @@ func TestServiceUpdateResolveImageChanged(t *testing.T) {
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
serviceUpdateFunc: func(serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
serviceUpdateFunc: func(serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||
receivedOptions = options
|
||||
receivedService = service
|
||||
return swarm.ServiceUpdateResponse{}, nil
|
||||
@ -105,7 +104,7 @@ func TestServiceUpdateResolveImageChanged(t *testing.T) {
|
||||
assert.Check(t, is.Equal(receivedService.TaskTemplate.ForceUpdate, tc.expectedForceUpdate))
|
||||
|
||||
receivedService = swarm.ServiceSpec{}
|
||||
receivedOptions = types.ServiceUpdateOptions{}
|
||||
receivedOptions = swarm.ServiceUpdateOptions{}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli/command/stack/formatter"
|
||||
"github.com/docker/cli/cli/compose/convert"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@ -14,7 +14,7 @@ import (
|
||||
func GetStacks(ctx context.Context, apiClient client.ServiceAPIClient) ([]*formatter.Stack, error) {
|
||||
services, err := apiClient.ServiceList(
|
||||
ctx,
|
||||
types.ServiceListOptions{Filters: getAllStacksFilter()})
|
||||
swarm.ServiceListOptions{Filters: getAllStacksFilter()})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import (
|
||||
"github.com/docker/cli/cli/command/idresolver"
|
||||
"github.com/docker/cli/cli/command/stack/options"
|
||||
"github.com/docker/cli/cli/command/task"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
)
|
||||
|
||||
// RunPS is the swarm implementation of docker stack ps
|
||||
@ -16,7 +16,7 @@ func RunPS(ctx context.Context, dockerCli command.Cli, opts options.PS) error {
|
||||
filter := getStackFilterFromOpt(opts.Namespace, opts.Filter)
|
||||
|
||||
client := dockerCli.Client()
|
||||
tasks, err := client.TaskList(ctx, types.TaskListOptions{Filters: filter})
|
||||
tasks, err := client.TaskList(ctx, swarm.TaskListOptions{Filters: filter})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import (
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/service"
|
||||
"github.com/docker/cli/cli/command/stack/options"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
)
|
||||
|
||||
@ -17,7 +16,7 @@ func GetServices(ctx context.Context, dockerCli command.Cli, opts options.Servic
|
||||
client = dockerCli.Client()
|
||||
)
|
||||
|
||||
listOpts := types.ServiceListOptions{
|
||||
listOpts := swarm.ServiceListOptions{
|
||||
Filters: getStackFilterFromOpt(opts.Namespace, opts.Filter),
|
||||
// When not running "quiet", also get service status (number of running
|
||||
// and desired tasks). Note that this is only supported on API v1.41 and
|
||||
|
||||
@ -96,7 +96,7 @@ func runCA(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet, opt
|
||||
func updateSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet, opts caOptions) {
|
||||
caCert := opts.rootCACert.Contents()
|
||||
caKey := opts.rootCAKey.Contents()
|
||||
opts.mergeSwarmSpecCAFlags(spec, flags, caCert)
|
||||
opts.mergeSwarmSpecCAFlags(spec, flags, &caCert)
|
||||
|
||||
spec.CAConfig.SigningCACert = caCert
|
||||
spec.CAConfig.SigningCAKey = caKey
|
||||
|
||||
@ -69,7 +69,7 @@ func writeFile(data string) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = tmpfile.Write([]byte(data))
|
||||
_, err = tmpfile.WriteString(data)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ package swarm
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/system"
|
||||
"github.com/docker/docker/client"
|
||||
@ -12,10 +11,10 @@ import (
|
||||
type fakeClient struct {
|
||||
client.Client
|
||||
infoFunc func() (system.Info, error)
|
||||
swarmInitFunc func() (string, error)
|
||||
swarmInitFunc func(req swarm.InitRequest) (string, error)
|
||||
swarmInspectFunc func() (swarm.Swarm, error)
|
||||
nodeInspectFunc func() (swarm.Node, []byte, error)
|
||||
swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error)
|
||||
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
||||
swarmJoinFunc func() error
|
||||
swarmLeaveFunc func() error
|
||||
swarmUpdateFunc func(swarm swarm.Spec, flags swarm.UpdateFlags) error
|
||||
@ -36,9 +35,9 @@ func (cli *fakeClient) NodeInspectWithRaw(context.Context, string) (swarm.Node,
|
||||
return swarm.Node{}, []byte{}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) SwarmInit(context.Context, swarm.InitRequest) (string, error) {
|
||||
func (cli *fakeClient) SwarmInit(_ context.Context, req swarm.InitRequest) (string, error) {
|
||||
if cli.swarmInitFunc != nil {
|
||||
return cli.swarmInitFunc()
|
||||
return cli.swarmInitFunc(req)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
@ -50,11 +49,11 @@ func (cli *fakeClient) SwarmInspect(context.Context) (swarm.Swarm, error) {
|
||||
return swarm.Swarm{}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) SwarmGetUnlockKey(context.Context) (types.SwarmUnlockKeyResponse, error) {
|
||||
func (cli *fakeClient) SwarmGetUnlockKey(context.Context) (swarm.UnlockKeyResponse, error) {
|
||||
if cli.swarmGetUnlockKeyFunc != nil {
|
||||
return cli.swarmGetUnlockKeyFunc()
|
||||
}
|
||||
return types.SwarmUnlockKeyResponse{}, nil
|
||||
return swarm.UnlockKeyResponse{}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) SwarmJoin(context.Context, swarm.JoinRequest) error {
|
||||
|
||||
@ -4,12 +4,14 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/golden"
|
||||
)
|
||||
|
||||
@ -17,22 +19,22 @@ func TestSwarmInitErrorOnAPIFailure(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
flags map[string]string
|
||||
swarmInitFunc func() (string, error)
|
||||
swarmInitFunc func(swarm.InitRequest) (string, error)
|
||||
swarmInspectFunc func() (swarm.Swarm, error)
|
||||
swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error)
|
||||
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
||||
nodeInspectFunc func() (swarm.Node, []byte, error)
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
name: "init-failed",
|
||||
swarmInitFunc: func() (string, error) {
|
||||
swarmInitFunc: func(swarm.InitRequest) (string, error) {
|
||||
return "", errors.New("error initializing the swarm")
|
||||
},
|
||||
expectedError: "error initializing the swarm",
|
||||
},
|
||||
{
|
||||
name: "init-failed-with-ip-choice",
|
||||
swarmInitFunc: func() (string, error) {
|
||||
swarmInitFunc: func(swarm.InitRequest) (string, error) {
|
||||
return "", errors.New("could not choose an IP address to advertise")
|
||||
},
|
||||
expectedError: "could not choose an IP address to advertise - specify one with --advertise-addr",
|
||||
@ -56,8 +58,8 @@ func TestSwarmInitErrorOnAPIFailure(t *testing.T) {
|
||||
flags: map[string]string{
|
||||
flagAutolock: "true",
|
||||
},
|
||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||
return types.SwarmUnlockKeyResponse{}, errors.New("error getting swarm unlock key")
|
||||
swarmGetUnlockKeyFunc: func() (swarm.UnlockKeyResponse, error) {
|
||||
return swarm.UnlockKeyResponse{}, errors.New("error getting swarm unlock key")
|
||||
},
|
||||
expectedError: "could not fetch unlock key: error getting swarm unlock key",
|
||||
},
|
||||
@ -86,14 +88,14 @@ func TestSwarmInit(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
flags map[string]string
|
||||
swarmInitFunc func() (string, error)
|
||||
swarmInitFunc func(req swarm.InitRequest) (string, error)
|
||||
swarmInspectFunc func() (swarm.Swarm, error)
|
||||
swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error)
|
||||
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
||||
nodeInspectFunc func() (swarm.Node, []byte, error)
|
||||
}{
|
||||
{
|
||||
name: "init",
|
||||
swarmInitFunc: func() (string, error) {
|
||||
swarmInitFunc: func(swarm.InitRequest) (string, error) {
|
||||
return "nodeID", nil
|
||||
},
|
||||
},
|
||||
@ -102,11 +104,11 @@ func TestSwarmInit(t *testing.T) {
|
||||
flags: map[string]string{
|
||||
flagAutolock: "true",
|
||||
},
|
||||
swarmInitFunc: func() (string, error) {
|
||||
swarmInitFunc: func(swarm.InitRequest) (string, error) {
|
||||
return "nodeID", nil
|
||||
},
|
||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||
return types.SwarmUnlockKeyResponse{
|
||||
swarmGetUnlockKeyFunc: func() (swarm.UnlockKeyResponse, error) {
|
||||
return swarm.UnlockKeyResponse{
|
||||
UnlockKey: "unlock-key",
|
||||
}, nil
|
||||
},
|
||||
@ -132,3 +134,28 @@ func TestSwarmInit(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSwarmInitWithExternalCA(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{
|
||||
swarmInitFunc: func(req swarm.InitRequest) (string, error) {
|
||||
if assert.Check(t, is.Len(req.Spec.CAConfig.ExternalCAs, 1)) {
|
||||
assert.Equal(t, req.Spec.CAConfig.ExternalCAs[0].CACert, cert)
|
||||
assert.Equal(t, req.Spec.CAConfig.ExternalCAs[0].Protocol, swarm.ExternalCAProtocolCFSSL)
|
||||
assert.Equal(t, req.Spec.CAConfig.ExternalCAs[0].URL, "https://example.com")
|
||||
}
|
||||
return "nodeID", nil
|
||||
},
|
||||
})
|
||||
|
||||
tempDir := t.TempDir()
|
||||
certFile := filepath.Join(tempDir, "cert.pem")
|
||||
err := os.WriteFile(certFile, []byte(cert), 0o644)
|
||||
assert.NilError(t, err)
|
||||
|
||||
cmd := newInitCommand(cli)
|
||||
cmd.SetArgs([]string{})
|
||||
cmd.SetOut(io.Discard)
|
||||
cmd.SetErr(io.Discard)
|
||||
assert.NilError(t, cmd.Flags().Set(flagExternalCA, "protocol=cfssl,url=https://example.com,cacert="+certFile))
|
||||
assert.NilError(t, cmd.Execute())
|
||||
}
|
||||
|
||||
@ -231,7 +231,7 @@ func addSwarmFlags(flags *pflag.FlagSet, options *swarmOptions) {
|
||||
addSwarmCAFlags(flags, &options.swarmCAOptions)
|
||||
}
|
||||
|
||||
func (o *swarmOptions) mergeSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet, caCert string) {
|
||||
func (o *swarmOptions) mergeSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet, caCert *string) {
|
||||
if flags.Changed(flagTaskHistoryLimit) {
|
||||
spec.Orchestration.TaskHistoryRetentionLimit = &o.taskHistoryLimit
|
||||
}
|
||||
@ -255,20 +255,24 @@ type swarmCAOptions struct {
|
||||
externalCA ExternalCAOption
|
||||
}
|
||||
|
||||
func (o *swarmCAOptions) mergeSwarmSpecCAFlags(spec *swarm.Spec, flags *pflag.FlagSet, caCert string) {
|
||||
func (o *swarmCAOptions) mergeSwarmSpecCAFlags(spec *swarm.Spec, flags *pflag.FlagSet, caCert *string) {
|
||||
if flags.Changed(flagCertExpiry) {
|
||||
spec.CAConfig.NodeCertExpiry = o.nodeCertExpiry
|
||||
}
|
||||
if flags.Changed(flagExternalCA) {
|
||||
spec.CAConfig.ExternalCAs = o.externalCA.Value()
|
||||
for _, ca := range spec.CAConfig.ExternalCAs {
|
||||
ca.CACert = caCert
|
||||
if caCert != nil {
|
||||
for _, ca := range spec.CAConfig.ExternalCAs {
|
||||
if ca.CACert == "" {
|
||||
ca.CACert = *caCert
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *swarmOptions) ToSpec(flags *pflag.FlagSet) swarm.Spec {
|
||||
var spec swarm.Spec
|
||||
o.mergeSwarmSpec(&spec, flags, "")
|
||||
o.mergeSwarmSpec(&spec, flags, nil)
|
||||
return spec
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ import (
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/progress"
|
||||
@ -52,7 +51,7 @@ func RootRotationProgress(ctx context.Context, dclient client.APIClient, progres
|
||||
return nil
|
||||
}
|
||||
|
||||
nodes, err := dclient.NodeList(ctx, types.NodeListOptions{})
|
||||
nodes, err := dclient.NodeList(ctx, swarm.NodeListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ func runUnlock(ctx context.Context, dockerCli command.Cli) error {
|
||||
return errors.New("Error: This node is not part of a swarm")
|
||||
case swarm.LocalNodeStateLocked:
|
||||
break
|
||||
default:
|
||||
case swarm.LocalNodeStatePending, swarm.LocalNodeStateActive, swarm.LocalNodeStateError:
|
||||
return errors.New("Error: swarm is not locked")
|
||||
}
|
||||
|
||||
@ -58,11 +58,10 @@ func runUnlock(ctx context.Context, dockerCli command.Cli) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := swarm.UnlockRequest{
|
||||
UnlockKey: key,
|
||||
}
|
||||
|
||||
return client.SwarmUnlock(ctx, req)
|
||||
return client.SwarmUnlock(ctx, swarm.UnlockRequest{
|
||||
UnlockKey: key,
|
||||
})
|
||||
}
|
||||
|
||||
func readKey(in *streams.In, prompt string) (string, error) {
|
||||
|
||||
@ -8,7 +8,6 @@ import (
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/builders"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/golden"
|
||||
@ -21,7 +20,7 @@ func TestSwarmUnlockKeyErrors(t *testing.T) {
|
||||
flags map[string]string
|
||||
swarmInspectFunc func() (swarm.Swarm, error)
|
||||
swarmUpdateFunc func(swarm swarm.Spec, flags swarm.UpdateFlags) error
|
||||
swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error)
|
||||
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
@ -64,17 +63,15 @@ func TestSwarmUnlockKeyErrors(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "swarm-get-unlock-key-failed",
|
||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||
return types.SwarmUnlockKeyResponse{}, errors.New("error getting unlock key")
|
||||
swarmGetUnlockKeyFunc: func() (swarm.UnlockKeyResponse, error) {
|
||||
return swarm.UnlockKeyResponse{}, errors.New("error getting unlock key")
|
||||
},
|
||||
expectedError: "error getting unlock key",
|
||||
},
|
||||
{
|
||||
name: "swarm-no-unlock-key-failed",
|
||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||
return types.SwarmUnlockKeyResponse{
|
||||
UnlockKey: "",
|
||||
}, nil
|
||||
swarmGetUnlockKeyFunc: func() (swarm.UnlockKeyResponse, error) {
|
||||
return swarm.UnlockKeyResponse{}, nil
|
||||
},
|
||||
expectedError: "no unlock key is set",
|
||||
},
|
||||
@ -108,12 +105,12 @@ func TestSwarmUnlockKey(t *testing.T) {
|
||||
flags map[string]string
|
||||
swarmInspectFunc func() (swarm.Swarm, error)
|
||||
swarmUpdateFunc func(swarm swarm.Spec, flags swarm.UpdateFlags) error
|
||||
swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error)
|
||||
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
||||
}{
|
||||
{
|
||||
name: "unlock-key",
|
||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||
return types.SwarmUnlockKeyResponse{
|
||||
swarmGetUnlockKeyFunc: func() (swarm.UnlockKeyResponse, error) {
|
||||
return swarm.UnlockKeyResponse{
|
||||
UnlockKey: "unlock-key",
|
||||
}, nil
|
||||
},
|
||||
@ -123,8 +120,8 @@ func TestSwarmUnlockKey(t *testing.T) {
|
||||
flags: map[string]string{
|
||||
flagQuiet: "true",
|
||||
},
|
||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||
return types.SwarmUnlockKeyResponse{
|
||||
swarmGetUnlockKeyFunc: func() (swarm.UnlockKeyResponse, error) {
|
||||
return swarm.UnlockKeyResponse{
|
||||
UnlockKey: "unlock-key",
|
||||
}, nil
|
||||
},
|
||||
@ -137,8 +134,8 @@ func TestSwarmUnlockKey(t *testing.T) {
|
||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||
return *builders.Swarm(builders.Autolock()), nil
|
||||
},
|
||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||
return types.SwarmUnlockKeyResponse{
|
||||
swarmGetUnlockKeyFunc: func() (swarm.UnlockKeyResponse, error) {
|
||||
return swarm.UnlockKeyResponse{
|
||||
UnlockKey: "unlock-key",
|
||||
}, nil
|
||||
},
|
||||
@ -152,8 +149,8 @@ func TestSwarmUnlockKey(t *testing.T) {
|
||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||
return *builders.Swarm(builders.Autolock()), nil
|
||||
},
|
||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||
return types.SwarmUnlockKeyResponse{
|
||||
swarmGetUnlockKeyFunc: func() (swarm.UnlockKeyResponse, error) {
|
||||
return swarm.UnlockKeyResponse{
|
||||
UnlockKey: "unlock-key",
|
||||
}, nil
|
||||
},
|
||||
|
||||
@ -53,7 +53,7 @@ func runUpdate(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet,
|
||||
|
||||
prevAutoLock := swarmInspect.Spec.EncryptionConfig.AutoLockManagers
|
||||
|
||||
opts.mergeSwarmSpec(&swarmInspect.Spec, flags, swarmInspect.ClusterInfo.TLSInfo.TrustRoot)
|
||||
opts.mergeSwarmSpec(&swarmInspect.Spec, flags, &swarmInspect.ClusterInfo.TLSInfo.TrustRoot)
|
||||
|
||||
curAutoLock := swarmInspect.Spec.EncryptionConfig.AutoLockManagers
|
||||
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/builders"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/golden"
|
||||
@ -22,7 +21,7 @@ func TestSwarmUpdateErrors(t *testing.T) {
|
||||
flags map[string]string
|
||||
swarmInspectFunc func() (swarm.Swarm, error)
|
||||
swarmUpdateFunc func(swarm swarm.Spec, flags swarm.UpdateFlags) error
|
||||
swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error)
|
||||
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
@ -58,8 +57,8 @@ func TestSwarmUpdateErrors(t *testing.T) {
|
||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||
return *builders.Swarm(), nil
|
||||
},
|
||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||
return types.SwarmUnlockKeyResponse{}, errors.New("error getting unlock key")
|
||||
swarmGetUnlockKeyFunc: func() (swarm.UnlockKeyResponse, error) {
|
||||
return swarm.UnlockKeyResponse{}, errors.New("error getting unlock key")
|
||||
},
|
||||
expectedError: "error getting unlock key",
|
||||
},
|
||||
@ -97,7 +96,7 @@ func TestSwarmUpdate(t *testing.T) {
|
||||
flags map[string]string
|
||||
swarmInspectFunc func() (swarm.Swarm, error)
|
||||
swarmUpdateFunc func(swarm swarm.Spec, flags swarm.UpdateFlags) error
|
||||
swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error)
|
||||
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
||||
}{
|
||||
{
|
||||
name: "noargs",
|
||||
@ -164,8 +163,8 @@ func TestSwarmUpdate(t *testing.T) {
|
||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||
return *builders.Swarm(), nil
|
||||
},
|
||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||
return types.SwarmUnlockKeyResponse{
|
||||
swarmGetUnlockKeyFunc: func() (swarm.UnlockKeyResponse, error) {
|
||||
return swarm.UnlockKeyResponse{
|
||||
UnlockKey: "unlock-key",
|
||||
}, nil
|
||||
},
|
||||
|
||||
@ -26,7 +26,7 @@ type fakeClient struct {
|
||||
infoFunc func(ctx context.Context) (system.Info, error)
|
||||
networkListFunc func(ctx context.Context, options network.ListOptions) ([]network.Summary, error)
|
||||
networkPruneFunc func(ctx context.Context, pruneFilter filters.Args) (network.PruneReport, error)
|
||||
nodeListFunc func(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error)
|
||||
nodeListFunc func(ctx context.Context, options swarm.NodeListOptions) ([]swarm.Node, error)
|
||||
serverVersion func(ctx context.Context) (types.Version, error)
|
||||
volumeListFunc func(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error)
|
||||
}
|
||||
@ -81,7 +81,7 @@ func (cli *fakeClient) NetworksPrune(ctx context.Context, pruneFilter filters.Ar
|
||||
return network.PruneReport{}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
|
||||
func (cli *fakeClient) NodeList(ctx context.Context, options swarm.NodeListOptions) ([]swarm.Node, error) {
|
||||
if cli.nodeListFunc != nil {
|
||||
return cli.nodeListFunc(ctx, options)
|
||||
}
|
||||
|
||||
@ -4,10 +4,10 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/docker/api/types"
|
||||
"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/swarm"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@ -211,7 +211,7 @@ func networkNames(dockerCLI completion.APIClientProvider, cmd *cobra.Command) []
|
||||
// nodeNames contacts the API to get a list of node names.
|
||||
// In case of an error, an empty list is returned.
|
||||
func nodeNames(dockerCLI completion.APIClientProvider, cmd *cobra.Command) []string {
|
||||
list, err := dockerCLI.Client().NodeList(cmd.Context(), types.NodeListOptions{})
|
||||
list, err := dockerCLI.Client().NodeList(cmd.Context(), swarm.NodeListOptions{})
|
||||
if err != nil {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ import (
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/builders"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
@ -111,7 +110,7 @@ func TestCompleteEventFilter(t *testing.T) {
|
||||
},
|
||||
{
|
||||
client: &fakeClient{
|
||||
nodeListFunc: func(_ context.Context, _ types.NodeListOptions) ([]swarm.Node, error) {
|
||||
nodeListFunc: func(_ context.Context, _ swarm.NodeListOptions) ([]swarm.Node, error) {
|
||||
return []swarm.Node{
|
||||
*builders.Node(builders.Hostname("n1")),
|
||||
}, nil
|
||||
@ -122,7 +121,7 @@ func TestCompleteEventFilter(t *testing.T) {
|
||||
},
|
||||
{
|
||||
client: &fakeClient{
|
||||
nodeListFunc: func(_ context.Context, _ types.NodeListOptions) ([]swarm.Node, error) {
|
||||
nodeListFunc: func(_ context.Context, _ swarm.NodeListOptions) ([]swarm.Node, error) {
|
||||
return []swarm.Node{}, errors.New("API error")
|
||||
},
|
||||
},
|
||||
|
||||
@ -15,9 +15,9 @@ import (
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/cli/cli/command/inspect"
|
||||
flagsHelper "github.com/docker/cli/cli/flags"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
@ -137,7 +137,7 @@ func inspectNode(ctx context.Context, dockerCli command.Cli) inspect.GetRefFunc
|
||||
func inspectService(ctx context.Context, dockerCli command.Cli) inspect.GetRefFunc {
|
||||
return func(ref string) (any, []byte, error) {
|
||||
// Service inspect shows defaults values in empty fields.
|
||||
return dockerCli.Client().ServiceInspectWithRaw(ctx, ref, types.ServiceInspectOptions{InsertDefaults: true})
|
||||
return dockerCli.Client().ServiceInspectWithRaw(ctx, ref, swarm.ServiceInspectOptions{InsertDefaults: true})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@ package task
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
)
|
||||
@ -11,7 +10,7 @@ import (
|
||||
type fakeClient struct {
|
||||
client.APIClient
|
||||
nodeInspectWithRaw func(ref string) (swarm.Node, []byte, error)
|
||||
serviceInspectWithRaw func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error)
|
||||
serviceInspectWithRaw func(ref string, options swarm.ServiceInspectOptions) (swarm.Service, []byte, error)
|
||||
}
|
||||
|
||||
func (cli *fakeClient) NodeInspectWithRaw(_ context.Context, ref string) (swarm.Node, []byte, error) {
|
||||
@ -21,7 +20,7 @@ func (cli *fakeClient) NodeInspectWithRaw(_ context.Context, ref string) (swarm.
|
||||
return swarm.Node{}, nil, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) ServiceInspectWithRaw(_ context.Context, ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
func (cli *fakeClient) ServiceInspectWithRaw(_ context.Context, ref string, options swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
if cli.serviceInspectWithRaw != nil {
|
||||
return cli.serviceInspectWithRaw(ref, options)
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
"github.com/docker/cli/cli/command/idresolver"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/builders"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/golden"
|
||||
@ -17,7 +16,7 @@ import (
|
||||
|
||||
func TestTaskPrintSorted(t *testing.T) {
|
||||
apiClient := &fakeClient{
|
||||
serviceInspectWithRaw: func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
serviceInspectWithRaw: func(ref string, options swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
if ref == "service-id-one" {
|
||||
return *builders.Service(builders.ServiceName("service-name-1")), nil, nil
|
||||
}
|
||||
@ -109,7 +108,7 @@ func TestTaskPrintWithIndentation(t *testing.T) {
|
||||
const trunc = false
|
||||
const noResolve = false
|
||||
apiClient := &fakeClient{
|
||||
serviceInspectWithRaw: func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
serviceInspectWithRaw: func(ref string, options swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
return *builders.Service(builders.ServiceName("service-name-foo")), nil, nil
|
||||
},
|
||||
nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
|
||||
@ -145,7 +144,7 @@ func TestTaskPrintWithResolution(t *testing.T) {
|
||||
const trunc = false
|
||||
const noResolve = false
|
||||
apiClient := &fakeClient{
|
||||
serviceInspectWithRaw: func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
serviceInspectWithRaw: func(ref string, options swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
return *builders.Service(builders.ServiceName("service-name-foo")), nil, nil
|
||||
},
|
||||
nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
|
||||
|
||||
@ -152,7 +152,8 @@ func (configFile *ConfigFile) Save() (retErr error) {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
temp.Close()
|
||||
// ignore error as the file may already be closed when we reach this.
|
||||
_ = temp.Close()
|
||||
if retErr != nil {
|
||||
if err := os.Remove(temp.Name()); err != nil {
|
||||
logrus.WithError(err).WithField("file", temp.Name()).Debug("Error cleaning up temp file")
|
||||
@ -169,10 +170,16 @@ func (configFile *ConfigFile) Save() (retErr error) {
|
||||
return errors.Wrap(err, "error closing temp file")
|
||||
}
|
||||
|
||||
// Handle situation where the configfile is a symlink
|
||||
// Handle situation where the configfile is a symlink, and allow for dangling symlinks
|
||||
cfgFile := configFile.Filename
|
||||
if f, err := os.Readlink(cfgFile); err == nil {
|
||||
if f, err := filepath.EvalSymlinks(cfgFile); err == nil {
|
||||
cfgFile = f
|
||||
} else if os.IsNotExist(err) {
|
||||
// extract the path from the error if the configfile does not exist or is a dangling symlink
|
||||
var pathError *os.PathError
|
||||
if errors.As(err, &pathError) {
|
||||
cfgFile = pathError.Path
|
||||
}
|
||||
}
|
||||
|
||||
// Try copying the current config file (if any) ownership and permissions
|
||||
|
||||
@ -538,6 +538,34 @@ func TestSaveWithSymlink(t *testing.T) {
|
||||
assert.Check(t, is.Equal(string(cfg), "{\n \"auths\": {}\n}"))
|
||||
}
|
||||
|
||||
func TestSaveWithRelativeSymlink(t *testing.T) {
|
||||
dir := fs.NewDir(t, t.Name(), fs.WithFile("real-config.json", `{}`))
|
||||
defer dir.Remove()
|
||||
|
||||
symLink := dir.Join("config.json")
|
||||
relativeRealFile := "real-config.json"
|
||||
realFile := dir.Join(relativeRealFile)
|
||||
err := os.Symlink(relativeRealFile, symLink)
|
||||
assert.NilError(t, err)
|
||||
|
||||
configFile := New(symLink)
|
||||
|
||||
err = configFile.Save()
|
||||
assert.NilError(t, err)
|
||||
|
||||
fi, err := os.Lstat(symLink)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, fi.Mode()&os.ModeSymlink != 0, "expected %s to be a symlink", symLink)
|
||||
|
||||
cfg, err := os.ReadFile(symLink)
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(string(cfg), "{\n \"auths\": {}\n}"))
|
||||
|
||||
cfg, err = os.ReadFile(realFile)
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(string(cfg), "{\n \"auths\": {}\n}"))
|
||||
}
|
||||
|
||||
func TestPluginConfig(t *testing.T) {
|
||||
configFile := New("test-plugin")
|
||||
defer os.Remove("test-plugin")
|
||||
|
||||
@ -6,7 +6,7 @@ ARG ALPINE_VERSION=3.21
|
||||
# BUILDX_VERSION sets the version of buildx to install in the dev container.
|
||||
# It must be a valid tag in the docker.io/docker/buildx-bin image repository
|
||||
# on Docker Hub.
|
||||
ARG BUILDX_VERSION=0.23.0
|
||||
ARG BUILDX_VERSION=0.24.0
|
||||
FROM docker/buildx-bin:${BUILDX_VERSION} AS buildx
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS golang
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
ARG GO_VERSION=1.24.3
|
||||
ARG ALPINE_VERSION=3.21
|
||||
ARG GOLANGCI_LINT_VERSION=v2.1.2
|
||||
ARG GOLANGCI_LINT_VERSION=v2.1.5
|
||||
|
||||
FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint
|
||||
|
||||
|
||||
@ -55,14 +55,14 @@ The following table provides an overview of the current status of deprecated fea
|
||||
|------------|------------------------------------------------------------------------------------------------------------------------------------|------------|--------|
|
||||
| Deprecated | [Configuration for pushing non-distributable artifacts](#configuration-for-pushing-non-distributable-artifacts) | v28.0 | v29.0 |
|
||||
| Deprecated | [`--time` option on `docker stop` and `docker restart`](#--time-option-on-docker-stop-and-docker-restart) | v28.0 | - |
|
||||
| Deprecated | [Non-standard fields in image inspect](#non-standard-fields-in-image-inspect) | v27.0 | v28.0 |
|
||||
| Removed | [Non-standard fields in image inspect](#non-standard-fields-in-image-inspect) | v27.0 | v28.2 |
|
||||
| Removed | [API CORS headers](#api-cors-headers) | v27.0 | v28.0 |
|
||||
| Deprecated | [Graphdriver plugins (experimental)](#graphdriver-plugins-experimental) | v27.0 | v28.0 |
|
||||
| Removed | [Graphdriver plugins (experimental)](#graphdriver-plugins-experimental) | v27.0 | v28.0 |
|
||||
| Deprecated | [Unauthenticated TCP connections](#unauthenticated-tcp-connections) | v26.0 | v28.0 |
|
||||
| Deprecated | [`Container` and `ContainerConfig` fields in Image inspect](#container-and-containerconfig-fields-in-image-inspect) | v25.0 | v26.0 |
|
||||
| Deprecated | [Deprecate legacy API versions](#deprecate-legacy-api-versions) | v25.0 | v26.0 |
|
||||
| Removed | [`Container` and `ContainerConfig` fields in Image inspect](#container-and-containerconfig-fields-in-image-inspect) | v25.0 | v26.0 |
|
||||
| Removed | [Deprecate legacy API versions](#deprecate-legacy-api-versions) | v25.0 | v26.0 |
|
||||
| Removed | [Container short ID in network Aliases field](#container-short-id-in-network-aliases-field) | v25.0 | v26.0 |
|
||||
| Deprecated | [IsAutomated field, and `is-automated` filter on `docker search`](#isautomated-field-and-is-automated-filter-on-docker-search) | v25.0 | v26.0 |
|
||||
| Removed | [IsAutomated field, and `is-automated` filter on `docker search`](#isautomated-field-and-is-automated-filter-on-docker-search) | v25.0 | v28.2 |
|
||||
| Removed | [logentries logging driver](#logentries-logging-driver) | v24.0 | v25.0 |
|
||||
| Removed | [OOM-score adjust for the daemon](#oom-score-adjust-for-the-daemon) | v24.0 | v25.0 |
|
||||
| Removed | [BuildKit build information](#buildkit-build-information) | v23.0 | v24.0 |
|
||||
@ -71,7 +71,7 @@ The following table provides an overview of the current status of deprecated fea
|
||||
| Removed | [Btrfs storage driver on CentOS 7 and RHEL 7](#btrfs-storage-driver-on-centos-7-and-rhel-7) | v20.10 | v23.0 |
|
||||
| Removed | [Support for encrypted TLS private keys](#support-for-encrypted-tls-private-keys) | v20.10 | v23.0 |
|
||||
| Removed | [Kubernetes stack and context support](#kubernetes-stack-and-context-support) | v20.10 | v23.0 |
|
||||
| Deprecated | [Pulling images from non-compliant image registries](#pulling-images-from-non-compliant-image-registries) | v20.10 | - |
|
||||
| Removed | [Pulling images from non-compliant image registries](#pulling-images-from-non-compliant-image-registries) | v20.10 | v28.2 |
|
||||
| Removed | [Linux containers on Windows (LCOW)](#linux-containers-on-windows-lcow-experimental) | v20.10 | v23.0 |
|
||||
| Deprecated | [BLKIO weight options with cgroups v1](#blkio-weight-options-with-cgroups-v1) | v20.10 | - |
|
||||
| Removed | [Kernel memory limit](#kernel-memory-limit) | v20.10 | v23.0 |
|
||||
@ -80,9 +80,9 @@ The following table provides an overview of the current status of deprecated fea
|
||||
| Deprecated | [CLI plugins support](#cli-plugins-support) | v20.10 | - |
|
||||
| Deprecated | [Dockerfile legacy `ENV name value` syntax](#dockerfile-legacy-env-name-value-syntax) | v20.10 | - |
|
||||
| Removed | [`docker build --stream` flag (experimental)](#docker-build---stream-flag-experimental) | v20.10 | v20.10 |
|
||||
| Deprecated | [`fluentd-async-connect` log opt](#fluentd-async-connect-log-opt) | v20.10 | v28.0 |
|
||||
| Removed | [`fluentd-async-connect` log opt](#fluentd-async-connect-log-opt) | v20.10 | v28.0 |
|
||||
| Removed | [Configuration options for experimental CLI features](#configuration-options-for-experimental-cli-features) | v19.03 | v23.0 |
|
||||
| Deprecated | [Pushing and pulling with image manifest v2 schema 1](#pushing-and-pulling-with-image-manifest-v2-schema-1) | v19.03 | v27.0 |
|
||||
| Removed | [Pushing and pulling with image manifest v2 schema 1](#pushing-and-pulling-with-image-manifest-v2-schema-1) | v19.03 | v28.2 |
|
||||
| Removed | [`docker engine` subcommands](#docker-engine-subcommands) | v19.03 | v20.10 |
|
||||
| Removed | [Top-level `docker deploy` subcommand (experimental)](#top-level-docker-deploy-subcommand-experimental) | v19.03 | v20.10 |
|
||||
| Removed | [`docker stack deploy` using "dab" files (experimental)](#docker-stack-deploy-using-dab-files-experimental) | v19.03 | v20.10 |
|
||||
@ -172,7 +172,7 @@ Users are encouraged to migrate to using the `--timeout` option instead.
|
||||
### Non-standard fields in image inspect
|
||||
|
||||
**Deprecated in Release: v27.0**
|
||||
**Target For Removal In Release: v28.0**
|
||||
**Removed In Release: v28.2**
|
||||
|
||||
The `Config` field returned shown in `docker image inspect` (and as returned by
|
||||
the `GET /images/{name}/json` API endpoint) returns additional fields that are
|
||||
@ -184,8 +184,9 @@ but are not omitted in the response when left empty. As these fields were not
|
||||
intended to be part of the image configuration response, they are deprecated,
|
||||
and will be removed from the API in thee next release.
|
||||
|
||||
The following fields are currently included in the API response, but are not
|
||||
part of the underlying image's `Config` field, and deprecated:
|
||||
The following fields are not part of the underlying image's `Config` field, and
|
||||
removed in the API response for API v1.50 and newer, corresponding with v28.2.
|
||||
They continue to be included when using clients that use an older API version:
|
||||
|
||||
- `Hostname`
|
||||
- `Domainname`
|
||||
@ -196,9 +197,9 @@ part of the underlying image's `Config` field, and deprecated:
|
||||
- `OpenStdin`
|
||||
- `StdinOnce`
|
||||
- `Image`
|
||||
- `NetworkDisabled` (already omitted unless set)
|
||||
- `MacAddress` (already omitted unless set)
|
||||
- `StopTimeout` (already omitted unless set)
|
||||
- `NetworkDisabled` (omitted unless set on older API versions)
|
||||
- `MacAddress` (omitted unless set on older API versions)
|
||||
- `StopTimeout` (omitted unless set on older API versions)
|
||||
|
||||
[Docker image specification]: https://github.com/moby/docker-image-spec/blob/v1.3.1/specs-go/v1/image.go#L19-L32
|
||||
[OCI image specification]: https://github.com/opencontainers/image-spec/blob/v1.1.0/specs-go/v1/config.go#L24-L62
|
||||
@ -210,19 +211,13 @@ part of the underlying image's `Config` field, and deprecated:
|
||||
**Target For Removal In Release: v28.0**
|
||||
|
||||
[Graphdriver plugins](https://github.com/docker/cli/blob/v26.1.4/docs/extend/plugins_graphdriver.md)
|
||||
are an experimental feature that allow extending the Docker Engine with custom
|
||||
were an experimental feature that allowed extending the Docker Engine with custom
|
||||
storage drivers for storing images and containers. This feature was not
|
||||
maintained since its inception, and will no longer be supported in upcoming
|
||||
releases.
|
||||
maintained since its inception.
|
||||
|
||||
Support for graphdriver plugins is disabled by default in v27.0, and will be
|
||||
removed v28.0. An `DOCKERD_DEPRECATED_GRAPHDRIVER_PLUGINS` environment variable
|
||||
is provided in v27.0 to re-enable the feature. This environment variable must
|
||||
be set to a non-empty value in the daemon's environment.
|
||||
|
||||
The `DOCKERD_DEPRECATED_GRAPHDRIVER_PLUGINS` environment variable, along with
|
||||
support for graphdriver plugins, will be removed in v28.0. Users of this feature
|
||||
are recommended to instead configure the Docker Engine to use the [containerd image store](https://docs.docker.com/storage/containerd/)
|
||||
Support for graphdriver plugins was disabled by default in v27.0, and removed
|
||||
in v28.0. Users of this feature are recommended to instead configure the Docker
|
||||
Engine to use the [containerd image store](https://docs.docker.com/storage/containerd/)
|
||||
and a custom [snapshotter](https://github.com/containerd/containerd/tree/v1.7.18/docs/snapshotters)
|
||||
|
||||
### API CORS headers
|
||||
@ -276,15 +271,15 @@ configuring TLS (or SSH) for the Docker daemon, refer to
|
||||
### `Container` and `ContainerConfig` fields in Image inspect
|
||||
|
||||
**Deprecated in Release: v25.0**
|
||||
**Target For Removal In Release: v26.0**
|
||||
**Removed In Release: v26.0**
|
||||
|
||||
The `Container` and `ContainerConfig` fields returned by `docker inspect` are
|
||||
mostly an implementation detail of the classic (non-BuildKit) image builder.
|
||||
These fields are not portable and are empty when using the
|
||||
BuildKit-based builder (enabled by default since v23.0).
|
||||
These fields are deprecated in v25.0 and will be omitted starting from v26.0.
|
||||
If image configuration of an image is needed, you can obtain it from the
|
||||
`Config` field.
|
||||
These fields are deprecated in v25.0 and are omitted starting from v26.0 (
|
||||
API version v1.45 and up). If image configuration of an image is needed,
|
||||
you can obtain it from the `Config` field.
|
||||
|
||||
### Deprecate legacy API versions
|
||||
|
||||
@ -326,20 +321,22 @@ Error response from daemon: client version 1.23 is too old. Minimum supported AP
|
||||
upgrade your client to a newer version
|
||||
```
|
||||
|
||||
Support for API versions lower than `1.24` has been permanently removed in Docker
|
||||
Engine v26, and the minimum supported API version will be incrementally raised
|
||||
in releases following that.
|
||||
|
||||
<!-- keeping the paragraphs below for when we incrementally raise the minimum API version -->
|
||||
<!--
|
||||
An environment variable (`DOCKER_MIN_API_VERSION`) is introduced that allows
|
||||
re-enabling older API versions in the daemon. This environment variable must
|
||||
be set in the daemon's environment (for example, through a [systemd override
|
||||
file](https://docs.docker.com/config/daemon/systemd/)), and the specified
|
||||
API version must be supported by the daemon (`1.12` or higher on Linux, or
|
||||
`1.24` or higher on Windows).
|
||||
|
||||
Support for API versions lower than `1.24` will be permanently removed in Docker
|
||||
Engine v26, and the minimum supported API version will be incrementally raised
|
||||
in releases following that.
|
||||
API version must be supported by the daemon (`1.24` or higher).
|
||||
|
||||
We do not recommend depending on the `DOCKER_MIN_API_VERSION` environment
|
||||
variable other than for exceptional cases where it's not possible to update
|
||||
old clients, and those clients must be supported.
|
||||
-->
|
||||
|
||||
### Container short ID in network Aliases field
|
||||
|
||||
@ -359,7 +356,7 @@ introduced in v25.0 and should be used instead of the `Aliases` field.
|
||||
### IsAutomated field, and `is-automated` filter on `docker search`
|
||||
|
||||
**Deprecated in Release: v25.0**
|
||||
**Target For Removal In Release: v26.0**
|
||||
**Removed In Release: v28.2**
|
||||
|
||||
The `is_automated` field has been deprecated by Docker Hub's search API.
|
||||
Consequently, the `IsAutomated` field in image search will always be set
|
||||
@ -368,7 +365,7 @@ results.
|
||||
|
||||
The `AUTOMATED` column has been removed from the default `docker search`
|
||||
and `docker image search` output in v25.0, and the corresponding `IsAutomated`
|
||||
templating option will be removed in v26.0.
|
||||
templating has been removed in v28.2.
|
||||
|
||||
### Logentries logging driver
|
||||
|
||||
@ -550,6 +547,7 @@ CLI configuration file are no longer used, and ignored.
|
||||
### Pulling images from non-compliant image registries
|
||||
|
||||
**Deprecated in Release: v20.10**
|
||||
**Removed in Release: v28.2**
|
||||
|
||||
Docker Engine v20.10 and up includes optimizations to verify if images in the
|
||||
local image cache need updating before pulling, preventing the Docker Engine
|
||||
@ -559,7 +557,7 @@ image registry to conform to the [Open Container Initiative Distribution Specifi
|
||||
While most registries conform to the specification, we encountered some registries
|
||||
to be non-compliant, resulting in `docker pull` to fail.
|
||||
|
||||
As a temporary solution, Docker Engine v20.10 includes a fallback mechanism to
|
||||
As a temporary solution, Docker Engine v20.10 added a fallback mechanism to
|
||||
allow `docker pull` to be functional when using a non-compliant registry. A
|
||||
warning message is printed in this situation:
|
||||
|
||||
@ -568,16 +566,13 @@ warning message is printed in this situation:
|
||||
pull by tag. This fallback is DEPRECATED, and will be removed in a future
|
||||
release.
|
||||
|
||||
The fallback is added to allow users to either migrate their images to a compliant
|
||||
registry, or for these registries to become compliant.
|
||||
The fallback was added to allow users to either migrate their images to a
|
||||
compliant registry, or for these registries to become compliant.
|
||||
|
||||
Note that this fallback only addresses failures on `docker pull`. Other commands,
|
||||
such as `docker stack deploy`, or pulling images with `containerd` will continue
|
||||
to fail.
|
||||
|
||||
Given that other functionality is still broken with these registries, we consider
|
||||
this fallback a _temporary_ solution, and will remove the fallback in an upcoming
|
||||
major release.
|
||||
GitHub deprecated the legacy `docker.pkg.github.com` registry, and it was
|
||||
[sunset on Feb 24th, 2025](https://github.blog/changelog/2025-01-23-legacy-docker-registry-closing-down/)
|
||||
in favor of GitHub Container Registry (GHCR, ghcr.io), making this fallback
|
||||
no longer needed.
|
||||
|
||||
### Linux containers on Windows (LCOW) (experimental)
|
||||
|
||||
@ -729,7 +724,7 @@ fluent#New: AsyncConnect is now deprecated, use Async instead
|
||||
```
|
||||
|
||||
Users are encouraged to use the `fluentd-async` option going forward, as support
|
||||
for the old option will be removed in a future release.
|
||||
for the old option has been removed.
|
||||
|
||||
### Pushing and pulling with image manifest v2 schema 1
|
||||
|
||||
@ -737,7 +732,8 @@ for the old option will be removed in a future release.
|
||||
|
||||
**Disabled by default in Release: v26.0**
|
||||
|
||||
**Target For Removal In Release: v27.0**
|
||||
**Removed in Release: v28.2**
|
||||
|
||||
|
||||
The image manifest [v2 schema 1](https://distribution.github.io/distribution/spec/deprecated-schema-v1/)
|
||||
and "Docker Image v1" formats were deprecated in favor of the
|
||||
@ -748,23 +744,17 @@ formats.
|
||||
These legacy formats should no longer be used, and users are recommended to
|
||||
update images to use current formats, or to upgrade to more current images.
|
||||
Starting with Docker v26.0, pulling these images is disabled by default, and
|
||||
produces an error when attempting to pull the image:
|
||||
support has been removed in v28.2. Attempting to pull a legacy image now
|
||||
produces an error:
|
||||
|
||||
```console
|
||||
$ docker pull ubuntu:10.04
|
||||
Error response from daemon:
|
||||
[DEPRECATION NOTICE] Docker Image Format v1 and Docker Image manifest version 2, schema 1 support is disabled by default and will be removed in an upcoming release.
|
||||
Docker Image Format v1 and Docker Image manifest version 2, schema 1 support has been removed.
|
||||
Suggest the author of docker.io/library/ubuntu:10.04 to upgrade the image to the OCI Format or Docker Image manifest v2, schema 2.
|
||||
More information at https://docs.docker.com/go/deprecated-image-specs/
|
||||
```
|
||||
|
||||
An environment variable (`DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE`) is
|
||||
added in Docker v26.0 that allows re-enabling support for these image formats
|
||||
in the daemon. This environment variable must be set to a non-empty value in
|
||||
the daemon's environment (for example, through a [systemd override file](https://docs.docker.com/config/daemon/systemd/)).
|
||||
Support for the `DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE` environment variable
|
||||
will be removed in Docker v27.0 after which this functionality is removed permanently.
|
||||
|
||||
### `docker engine` subcommands
|
||||
|
||||
**Deprecated in Release: v19.03**
|
||||
|
||||
@ -9,10 +9,11 @@ Remove one or more images
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:----------------|:-------|:--------|:-------------------------------|
|
||||
| `-f`, `--force` | `bool` | | Force removal of the image |
|
||||
| `--no-prune` | `bool` | | Do not delete untagged parents |
|
||||
| Name | Type | Default | Description |
|
||||
|:--------------------------|:--------------|:--------|:-------------------------------------------------------------------------------------------------|
|
||||
| `-f`, `--force` | `bool` | | Force removal of the image |
|
||||
| `--no-prune` | `bool` | | Do not delete untagged parents |
|
||||
| [`--platform`](#platform) | `stringSlice` | | Remove only the given platform variant. Formatted as `os[/arch[/variant]]` (e.g., `linux/amd64`) |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
@ -105,3 +106,73 @@ Deleted: 4986bf8c15363d1c5d15512d5266f8777bfba4974ac56e3270e7760f6f0a8125
|
||||
Deleted: ea13149945cb6b1e746bf28032f02e9b5a793523481a0a18645fc77ad53c4ea2
|
||||
Deleted: df7546f9f060a2268024c8a230d8639878585defcc1bc6f79d2728a13957871b
|
||||
```
|
||||
|
||||
### <a name="platform"></a> Remove specific platforms (`--platform`)
|
||||
|
||||
The `--platform` option allows you to specify which platform variants of the
|
||||
image to remove. By default, `docker image remove` removes all platform variants
|
||||
that are present. Use the `--platform` option to specify which platform variant
|
||||
of the image to remove.
|
||||
|
||||
Removing a specific platform removes the image from all images that reference
|
||||
the same content, and requires the `--force` option to be used. Omitting the
|
||||
`--force` option produces a warning, and the remove is canceled:
|
||||
|
||||
```console
|
||||
$ docker image rm --platform=linux/amd64 alpine
|
||||
Error response from daemon: Content will be removed from all images referencing this variant. Use —-force to force delete.
|
||||
```
|
||||
|
||||
The platform option takes the `os[/arch[/variant]]` format; for example,
|
||||
`linux/amd64` or `linux/arm64/v8`. Architecture and variant are optional,
|
||||
and default to the daemon's native architecture if omitted.
|
||||
|
||||
You can pass multiple platforms either by passing the `--platform` flag
|
||||
multiple times, or by passing a comma-separated list of platforms to remove.
|
||||
The following uses of this option are equivalent;
|
||||
|
||||
```console
|
||||
$ docker image rm --plaform linux/amd64 --platform linux/ppc64le myimage
|
||||
$ docker image rm --plaform linux/amd64,linux/ppc64le myimage
|
||||
```
|
||||
|
||||
The following example removes the `linux/amd64` and `linux/ppc64le` variants
|
||||
of an `alpine` image that contains multiple platform variants in the image
|
||||
cache:
|
||||
|
||||
```console
|
||||
$ docker image ls --tree
|
||||
|
||||
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
|
||||
alpine:latest a8560b36e8b8 37.8MB 11.2MB U
|
||||
├─ linux/amd64 1c4eef651f65 12.1MB 3.64MB U
|
||||
├─ linux/arm/v6 903bfe2ae994 0B 0B
|
||||
├─ linux/arm/v7 9c2d245b3c01 0B 0B
|
||||
├─ linux/arm64/v8 757d680068d7 12.8MB 3.99MB
|
||||
├─ linux/386 2436f2b3b7d2 0B 0B
|
||||
├─ linux/ppc64le 9ed53fd3b831 12.8MB 3.58MB
|
||||
├─ linux/riscv64 1de5eb4a9a67 0B 0B
|
||||
└─ linux/s390x fe0dcdd1f783 0B 0B
|
||||
|
||||
$ docker image --platform=linux/amd64,linux/ppc64le --force alpine
|
||||
Deleted: sha256:1c4eef651f65e2f7daee7ee785882ac164b02b78fb74503052a26dc061c90474
|
||||
Deleted: sha256:9ed53fd3b83120f78b33685d930ce9bf5aa481f6e2d165c42cbbddbeaa196f6f
|
||||
```
|
||||
|
||||
After the command completes, the given variants of the `alpine` image are removed
|
||||
from the image cache:
|
||||
|
||||
```console
|
||||
$ docker image ls --tree
|
||||
|
||||
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
|
||||
alpine:latest a8560b36e8b8 12.8MB 3.99MB
|
||||
├─ linux/amd64 1c4eef651f65 0B 0B
|
||||
├─ linux/arm/v6 903bfe2ae994 0B 0B
|
||||
├─ linux/arm/v7 9c2d245b3c01 0B 0B
|
||||
├─ linux/arm64/v8 757d680068d7 12.8MB 3.99MB
|
||||
├─ linux/386 2436f2b3b7d2 0B 0B
|
||||
├─ linux/ppc64le 9ed53fd3b831 0B 0B
|
||||
├─ linux/riscv64 1de5eb4a9a67 0B 0B
|
||||
└─ linux/s390x fe0dcdd1f783 0B 0B
|
||||
```
|
||||
|
||||
@ -9,10 +9,11 @@ Remove one or more images
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:----------------|:-------|:--------|:-------------------------------|
|
||||
| `-f`, `--force` | `bool` | | Force removal of the image |
|
||||
| `--no-prune` | `bool` | | Do not delete untagged parents |
|
||||
| Name | Type | Default | Description |
|
||||
|:----------------|:--------------|:--------|:-------------------------------------------------------------------------------------------------|
|
||||
| `-f`, `--force` | `bool` | | Force removal of the image |
|
||||
| `--no-prune` | `bool` | | Do not delete untagged parents |
|
||||
| `--platform` | `stringSlice` | | Remove only the given platform variant. Formatted as `os[/arch[/variant]]` (e.g., `linux/amd64`) |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@ -58,7 +58,7 @@ func TestPluginSocketBackwardsCompatible(t *testing.T) {
|
||||
|
||||
ptmx, err := pty.Start(command)
|
||||
assert.NilError(t, err, "failed to launch command with fake TTY")
|
||||
_, _ = ptmx.Write([]byte("hello!"))
|
||||
_, _ = ptmx.WriteString("hello!")
|
||||
|
||||
done := make(chan error)
|
||||
go func() {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package opts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
@ -25,13 +25,13 @@ func TestParseHost(t *testing.T) {
|
||||
"fd://something": "fd://something",
|
||||
"tcp://host:": "tcp://host:" + defaultHTTPPort,
|
||||
"tcp://": defaultTCPHost,
|
||||
"tcp://:2375": fmt.Sprintf("tcp://%s:%s", defaultHTTPHost, defaultHTTPPort),
|
||||
"tcp://:2376": fmt.Sprintf("tcp://%s:%s", defaultHTTPHost, defaultTLSHTTPPort),
|
||||
"tcp://:2375": "tcp://" + net.JoinHostPort(defaultHTTPHost, defaultHTTPPort),
|
||||
"tcp://:2376": "tcp://" + net.JoinHostPort(defaultHTTPHost, defaultTLSHTTPPort),
|
||||
"tcp://0.0.0.0:8080": "tcp://0.0.0.0:8080",
|
||||
"tcp://192.168.0.0:12000": "tcp://192.168.0.0:12000",
|
||||
"tcp://192.168:8080": "tcp://192.168:8080",
|
||||
"tcp://0.0.0.0:1234567890": "tcp://0.0.0.0:1234567890", // yeah it's valid :P
|
||||
" tcp://:7777/path ": fmt.Sprintf("tcp://%s:7777/path", defaultHTTPHost),
|
||||
" tcp://:7777/path ": "tcp://" + net.JoinHostPort(defaultHTTPHost, "7777") + "/path",
|
||||
"tcp://docker.com:2375": "tcp://docker.com:2375",
|
||||
"unix://": "unix://" + defaultUnixSocket,
|
||||
"unix://path/to/socket": "unix://path/to/socket",
|
||||
@ -70,11 +70,11 @@ func TestParseDockerDaemonHost(t *testing.T) {
|
||||
"[::1]:5555/path": "tcp://[::1]:5555/path",
|
||||
"[0:0:0:0:0:0:0:1]:": "tcp://[0:0:0:0:0:0:0:1]:2375",
|
||||
"[0:0:0:0:0:0:0:1]:5555/path": "tcp://[0:0:0:0:0:0:0:1]:5555/path",
|
||||
":6666": fmt.Sprintf("tcp://%s:6666", defaultHTTPHost),
|
||||
":6666/path": fmt.Sprintf("tcp://%s:6666/path", defaultHTTPHost),
|
||||
":6666": "tcp://" + net.JoinHostPort(defaultHTTPHost, "6666"),
|
||||
":6666/path": "tcp://" + net.JoinHostPort(defaultHTTPHost, "6666") + "/path",
|
||||
"tcp://": defaultTCPHost,
|
||||
"tcp://:7777": fmt.Sprintf("tcp://%s:7777", defaultHTTPHost),
|
||||
"tcp://:7777/path": fmt.Sprintf("tcp://%s:7777/path", defaultHTTPHost),
|
||||
"tcp://:7777": "tcp://" + net.JoinHostPort(defaultHTTPHost, "7777"),
|
||||
"tcp://:7777/path": "tcp://" + net.JoinHostPort(defaultHTTPHost, "7777") + "/path",
|
||||
"unix:///run/docker.sock": "unix:///run/docker.sock",
|
||||
"unix://": "unix://" + defaultUnixSocket,
|
||||
"fd://": "fd://",
|
||||
@ -96,7 +96,7 @@ func TestParseDockerDaemonHost(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestParseTCP(t *testing.T) {
|
||||
defaultHTTPHost := "tcp://127.0.0.1:2376"
|
||||
const defaultHost = "tcp://127.0.0.1:2376"
|
||||
invalids := map[string]string{
|
||||
"tcp:a.b.c.d": "",
|
||||
"tcp:a.b.c.d/path": "",
|
||||
@ -104,8 +104,8 @@ func TestParseTCP(t *testing.T) {
|
||||
"udp://127.0.0.1:2375": "invalid proto, expected tcp: udp://127.0.0.1:2375",
|
||||
}
|
||||
valids := map[string]string{
|
||||
"": defaultHTTPHost,
|
||||
"tcp://": defaultHTTPHost,
|
||||
"": defaultHost,
|
||||
"tcp://": defaultHost,
|
||||
"0.0.0.1:": "tcp://0.0.0.1:2376",
|
||||
"0.0.0.1:5555": "tcp://0.0.0.1:5555",
|
||||
"0.0.0.1:5555/path": "tcp://0.0.0.1:5555/path",
|
||||
@ -124,12 +124,12 @@ func TestParseTCP(t *testing.T) {
|
||||
"localhost:5555/path": "tcp://localhost:5555/path",
|
||||
}
|
||||
for invalidAddr, expectedError := range invalids {
|
||||
if addr, err := ParseTCPAddr(invalidAddr, defaultHTTPHost); err == nil || expectedError != "" && err.Error() != expectedError {
|
||||
if addr, err := ParseTCPAddr(invalidAddr, defaultHost); err == nil || expectedError != "" && err.Error() != expectedError {
|
||||
t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr)
|
||||
}
|
||||
}
|
||||
for validAddr, expectedAddr := range valids {
|
||||
if addr, err := ParseTCPAddr(validAddr, defaultHTTPHost); err != nil || addr != expectedAddr {
|
||||
if addr, err := ParseTCPAddr(validAddr, defaultHost); err != nil || addr != expectedAddr {
|
||||
t.Errorf("%v -> expected %v, got %v and addr %v", validAddr, expectedAddr, err, addr)
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ func (m *MountOpt) Set(value string) error {
|
||||
mount.Type = mounttypes.Type(strings.ToLower(val))
|
||||
case "source", "src":
|
||||
mount.Source = val
|
||||
if strings.HasPrefix(val, "."+string(filepath.Separator)) || val == "." {
|
||||
if !filepath.IsAbs(val) && strings.HasPrefix(val, ".") {
|
||||
if abs, err := filepath.Abs(val); err == nil {
|
||||
mount.Source = abs
|
||||
}
|
||||
|
||||
@ -39,11 +39,22 @@ func TestMountRelative(t *testing.T) {
|
||||
name: "Current path",
|
||||
path: ".",
|
||||
bind: "type=bind,source=.,target=/target",
|
||||
}, {
|
||||
},
|
||||
{
|
||||
name: "Current path with slash",
|
||||
path: "./",
|
||||
bind: "type=bind,source=./,target=/target",
|
||||
},
|
||||
{
|
||||
name: "Parent path with slash",
|
||||
path: "../",
|
||||
bind: "type=bind,source=../,target=/target",
|
||||
},
|
||||
{
|
||||
name: "Parent path",
|
||||
path: "..",
|
||||
bind: "type=bind,source=..,target=/target",
|
||||
},
|
||||
} {
|
||||
t.Run(testcase.name, func(t *testing.T) {
|
||||
var mount MountOpt
|
||||
|
||||
@ -13,9 +13,9 @@ require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7
|
||||
github.com/creack/pty v1.1.24
|
||||
github.com/distribution/reference v0.6.0
|
||||
github.com/docker/cli-docs-tool v0.9.0
|
||||
github.com/docker/cli-docs-tool v0.10.0
|
||||
github.com/docker/distribution v2.8.3+incompatible
|
||||
github.com/docker/docker v28.1.2-0.20250519114040-7937f0846c13+incompatible // master, v28.x dev
|
||||
github.com/docker/docker v28.2.2-0.20250530085359-45873be4ae3f+incompatible // v28.2-dev
|
||||
github.com/docker/docker-credential-helpers v0.9.3
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/docker/go-units v0.5.0
|
||||
@ -68,6 +68,7 @@ require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
|
||||
|
||||
10
vendor.sum
10
vendor.sum
@ -34,6 +34,8 @@ github.com/cloudflare/cfssl v1.6.4 h1:NMOvfrEjFfC63K3SGXgAnFdsgkmiq4kATme5BfcqrO
|
||||
github.com/cloudflare/cfssl v1.6.4/go.mod h1:8b3CQMxfWPAeom3zBnGJ6sd+G1NkL5TXqmDXacb+1J0=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/platforms v1.0.0-rc.1 h1:83KIq4yy1erSRgOVHNk1HYdPvzdJ5CnsWaRoJX4C41E=
|
||||
@ -50,13 +52,13 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/cli-docs-tool v0.9.0 h1:CVwQbE+ZziwlPqrJ7LRyUF6GvCA+6gj7MTCsayaK9t0=
|
||||
github.com/docker/cli-docs-tool v0.9.0/go.mod h1:ClrwlNW+UioiRyH9GiAOe1o3J/TsY3Tr1ipoypjAUtc=
|
||||
github.com/docker/cli-docs-tool v0.10.0 h1:bOD6mKynPQgojQi3s2jgcUWGp/Ebqy1SeCr9VfKQLLU=
|
||||
github.com/docker/cli-docs-tool v0.10.0/go.mod h1:5EM5zPnT2E7yCLERZmrDA234Vwn09fzRHP4aX1qwp1U=
|
||||
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 v28.1.2-0.20250519114040-7937f0846c13+incompatible h1:hQ0dI0strJB2gjh/Sx+WthVEhOe89DPjAwiZVwjbpIg=
|
||||
github.com/docker/docker v28.1.2-0.20250519114040-7937f0846c13+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v28.2.2-0.20250530085359-45873be4ae3f+incompatible h1:Pv7Z5UMmGkOzACssMUwY4HlxQ9sd5lyLnoaLDbj3Mec=
|
||||
github.com/docker/docker v28.2.2-0.20250530085359-45873be4ae3f+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
||||
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||
|
||||
191
vendor/github.com/containerd/errdefs/pkg/LICENSE
generated
vendored
Normal file
191
vendor/github.com/containerd/errdefs/pkg/LICENSE
generated
vendored
Normal file
@ -0,0 +1,191 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
https://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright The containerd Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
96
vendor/github.com/containerd/errdefs/pkg/errhttp/http.go
generated
vendored
Normal file
96
vendor/github.com/containerd/errdefs/pkg/errhttp/http.go
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package errhttp provides utility functions for translating errors to
|
||||
// and from a HTTP context.
|
||||
//
|
||||
// The functions ToHTTP and ToNative can be used to map server-side and
|
||||
// client-side errors to the correct types.
|
||||
package errhttp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/containerd/errdefs"
|
||||
"github.com/containerd/errdefs/pkg/internal/cause"
|
||||
)
|
||||
|
||||
// ToHTTP returns the best status code for the given error
|
||||
func ToHTTP(err error) int {
|
||||
switch {
|
||||
case errdefs.IsNotFound(err):
|
||||
return http.StatusNotFound
|
||||
case errdefs.IsInvalidArgument(err):
|
||||
return http.StatusBadRequest
|
||||
case errdefs.IsConflict(err):
|
||||
return http.StatusConflict
|
||||
case errdefs.IsNotModified(err):
|
||||
return http.StatusNotModified
|
||||
case errdefs.IsFailedPrecondition(err):
|
||||
return http.StatusPreconditionFailed
|
||||
case errdefs.IsUnauthorized(err):
|
||||
return http.StatusUnauthorized
|
||||
case errdefs.IsPermissionDenied(err):
|
||||
return http.StatusForbidden
|
||||
case errdefs.IsResourceExhausted(err):
|
||||
return http.StatusTooManyRequests
|
||||
case errdefs.IsInternal(err):
|
||||
return http.StatusInternalServerError
|
||||
case errdefs.IsNotImplemented(err):
|
||||
return http.StatusNotImplemented
|
||||
case errdefs.IsUnavailable(err):
|
||||
return http.StatusServiceUnavailable
|
||||
case errdefs.IsUnknown(err):
|
||||
var unexpected cause.ErrUnexpectedStatus
|
||||
if errors.As(err, &unexpected) && unexpected.Status >= 200 && unexpected.Status < 600 {
|
||||
return unexpected.Status
|
||||
}
|
||||
return http.StatusInternalServerError
|
||||
default:
|
||||
return http.StatusInternalServerError
|
||||
}
|
||||
}
|
||||
|
||||
// ToNative returns the error best matching the HTTP status code
|
||||
func ToNative(statusCode int) error {
|
||||
switch statusCode {
|
||||
case http.StatusNotFound:
|
||||
return errdefs.ErrNotFound
|
||||
case http.StatusBadRequest:
|
||||
return errdefs.ErrInvalidArgument
|
||||
case http.StatusConflict:
|
||||
return errdefs.ErrConflict
|
||||
case http.StatusPreconditionFailed:
|
||||
return errdefs.ErrFailedPrecondition
|
||||
case http.StatusUnauthorized:
|
||||
return errdefs.ErrUnauthenticated
|
||||
case http.StatusForbidden:
|
||||
return errdefs.ErrPermissionDenied
|
||||
case http.StatusNotModified:
|
||||
return errdefs.ErrNotModified
|
||||
case http.StatusTooManyRequests:
|
||||
return errdefs.ErrResourceExhausted
|
||||
case http.StatusInternalServerError:
|
||||
return errdefs.ErrInternal
|
||||
case http.StatusNotImplemented:
|
||||
return errdefs.ErrNotImplemented
|
||||
case http.StatusServiceUnavailable:
|
||||
return errdefs.ErrUnavailable
|
||||
default:
|
||||
return cause.ErrUnexpectedStatus{Status: statusCode}
|
||||
}
|
||||
}
|
||||
33
vendor/github.com/containerd/errdefs/pkg/internal/cause/cause.go
generated
vendored
Normal file
33
vendor/github.com/containerd/errdefs/pkg/internal/cause/cause.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package cause is used to define root causes for errors
|
||||
// common to errors packages like grpc and http.
|
||||
package cause
|
||||
|
||||
import "fmt"
|
||||
|
||||
type ErrUnexpectedStatus struct {
|
||||
Status int
|
||||
}
|
||||
|
||||
const UnexpectedStatusPrefix = "unexpected status "
|
||||
|
||||
func (e ErrUnexpectedStatus) Error() string {
|
||||
return fmt.Sprintf("%s%d", UnexpectedStatusPrefix, e.Status)
|
||||
}
|
||||
|
||||
func (ErrUnexpectedStatus) Unknown() {}
|
||||
42
vendor/github.com/docker/cli-docs-tool/.golangci.yml
generated
vendored
42
vendor/github.com/docker/cli-docs-tool/.golangci.yml
generated
vendored
@ -1,34 +1,38 @@
|
||||
run:
|
||||
timeout: 10m
|
||||
version: "2"
|
||||
|
||||
linters:
|
||||
default: none
|
||||
enable:
|
||||
- depguard
|
||||
- gofmt
|
||||
- goimports
|
||||
- revive
|
||||
- govet
|
||||
- importas
|
||||
- ineffassign
|
||||
- misspell
|
||||
- typecheck
|
||||
- errname
|
||||
- makezero
|
||||
- whitespace
|
||||
disable-all: true
|
||||
|
||||
linters-settings:
|
||||
depguard:
|
||||
settings:
|
||||
depguard:
|
||||
rules:
|
||||
main:
|
||||
deny:
|
||||
- pkg: io/ioutil
|
||||
desc: The io/ioutil package has been deprecated, see https://go.dev/doc/go1.16#ioutil
|
||||
importas:
|
||||
no-unaliased: true
|
||||
exclusions:
|
||||
generated: lax
|
||||
rules:
|
||||
main:
|
||||
deny:
|
||||
- pkg: io/ioutil
|
||||
desc: The io/ioutil package has been deprecated, see https://go.dev/doc/go1.16#ioutil
|
||||
importas:
|
||||
no-unaliased: true
|
||||
- linters:
|
||||
- revive
|
||||
text: stutters
|
||||
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- linters:
|
||||
- revive
|
||||
text: "stutters"
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
|
||||
4
vendor/github.com/docker/cli-docs-tool/Dockerfile
generated
vendored
4
vendor/github.com/docker/cli-docs-tool/Dockerfile
generated
vendored
@ -14,9 +14,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ARG GO_VERSION="1.23"
|
||||
ARG GO_VERSION="1.24"
|
||||
ARG XX_VERSION="1.6.1"
|
||||
ARG GOLANGCI_LINT_VERSION="v1.62"
|
||||
ARG GOLANGCI_LINT_VERSION="v2.1.5"
|
||||
ARG ADDLICENSE_VERSION="v1.1.1"
|
||||
|
||||
ARG LICENSE_ARGS="-c cli-docs-tool -l apache"
|
||||
|
||||
1
vendor/github.com/docker/cli-docs-tool/annotation/annotation.go
generated
vendored
1
vendor/github.com/docker/cli-docs-tool/annotation/annotation.go
generated
vendored
@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package annotation handles annotations for CLI commands.
|
||||
package annotation
|
||||
|
||||
const (
|
||||
|
||||
1
vendor/github.com/docker/cli-docs-tool/clidocstool.go
generated
vendored
1
vendor/github.com/docker/cli-docs-tool/clidocstool.go
generated
vendored
@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package clidocstool provides tools for generating CLI documentation.
|
||||
package clidocstool
|
||||
|
||||
import (
|
||||
|
||||
8
vendor/github.com/docker/cli-docs-tool/clidocstool_man.go
generated
vendored
8
vendor/github.com/docker/cli-docs-tool/clidocstool_man.go
generated
vendored
@ -64,6 +64,14 @@ func (c *Client) genManTreeCustom(cmd *cobra.Command) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Skip hidden command recursively
|
||||
for curr := cmd; curr != nil; curr = curr.Parent() {
|
||||
if curr.Hidden {
|
||||
log.Printf("INFO: Skipping Man for %q (hidden command)", curr.CommandPath())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("INFO: Generating Man for %q", cmd.CommandPath())
|
||||
|
||||
return doc.GenManTreeFromOpts(cmd, doc.GenManTreeOptions{
|
||||
|
||||
10
vendor/github.com/docker/cli-docs-tool/clidocstool_md.go
generated
vendored
10
vendor/github.com/docker/cli-docs-tool/clidocstool_md.go
generated
vendored
@ -53,10 +53,12 @@ func (c *Client) GenMarkdownTree(cmd *cobra.Command) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Skip hidden command
|
||||
if cmd.Hidden {
|
||||
log.Printf("INFO: Skipping Markdown for %q (hidden command)", cmd.CommandPath())
|
||||
return nil
|
||||
// Skip hidden command recursively
|
||||
for curr := cmd; curr != nil; curr = curr.Parent() {
|
||||
if curr.Hidden {
|
||||
log.Printf("INFO: Skipping Markdown for %q (hidden command)", curr.CommandPath())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("INFO: Generating Markdown for %q", cmd.CommandPath())
|
||||
|
||||
7
vendor/github.com/docker/cli-docs-tool/clidocstool_yaml.go
generated
vendored
7
vendor/github.com/docker/cli-docs-tool/clidocstool_yaml.go
generated
vendored
@ -169,6 +169,9 @@ func (c *Client) genYamlCustom(cmd *cobra.Command, w io.Writer) error {
|
||||
|
||||
// check recursively to handle inherited annotations
|
||||
for curr := cmd; curr != nil; curr = curr.Parent() {
|
||||
if curr.Hidden {
|
||||
cliDoc.Hidden = true
|
||||
}
|
||||
if v, ok := curr.Annotations["version"]; ok && cliDoc.MinAPIVersion == "" {
|
||||
cliDoc.MinAPIVersion = v
|
||||
}
|
||||
@ -349,9 +352,9 @@ func genFlagResult(cmd *cobra.Command, flags *pflag.FlagSet, anchors map[string]
|
||||
//
|
||||
// This makes the generated YAML more readable, and easier to review changes.
|
||||
// max can be used to customize the width to keep the whole line < 80 chars.
|
||||
func forceMultiLine(s string, max int) string {
|
||||
func forceMultiLine(s string, maxWidth int) string {
|
||||
s = strings.TrimSpace(s)
|
||||
if len(s) > max && !strings.Contains(s, "\n") {
|
||||
if len(s) > maxWidth && !strings.Contains(s, "\n") {
|
||||
s = s + "\n"
|
||||
}
|
||||
return s
|
||||
|
||||
154
vendor/github.com/docker/docker/api/swagger.yaml
generated
vendored
154
vendor/github.com/docker/docker/api/swagger.yaml
generated
vendored
@ -1428,63 +1428,10 @@ definitions:
|
||||
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>
|
||||
|
||||
> **Deprecated**: this field is not part of the image specification and is
|
||||
> always empty. It must not be used, and will be removed in API v1.48.
|
||||
type: "string"
|
||||
example: ""
|
||||
Domainname:
|
||||
description: |
|
||||
The domain name to use for the container.
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
> **Deprecated**: this field is not part of the image specification and is
|
||||
> always empty. It must not be used, and will be removed in API v1.48.
|
||||
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>
|
||||
|
||||
> **Deprecated**: this field is not part of the image specification and is
|
||||
> always false. It must not be used, and will be removed in API v1.48.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
AttachStdout:
|
||||
description: |
|
||||
Whether to attach to `stdout`.
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
> **Deprecated**: this field is not part of the image specification and is
|
||||
> always false. It must not be used, and will be removed in API v1.48.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
AttachStderr:
|
||||
description: |
|
||||
Whether to attach to `stderr`.
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
> **Deprecated**: this field is not part of the image specification and is
|
||||
> always false. It must not be used, and will be removed in API v1.48.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ExposedPorts:
|
||||
description: |
|
||||
An object mapping ports to an empty object in the form:
|
||||
@ -1501,39 +1448,6 @@ definitions:
|
||||
"80/tcp": {},
|
||||
"443/tcp": {}
|
||||
}
|
||||
Tty:
|
||||
description: |
|
||||
Attach standard streams to a TTY, including `stdin` if it is not closed.
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
> **Deprecated**: this field is not part of the image specification and is
|
||||
> always false. It must not be used, and will be removed in API v1.48.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
OpenStdin:
|
||||
description: |
|
||||
Open `stdin`
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
> **Deprecated**: this field is not part of the image specification and is
|
||||
> always false. It must not be used, and will be removed in API v1.48.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
StdinOnce:
|
||||
description: |
|
||||
Close `stdin` after one attached client disconnects.
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
> **Deprecated**: this field is not part of the image specification and is
|
||||
> always false. It must not be used, and will be removed in API v1.48.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Env:
|
||||
description: |
|
||||
A list of environment variables to set inside the container in the
|
||||
@ -1559,18 +1473,6 @@ definitions:
|
||||
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>
|
||||
|
||||
> **Deprecated**: this field is not part of the image specification and is
|
||||
> always empty. It must not be used, and will be removed in API v1.48.
|
||||
type: "string"
|
||||
default: ""
|
||||
example: ""
|
||||
Volumes:
|
||||
description: |
|
||||
An object mapping mount point paths inside the container to empty
|
||||
@ -1599,30 +1501,6 @@ definitions:
|
||||
items:
|
||||
type: "string"
|
||||
example: []
|
||||
NetworkDisabled:
|
||||
description: |
|
||||
Disable networking for the container.
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
> **Deprecated**: this field is not part of the image specification and is
|
||||
> always omitted. It must not be used, and will be removed in API v1.48.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
x-nullable: true
|
||||
MacAddress:
|
||||
description: |
|
||||
MAC address of the container.
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
> **Deprecated**: this field is not part of the image specification and is
|
||||
> always omitted. It must not be used, and will be removed in API v1.48.
|
||||
type: "string"
|
||||
default: ""
|
||||
example: ""
|
||||
x-nullable: true
|
||||
OnBuild:
|
||||
description: |
|
||||
`ONBUILD` metadata that were defined in the image's `Dockerfile`.
|
||||
@ -1645,17 +1523,6 @@ definitions:
|
||||
type: "string"
|
||||
example: "SIGTERM"
|
||||
x-nullable: true
|
||||
StopTimeout:
|
||||
description: |
|
||||
Timeout to stop a container in seconds.
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
> **Deprecated**: this field is not part of the image specification and is
|
||||
> always omitted. It must not be used, and will be removed in API v1.48.
|
||||
type: "integer"
|
||||
default: 10
|
||||
x-nullable: true
|
||||
Shell:
|
||||
description: |
|
||||
Shell for when `RUN`, `CMD`, and `ENTRYPOINT` uses a shell.
|
||||
@ -1666,19 +1533,11 @@ definitions:
|
||||
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": {
|
||||
@ -1690,7 +1549,6 @@ definitions:
|
||||
"StartInterval": 0
|
||||
}
|
||||
"ArgsEscaped": true
|
||||
"Image": ""
|
||||
"Volumes": {
|
||||
"/app/data": {},
|
||||
"/app/config": {}
|
||||
@ -9960,6 +9818,18 @@ paths:
|
||||
description: "Do not delete untagged parent images"
|
||||
type: "boolean"
|
||||
default: false
|
||||
- name: "platforms"
|
||||
in: "query"
|
||||
description: |
|
||||
Select platform-specific content to delete.
|
||||
Multiple values are accepted.
|
||||
Each platform is a OCI platform encoded as a JSON string.
|
||||
type: "array"
|
||||
items:
|
||||
# This should be OCIPlatform
|
||||
# but $ref is not supported for array in query in Swagger 2.0
|
||||
# $ref: "#/definitions/OCIPlatform"
|
||||
type: "string"
|
||||
tags: ["Image"]
|
||||
/images/search:
|
||||
get:
|
||||
|
||||
90
vendor/github.com/docker/docker/api/types/client.go
generated
vendored
90
vendor/github.com/docker/docker/api/types/client.go
generated
vendored
@ -4,8 +4,6 @@ import (
|
||||
"bufio"
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
)
|
||||
|
||||
// NewHijackedResponse initializes a [HijackedResponse] type.
|
||||
@ -48,87 +46,6 @@ func (h *HijackedResponse) CloseWrite() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// NodeListOptions holds parameters to list nodes with.
|
||||
type NodeListOptions struct {
|
||||
Filters filters.Args
|
||||
}
|
||||
|
||||
// NodeRemoveOptions holds parameters to remove nodes with.
|
||||
type NodeRemoveOptions struct {
|
||||
Force bool
|
||||
}
|
||||
|
||||
// ServiceCreateOptions contains the options to use when creating a service.
|
||||
type ServiceCreateOptions struct {
|
||||
// EncodedRegistryAuth is the encoded registry authorization credentials to
|
||||
// use when updating the service.
|
||||
//
|
||||
// This field follows the format of the X-Registry-Auth header.
|
||||
EncodedRegistryAuth string
|
||||
|
||||
// QueryRegistry indicates whether the service update requires
|
||||
// contacting a registry. A registry may be contacted to retrieve
|
||||
// the image digest and manifest, which in turn can be used to update
|
||||
// platform or other information about the service.
|
||||
QueryRegistry bool
|
||||
}
|
||||
|
||||
// Values for RegistryAuthFrom in ServiceUpdateOptions
|
||||
const (
|
||||
RegistryAuthFromSpec = "spec"
|
||||
RegistryAuthFromPreviousSpec = "previous-spec"
|
||||
)
|
||||
|
||||
// ServiceUpdateOptions contains the options to be used for updating services.
|
||||
type ServiceUpdateOptions struct {
|
||||
// EncodedRegistryAuth is the encoded registry authorization credentials to
|
||||
// use when updating the service.
|
||||
//
|
||||
// This field follows the format of the X-Registry-Auth header.
|
||||
EncodedRegistryAuth string
|
||||
|
||||
// TODO(stevvooe): Consider moving the version parameter of ServiceUpdate
|
||||
// into this field. While it does open API users up to racy writes, most
|
||||
// users may not need that level of consistency in practice.
|
||||
|
||||
// RegistryAuthFrom specifies where to find the registry authorization
|
||||
// credentials if they are not given in EncodedRegistryAuth. Valid
|
||||
// values are "spec" and "previous-spec".
|
||||
RegistryAuthFrom string
|
||||
|
||||
// Rollback indicates whether a server-side rollback should be
|
||||
// performed. When this is set, the provided spec will be ignored.
|
||||
// The valid values are "previous" and "none". An empty value is the
|
||||
// same as "none".
|
||||
Rollback string
|
||||
|
||||
// QueryRegistry indicates whether the service update requires
|
||||
// contacting a registry. A registry may be contacted to retrieve
|
||||
// the image digest and manifest, which in turn can be used to update
|
||||
// platform or other information about the service.
|
||||
QueryRegistry bool
|
||||
}
|
||||
|
||||
// ServiceListOptions holds parameters to list services with.
|
||||
type ServiceListOptions struct {
|
||||
Filters filters.Args
|
||||
|
||||
// Status indicates whether the server should include the service task
|
||||
// count of running and desired tasks.
|
||||
Status bool
|
||||
}
|
||||
|
||||
// ServiceInspectOptions holds parameters related to the "service inspect"
|
||||
// operation.
|
||||
type ServiceInspectOptions struct {
|
||||
InsertDefaults bool
|
||||
}
|
||||
|
||||
// TaskListOptions holds parameters to list tasks with.
|
||||
type TaskListOptions struct {
|
||||
Filters filters.Args
|
||||
}
|
||||
|
||||
// PluginRemoveOptions holds parameters to remove plugins.
|
||||
type PluginRemoveOptions struct {
|
||||
Force bool
|
||||
@ -162,13 +79,6 @@ type PluginInstallOptions struct {
|
||||
Args []string
|
||||
}
|
||||
|
||||
// SwarmUnlockKeyResponse contains the response for Engine API:
|
||||
// GET /swarm/unlockkey
|
||||
type SwarmUnlockKeyResponse struct {
|
||||
// UnlockKey is the unlock key in ASCII-armored format.
|
||||
UnlockKey string
|
||||
}
|
||||
|
||||
// PluginCreateOptions hold all options to plugin create.
|
||||
type PluginCreateOptions struct {
|
||||
RepoName string
|
||||
|
||||
3
vendor/github.com/docker/docker/api/types/image/image_inspect.go
generated
vendored
3
vendor/github.com/docker/docker/api/types/image/image_inspect.go
generated
vendored
@ -3,6 +3,7 @@ package image
|
||||
import (
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/storage"
|
||||
dockerspec "github.com/moby/docker-image-spec/specs-go/v1"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
@ -84,7 +85,7 @@ type InspectResponse struct {
|
||||
// Author is the name of the author that was specified when committing the
|
||||
// image, or as specified through MAINTAINER (deprecated) in the Dockerfile.
|
||||
Author string
|
||||
Config *container.Config
|
||||
Config *dockerspec.DockerOCIImageConfig
|
||||
|
||||
// Architecture is the hardware CPU architecture that the image runs on.
|
||||
Architecture string
|
||||
|
||||
1
vendor/github.com/docker/docker/api/types/image/opts.go
generated
vendored
1
vendor/github.com/docker/docker/api/types/image/opts.go
generated
vendored
@ -83,6 +83,7 @@ type ListOptions struct {
|
||||
|
||||
// RemoveOptions holds parameters to remove images.
|
||||
type RemoveOptions struct {
|
||||
Platforms []ocispec.Platform
|
||||
Force bool
|
||||
PruneChildren bool
|
||||
}
|
||||
|
||||
11
vendor/github.com/docker/docker/api/types/swarm/node.go
generated
vendored
11
vendor/github.com/docker/docker/api/types/swarm/node.go
generated
vendored
@ -1,4 +1,5 @@
|
||||
package swarm // import "github.com/docker/docker/api/types/swarm"
|
||||
import "github.com/docker/docker/api/types/filters"
|
||||
|
||||
// Node represents a node.
|
||||
type Node struct {
|
||||
@ -137,3 +138,13 @@ const (
|
||||
type Topology struct {
|
||||
Segments map[string]string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// NodeListOptions holds parameters to list nodes with.
|
||||
type NodeListOptions struct {
|
||||
Filters filters.Args
|
||||
}
|
||||
|
||||
// NodeRemoveOptions holds parameters to remove nodes with.
|
||||
type NodeRemoveOptions struct {
|
||||
Force bool
|
||||
}
|
||||
|
||||
72
vendor/github.com/docker/docker/api/types/swarm/service.go
generated
vendored
72
vendor/github.com/docker/docker/api/types/swarm/service.go
generated
vendored
@ -1,6 +1,10 @@
|
||||
package swarm // import "github.com/docker/docker/api/types/swarm"
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
)
|
||||
|
||||
// Service represents a service.
|
||||
type Service struct {
|
||||
@ -200,3 +204,69 @@ type JobStatus struct {
|
||||
// Swarm manager.
|
||||
LastExecution time.Time `json:",omitempty"`
|
||||
}
|
||||
|
||||
// ServiceCreateOptions contains the options to use when creating a service.
|
||||
type ServiceCreateOptions struct {
|
||||
// EncodedRegistryAuth is the encoded registry authorization credentials to
|
||||
// use when updating the service.
|
||||
//
|
||||
// This field follows the format of the X-Registry-Auth header.
|
||||
EncodedRegistryAuth string
|
||||
|
||||
// QueryRegistry indicates whether the service update requires
|
||||
// contacting a registry. A registry may be contacted to retrieve
|
||||
// the image digest and manifest, which in turn can be used to update
|
||||
// platform or other information about the service.
|
||||
QueryRegistry bool
|
||||
}
|
||||
|
||||
// Values for RegistryAuthFrom in ServiceUpdateOptions
|
||||
const (
|
||||
RegistryAuthFromSpec = "spec"
|
||||
RegistryAuthFromPreviousSpec = "previous-spec"
|
||||
)
|
||||
|
||||
// ServiceUpdateOptions contains the options to be used for updating services.
|
||||
type ServiceUpdateOptions struct {
|
||||
// EncodedRegistryAuth is the encoded registry authorization credentials to
|
||||
// use when updating the service.
|
||||
//
|
||||
// This field follows the format of the X-Registry-Auth header.
|
||||
EncodedRegistryAuth string
|
||||
|
||||
// TODO(stevvooe): Consider moving the version parameter of ServiceUpdate
|
||||
// into this field. While it does open API users up to racy writes, most
|
||||
// users may not need that level of consistency in practice.
|
||||
|
||||
// RegistryAuthFrom specifies where to find the registry authorization
|
||||
// credentials if they are not given in EncodedRegistryAuth. Valid
|
||||
// values are "spec" and "previous-spec".
|
||||
RegistryAuthFrom string
|
||||
|
||||
// Rollback indicates whether a server-side rollback should be
|
||||
// performed. When this is set, the provided spec will be ignored.
|
||||
// The valid values are "previous" and "none". An empty value is the
|
||||
// same as "none".
|
||||
Rollback string
|
||||
|
||||
// QueryRegistry indicates whether the service update requires
|
||||
// contacting a registry. A registry may be contacted to retrieve
|
||||
// the image digest and manifest, which in turn can be used to update
|
||||
// platform or other information about the service.
|
||||
QueryRegistry bool
|
||||
}
|
||||
|
||||
// ServiceListOptions holds parameters to list services with.
|
||||
type ServiceListOptions struct {
|
||||
Filters filters.Args
|
||||
|
||||
// Status indicates whether the server should include the service task
|
||||
// count of running and desired tasks.
|
||||
Status bool
|
||||
}
|
||||
|
||||
// ServiceInspectOptions holds parameters related to the "service inspect"
|
||||
// operation.
|
||||
type ServiceInspectOptions struct {
|
||||
InsertDefaults bool
|
||||
}
|
||||
|
||||
7
vendor/github.com/docker/docker/api/types/swarm/swarm.go
generated
vendored
7
vendor/github.com/docker/docker/api/types/swarm/swarm.go
generated
vendored
@ -235,3 +235,10 @@ type UpdateFlags struct {
|
||||
RotateManagerToken bool
|
||||
RotateManagerUnlockKey bool
|
||||
}
|
||||
|
||||
// UnlockKeyResponse contains the response for Engine API:
|
||||
// GET /swarm/unlockkey
|
||||
type UnlockKeyResponse struct {
|
||||
// UnlockKey is the unlock key in ASCII-armored format.
|
||||
UnlockKey string
|
||||
}
|
||||
|
||||
6
vendor/github.com/docker/docker/api/types/swarm/task.go
generated
vendored
6
vendor/github.com/docker/docker/api/types/swarm/task.go
generated
vendored
@ -3,6 +3,7 @@ package swarm // import "github.com/docker/docker/api/types/swarm"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/swarm/runtime"
|
||||
)
|
||||
|
||||
@ -223,3 +224,8 @@ type VolumeAttachment struct {
|
||||
// in the ContainerSpec, that this volume fulfills.
|
||||
Target string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// TaskListOptions holds parameters to list tasks with.
|
||||
type TaskListOptions struct {
|
||||
Filters filters.Args
|
||||
}
|
||||
|
||||
47
vendor/github.com/docker/docker/api/types/types_deprecated.go
generated
vendored
47
vendor/github.com/docker/docker/api/types/types_deprecated.go
generated
vendored
@ -138,6 +138,53 @@ type ConfigCreateResponse = swarm.ConfigCreateResponse
|
||||
// Deprecated: use [swarm.ConfigListOptions].
|
||||
type ConfigListOptions = swarm.ConfigListOptions
|
||||
|
||||
// NodeListOptions holds parameters to list nodes with.
|
||||
//
|
||||
// Deprecated: use [swarm.NodeListOptions].
|
||||
type NodeListOptions = swarm.NodeListOptions
|
||||
|
||||
// NodeRemoveOptions holds parameters to remove nodes with.
|
||||
//
|
||||
// Deprecated: use [swarm.NodeRemoveOptions].
|
||||
type NodeRemoveOptions = swarm.NodeRemoveOptions
|
||||
|
||||
// TaskListOptions holds parameters to list tasks with.
|
||||
//
|
||||
// Deprecated: use [swarm.TaskListOptions].
|
||||
type TaskListOptions = swarm.TaskListOptions
|
||||
|
||||
// ServiceCreateOptions contains the options to use when creating a service.
|
||||
//
|
||||
// Deprecated: use [swarm.ServiceCreateOptions].
|
||||
type ServiceCreateOptions = swarm.ServiceCreateOptions
|
||||
|
||||
// ServiceUpdateOptions contains the options to be used for updating services.
|
||||
//
|
||||
// Deprecated: use [swarm.ServiceCreateOptions].
|
||||
type ServiceUpdateOptions = swarm.ServiceUpdateOptions
|
||||
|
||||
const (
|
||||
RegistryAuthFromSpec = swarm.RegistryAuthFromSpec // Deprecated: use [swarm.RegistryAuthFromSpec].
|
||||
RegistryAuthFromPreviousSpec = swarm.RegistryAuthFromPreviousSpec // Deprecated: use [swarm.RegistryAuthFromPreviousSpec].
|
||||
)
|
||||
|
||||
// ServiceListOptions holds parameters to list services with.
|
||||
//
|
||||
// Deprecated: use [swarm.ServiceListOptions].
|
||||
type ServiceListOptions = swarm.ServiceListOptions
|
||||
|
||||
// ServiceInspectOptions holds parameters related to the "service inspect"
|
||||
// operation.
|
||||
//
|
||||
// Deprecated: use [swarm.ServiceInspectOptions].
|
||||
type ServiceInspectOptions = swarm.ServiceInspectOptions
|
||||
|
||||
// SwarmUnlockKeyResponse contains the response for Engine API:
|
||||
// GET /swarm/unlockkey
|
||||
//
|
||||
// Deprecated: use [swarm.UnlockKeyResponse].
|
||||
type SwarmUnlockKeyResponse = swarm.UnlockKeyResponse
|
||||
|
||||
// BuildCache contains information about a build cache record.
|
||||
//
|
||||
// Deprecated: deprecated in API 1.49. Use [build.CacheRecord] instead.
|
||||
|
||||
16
vendor/github.com/docker/docker/client/client_interfaces.go
generated
vendored
16
vendor/github.com/docker/docker/client/client_interfaces.go
generated
vendored
@ -155,8 +155,8 @@ type NetworkAPIClient interface {
|
||||
// NodeAPIClient defines API client methods for the nodes
|
||||
type NodeAPIClient interface {
|
||||
NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error)
|
||||
NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error)
|
||||
NodeRemove(ctx context.Context, nodeID string, options types.NodeRemoveOptions) error
|
||||
NodeList(ctx context.Context, options swarm.NodeListOptions) ([]swarm.Node, error)
|
||||
NodeRemove(ctx context.Context, nodeID string, options swarm.NodeRemoveOptions) error
|
||||
NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error
|
||||
}
|
||||
|
||||
@ -176,22 +176,22 @@ type PluginAPIClient interface {
|
||||
|
||||
// ServiceAPIClient defines API client methods for the services
|
||||
type ServiceAPIClient interface {
|
||||
ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (swarm.ServiceCreateResponse, error)
|
||||
ServiceInspectWithRaw(ctx context.Context, serviceID string, options types.ServiceInspectOptions) (swarm.Service, []byte, error)
|
||||
ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error)
|
||||
ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options swarm.ServiceCreateOptions) (swarm.ServiceCreateResponse, error)
|
||||
ServiceInspectWithRaw(ctx context.Context, serviceID string, options swarm.ServiceInspectOptions) (swarm.Service, []byte, error)
|
||||
ServiceList(ctx context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error)
|
||||
ServiceRemove(ctx context.Context, serviceID string) error
|
||||
ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
|
||||
ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)
|
||||
ServiceLogs(ctx context.Context, serviceID string, options container.LogsOptions) (io.ReadCloser, error)
|
||||
TaskLogs(ctx context.Context, taskID string, options container.LogsOptions) (io.ReadCloser, error)
|
||||
TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error)
|
||||
TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error)
|
||||
TaskList(ctx context.Context, options swarm.TaskListOptions) ([]swarm.Task, error)
|
||||
}
|
||||
|
||||
// SwarmAPIClient defines API client methods for the swarm
|
||||
type SwarmAPIClient interface {
|
||||
SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error)
|
||||
SwarmJoin(ctx context.Context, req swarm.JoinRequest) error
|
||||
SwarmGetUnlockKey(ctx context.Context) (types.SwarmUnlockKeyResponse, error)
|
||||
SwarmGetUnlockKey(ctx context.Context) (swarm.UnlockKeyResponse, error)
|
||||
SwarmUnlock(ctx context.Context, req swarm.UnlockRequest) error
|
||||
SwarmLeave(ctx context.Context, force bool) error
|
||||
SwarmInspect(ctx context.Context) (swarm.Swarm, error)
|
||||
|
||||
42
vendor/github.com/docker/docker/client/errors.go
generated
vendored
42
vendor/github.com/docker/docker/client/errors.go
generated
vendored
@ -4,8 +4,10 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/errdefs/pkg/errhttp"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
)
|
||||
|
||||
@ -85,3 +87,43 @@ func (cli *Client) NewVersionError(ctx context.Context, APIrequired, feature str
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type httpError struct {
|
||||
err error
|
||||
errdef error
|
||||
}
|
||||
|
||||
func (e *httpError) Error() string {
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
func (e *httpError) Unwrap() error {
|
||||
return e.err
|
||||
}
|
||||
|
||||
func (e *httpError) Is(target error) bool {
|
||||
return errors.Is(e.errdef, target)
|
||||
}
|
||||
|
||||
// httpErrorFromStatusCode creates an errdef error, based on the provided HTTP status-code
|
||||
func httpErrorFromStatusCode(err error, statusCode int) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
base := errhttp.ToNative(statusCode)
|
||||
if base != nil {
|
||||
return &httpError{err: err, errdef: base}
|
||||
}
|
||||
|
||||
switch {
|
||||
case statusCode >= http.StatusOK && statusCode < http.StatusBadRequest:
|
||||
// it's a client error
|
||||
return err
|
||||
case statusCode >= http.StatusBadRequest && statusCode < http.StatusInternalServerError:
|
||||
return &httpError{err: err, errdef: cerrdefs.ErrInvalidArgument}
|
||||
case statusCode >= http.StatusInternalServerError && statusCode < 600:
|
||||
return &httpError{err: err, errdef: cerrdefs.ErrInternal}
|
||||
default:
|
||||
return &httpError{err: err, errdef: cerrdefs.ErrUnknown}
|
||||
}
|
||||
}
|
||||
|
||||
4
vendor/github.com/docker/docker/client/image_pull.go
generated
vendored
4
vendor/github.com/docker/docker/client/image_pull.go
generated
vendored
@ -6,9 +6,9 @@ import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/errdefs"
|
||||
)
|
||||
|
||||
// ImagePull requests the docker host to pull an image from a remote registry.
|
||||
@ -35,7 +35,7 @@ func (cli *Client) ImagePull(ctx context.Context, refStr string, options image.P
|
||||
}
|
||||
|
||||
resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth)
|
||||
if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
|
||||
if cerrdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
|
||||
newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx)
|
||||
if privilegeErr != nil {
|
||||
return nil, privilegeErr
|
||||
|
||||
4
vendor/github.com/docker/docker/client/image_push.go
generated
vendored
4
vendor/github.com/docker/docker/client/image_push.go
generated
vendored
@ -9,10 +9,10 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/errdefs"
|
||||
)
|
||||
|
||||
// ImagePush requests the docker host to push an image to a remote registry.
|
||||
@ -52,7 +52,7 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options image.Pu
|
||||
}
|
||||
|
||||
resp, err := cli.tryImagePush(ctx, ref.Name(), query, options.RegistryAuth)
|
||||
if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
|
||||
if cerrdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
|
||||
newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx)
|
||||
if privilegeErr != nil {
|
||||
return nil, privilegeErr
|
||||
|
||||
8
vendor/github.com/docker/docker/client/image_remove.go
generated
vendored
8
vendor/github.com/docker/docker/client/image_remove.go
generated
vendored
@ -19,6 +19,14 @@ func (cli *Client) ImageRemove(ctx context.Context, imageID string, options imag
|
||||
query.Set("noprune", "1")
|
||||
}
|
||||
|
||||
if len(options.Platforms) > 0 {
|
||||
p, err := encodePlatforms(options.Platforms...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query["platforms"] = p
|
||||
}
|
||||
|
||||
resp, err := cli.delete(ctx, "/images/"+imageID, query, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
|
||||
4
vendor/github.com/docker/docker/client/image_search.go
generated
vendored
4
vendor/github.com/docker/docker/client/image_search.go
generated
vendored
@ -7,9 +7,9 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/errdefs"
|
||||
)
|
||||
|
||||
// ImageSearch makes the docker host search by a term in a remote registry.
|
||||
@ -32,7 +32,7 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options registr
|
||||
|
||||
resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth)
|
||||
defer ensureReaderClosed(resp)
|
||||
if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
|
||||
if cerrdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
|
||||
newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx)
|
||||
if privilegeErr != nil {
|
||||
return results, privilegeErr
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user