github.com/olljanat/moby@v1.13.1/cli/command/stack/remove.go (about)

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