mirror of
https://github.com/docker/cli.git
synced 2026-01-06 05:41:44 +03:00
remove API-version compatibility for API < v1.44
Support for API versions < v1.44 was removed in the client in [moby@96b29f5] and [moby@7652f38], so we can remove fallback-code from the CLI as well, as it won't be able to use those versions. [moby@96b29f5]:96b29f5a1f[moby@7652f38]:7652f38c28Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/docker/cli/internal/prompt"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -112,17 +111,9 @@ type cancelledErr struct{ error }
|
||||
|
||||
func (cancelledErr) Cancelled() {}
|
||||
|
||||
type errNotImplemented struct{ error }
|
||||
|
||||
func (errNotImplemented) NotImplemented() {}
|
||||
|
||||
// pruneFn prunes the build cache for use in "docker system prune" and
|
||||
// returns the amount of space reclaimed and a detailed output string.
|
||||
func pruneFn(ctx context.Context, dockerCLI command.Cli, options pruner.PruneOptions) (uint64, string, error) {
|
||||
if ver := dockerCLI.Client().ClientVersion(); ver != "" && versions.LessThan(ver, "1.31") {
|
||||
// Not supported on older daemons.
|
||||
return 0, "", errNotImplemented{errors.New("builder prune requires API version 1.31 or greater")}
|
||||
}
|
||||
if !options.Confirmed {
|
||||
// Dry-run: perform validation and produce confirmation before pruning.
|
||||
var confirmMsg string
|
||||
|
||||
@@ -164,7 +164,7 @@ func TestInitializeFromClient(t *testing.T) {
|
||||
{
|
||||
doc: "successful ping",
|
||||
pingFunc: func() (types.Ping, error) {
|
||||
return types.Ping{Experimental: true, OSType: "linux", APIVersion: "v1.30"}, nil
|
||||
return types.Ping{Experimental: true, OSType: "linux", APIVersion: "v1.44"}, nil
|
||||
},
|
||||
expectedServer: ServerInfo{HasExperimental: true, OSType: "linux"},
|
||||
negotiated: true,
|
||||
@@ -179,7 +179,7 @@ func TestInitializeFromClient(t *testing.T) {
|
||||
{
|
||||
doc: "failed ping, with API version",
|
||||
pingFunc: func() (types.Ping, error) {
|
||||
return types.Ping{APIVersion: "v1.33"}, errors.New("failed")
|
||||
return types.Ping{APIVersion: "v1.44"}, errors.New("failed")
|
||||
},
|
||||
expectedServer: ServerInfo{HasExperimental: true},
|
||||
negotiated: true,
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"github.com/docker/cli/internal/jsonstream"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/moby/moby/api/types/mount"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/client"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -306,11 +305,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
|
||||
}
|
||||
|
||||
var platform *ocispec.Platform
|
||||
// Engine API version 1.41 first introduced the option to specify platform on
|
||||
// create. It will produce an error if you try to set a platform on older API
|
||||
// versions, so check the API version here to maintain backwards
|
||||
// compatibility for CLI users.
|
||||
if options.platform != "" && versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.41") {
|
||||
if options.platform != "" {
|
||||
p, err := platforms.Parse(options.platform)
|
||||
if err != nil {
|
||||
return "", invalidParameter(fmt.Errorf("error parsing specified platform: %w", err))
|
||||
|
||||
@@ -61,7 +61,7 @@ func TestRunLabel(t *testing.T) {
|
||||
ID: "id",
|
||||
}, nil
|
||||
},
|
||||
Version: "1.36",
|
||||
Version: client.MaxAPIVersion,
|
||||
})
|
||||
cmd := newRunCommand(fakeCLI)
|
||||
cmd.SetArgs([]string{"--detach=true", "--label", "foo", "busybox"})
|
||||
@@ -103,8 +103,8 @@ func TestRunAttach(t *testing.T) {
|
||||
return responseChan, errChan
|
||||
},
|
||||
// use new (non-legacy) wait API
|
||||
// see: 38591f20d07795aaef45d400df89ca12f29c603b
|
||||
Version: "1.30",
|
||||
// see: https://github.com/docker/cli/commit/38591f20d07795aaef45d400df89ca12f29c603b
|
||||
Version: client.MaxAPIVersion,
|
||||
}, func(fc *test.FakeCli) {
|
||||
fc.SetOut(streams.NewOut(tty))
|
||||
fc.SetIn(streams.NewIn(tty))
|
||||
@@ -180,8 +180,8 @@ func TestRunAttachTermination(t *testing.T) {
|
||||
return responseChan, errChan
|
||||
},
|
||||
// use new (non-legacy) wait API
|
||||
// see: 38591f20d07795aaef45d400df89ca12f29c603b
|
||||
Version: "1.30",
|
||||
// see: https://github.com/docker/cli/commit/38591f20d07795aaef45d400df89ca12f29c603b
|
||||
Version: client.MaxAPIVersion,
|
||||
}, func(fc *test.FakeCli) {
|
||||
fc.SetOut(streams.NewOut(tty))
|
||||
fc.SetIn(streams.NewIn(tty))
|
||||
@@ -262,7 +262,7 @@ func TestRunPullTermination(t *testing.T) {
|
||||
attachCh <- struct{}{}
|
||||
return respReader, nil
|
||||
},
|
||||
Version: "1.30",
|
||||
Version: client.MaxAPIVersion,
|
||||
})
|
||||
|
||||
cmd := newRunCommand(fakeCLI)
|
||||
|
||||
@@ -126,8 +126,6 @@ func (c *buildCacheContext) Parent() string {
|
||||
var parent string
|
||||
if len(c.v.Parents) > 0 {
|
||||
parent = strings.Join(c.v.Parents, ", ")
|
||||
} else {
|
||||
parent = c.v.Parent //nolint:staticcheck // Ignore SA1019: Field was deprecated in API v1.42, but kept for backward compatibility
|
||||
}
|
||||
if c.trunc {
|
||||
return TruncateID(parent)
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
cliopts "github.com/docker/cli/opts"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
@@ -132,9 +131,7 @@ func runCreate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet,
|
||||
}
|
||||
|
||||
// query registry if flag disabling it was not set
|
||||
if !opts.noResolveImage && versions.GreaterThanOrEqualTo(apiClient.ClientVersion(), "1.30") {
|
||||
createOpts.QueryRegistry = true
|
||||
}
|
||||
createOpts.QueryRegistry = !opts.noResolveImage
|
||||
|
||||
response, err := apiClient.ServiceCreate(ctx, service, createOpts)
|
||||
if err != nil {
|
||||
@@ -147,7 +144,7 @@ func runCreate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet,
|
||||
|
||||
_, _ = fmt.Fprintln(dockerCLI.Out(), response.ID)
|
||||
|
||||
if opts.detach || versions.LessThan(apiClient.ClientVersion(), "1.29") {
|
||||
if opts.detach {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/builders"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/client"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
@@ -63,59 +62,12 @@ func TestServiceListServiceStatus(t *testing.T) {
|
||||
cluster: &cluster{}, // force an empty cluster
|
||||
expected: []listResponse{},
|
||||
},
|
||||
{
|
||||
// Services are running, but no active nodes were found. On API v1.40
|
||||
// and below, this will cause looking up the "running" tasks to fail,
|
||||
// as well as looking up "desired" tasks for global services.
|
||||
doc: "API v1.40 no active nodes",
|
||||
opts: clusterOpts{
|
||||
apiVersion: "1.40",
|
||||
activeNodes: 0,
|
||||
runningTasks: 2,
|
||||
desiredTasks: 4,
|
||||
},
|
||||
expected: []listResponse{
|
||||
{ID: "replicated", Replicas: "0/4"},
|
||||
{ID: "global", Replicas: "0/0"},
|
||||
{ID: "none-id", Replicas: "0/0"},
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "API v1.40 3 active nodes, 1 task running",
|
||||
opts: clusterOpts{
|
||||
apiVersion: "1.40",
|
||||
activeNodes: 3,
|
||||
runningTasks: 1,
|
||||
desiredTasks: 2,
|
||||
},
|
||||
expected: []listResponse{
|
||||
{ID: "replicated", Replicas: "1/2"},
|
||||
{ID: "global", Replicas: "1/3"},
|
||||
{ID: "none-id", Replicas: "0/0"},
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "API v1.40 3 active nodes, all tasks running",
|
||||
opts: clusterOpts{
|
||||
apiVersion: "1.40",
|
||||
activeNodes: 3,
|
||||
runningTasks: 3,
|
||||
desiredTasks: 3,
|
||||
},
|
||||
expected: []listResponse{
|
||||
{ID: "replicated", Replicas: "3/3"},
|
||||
{ID: "global", Replicas: "3/3"},
|
||||
{ID: "none-id", Replicas: "0/0"},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
// Services are running, but no active nodes were found. On API v1.41
|
||||
// and up, the ServiceStatus is sent by the daemon, so this should not
|
||||
// affect the results.
|
||||
doc: "API v1.41 no active nodes",
|
||||
doc: "no active nodes",
|
||||
opts: clusterOpts{
|
||||
apiVersion: "1.41",
|
||||
activeNodes: 0,
|
||||
runningTasks: 2,
|
||||
desiredTasks: 4,
|
||||
@@ -127,9 +79,8 @@ func TestServiceListServiceStatus(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "API v1.41 3 active nodes, 1 task running",
|
||||
doc: "active nodes, 1 task running",
|
||||
opts: clusterOpts{
|
||||
apiVersion: "1.41",
|
||||
activeNodes: 3,
|
||||
runningTasks: 1,
|
||||
desiredTasks: 2,
|
||||
@@ -141,9 +92,8 @@ func TestServiceListServiceStatus(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "API v1.41 3 active nodes, all tasks running",
|
||||
doc: "active nodes, all tasks running",
|
||||
opts: clusterOpts{
|
||||
apiVersion: "1.41",
|
||||
activeNodes: 3,
|
||||
runningTasks: 3,
|
||||
desiredTasks: 3,
|
||||
@@ -174,7 +124,7 @@ func TestServiceListServiceStatus(t *testing.T) {
|
||||
}
|
||||
cli := test.NewFakeCli(&fakeClient{
|
||||
serviceListFunc: func(ctx context.Context, options client.ServiceListOptions) ([]swarm.Service, error) {
|
||||
if !options.Status || versions.LessThan(tc.opts.apiVersion, "1.41") {
|
||||
if !options.Status {
|
||||
// Don't return "ServiceStatus" if not requested, or on older API versions
|
||||
for i := range tc.cluster.services {
|
||||
tc.cluster.services[i].ServiceStatus = nil
|
||||
@@ -214,7 +164,6 @@ func TestServiceListServiceStatus(t *testing.T) {
|
||||
}
|
||||
|
||||
type clusterOpts struct {
|
||||
apiVersion string
|
||||
activeNodes uint64
|
||||
desiredTasks uint64
|
||||
runningTasks uint64
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -54,7 +53,7 @@ func runRollback(ctx context.Context, dockerCLI command.Cli, options *serviceOpt
|
||||
|
||||
_, _ = fmt.Fprintln(dockerCLI.Out(), serviceID)
|
||||
|
||||
if options.detach || versions.LessThan(apiClient.ClientVersion(), "1.29") {
|
||||
if options.detach {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,8 @@ func TestRollback(t *testing.T) {
|
||||
})
|
||||
cmd := newRollbackCommand(cli)
|
||||
cmd.SetArgs(tc.args)
|
||||
cmd.Flags().Set("quiet", "true")
|
||||
assert.NilError(t, cmd.Flags().Set("quiet", "true"))
|
||||
assert.NilError(t, cmd.Flags().Set("detach", "true"))
|
||||
cmd.SetOut(io.Discard)
|
||||
assert.NilError(t, cmd.Execute())
|
||||
assert.Check(t, is.Equal(strings.TrimSpace(cli.ErrBuffer().String()), tc.expectedDockerCliErr))
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -83,7 +82,7 @@ func runScale(ctx context.Context, dockerCLI command.Cli, options *scaleOptions,
|
||||
serviceIDs = append(serviceIDs, serviceID)
|
||||
}
|
||||
|
||||
if len(serviceIDs) > 0 && !options.detach && versions.GreaterThanOrEqualTo(dockerCLI.Client().ClientVersion(), "1.29") {
|
||||
if len(serviceIDs) > 0 && !options.detach {
|
||||
for _, serviceID := range serviceIDs {
|
||||
if err := WaitOnService(ctx, dockerCLI, serviceID, false); err != nil {
|
||||
errs = append(errs, fmt.Errorf("%s: %v", serviceID, err))
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"github.com/moby/moby/api/types/mount"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/swarmkit/v2/api/defaults"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -165,14 +164,6 @@ func runUpdate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet,
|
||||
return err
|
||||
}
|
||||
|
||||
// There are two ways to do user-requested rollback. The old way is
|
||||
// client-side, but with a sufficiently recent daemon we prefer
|
||||
// server-side, because it will honor the rollback parameters.
|
||||
var (
|
||||
clientSideRollback bool
|
||||
serverSideRollback bool
|
||||
)
|
||||
|
||||
spec := &service.Spec
|
||||
if rollback {
|
||||
// Rollback can't be combined with other flags.
|
||||
@@ -188,20 +179,10 @@ func runUpdate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet,
|
||||
if otherFlagsPassed {
|
||||
return errors.New("other flags may not be combined with --rollback")
|
||||
}
|
||||
|
||||
if versions.LessThan(apiClient.ClientVersion(), "1.28") {
|
||||
clientSideRollback = true
|
||||
spec = service.PreviousSpec
|
||||
if spec == nil {
|
||||
return errors.New("service does not have a previous specification to roll back to")
|
||||
}
|
||||
} else {
|
||||
serverSideRollback = true
|
||||
}
|
||||
}
|
||||
|
||||
updateOpts := client.ServiceUpdateOptions{}
|
||||
if serverSideRollback {
|
||||
if rollback {
|
||||
updateOpts.Rollback = "previous"
|
||||
}
|
||||
|
||||
@@ -214,9 +195,7 @@ func runUpdate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet,
|
||||
if err := resolveServiceImageDigestContentTrust(dockerCLI, spec); err != nil {
|
||||
return err
|
||||
}
|
||||
if !options.noResolveImage && versions.GreaterThanOrEqualTo(apiClient.ClientVersion(), "1.30") {
|
||||
updateOpts.QueryRegistry = true
|
||||
}
|
||||
updateOpts.QueryRegistry = !options.noResolveImage
|
||||
}
|
||||
|
||||
updatedSecrets, err := getUpdatedSecrets(ctx, apiClient, flags, spec.TaskTemplate.ContainerSpec.Secrets)
|
||||
@@ -243,8 +222,7 @@ func runUpdate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch {
|
||||
case sendAuth:
|
||||
if sendAuth {
|
||||
// Retrieve encoded auth token from the image reference
|
||||
// This would be the old image if it didn't change in this update
|
||||
image := spec.TaskTemplate.ContainerSpec.Image
|
||||
@@ -253,9 +231,7 @@ func runUpdate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet,
|
||||
return err
|
||||
}
|
||||
updateOpts.EncodedRegistryAuth = encodedAuth
|
||||
case clientSideRollback:
|
||||
updateOpts.RegistryAuthFrom = swarm.RegistryAuthFromPreviousSpec
|
||||
default:
|
||||
} else {
|
||||
updateOpts.RegistryAuthFrom = swarm.RegistryAuthFromSpec
|
||||
}
|
||||
|
||||
@@ -270,7 +246,7 @@ func runUpdate(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet,
|
||||
|
||||
_, _ = fmt.Fprintln(dockerCLI.Out(), serviceID)
|
||||
|
||||
if options.detach || versions.LessThan(apiClient.ClientVersion(), "1.29") {
|
||||
if options.detach {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,6 @@ import (
|
||||
type fakeClient struct {
|
||||
client.Client
|
||||
|
||||
version string
|
||||
|
||||
services []string
|
||||
networks []string
|
||||
secrets []string
|
||||
@@ -49,8 +47,8 @@ func (*fakeClient) ServerVersion(context.Context) (types.Version, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) ClientVersion() string {
|
||||
return cli.version
|
||||
func (*fakeClient) ClientVersion() string {
|
||||
return client.MaxAPIVersion
|
||||
}
|
||||
|
||||
func (cli *fakeClient) ServiceList(_ context.Context, options client.ServiceListOptions) ([]swarm.Service, error) {
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/docker/cli/cli/compose/convert"
|
||||
composetypes "github.com/docker/cli/cli/compose/types"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
@@ -81,13 +80,6 @@ func runDeploy(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet,
|
||||
return fmt.Errorf("invalid option %s for flag --resolve-image", opts.resolveImage)
|
||||
}
|
||||
|
||||
// client side image resolution should not be done when the supported
|
||||
// server version is older than 1.30
|
||||
if versions.LessThan(dockerCLI.Client().ClientVersion(), "1.30") {
|
||||
// TODO(thaJeztah): should this error if "opts.ResolveImage" is already other (unsupported) values?
|
||||
opts.resolveImage = resolveImageNever
|
||||
}
|
||||
|
||||
if opts.detach && !flags.Changed("detach") {
|
||||
_, _ = fmt.Fprintln(dockerCLI.Err(), "Since --detach=false was not specified, tasks will be created in the background.\n"+
|
||||
"In a future release, --detach=false will become the default.")
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -61,20 +60,14 @@ func runRemove(ctx context.Context, dockerCli command.Cli, opts removeOptions) e
|
||||
return err
|
||||
}
|
||||
|
||||
var secrets []swarm.Secret
|
||||
if versions.GreaterThanOrEqualTo(apiClient.ClientVersion(), "1.25") {
|
||||
secrets, err = getStackSecrets(ctx, apiClient, namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
secrets, err := getStackSecrets(ctx, apiClient, namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var configs []swarm.Config
|
||||
if versions.GreaterThanOrEqualTo(apiClient.ClientVersion(), "1.30") {
|
||||
configs, err = getStackConfigs(ctx, apiClient, namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
configs, err := getStackConfigs(ctx, apiClient, namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(services)+len(networks)+len(secrets)+len(configs) == 0 {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
|
||||
func fakeClientForRemoveStackTest(version string) *fakeClient {
|
||||
func fakeClientForRemoveStackTest() *fakeClient {
|
||||
allServices := []string{
|
||||
objectName("foo", "service1"),
|
||||
objectName("foo", "service2"),
|
||||
@@ -33,7 +33,6 @@ func fakeClientForRemoveStackTest(version string) *fakeClient {
|
||||
objectName("bar", "config1"),
|
||||
}
|
||||
return &fakeClient{
|
||||
version: version,
|
||||
services: allServices,
|
||||
networks: allNetworks,
|
||||
secrets: allSecrets,
|
||||
@@ -50,40 +49,16 @@ func TestRemoveWithEmptyName(t *testing.T) {
|
||||
assert.ErrorContains(t, cmd.Execute(), `invalid stack name: "' '"`)
|
||||
}
|
||||
|
||||
func TestRemoveStackVersion124DoesNotRemoveConfigsOrSecrets(t *testing.T) {
|
||||
client := fakeClientForRemoveStackTest("1.24")
|
||||
cmd := newRemoveCommand(test.NewFakeCli(client))
|
||||
func TestRemoveStackRemovesEverything(t *testing.T) {
|
||||
apiClient := fakeClientForRemoveStackTest()
|
||||
cmd := newRemoveCommand(test.NewFakeCli(apiClient))
|
||||
cmd.SetArgs([]string{"foo", "bar"})
|
||||
|
||||
assert.NilError(t, cmd.Execute())
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(client.services), client.removedServices))
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(client.networks), client.removedNetworks))
|
||||
assert.Check(t, is.Len(client.removedSecrets, 0))
|
||||
assert.Check(t, is.Len(client.removedConfigs, 0))
|
||||
}
|
||||
|
||||
func TestRemoveStackVersion125DoesNotRemoveConfigs(t *testing.T) {
|
||||
client := fakeClientForRemoveStackTest("1.25")
|
||||
cmd := newRemoveCommand(test.NewFakeCli(client))
|
||||
cmd.SetArgs([]string{"foo", "bar"})
|
||||
|
||||
assert.NilError(t, cmd.Execute())
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(client.services), client.removedServices))
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(client.networks), client.removedNetworks))
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(client.secrets), client.removedSecrets))
|
||||
assert.Check(t, is.Len(client.removedConfigs, 0))
|
||||
}
|
||||
|
||||
func TestRemoveStackVersion130RemovesEverything(t *testing.T) {
|
||||
client := fakeClientForRemoveStackTest("1.30")
|
||||
cmd := newRemoveCommand(test.NewFakeCli(client))
|
||||
cmd.SetArgs([]string{"foo", "bar"})
|
||||
|
||||
assert.NilError(t, cmd.Execute())
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(client.services), client.removedServices))
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(client.networks), client.removedNetworks))
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(client.secrets), client.removedSecrets))
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(client.configs), client.removedConfigs))
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(apiClient.services), apiClient.removedServices))
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(apiClient.networks), apiClient.removedNetworks))
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(apiClient.secrets), apiClient.removedSecrets))
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs(apiClient.configs), apiClient.removedConfigs))
|
||||
}
|
||||
|
||||
func TestRemoveStackSkipEmpty(t *testing.T) {
|
||||
@@ -100,7 +75,6 @@ func TestRemoveStackSkipEmpty(t *testing.T) {
|
||||
allConfigIDs := buildObjectIDs(allConfigs)
|
||||
|
||||
apiClient := &fakeClient{
|
||||
version: "1.30",
|
||||
services: allServices,
|
||||
networks: allNetworks,
|
||||
secrets: allSecrets,
|
||||
@@ -141,7 +115,6 @@ func TestRemoveContinueAfterError(t *testing.T) {
|
||||
|
||||
removedServices := []string{}
|
||||
apiClient := &fakeClient{
|
||||
version: "1.30",
|
||||
services: allServices,
|
||||
networks: allNetworks,
|
||||
secrets: allSecrets,
|
||||
|
||||
@@ -22,24 +22,8 @@ import (
|
||||
_ "github.com/docker/cli/cli/command/volume"
|
||||
)
|
||||
|
||||
func TestPrunePromptPre131DoesNotIncludeBuildCache(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{version: "1.30"})
|
||||
cmd := newPruneCommand(cli)
|
||||
cmd.SetArgs([]string{})
|
||||
cmd.SetOut(io.Discard)
|
||||
cmd.SetErr(io.Discard)
|
||||
assert.ErrorContains(t, cmd.Execute(), "system prune has been cancelled")
|
||||
expected := `WARNING! This will remove:
|
||||
- all stopped containers
|
||||
- all networks not used by at least one container
|
||||
- all dangling images
|
||||
|
||||
Are you sure you want to continue? [y/N] `
|
||||
assert.Check(t, is.Equal(expected, cli.OutBuffer().String()))
|
||||
}
|
||||
|
||||
func TestPrunePromptFilters(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{version: "1.31"})
|
||||
cli := test.NewFakeCli(&fakeClient{version: "1.51"})
|
||||
cli.SetConfigFile(&configfile.ConfigFile{
|
||||
PruneFilters: []string{"label!=never=remove-me", "label=remove=me"},
|
||||
})
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/docker/cli/internal/prompt"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -72,16 +71,11 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
|
||||
pruneFilters := command.PruneFilters(dockerCli, options.filter.Value())
|
||||
|
||||
warning := unusedVolumesWarning
|
||||
if versions.GreaterThanOrEqualTo(dockerCli.CurrentVersion(), "1.42") {
|
||||
if options.all {
|
||||
if _, ok := pruneFilters["all"]; ok {
|
||||
return 0, "", invalidParamErr{errors.New("conflicting options: cannot specify both --all and --filter all=1")}
|
||||
}
|
||||
pruneFilters.Add("all", "true")
|
||||
warning = allVolumesWarning
|
||||
if options.all {
|
||||
if _, ok := pruneFilters["all"]; ok {
|
||||
return 0, "", invalidParamErr{errors.New("conflicting options: cannot specify both --all and --filter all=1")}
|
||||
}
|
||||
} else {
|
||||
// API < v1.42 removes all volumes (anonymous and named) by default.
|
||||
pruneFilters.Add("all", "true")
|
||||
warning = allVolumesWarning
|
||||
}
|
||||
if !options.force {
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/client"
|
||||
)
|
||||
|
||||
@@ -44,7 +43,7 @@ func Services(
|
||||
return nil, fmt.Errorf("service %s: %w", service.Name, err)
|
||||
}
|
||||
|
||||
serviceSpec, err := Service(apiClient.ClientVersion(), namespace, service, config.Networks, config.Volumes, secrets, configs)
|
||||
serviceSpec, err := Service(namespace, service, config.Networks, config.Volumes, secrets, configs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("service %s: %w", service.Name, err)
|
||||
}
|
||||
@@ -56,7 +55,6 @@ func Services(
|
||||
|
||||
// Service converts a ServiceConfig into a swarm ServiceSpec
|
||||
func Service(
|
||||
apiVersion string,
|
||||
namespace Namespace,
|
||||
service composetypes.ServiceConfig,
|
||||
networkConfigs map[string]composetypes.NetworkConfig,
|
||||
@@ -161,6 +159,7 @@ func Service(
|
||||
Preferences: getPlacementPreference(service.Deploy.Placement.Preferences),
|
||||
MaxReplicas: service.Deploy.Placement.MaxReplicas,
|
||||
},
|
||||
Networks: networks,
|
||||
},
|
||||
EndpointSpec: endpoint,
|
||||
Mode: mode,
|
||||
@@ -171,18 +170,6 @@ func Service(
|
||||
// add an image label to serviceSpec
|
||||
serviceSpec.Labels[LabelImage] = service.Image
|
||||
|
||||
// ServiceSpec.Networks is deprecated and should not have been used by
|
||||
// this package. It is possible to update TaskTemplate.Networks, but it
|
||||
// is not possible to update ServiceSpec.Networks. Unfortunately, we
|
||||
// can't unconditionally start using TaskTemplate.Networks, because that
|
||||
// will break with older daemons that don't support migrating from
|
||||
// ServiceSpec.Networks to TaskTemplate.Networks. So which field to use
|
||||
// is conditional on daemon version.
|
||||
if versions.LessThan(apiVersion, "1.29") {
|
||||
serviceSpec.Networks = networks //nolint:staticcheck // ignore SA1019: field is deprecated.
|
||||
} else {
|
||||
serviceSpec.TaskTemplate.Networks = networks
|
||||
}
|
||||
return serviceSpec, nil
|
||||
}
|
||||
|
||||
@@ -670,7 +657,6 @@ func toNetipAddrSlice(ips []string) []netip.Addr {
|
||||
func convertCredentialSpec(namespace Namespace, spec composetypes.CredentialSpecConfig, refs []*swarm.ConfigReference) (*swarm.CredentialSpec, error) {
|
||||
var o []string
|
||||
|
||||
// Config was added in API v1.40
|
||||
if spec.Config != "" {
|
||||
o = append(o, `"Config"`)
|
||||
}
|
||||
|
||||
@@ -495,7 +495,7 @@ func TestServiceConvertsIsolation(t *testing.T) {
|
||||
src := composetypes.ServiceConfig{
|
||||
Isolation: "hyperv",
|
||||
}
|
||||
result, err := Service("1.35", Namespace{name: "foo"}, src, nil, nil, nil, nil)
|
||||
result, err := Service(Namespace{name: "foo"}, src, nil, nil, nil, nil)
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(container.IsolationHyperV, result.TaskTemplate.ContainerSpec.Isolation))
|
||||
}
|
||||
@@ -692,7 +692,7 @@ func TestConvertServiceCapAddAndCapDrop(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
result, err := Service("1.41", Namespace{name: "foo"}, tc.in, nil, nil, nil, nil)
|
||||
result, err := Service(Namespace{name: "foo"}, tc.in, nil, nil, nil, nil)
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.DeepEqual(result.TaskTemplate.ContainerSpec.CapabilityAdd, tc.out.CapAdd))
|
||||
assert.Check(t, is.DeepEqual(result.TaskTemplate.ContainerSpec.CapabilityDrop, tc.out.CapDrop))
|
||||
|
||||
@@ -210,7 +210,6 @@ func TestRunWithCgroupNamespace(t *testing.T) {
|
||||
|
||||
func TestMountSubvolume(t *testing.T) {
|
||||
skip.If(t, versions.LessThan(environment.DaemonAPIVersion(t), "1.45"))
|
||||
|
||||
volName := "test-volume-" + t.Name()
|
||||
icmd.RunCommand("docker", "volume", "create", volName).Assert(t, icmd.Success)
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
"github.com/docker/cli/e2e/testutils"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/environment"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/icmd"
|
||||
"gotest.tools/v3/poll"
|
||||
@@ -144,7 +143,6 @@ func TestPromptExitCode(t *testing.T) {
|
||||
run: func(t *testing.T) icmd.Cmd {
|
||||
t.Helper()
|
||||
t.Skip("flaky test: see https://github.com/docker/cli/issues/6248")
|
||||
skip.If(t, versions.LessThan(environment.DaemonAPIVersion(t), "1.44"))
|
||||
|
||||
const plugin = "registry:5000/plugin-install-test:latest"
|
||||
|
||||
@@ -162,7 +160,6 @@ func TestPromptExitCode(t *testing.T) {
|
||||
run: func(t *testing.T) icmd.Cmd {
|
||||
t.Helper()
|
||||
t.Skip("flaky test: see https://github.com/docker/cli/issues/6248")
|
||||
skip.If(t, versions.LessThan(environment.DaemonAPIVersion(t), "1.44"))
|
||||
|
||||
const plugin = "registry:5000/plugin-upgrade-test"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user