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