1
0
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]: 7652f38c28

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-10-10 18:54:19 +02:00
parent a3e954551d
commit d36f16e224
21 changed files with 49 additions and 228 deletions

View File

@@ -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

View File

@@ -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,

View File

@@ -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))

View File

@@ -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)

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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))

View File

@@ -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))

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -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.")

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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"},
})

View File

@@ -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 {

View File

@@ -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"`)
}

View File

@@ -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))

View File

@@ -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)

View File

@@ -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"