github.com/ali-iotechsys/cli@v20.10.0+incompatible/cli/command/stack/swarm/remove.go (about)

     1  package swarm
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"sort"
     7  	"strings"
     8  
     9  	"github.com/docker/cli/cli/command"
    10  	"github.com/docker/cli/cli/command/stack/options"
    11  	"github.com/docker/docker/api/types"
    12  	"github.com/docker/docker/api/types/swarm"
    13  	"github.com/docker/docker/api/types/versions"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  // RunRemove is the swarm implementation of docker stack remove
    18  func RunRemove(dockerCli command.Cli, opts options.Remove) error {
    19  	client := dockerCli.Client()
    20  	ctx := context.Background()
    21  
    22  	var errs []string
    23  	for _, namespace := range opts.Namespaces {
    24  		services, err := getStackServices(ctx, client, namespace)
    25  		if err != nil {
    26  			return err
    27  		}
    28  
    29  		networks, err := getStackNetworks(ctx, client, namespace)
    30  		if err != nil {
    31  			return err
    32  		}
    33  
    34  		var secrets []swarm.Secret
    35  		if versions.GreaterThanOrEqualTo(client.ClientVersion(), "1.25") {
    36  			secrets, err = getStackSecrets(ctx, client, namespace)
    37  			if err != nil {
    38  				return err
    39  			}
    40  		}
    41  
    42  		var configs []swarm.Config
    43  		if versions.GreaterThanOrEqualTo(client.ClientVersion(), "1.30") {
    44  			configs, err = getStackConfigs(ctx, client, namespace)
    45  			if err != nil {
    46  				return err
    47  			}
    48  		}
    49  
    50  		if len(services)+len(networks)+len(secrets)+len(configs) == 0 {
    51  			fmt.Fprintf(dockerCli.Err(), "Nothing found in stack: %s\n", namespace)
    52  			continue
    53  		}
    54  
    55  		hasError := removeServices(ctx, dockerCli, services)
    56  		hasError = removeSecrets(ctx, dockerCli, secrets) || hasError
    57  		hasError = removeConfigs(ctx, dockerCli, configs) || hasError
    58  		hasError = removeNetworks(ctx, dockerCli, networks) || hasError
    59  
    60  		if hasError {
    61  			errs = append(errs, fmt.Sprintf("Failed to remove some resources from stack: %s", namespace))
    62  		}
    63  	}
    64  
    65  	if len(errs) > 0 {
    66  		return errors.Errorf(strings.Join(errs, "\n"))
    67  	}
    68  	return nil
    69  }
    70  
    71  func sortServiceByName(services []swarm.Service) func(i, j int) bool {
    72  	return func(i, j int) bool {
    73  		return services[i].Spec.Name < services[j].Spec.Name
    74  	}
    75  }
    76  
    77  func removeServices(
    78  	ctx context.Context,
    79  	dockerCli command.Cli,
    80  	services []swarm.Service,
    81  ) bool {
    82  	var hasError bool
    83  	sort.Slice(services, sortServiceByName(services))
    84  	for _, service := range services {
    85  		fmt.Fprintf(dockerCli.Out(), "Removing service %s\n", service.Spec.Name)
    86  		if err := dockerCli.Client().ServiceRemove(ctx, service.ID); err != nil {
    87  			hasError = true
    88  			fmt.Fprintf(dockerCli.Err(), "Failed to remove service %s: %s", service.ID, err)
    89  		}
    90  	}
    91  	return hasError
    92  }
    93  
    94  func removeNetworks(
    95  	ctx context.Context,
    96  	dockerCli command.Cli,
    97  	networks []types.NetworkResource,
    98  ) bool {
    99  	var hasError bool
   100  	for _, network := range networks {
   101  		fmt.Fprintf(dockerCli.Out(), "Removing network %s\n", network.Name)
   102  		if err := dockerCli.Client().NetworkRemove(ctx, network.ID); err != nil {
   103  			hasError = true
   104  			fmt.Fprintf(dockerCli.Err(), "Failed to remove network %s: %s", network.ID, err)
   105  		}
   106  	}
   107  	return hasError
   108  }
   109  
   110  func removeSecrets(
   111  	ctx context.Context,
   112  	dockerCli command.Cli,
   113  	secrets []swarm.Secret,
   114  ) bool {
   115  	var hasError bool
   116  	for _, secret := range secrets {
   117  		fmt.Fprintf(dockerCli.Out(), "Removing secret %s\n", secret.Spec.Name)
   118  		if err := dockerCli.Client().SecretRemove(ctx, secret.ID); err != nil {
   119  			hasError = true
   120  			fmt.Fprintf(dockerCli.Err(), "Failed to remove secret %s: %s", secret.ID, err)
   121  		}
   122  	}
   123  	return hasError
   124  }
   125  
   126  func removeConfigs(
   127  	ctx context.Context,
   128  	dockerCli command.Cli,
   129  	configs []swarm.Config,
   130  ) bool {
   131  	var hasError bool
   132  	for _, config := range configs {
   133  		fmt.Fprintf(dockerCli.Out(), "Removing config %s\n", config.Spec.Name)
   134  		if err := dockerCli.Client().ConfigRemove(ctx, config.ID); err != nil {
   135  			hasError = true
   136  			fmt.Fprintf(dockerCli.Err(), "Failed to remove config %s: %s", config.ID, err)
   137  		}
   138  	}
   139  	return hasError
   140  }