Add support for --detach/-d flag in stack rm

Added --detach/-d to stack rm. Setting --detach=false waits until
all of the stack tasks have reached a terminal state.

Co-authored-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: George Margaritis <gmargaritis@protonmail.com>
This commit is contained in:
George Margaritis 2023-05-05 15:36:36 +03:00 committed by Sebastiaan van Stijn
parent 4a43b8eaed
commit 238d659ff9
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
5 changed files with 65 additions and 0 deletions

View File

@ -38,6 +38,7 @@ type PS struct {
// Remove holds docker stack remove options // Remove holds docker stack remove options
type Remove struct { type Remove struct {
Namespaces []string Namespaces []string
Detach bool
} }
// Services holds docker stack services options // Services holds docker stack services options

View File

@ -27,5 +27,8 @@ func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
return completeNames(dockerCli)(cmd, args, toComplete) return completeNames(dockerCli)(cmd, args, toComplete)
}, },
} }
flags := cmd.Flags()
flags.BoolVarP(&opts.Detach, "detach", "d", true, "Do not wait for stack removal")
return cmd return cmd
} }

View File

@ -44,3 +44,7 @@ func getStackSecrets(ctx context.Context, apiclient client.APIClient, namespace
func getStackConfigs(ctx context.Context, apiclient client.APIClient, namespace string) ([]swarm.Config, error) { func getStackConfigs(ctx context.Context, apiclient client.APIClient, namespace string) ([]swarm.Config, error) {
return apiclient.ConfigList(ctx, types.ConfigListOptions{Filters: getStackFilter(namespace)}) return apiclient.ConfigList(ctx, types.ConfigListOptions{Filters: getStackFilter(namespace)})
} }
func getStackTasks(ctx context.Context, apiclient client.APIClient, namespace string) ([]swarm.Task, error) {
return apiclient.TaskList(ctx, types.TaskListOptions{Filters: getStackFilter(namespace)})
}

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
apiclient "github.com/docker/docker/client"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -58,6 +59,14 @@ func RunRemove(ctx context.Context, dockerCli command.Cli, opts options.Remove)
if hasError { if hasError {
errs = append(errs, fmt.Sprintf("Failed to remove some resources from stack: %s", namespace)) errs = append(errs, fmt.Sprintf("Failed to remove some resources from stack: %s", namespace))
continue
}
if !opts.Detach {
err = waitOnTasks(ctx, client, namespace)
if err != nil {
errs = append(errs, fmt.Sprintf("Failed to wait on tasks of stack: %s: %s", namespace, err))
}
} }
} }
@ -137,3 +146,45 @@ func removeConfigs(
} }
return hasError return hasError
} }
var numberedStates = map[swarm.TaskState]int64{
swarm.TaskStateNew: 1,
swarm.TaskStateAllocated: 2,
swarm.TaskStatePending: 3,
swarm.TaskStateAssigned: 4,
swarm.TaskStateAccepted: 5,
swarm.TaskStatePreparing: 6,
swarm.TaskStateReady: 7,
swarm.TaskStateStarting: 8,
swarm.TaskStateRunning: 9,
swarm.TaskStateComplete: 10,
swarm.TaskStateShutdown: 11,
swarm.TaskStateFailed: 12,
swarm.TaskStateRejected: 13,
}
func terminalState(state swarm.TaskState) bool {
return numberedStates[state] > numberedStates[swarm.TaskStateRunning]
}
func waitOnTasks(ctx context.Context, client apiclient.APIClient, namespace string) error {
terminalStatesReached := 0
for {
tasks, err := getStackTasks(ctx, client, namespace)
if err != nil {
return fmt.Errorf("failed to get tasks: %w", err)
}
for _, task := range tasks {
if terminalState(task.Status.State) {
terminalStatesReached++
break
}
}
if terminalStatesReached == len(tasks) {
break
}
}
return nil
}

View File

@ -7,6 +7,12 @@ Remove one or more stacks
`docker stack rm`, `docker stack remove`, `docker stack down` `docker stack rm`, `docker stack remove`, `docker stack down`
### Options
| Name | Type | Default | Description |
|:-----------------|:-------|:--------|:------------------------------|
| `-d`, `--detach` | `bool` | `true` | Do not wait for stack removal |
<!---MARKER_GEN_END--> <!---MARKER_GEN_END-->