github.com/kunnos/engine@v1.13.1/cli/command/node/list.go (about)

     1  package node
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"text/tabwriter"
     7  
     8  	"golang.org/x/net/context"
     9  
    10  	"github.com/docker/docker/api/types"
    11  	"github.com/docker/docker/api/types/swarm"
    12  	"github.com/docker/docker/cli"
    13  	"github.com/docker/docker/cli/command"
    14  	"github.com/docker/docker/opts"
    15  	"github.com/spf13/cobra"
    16  )
    17  
    18  const (
    19  	listItemFmt = "%s\t%s\t%s\t%s\t%s\n"
    20  )
    21  
    22  type listOptions struct {
    23  	quiet  bool
    24  	filter opts.FilterOpt
    25  }
    26  
    27  func newListCommand(dockerCli *command.DockerCli) *cobra.Command {
    28  	opts := listOptions{filter: opts.NewFilterOpt()}
    29  
    30  	cmd := &cobra.Command{
    31  		Use:     "ls [OPTIONS]",
    32  		Aliases: []string{"list"},
    33  		Short:   "List nodes in the swarm",
    34  		Args:    cli.NoArgs,
    35  		RunE: func(cmd *cobra.Command, args []string) error {
    36  			return runList(dockerCli, opts)
    37  		},
    38  	}
    39  	flags := cmd.Flags()
    40  	flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only display IDs")
    41  	flags.VarP(&opts.filter, "filter", "f", "Filter output based on conditions provided")
    42  
    43  	return cmd
    44  }
    45  
    46  func runList(dockerCli *command.DockerCli, opts listOptions) error {
    47  	client := dockerCli.Client()
    48  	out := dockerCli.Out()
    49  	ctx := context.Background()
    50  
    51  	nodes, err := client.NodeList(
    52  		ctx,
    53  		types.NodeListOptions{Filters: opts.filter.Value()})
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	if len(nodes) > 0 && !opts.quiet {
    59  		// only non-empty nodes and not quiet, should we call /info api
    60  		info, err := client.Info(ctx)
    61  		if err != nil {
    62  			return err
    63  		}
    64  		printTable(out, nodes, info)
    65  	} else if !opts.quiet {
    66  		// no nodes and not quiet, print only one line with columns ID, HOSTNAME, ...
    67  		printTable(out, nodes, types.Info{})
    68  	} else {
    69  		printQuiet(out, nodes)
    70  	}
    71  
    72  	return nil
    73  }
    74  
    75  func printTable(out io.Writer, nodes []swarm.Node, info types.Info) {
    76  	writer := tabwriter.NewWriter(out, 0, 4, 2, ' ', 0)
    77  
    78  	// Ignore flushing errors
    79  	defer writer.Flush()
    80  
    81  	fmt.Fprintf(writer, listItemFmt, "ID", "HOSTNAME", "STATUS", "AVAILABILITY", "MANAGER STATUS")
    82  	for _, node := range nodes {
    83  		name := node.Description.Hostname
    84  		availability := string(node.Spec.Availability)
    85  
    86  		reachability := ""
    87  		if node.ManagerStatus != nil {
    88  			if node.ManagerStatus.Leader {
    89  				reachability = "Leader"
    90  			} else {
    91  				reachability = string(node.ManagerStatus.Reachability)
    92  			}
    93  		}
    94  
    95  		ID := node.ID
    96  		if node.ID == info.Swarm.NodeID {
    97  			ID = ID + " *"
    98  		}
    99  
   100  		fmt.Fprintf(
   101  			writer,
   102  			listItemFmt,
   103  			ID,
   104  			name,
   105  			command.PrettyPrint(string(node.Status.State)),
   106  			command.PrettyPrint(availability),
   107  			command.PrettyPrint(reachability))
   108  	}
   109  }
   110  
   111  func printQuiet(out io.Writer, nodes []swarm.Node) {
   112  	for _, node := range nodes {
   113  		fmt.Fprintln(out, node.ID)
   114  	}
   115  }