remove.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package stack
  2. import (
  3. "fmt"
  4. "github.com/docker/docker/api/types"
  5. "github.com/docker/docker/api/types/swarm"
  6. "github.com/docker/docker/cli"
  7. "github.com/docker/docker/cli/command"
  8. "github.com/pkg/errors"
  9. "github.com/spf13/cobra"
  10. "golang.org/x/net/context"
  11. )
  12. type removeOptions struct {
  13. namespace string
  14. }
  15. func newRemoveCommand(dockerCli *command.DockerCli) *cobra.Command {
  16. var opts removeOptions
  17. cmd := &cobra.Command{
  18. Use: "rm STACK",
  19. Aliases: []string{"remove", "down"},
  20. Short: "Remove the stack",
  21. Args: cli.ExactArgs(1),
  22. RunE: func(cmd *cobra.Command, args []string) error {
  23. opts.namespace = args[0]
  24. return runRemove(dockerCli, opts)
  25. },
  26. }
  27. return cmd
  28. }
  29. func runRemove(dockerCli *command.DockerCli, opts removeOptions) error {
  30. namespace := opts.namespace
  31. client := dockerCli.Client()
  32. ctx := context.Background()
  33. services, err := getServices(ctx, client, namespace)
  34. if err != nil {
  35. return err
  36. }
  37. networks, err := getStackNetworks(ctx, client, namespace)
  38. if err != nil {
  39. return err
  40. }
  41. secrets, err := getStackSecrets(ctx, client, namespace)
  42. if err != nil {
  43. return err
  44. }
  45. if len(services)+len(networks)+len(secrets) == 0 {
  46. fmt.Fprintf(dockerCli.Out(), "Nothing found in stack: %s\n", namespace)
  47. return nil
  48. }
  49. hasError := removeServices(ctx, dockerCli, services)
  50. hasError = removeSecrets(ctx, dockerCli, secrets) || hasError
  51. hasError = removeNetworks(ctx, dockerCli, networks) || hasError
  52. if hasError {
  53. return errors.Errorf("Failed to remove some resources")
  54. }
  55. return nil
  56. }
  57. func removeServices(
  58. ctx context.Context,
  59. dockerCli command.Cli,
  60. services []swarm.Service,
  61. ) bool {
  62. var err error
  63. for _, service := range services {
  64. fmt.Fprintf(dockerCli.Err(), "Removing service %s\n", service.Spec.Name)
  65. if err = dockerCli.Client().ServiceRemove(ctx, service.ID); err != nil {
  66. fmt.Fprintf(dockerCli.Err(), "Failed to remove service %s: %s", service.ID, err)
  67. }
  68. }
  69. return err != nil
  70. }
  71. func removeNetworks(
  72. ctx context.Context,
  73. dockerCli command.Cli,
  74. networks []types.NetworkResource,
  75. ) bool {
  76. var err error
  77. for _, network := range networks {
  78. fmt.Fprintf(dockerCli.Err(), "Removing network %s\n", network.Name)
  79. if err = dockerCli.Client().NetworkRemove(ctx, network.ID); err != nil {
  80. fmt.Fprintf(dockerCli.Err(), "Failed to remove network %s: %s", network.ID, err)
  81. }
  82. }
  83. return err != nil
  84. }
  85. func removeSecrets(
  86. ctx context.Context,
  87. dockerCli command.Cli,
  88. secrets []swarm.Secret,
  89. ) bool {
  90. var err error
  91. for _, secret := range secrets {
  92. fmt.Fprintf(dockerCli.Err(), "Removing secret %s\n", secret.Spec.Name)
  93. if err = dockerCli.Client().SecretRemove(ctx, secret.ID); err != nil {
  94. fmt.Fprintf(dockerCli.Err(), "Failed to remove secret %s: %s", secret.ID, err)
  95. }
  96. }
  97. return err != nil
  98. }