123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- package stack
- import (
- "fmt"
- "io"
- "strconv"
- "text/tabwriter"
- "golang.org/x/net/context"
- "github.com/docker/docker/api/types"
- "github.com/docker/docker/api/types/filters"
- "github.com/docker/docker/cli"
- "github.com/docker/docker/cli/command"
- "github.com/docker/docker/client"
- "github.com/spf13/cobra"
- )
- const (
- listItemFmt = "%s\t%s\n"
- )
- type listOptions struct {
- }
- func newListCommand(dockerCli *command.DockerCli) *cobra.Command {
- opts := listOptions{}
- cmd := &cobra.Command{
- Use: "ls",
- Aliases: []string{"list"},
- Short: "List stacks",
- Args: cli.NoArgs,
- RunE: func(cmd *cobra.Command, args []string) error {
- return runList(dockerCli, opts)
- },
- }
- return cmd
- }
- func runList(dockerCli *command.DockerCli, opts listOptions) error {
- client := dockerCli.Client()
- ctx := context.Background()
- stacks, err := getStacks(ctx, client)
- if err != nil {
- return err
- }
- out := dockerCli.Out()
- printTable(out, stacks)
- return nil
- }
- func printTable(out io.Writer, stacks []*stack) {
- writer := tabwriter.NewWriter(out, 0, 4, 2, ' ', 0)
- // Ignore flushing errors
- defer writer.Flush()
- fmt.Fprintf(writer, listItemFmt, "NAME", "SERVICES")
- for _, stack := range stacks {
- fmt.Fprintf(
- writer,
- listItemFmt,
- stack.Name,
- strconv.Itoa(stack.Services),
- )
- }
- }
- type stack struct {
- // Name is the name of the stack
- Name string
- // Services is the number of the services
- Services int
- }
- func getStacks(
- ctx context.Context,
- apiclient client.APIClient,
- ) ([]*stack, error) {
- filter := filters.NewArgs()
- filter.Add("label", labelNamespace)
- services, err := apiclient.ServiceList(
- ctx,
- types.ServiceListOptions{Filters: filter})
- if err != nil {
- return nil, err
- }
- m := make(map[string]*stack, 0)
- for _, service := range services {
- labels := service.Spec.Labels
- name, ok := labels[labelNamespace]
- if !ok {
- return nil, fmt.Errorf("cannot get label %s for service %s",
- labelNamespace, service.ID)
- }
- ztack, ok := m[name]
- if !ok {
- m[name] = &stack{
- Name: name,
- Services: 1,
- }
- } else {
- ztack.Services++
- }
- }
- var stacks []*stack
- for _, stack := range m {
- stacks = append(stacks, stack)
- }
- return stacks, nil
- }
|