remove.go 2.7 KB

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