Browse Source

api/client/service: list running services over replicas

To provide users a view of service status, list the number of running
task over the requested number of replicas.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
Stephen J Day 9 years ago
parent
commit
b86cb293ec
1 changed files with 27 additions and 11 deletions
  1. 27 11
      api/client/service/list.go

+ 27 - 11
api/client/service/list.go

@@ -6,15 +6,15 @@ import (
 	"strings"
 	"strings"
 	"text/tabwriter"
 	"text/tabwriter"
 
 
-	"golang.org/x/net/context"
-
 	"github.com/docker/docker/api/client"
 	"github.com/docker/docker/api/client"
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/engine-api/types"
 	"github.com/docker/engine-api/types"
+	"github.com/docker/engine-api/types/filters"
 	"github.com/docker/engine-api/types/swarm"
 	"github.com/docker/engine-api/types/swarm"
 	"github.com/spf13/cobra"
 	"github.com/spf13/cobra"
+	"golang.org/x/net/context"
 )
 )
 
 
 const (
 const (
@@ -47,11 +47,10 @@ func newListCommand(dockerCli *client.DockerCli) *cobra.Command {
 }
 }
 
 
 func runList(dockerCli *client.DockerCli, opts listOptions) error {
 func runList(dockerCli *client.DockerCli, opts listOptions) error {
+	ctx := context.Background()
 	client := dockerCli.Client()
 	client := dockerCli.Client()
 
 
-	services, err := client.ServiceList(
-		context.Background(),
-		types.ServiceListOptions{Filter: opts.filter.Value()})
+	services, err := client.ServiceList(ctx, types.ServiceListOptions{Filter: opts.filter.Value()})
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -60,12 +59,29 @@ func runList(dockerCli *client.DockerCli, opts listOptions) error {
 	if opts.quiet {
 	if opts.quiet {
 		printQuiet(out, services)
 		printQuiet(out, services)
 	} else {
 	} else {
-		printTable(out, services)
+		taskFilter := filters.NewArgs()
+		for _, service := range services {
+			taskFilter.Add("service", service.ID)
+		}
+
+		tasks, err := client.TaskList(ctx, types.TaskListOptions{Filter: taskFilter})
+		if err != nil {
+			return err
+		}
+
+		running := map[string]int{}
+		for _, task := range tasks {
+			if task.Status.State == "running" {
+				running[task.ServiceID]++
+			}
+		}
+
+		printTable(out, services, running)
 	}
 	}
 	return nil
 	return nil
 }
 }
 
 
-func printTable(out io.Writer, services []swarm.Service) {
+func printTable(out io.Writer, services []swarm.Service, running map[string]int) {
 	writer := tabwriter.NewWriter(out, 0, 4, 2, ' ', 0)
 	writer := tabwriter.NewWriter(out, 0, 4, 2, ' ', 0)
 
 
 	// Ignore flushing errors
 	// Ignore flushing errors
@@ -73,18 +89,18 @@ func printTable(out io.Writer, services []swarm.Service) {
 
 
 	fmt.Fprintf(writer, listItemFmt, "ID", "NAME", "REPLICAS", "IMAGE", "COMMAND")
 	fmt.Fprintf(writer, listItemFmt, "ID", "NAME", "REPLICAS", "IMAGE", "COMMAND")
 	for _, service := range services {
 	for _, service := range services {
-		scale := ""
+		replicas := ""
 		if service.Spec.Mode.Replicated != nil && service.Spec.Mode.Replicated.Replicas != nil {
 		if service.Spec.Mode.Replicated != nil && service.Spec.Mode.Replicated.Replicas != nil {
-			scale = fmt.Sprintf("%d", *service.Spec.Mode.Replicated.Replicas)
+			replicas = fmt.Sprintf("%d/%d", running[service.ID], *service.Spec.Mode.Replicated.Replicas)
 		} else if service.Spec.Mode.Global != nil {
 		} else if service.Spec.Mode.Global != nil {
-			scale = "global"
+			replicas = "global"
 		}
 		}
 		fmt.Fprintf(
 		fmt.Fprintf(
 			writer,
 			writer,
 			listItemFmt,
 			listItemFmt,
 			stringid.TruncateID(service.ID),
 			stringid.TruncateID(service.ID),
 			service.Spec.Name,
 			service.Spec.Name,
-			scale,
+			replicas,
 			service.Spec.TaskTemplate.ContainerSpec.Image,
 			service.Spec.TaskTemplate.ContainerSpec.Image,
 			strings.Join(service.Spec.TaskTemplate.ContainerSpec.Args, " "))
 			strings.Join(service.Spec.TaskTemplate.ContainerSpec.Args, " "))
 	}
 	}