mirror of https://github.com/docker/cli.git
Don't attempt to remove unsupported resources on older daemon
When running `docker stack rm <some stack>` against an older daemon, a warning was printed for "configs" being ignored; WARNING: ignoring "configs" (requires API version 1.30, but the Docker daemon API version is 1.26) Given that an old daemon cannot _have_ configs, there should not be a need to warn, or _attempt_ to remove these resources. This patch removes the warning, and skips fetching (and removing) configs. A check if _secrets_ are supported by the daemon is also added, given that this would result in an error when attempted against an older (pre 1.13) daemon. There is one situation where this could lead to secrets or configs being left behind; if the client is connecting to a daemon that _does_ support secrets, configs, but the API version is overridden using `DOCKER_API_VERSION`, no warning is printed, and secrets and configs are not attempted to be removed. Given that `DOCKER_API_VERSION` is regarded a feature for debugging / "power users", it should be ok to ignore this. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
6908e58f0f
commit
2429f15672
|
@ -15,6 +15,8 @@ import (
|
||||||
type fakeClient struct {
|
type fakeClient struct {
|
||||||
client.Client
|
client.Client
|
||||||
|
|
||||||
|
version string
|
||||||
|
|
||||||
services []string
|
services []string
|
||||||
networks []string
|
networks []string
|
||||||
secrets []string
|
secrets []string
|
||||||
|
@ -45,6 +47,10 @@ func (cli *fakeClient) ServerVersion(ctx context.Context) (types.Version, error)
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cli *fakeClient) ClientVersion() string {
|
||||||
|
return cli.version
|
||||||
|
}
|
||||||
|
|
||||||
func (cli *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
func (cli *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||||
if cli.serviceListFunc != nil {
|
if cli.serviceListFunc != nil {
|
||||||
return cli.serviceListFunc(options)
|
return cli.serviceListFunc(options)
|
||||||
|
|
|
@ -51,20 +51,16 @@ func runRemove(dockerCli command.Cli, opts removeOptions) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
secrets, err := getStackSecrets(ctx, client, namespace)
|
var secrets []swarm.Secret
|
||||||
if err != nil {
|
if versions.GreaterThanOrEqualTo(client.ClientVersion(), "1.25") {
|
||||||
return err
|
secrets, err = getStackSecrets(ctx, client, namespace)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var configs []swarm.Config
|
var configs []swarm.Config
|
||||||
|
if versions.GreaterThanOrEqualTo(client.ClientVersion(), "1.30") {
|
||||||
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 {
|
|
||||||
configs, err = getStackConfigs(ctx, client, namespace)
|
configs, err = getStackConfigs(ctx, client, namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -40,7 +40,9 @@ func TestRemoveStack(t *testing.T) {
|
||||||
}
|
}
|
||||||
allConfigIDs := buildObjectIDs(allConfigs)
|
allConfigIDs := buildObjectIDs(allConfigs)
|
||||||
|
|
||||||
|
// Using API 1.24; removes services, networks, but doesn't remove configs and secrets
|
||||||
cli := &fakeClient{
|
cli := &fakeClient{
|
||||||
|
version: "1.24",
|
||||||
services: allServices,
|
services: allServices,
|
||||||
networks: allNetworks,
|
networks: allNetworks,
|
||||||
secrets: allSecrets,
|
secrets: allSecrets,
|
||||||
|
@ -49,6 +51,40 @@ func TestRemoveStack(t *testing.T) {
|
||||||
cmd := newRemoveCommand(test.NewFakeCli(cli, &bytes.Buffer{}))
|
cmd := newRemoveCommand(test.NewFakeCli(cli, &bytes.Buffer{}))
|
||||||
cmd.SetArgs([]string{"foo", "bar"})
|
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.NoError(t, cmd.Execute())
|
||||||
assert.Equal(t, allServiceIDs, cli.removedServices)
|
assert.Equal(t, allServiceIDs, cli.removedServices)
|
||||||
assert.Equal(t, allNetworkIDs, cli.removedNetworks)
|
assert.Equal(t, allNetworkIDs, cli.removedNetworks)
|
||||||
|
@ -72,6 +108,7 @@ func TestRemoveStackSkipEmpty(t *testing.T) {
|
||||||
allConfigIDs := buildObjectIDs(allConfigs)
|
allConfigIDs := buildObjectIDs(allConfigs)
|
||||||
|
|
||||||
fakeClient := &fakeClient{
|
fakeClient := &fakeClient{
|
||||||
|
version: "1.30",
|
||||||
services: allServices,
|
services: allServices,
|
||||||
networks: allNetworks,
|
networks: allNetworks,
|
||||||
secrets: allSecrets,
|
secrets: allSecrets,
|
||||||
|
@ -106,6 +143,7 @@ func TestRemoveContinueAfterError(t *testing.T) {
|
||||||
|
|
||||||
removedServices := []string{}
|
removedServices := []string{}
|
||||||
cli := &fakeClient{
|
cli := &fakeClient{
|
||||||
|
version: "1.30",
|
||||||
services: allServices,
|
services: allServices,
|
||||||
networks: allNetworks,
|
networks: allNetworks,
|
||||||
secrets: allSecrets,
|
secrets: allSecrets,
|
||||||
|
|
Loading…
Reference in New Issue