diff --git a/cli/command/stack/client_test.go b/cli/command/stack/client_test.go index 50442783fa..d1d85193e7 100644 --- a/cli/command/stack/client_test.go +++ b/cli/command/stack/client_test.go @@ -15,6 +15,8 @@ import ( type fakeClient struct { client.Client + version string + services []string networks []string secrets []string @@ -45,6 +47,10 @@ func (cli *fakeClient) ServerVersion(ctx context.Context) (types.Version, error) }, nil } +func (cli *fakeClient) ClientVersion() string { + return cli.version +} + func (cli *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { if cli.serviceListFunc != nil { return cli.serviceListFunc(options) diff --git a/cli/command/stack/remove.go b/cli/command/stack/remove.go index fc7752407e..d95171aabf 100644 --- a/cli/command/stack/remove.go +++ b/cli/command/stack/remove.go @@ -51,20 +51,16 @@ func runRemove(dockerCli command.Cli, opts removeOptions) error { return err } - secrets, err := getStackSecrets(ctx, client, namespace) - if err != nil { - return err + var secrets []swarm.Secret + if versions.GreaterThanOrEqualTo(client.ClientVersion(), "1.25") { + secrets, err = getStackSecrets(ctx, client, namespace) + if err != nil { + return err + } } var configs []swarm.Config - - version, err := client.ServerVersion(ctx) - if err != nil { - return err - } - if versions.LessThan(version.APIVersion, "1.30") { - fmt.Fprintf(dockerCli.Err(), "WARNING: ignoring \"configs\" (requires API version 1.30, but the Docker daemon API version is %s)\n", version.APIVersion) - } else { + if versions.GreaterThanOrEqualTo(client.ClientVersion(), "1.30") { configs, err = getStackConfigs(ctx, client, namespace) if err != nil { return err diff --git a/cli/command/stack/remove_test.go b/cli/command/stack/remove_test.go index a196bf1653..c29f1b872f 100644 --- a/cli/command/stack/remove_test.go +++ b/cli/command/stack/remove_test.go @@ -39,7 +39,9 @@ func TestRemoveStack(t *testing.T) { } allConfigIDs := buildObjectIDs(allConfigs) + // Using API 1.24; removes services, networks, but doesn't remove configs and secrets cli := &fakeClient{ + version: "1.24", services: allServices, networks: allNetworks, secrets: allSecrets, @@ -48,6 +50,40 @@ func TestRemoveStack(t *testing.T) { cmd := newRemoveCommand(test.NewFakeCli(cli)) cmd.SetArgs([]string{"foo", "bar"}) + assert.NoError(t, cmd.Execute()) + assert.Equal(t, allServiceIDs, cli.removedServices) + assert.Equal(t, allNetworkIDs, cli.removedNetworks) + assert.Nil(t, cli.removedSecrets) + assert.Nil(t, cli.removedConfigs) + + // Using API 1.25; removes services, networks, but doesn't remove configs + cli = &fakeClient{ + version: "1.25", + services: allServices, + networks: allNetworks, + secrets: allSecrets, + configs: allConfigs, + } + cmd = newRemoveCommand(test.NewFakeCli(cli, &bytes.Buffer{})) + cmd.SetArgs([]string{"foo", "bar"}) + + assert.NoError(t, cmd.Execute()) + assert.Equal(t, allServiceIDs, cli.removedServices) + assert.Equal(t, allNetworkIDs, cli.removedNetworks) + assert.Equal(t, allSecretIDs, cli.removedSecrets) + assert.Nil(t, cli.removedConfigs) + + // Using API 1.30; removes services, networks, configs, and secrets + cli = &fakeClient{ + version: "1.30", + services: allServices, + networks: allNetworks, + secrets: allSecrets, + configs: allConfigs, + } + cmd = newRemoveCommand(test.NewFakeCli(cli, &bytes.Buffer{})) + cmd.SetArgs([]string{"foo", "bar"}) + assert.NoError(t, cmd.Execute()) assert.Equal(t, allServiceIDs, cli.removedServices) assert.Equal(t, allNetworkIDs, cli.removedNetworks) @@ -69,6 +105,7 @@ func TestRemoveStackSkipEmpty(t *testing.T) { allConfigIDs := buildObjectIDs(allConfigs) fakeClient := &fakeClient{ + version: "1.30", services: allServices, networks: allNetworks, secrets: allSecrets, @@ -102,6 +139,7 @@ func TestRemoveContinueAfterError(t *testing.T) { removedServices := []string{} cli := &fakeClient{ + version: "1.30", services: allServices, networks: allNetworks, secrets: allSecrets,