Files
docker-cli/cli/command/node/list.go
Boaz Shuster 1333b49194 Sort swarm stacks and nodes using natural sorting
This commit changes the order stacks and nodes are displayed.
For example, running "docker stack ls" is expected to
display the following list:

NAME          SERVICES
service-1     1
service-2     1
service-10    1

However, currently this is what is printed:

NAME          SERVICES
service-1     1
service-10    1
service-2     1

To fix this, "docker stack ls" and "docker node ls" are using
natural sorting to make it more human readable.

Signed-off-by: Boaz Shuster <ripcurld.github@gmail.com>
2017-07-13 14:33:02 +03:00

86 lines
2.2 KiB
Go

package node
import (
"sort"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/spf13/cobra"
"golang.org/x/net/context"
"vbom.ml/util/sortorder"
)
type byHostname []swarm.Node
func (n byHostname) Len() int { return len(n) }
func (n byHostname) Swap(i, j int) { n[i], n[j] = n[j], n[i] }
func (n byHostname) Less(i, j int) bool {
return sortorder.NaturalLess(n[i].Description.Hostname, n[j].Description.Hostname)
}
type listOptions struct {
quiet bool
format string
filter opts.FilterOpt
}
func newListCommand(dockerCli command.Cli) *cobra.Command {
options := listOptions{filter: opts.NewFilterOpt()}
cmd := &cobra.Command{
Use: "ls [OPTIONS]",
Aliases: []string{"list"},
Short: "List nodes in the swarm",
Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return runList(dockerCli, options)
},
}
flags := cmd.Flags()
flags.BoolVarP(&options.quiet, "quiet", "q", false, "Only display IDs")
flags.StringVar(&options.format, "format", "", "Pretty-print nodes using a Go template")
flags.VarP(&options.filter, "filter", "f", "Filter output based on conditions provided")
return cmd
}
func runList(dockerCli command.Cli, options listOptions) error {
client := dockerCli.Client()
ctx := context.Background()
nodes, err := client.NodeList(
ctx,
types.NodeListOptions{Filters: options.filter.Value()})
if err != nil {
return err
}
info := types.Info{}
if len(nodes) > 0 && !options.quiet {
// only non-empty nodes and not quiet, should we call /info api
info, err = client.Info(ctx)
if err != nil {
return err
}
}
format := options.format
if len(format) == 0 {
format = formatter.TableFormatKey
if len(dockerCli.ConfigFile().NodesFormat) > 0 && !options.quiet {
format = dockerCli.ConfigFile().NodesFormat
}
}
nodesCtx := formatter.Context{
Output: dockerCli.Out(),
Format: formatter.NewNodeFormat(format, options.quiet),
}
sort.Sort(byHostname(nodes))
return formatter.NodeWrite(nodesCtx, nodes, info)
}