github.1git.de/docker/cli@v26.1.3+incompatible/cli/command/context/remove.go (about)

     1  package context
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/docker/cli/cli"
     9  	"github.com/docker/cli/cli/command"
    10  	"github.com/docker/docker/errdefs"
    11  	"github.com/pkg/errors"
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  // RemoveOptions are the options used to remove contexts
    16  type RemoveOptions struct {
    17  	Force bool
    18  }
    19  
    20  func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
    21  	var opts RemoveOptions
    22  	cmd := &cobra.Command{
    23  		Use:     "rm CONTEXT [CONTEXT...]",
    24  		Aliases: []string{"remove"},
    25  		Short:   "Remove one or more contexts",
    26  		Args:    cli.RequiresMinArgs(1),
    27  		RunE: func(cmd *cobra.Command, args []string) error {
    28  			return RunRemove(dockerCli, opts, args)
    29  		},
    30  	}
    31  	cmd.Flags().BoolVarP(&opts.Force, "force", "f", false, "Force the removal of a context in use")
    32  	return cmd
    33  }
    34  
    35  // RunRemove removes one or more contexts
    36  func RunRemove(dockerCli command.Cli, opts RemoveOptions, names []string) error {
    37  	var errs []string
    38  	currentCtx := dockerCli.CurrentContext()
    39  	for _, name := range names {
    40  		if name == "default" {
    41  			errs = append(errs, `default: context "default" cannot be removed`)
    42  		} else if err := doRemove(dockerCli, name, name == currentCtx, opts.Force); err != nil {
    43  			errs = append(errs, err.Error())
    44  		} else {
    45  			fmt.Fprintln(dockerCli.Out(), name)
    46  		}
    47  	}
    48  	if len(errs) > 0 {
    49  		return errors.New(strings.Join(errs, "\n"))
    50  	}
    51  	return nil
    52  }
    53  
    54  func doRemove(dockerCli command.Cli, name string, isCurrent, force bool) error {
    55  	if isCurrent {
    56  		if !force {
    57  			return errors.Errorf("context %q is in use, set -f flag to force remove", name)
    58  		}
    59  		// fallback to DOCKER_HOST
    60  		cfg := dockerCli.ConfigFile()
    61  		cfg.CurrentContext = ""
    62  		if err := cfg.Save(); err != nil {
    63  			return err
    64  		}
    65  	}
    66  
    67  	if !force {
    68  		if err := checkContextExists(dockerCli, name); err != nil {
    69  			return err
    70  		}
    71  	}
    72  	return dockerCli.ContextStore().Remove(name)
    73  }
    74  
    75  // checkContextExists returns an error if the context directory does not exist.
    76  func checkContextExists(dockerCli command.Cli, name string) error {
    77  	contextDir := dockerCli.ContextStore().GetStorageInfo(name).MetadataPath
    78  	_, err := os.Stat(contextDir)
    79  	if os.IsNotExist(err) {
    80  		return errdefs.NotFound(errors.Errorf("context %q does not exist", name))
    81  	}
    82  	// Ignore other errors; if relevant, they will produce an error when
    83  	// performing the actual delete.
    84  	return nil
    85  }