Browse Source

Add HEALTH column to compose ps

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 4 years ago
parent
commit
c4f6b1bd14
3 changed files with 43 additions and 24 deletions
  1. 1 0
      api/compose/api.go
  2. 2 2
      cli/cmd/compose/ps.go
  3. 40 22
      local/compose/ps.go

+ 1 - 0
api/compose/api.go

@@ -106,6 +106,7 @@ type ContainerSummary struct {
 	Project    string
 	Service    string
 	State      string
+	Health     string
 	Publishers []PortPublisher
 }
 

+ 2 - 2
cli/cmd/compose/ps.go

@@ -88,8 +88,8 @@ func runPs(ctx context.Context, opts psOptions) error {
 						ports = append(ports, fmt.Sprintf("%s->%d/%s", p.URL, p.TargetPort, p.Protocol))
 					}
 				}
-				_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", container.Name, container.Service, container.State, strings.Join(ports, ", "))
+				_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", container.Name, container.Service, container.State, container.Health, strings.Join(ports, ", "))
 			}
 		},
-		"NAME", "SERVICE", "STATE", "PORTS")
+		"NAME", "SERVICE", "STATE", "HEALTH", "PORTS")
 }

+ 40 - 22
local/compose/ps.go

@@ -23,6 +23,7 @@ import (
 
 	moby "github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
+	"golang.org/x/sync/errgroup"
 
 	"github.com/docker/compose-cli/api/compose"
 )
@@ -37,32 +38,49 @@ func (s *composeService) Ps(ctx context.Context, projectName string) ([]compose.
 		return nil, err
 	}
 
-	var summary []compose.ContainerSummary
-	for _, c := range containers {
-		var publishers []compose.PortPublisher
-		for _, p := range c.Ports {
-			var url string
-			if p.PublicPort != 0 {
-				url = fmt.Sprintf("%s:%d", p.IP, p.PublicPort)
+	summary := make([]compose.ContainerSummary, len(containers))
+	eg, ctx := errgroup.WithContext(ctx)
+	for i, c := range containers {
+		container := c
+		i := i
+		eg.Go(func() error {
+			var publishers []compose.PortPublisher
+			for _, p := range container.Ports {
+				var url string
+				if p.PublicPort != 0 {
+					url = fmt.Sprintf("%s:%d", p.IP, p.PublicPort)
+				}
+				publishers = append(publishers, compose.PortPublisher{
+					URL:           url,
+					TargetPort:    int(p.PrivatePort),
+					PublishedPort: int(p.PublicPort),
+					Protocol:      p.Type,
+				})
+			}
+
+			inspect, err := s.apiClient.ContainerInspect(ctx, container.ID)
+			if err != nil {
+				return err
 			}
-			publishers = append(publishers, compose.PortPublisher{
-				URL:           url,
-				TargetPort:    int(p.PrivatePort),
-				PublishedPort: int(p.PublicPort),
-				Protocol:      p.Type,
-			})
-		}
 
-		summary = append(summary, compose.ContainerSummary{
-			ID:         c.ID,
-			Name:       getCanonicalContainerName(c),
-			Project:    c.Labels[projectLabel],
-			Service:    c.Labels[serviceLabel],
-			State:      c.State,
-			Publishers: publishers,
+			var health string
+			if inspect.State != nil && inspect.State.Health != nil {
+				health = inspect.State.Health.Status
+			}
+
+			summary[i] = compose.ContainerSummary{
+				ID:         container.ID,
+				Name:       getCanonicalContainerName(container),
+				Project:    container.Labels[projectLabel],
+				Service:    container.Labels[serviceLabel],
+				State:      container.State,
+				Health:     health,
+				Publishers: publishers,
+			}
+			return nil
 		})
 	}
-	return summary, nil
+	return summary, eg.Wait()
 }
 
 func groupContainerByLabel(containers []moby.Container, labelName string) (map[string][]moby.Container, []string, error) {