mirror of https://github.com/docker/cli.git
Remove stack configs on stack removal
Signed-off-by: John Stephens <johnstep@docker.com>
This commit is contained in:
parent
1b8b63be5c
commit
f05cd11ee2
|
@ -17,17 +17,21 @@ type fakeClient struct {
|
||||||
services []string
|
services []string
|
||||||
networks []string
|
networks []string
|
||||||
secrets []string
|
secrets []string
|
||||||
|
configs []string
|
||||||
|
|
||||||
removedServices []string
|
removedServices []string
|
||||||
removedNetworks []string
|
removedNetworks []string
|
||||||
removedSecrets []string
|
removedSecrets []string
|
||||||
|
removedConfigs []string
|
||||||
|
|
||||||
serviceListFunc func(options types.ServiceListOptions) ([]swarm.Service, error)
|
serviceListFunc func(options types.ServiceListOptions) ([]swarm.Service, error)
|
||||||
networkListFunc func(options types.NetworkListOptions) ([]types.NetworkResource, error)
|
networkListFunc func(options types.NetworkListOptions) ([]types.NetworkResource, error)
|
||||||
secretListFunc func(options types.SecretListOptions) ([]swarm.Secret, error)
|
secretListFunc func(options types.SecretListOptions) ([]swarm.Secret, error)
|
||||||
|
configListFunc func(options types.ConfigListOptions) ([]swarm.Config, error)
|
||||||
serviceRemoveFunc func(serviceID string) error
|
serviceRemoveFunc func(serviceID string) error
|
||||||
networkRemoveFunc func(networkID string) error
|
networkRemoveFunc func(networkID string) error
|
||||||
secretRemoveFunc func(secretID string) error
|
secretRemoveFunc func(secretID string) error
|
||||||
|
configRemoveFunc func(configID string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -75,6 +79,21 @@ func (cli *fakeClient) SecretList(ctx context.Context, options types.SecretListO
|
||||||
return secretsList, nil
|
return secretsList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cli *fakeClient) ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
|
||||||
|
if cli.configListFunc != nil {
|
||||||
|
return cli.configListFunc(options)
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace := namespaceFromFilters(options.Filters)
|
||||||
|
configsList := []swarm.Config{}
|
||||||
|
for _, name := range cli.configs {
|
||||||
|
if belongToNamespace(name, namespace) {
|
||||||
|
configsList = append(configsList, configFromName(name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return configsList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (cli *fakeClient) ServiceRemove(ctx context.Context, serviceID string) error {
|
func (cli *fakeClient) ServiceRemove(ctx context.Context, serviceID string) error {
|
||||||
if cli.serviceRemoveFunc != nil {
|
if cli.serviceRemoveFunc != nil {
|
||||||
return cli.serviceRemoveFunc(serviceID)
|
return cli.serviceRemoveFunc(serviceID)
|
||||||
|
@ -102,6 +121,15 @@ func (cli *fakeClient) SecretRemove(ctx context.Context, secretID string) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cli *fakeClient) ConfigRemove(ctx context.Context, configID string) error {
|
||||||
|
if cli.configRemoveFunc != nil {
|
||||||
|
return cli.configRemoveFunc(configID)
|
||||||
|
}
|
||||||
|
|
||||||
|
cli.removedConfigs = append(cli.removedConfigs, configID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func serviceFromName(name string) swarm.Service {
|
func serviceFromName(name string) swarm.Service {
|
||||||
return swarm.Service{
|
return swarm.Service{
|
||||||
ID: "ID-" + name,
|
ID: "ID-" + name,
|
||||||
|
@ -127,6 +155,15 @@ func secretFromName(name string) swarm.Secret {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func configFromName(name string) swarm.Config {
|
||||||
|
return swarm.Config{
|
||||||
|
ID: "ID-" + name,
|
||||||
|
Spec: swarm.ConfigSpec{
|
||||||
|
Annotations: swarm.Annotations{Name: name},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func namespaceFromFilters(filters filters.Args) string {
|
func namespaceFromFilters(filters filters.Args) string {
|
||||||
label := filters.Get("label")[0]
|
label := filters.Get("label")[0]
|
||||||
return strings.TrimPrefix(label, convert.LabelNamespace+"=")
|
return strings.TrimPrefix(label, convert.LabelNamespace+"=")
|
||||||
|
|
|
@ -61,3 +61,13 @@ func getStackSecrets(
|
||||||
ctx,
|
ctx,
|
||||||
types.SecretListOptions{Filters: getStackFilter(namespace)})
|
types.SecretListOptions{Filters: getStackFilter(namespace)})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getStackConfigs(
|
||||||
|
ctx context.Context,
|
||||||
|
apiclient client.APIClient,
|
||||||
|
namespace string,
|
||||||
|
) ([]swarm.Config, error) {
|
||||||
|
return apiclient.ConfigList(
|
||||||
|
ctx,
|
||||||
|
types.ConfigListOptions{Filters: getStackFilter(namespace)})
|
||||||
|
}
|
||||||
|
|
|
@ -55,13 +55,19 @@ func runRemove(dockerCli command.Cli, opts removeOptions) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(services)+len(networks)+len(secrets) == 0 {
|
configs, err := getStackConfigs(ctx, client, namespace)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(services)+len(networks)+len(secrets)+len(configs) == 0 {
|
||||||
fmt.Fprintf(dockerCli.Out(), "Nothing found in stack: %s\n", namespace)
|
fmt.Fprintf(dockerCli.Out(), "Nothing found in stack: %s\n", namespace)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
hasError := removeServices(ctx, dockerCli, services)
|
hasError := removeServices(ctx, dockerCli, services)
|
||||||
hasError = removeSecrets(ctx, dockerCli, secrets) || hasError
|
hasError = removeSecrets(ctx, dockerCli, secrets) || hasError
|
||||||
|
hasError = removeConfigs(ctx, dockerCli, configs) || hasError
|
||||||
hasError = removeNetworks(ctx, dockerCli, networks) || hasError
|
hasError = removeNetworks(ctx, dockerCli, networks) || hasError
|
||||||
|
|
||||||
if hasError {
|
if hasError {
|
||||||
|
@ -119,3 +125,18 @@ func removeSecrets(
|
||||||
}
|
}
|
||||||
return err != nil
|
return err != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func removeConfigs(
|
||||||
|
ctx context.Context,
|
||||||
|
dockerCli command.Cli,
|
||||||
|
configs []swarm.Config,
|
||||||
|
) bool {
|
||||||
|
var err error
|
||||||
|
for _, config := range configs {
|
||||||
|
fmt.Fprintf(dockerCli.Err(), "Removing config %s\n", config.Spec.Name)
|
||||||
|
if err = dockerCli.Client().ConfigRemove(ctx, config.ID); err != nil {
|
||||||
|
fmt.Fprintf(dockerCli.Err(), "Failed to remove config %s: %s", config.ID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err != nil
|
||||||
|
}
|
||||||
|
|
|
@ -32,10 +32,18 @@ func TestRemoveStack(t *testing.T) {
|
||||||
}
|
}
|
||||||
allSecretIDs := buildObjectIDs(allSecrets)
|
allSecretIDs := buildObjectIDs(allSecrets)
|
||||||
|
|
||||||
|
allConfigs := []string{
|
||||||
|
objectName("foo", "config1"),
|
||||||
|
objectName("foo", "config2"),
|
||||||
|
objectName("bar", "config1"),
|
||||||
|
}
|
||||||
|
allConfigIDs := buildObjectIDs(allConfigs)
|
||||||
|
|
||||||
cli := &fakeClient{
|
cli := &fakeClient{
|
||||||
services: allServices,
|
services: allServices,
|
||||||
networks: allNetworks,
|
networks: allNetworks,
|
||||||
secrets: allSecrets,
|
secrets: allSecrets,
|
||||||
|
configs: allConfigs,
|
||||||
}
|
}
|
||||||
cmd := newRemoveCommand(test.NewFakeCli(cli, &bytes.Buffer{}))
|
cmd := newRemoveCommand(test.NewFakeCli(cli, &bytes.Buffer{}))
|
||||||
cmd.SetArgs([]string{"foo", "bar"})
|
cmd.SetArgs([]string{"foo", "bar"})
|
||||||
|
@ -44,6 +52,7 @@ func TestRemoveStack(t *testing.T) {
|
||||||
assert.Equal(t, allServiceIDs, cli.removedServices)
|
assert.Equal(t, allServiceIDs, cli.removedServices)
|
||||||
assert.Equal(t, allNetworkIDs, cli.removedNetworks)
|
assert.Equal(t, allNetworkIDs, cli.removedNetworks)
|
||||||
assert.Equal(t, allSecretIDs, cli.removedSecrets)
|
assert.Equal(t, allSecretIDs, cli.removedSecrets)
|
||||||
|
assert.Equal(t, allConfigIDs, cli.removedConfigs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSkipEmptyStack(t *testing.T) {
|
func TestSkipEmptyStack(t *testing.T) {
|
||||||
|
@ -57,10 +66,14 @@ func TestSkipEmptyStack(t *testing.T) {
|
||||||
allSecrets := []string{objectName("bar", "secret1")}
|
allSecrets := []string{objectName("bar", "secret1")}
|
||||||
allSecretIDs := buildObjectIDs(allSecrets)
|
allSecretIDs := buildObjectIDs(allSecrets)
|
||||||
|
|
||||||
|
allConfigs := []string{objectName("bar", "config1")}
|
||||||
|
allConfigIDs := buildObjectIDs(allConfigs)
|
||||||
|
|
||||||
cli := &fakeClient{
|
cli := &fakeClient{
|
||||||
services: allServices,
|
services: allServices,
|
||||||
networks: allNetworks,
|
networks: allNetworks,
|
||||||
secrets: allSecrets,
|
secrets: allSecrets,
|
||||||
|
configs: allConfigs,
|
||||||
}
|
}
|
||||||
cmd := newRemoveCommand(test.NewFakeCli(cli, buf))
|
cmd := newRemoveCommand(test.NewFakeCli(cli, buf))
|
||||||
cmd.SetArgs([]string{"foo", "bar"})
|
cmd.SetArgs([]string{"foo", "bar"})
|
||||||
|
@ -70,6 +83,7 @@ func TestSkipEmptyStack(t *testing.T) {
|
||||||
assert.Equal(t, allServiceIDs, cli.removedServices)
|
assert.Equal(t, allServiceIDs, cli.removedServices)
|
||||||
assert.Equal(t, allNetworkIDs, cli.removedNetworks)
|
assert.Equal(t, allNetworkIDs, cli.removedNetworks)
|
||||||
assert.Equal(t, allSecretIDs, cli.removedSecrets)
|
assert.Equal(t, allSecretIDs, cli.removedSecrets)
|
||||||
|
assert.Equal(t, allConfigIDs, cli.removedConfigs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContinueAfterError(t *testing.T) {
|
func TestContinueAfterError(t *testing.T) {
|
||||||
|
@ -82,11 +96,15 @@ func TestContinueAfterError(t *testing.T) {
|
||||||
allSecrets := []string{objectName("foo", "secret1"), objectName("bar", "secret1")}
|
allSecrets := []string{objectName("foo", "secret1"), objectName("bar", "secret1")}
|
||||||
allSecretIDs := buildObjectIDs(allSecrets)
|
allSecretIDs := buildObjectIDs(allSecrets)
|
||||||
|
|
||||||
|
allConfigs := []string{objectName("foo", "config1"), objectName("bar", "config1")}
|
||||||
|
allConfigIDs := buildObjectIDs(allConfigs)
|
||||||
|
|
||||||
removedServices := []string{}
|
removedServices := []string{}
|
||||||
cli := &fakeClient{
|
cli := &fakeClient{
|
||||||
services: allServices,
|
services: allServices,
|
||||||
networks: allNetworks,
|
networks: allNetworks,
|
||||||
secrets: allSecrets,
|
secrets: allSecrets,
|
||||||
|
configs: allConfigs,
|
||||||
|
|
||||||
serviceRemoveFunc: func(serviceID string) error {
|
serviceRemoveFunc: func(serviceID string) error {
|
||||||
removedServices = append(removedServices, serviceID)
|
removedServices = append(removedServices, serviceID)
|
||||||
|
@ -104,4 +122,5 @@ func TestContinueAfterError(t *testing.T) {
|
||||||
assert.Equal(t, allServiceIDs, removedServices)
|
assert.Equal(t, allServiceIDs, removedServices)
|
||||||
assert.Equal(t, allNetworkIDs, cli.removedNetworks)
|
assert.Equal(t, allNetworkIDs, cli.removedNetworks)
|
||||||
assert.Equal(t, allSecretIDs, cli.removedSecrets)
|
assert.Equal(t, allSecretIDs, cli.removedSecrets)
|
||||||
|
assert.Equal(t, allConfigIDs, cli.removedConfigs)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue