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

     1  package context
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"sort"
     7  
     8  	"github.com/docker/cli/cli"
     9  	"github.com/docker/cli/cli/command"
    10  	"github.com/docker/cli/cli/command/completion"
    11  	"github.com/docker/cli/cli/command/formatter"
    12  	"github.com/docker/cli/cli/context/docker"
    13  	flagsHelper "github.com/docker/cli/cli/flags"
    14  	"github.com/docker/docker/client"
    15  	"github.com/fvbommel/sortorder"
    16  	"github.com/spf13/cobra"
    17  )
    18  
    19  type listOptions struct {
    20  	format string
    21  	quiet  bool
    22  }
    23  
    24  func newListCommand(dockerCli command.Cli) *cobra.Command {
    25  	opts := &listOptions{}
    26  	cmd := &cobra.Command{
    27  		Use:     "ls [OPTIONS]",
    28  		Aliases: []string{"list"},
    29  		Short:   "List contexts",
    30  		Args:    cli.NoArgs,
    31  		RunE: func(cmd *cobra.Command, args []string) error {
    32  			return runList(dockerCli, opts)
    33  		},
    34  		ValidArgsFunction: completion.NoComplete,
    35  	}
    36  
    37  	flags := cmd.Flags()
    38  	flags.StringVar(&opts.format, "format", "", flagsHelper.FormatHelp)
    39  	flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only show context names")
    40  	return cmd
    41  }
    42  
    43  func runList(dockerCli command.Cli, opts *listOptions) error {
    44  	if opts.format == "" {
    45  		opts.format = formatter.TableFormatKey
    46  	}
    47  	contextMap, err := dockerCli.ContextStore().List()
    48  	if err != nil {
    49  		return err
    50  	}
    51  	var (
    52  		curContext = dockerCli.CurrentContext()
    53  		curFound   bool
    54  		contexts   = make([]*formatter.ClientContext, 0, len(contextMap))
    55  	)
    56  	for _, rawMeta := range contextMap {
    57  		isCurrent := rawMeta.Name == curContext
    58  		if isCurrent {
    59  			curFound = true
    60  		}
    61  		meta, err := command.GetDockerContext(rawMeta)
    62  		if err != nil {
    63  			// Add a stub-entry to the list, including the error-message
    64  			// indicating that the context couldn't be loaded.
    65  			contexts = append(contexts, &formatter.ClientContext{
    66  				Name:    rawMeta.Name,
    67  				Current: isCurrent,
    68  				Error:   err.Error(),
    69  			})
    70  			continue
    71  		}
    72  		var errMsg string
    73  		dockerEndpoint, err := docker.EndpointFromContext(rawMeta)
    74  		if err != nil {
    75  			errMsg = err.Error()
    76  		}
    77  		desc := formatter.ClientContext{
    78  			Name:           rawMeta.Name,
    79  			Current:        isCurrent,
    80  			Description:    meta.Description,
    81  			DockerEndpoint: dockerEndpoint.Host,
    82  			Error:          errMsg,
    83  		}
    84  		contexts = append(contexts, &desc)
    85  	}
    86  	if !curFound {
    87  		// The currently specified context wasn't found. We add a stub-entry
    88  		// to the list, including the error-message indicating that the context
    89  		// wasn't found.
    90  		var errMsg string
    91  		_, err := dockerCli.ContextStore().GetMetadata(curContext)
    92  		if err != nil {
    93  			errMsg = err.Error()
    94  		}
    95  		contexts = append(contexts, &formatter.ClientContext{
    96  			Name:    curContext,
    97  			Current: true,
    98  			Error:   errMsg,
    99  		})
   100  	}
   101  	sort.Slice(contexts, func(i, j int) bool {
   102  		return sortorder.NaturalLess(contexts[i].Name, contexts[j].Name)
   103  	})
   104  	if err := format(dockerCli, opts, contexts); err != nil {
   105  		return err
   106  	}
   107  	if os.Getenv(client.EnvOverrideHost) != "" {
   108  		_, _ = fmt.Fprintf(dockerCli.Err(), "Warning: %[1]s environment variable overrides the active context. "+
   109  			"To use a context, either set the global --context flag, or unset %[1]s environment variable.\n", client.EnvOverrideHost)
   110  	}
   111  	return nil
   112  }
   113  
   114  func format(dockerCli command.Cli, opts *listOptions, contexts []*formatter.ClientContext) error {
   115  	contextCtx := formatter.Context{
   116  		Output: dockerCli.Out(),
   117  		Format: formatter.NewClientContextFormat(opts.format, opts.quiet),
   118  	}
   119  	return formatter.ClientContextWrite(contextCtx, contexts)
   120  }