ソースを参照

`Ps` return ContainerSummary, not Services

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 5 年 前
コミット
1d859dc807

+ 21 - 3
aci/compose.go

@@ -29,6 +29,7 @@ import (
 	"github.com/docker/compose-cli/api/compose"
 	"github.com/docker/compose-cli/api/compose"
 	"github.com/docker/compose-cli/context/store"
 	"github.com/docker/compose-cli/context/store"
 	"github.com/docker/compose-cli/errdefs"
 	"github.com/docker/compose-cli/errdefs"
+	"github.com/docker/compose-cli/utils/formatter"
 )
 )
 
 
 type aciComposeService struct {
 type aciComposeService struct {
@@ -119,7 +120,7 @@ func (cs *aciComposeService) Down(ctx context.Context, project string) error {
 	return err
 	return err
 }
 }
 
 
-func (cs *aciComposeService) Ps(ctx context.Context, project string) ([]compose.ServiceStatus, error) {
+func (cs *aciComposeService) Ps(ctx context.Context, project string) ([]compose.ContainerSummary, error) {
 	groupsClient, err := login.NewContainerGroupsClient(cs.ctx.SubscriptionID)
 	groupsClient, err := login.NewContainerGroupsClient(cs.ctx.SubscriptionID)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -134,12 +135,29 @@ func (cs *aciComposeService) Ps(ctx context.Context, project string) ([]compose.
 		return nil, fmt.Errorf("no containers found in ACI container group %s", project)
 		return nil, fmt.Errorf("no containers found in ACI container group %s", project)
 	}
 	}
 
 
-	res := []compose.ServiceStatus{}
+	res := []compose.ContainerSummary{}
 	for _, container := range *group.Containers {
 	for _, container := range *group.Containers {
 		if isContainerVisible(container, group, false) {
 		if isContainerVisible(container, group, false) {
 			continue
 			continue
 		}
 		}
-		res = append(res, convert.ContainerGroupToServiceStatus(getContainerID(group, container), group, container, cs.ctx.Location))
+		var publishers []compose.PortPublisher
+		urls := formatter.PortsToStrings(convert.ToPorts(group.IPAddress, *container.Ports), convert.FQDN(group, cs.ctx.Location))
+		for i, p := range *container.Ports {
+			publishers = append(publishers, compose.PortPublisher{
+				URL:           urls[i],
+				TargetPort:    int(*p.Port),
+				PublishedPort: int(*p.Port),
+				Protocol:      string(p.Protocol),
+			})
+		}
+		res = append(res, compose.ContainerSummary{
+			ID:         *container.Name,
+			Name:       *container.Name,
+			Project:    project,
+			Service:    *container.Name,
+			State:      convert.GetStatus(container, group),
+			Publishers: publishers,
+		})
 	}
 	}
 	return res, nil
 	return res, nil
 }
 }

+ 4 - 3
aci/convert/convert.go

@@ -314,13 +314,14 @@ func ContainerGroupToServiceStatus(containerID string, group containerinstance.C
 	return compose.ServiceStatus{
 	return compose.ServiceStatus{
 		ID:       containerID,
 		ID:       containerID,
 		Name:     *container.Name,
 		Name:     *container.Name,
-		Ports:    formatter.PortsToStrings(ToPorts(group.IPAddress, *container.Ports), fqdn(group, region)),
+		Ports:    formatter.PortsToStrings(ToPorts(group.IPAddress, *container.Ports), FQDN(group, region)),
 		Replicas: replicas,
 		Replicas: replicas,
 		Desired:  1,
 		Desired:  1,
 	}
 	}
 }
 }
 
 
-func fqdn(group containerinstance.ContainerGroup, region string) string {
+// FQDN retrieve the fully qualified domain name for a ContainerGroup
+func FQDN(group containerinstance.ContainerGroup, region string) string {
 	fqdn := ""
 	fqdn := ""
 	if group.IPAddress != nil && group.IPAddress.DNSNameLabel != nil && *group.IPAddress.DNSNameLabel != "" {
 	if group.IPAddress != nil && group.IPAddress.DNSNameLabel != nil && *group.IPAddress.DNSNameLabel != "" {
 		fqdn = *group.IPAddress.DNSNameLabel + "." + region + ".azurecontainer.io"
 		fqdn = *group.IPAddress.DNSNameLabel + "." + region + ".azurecontainer.io"
@@ -348,7 +349,7 @@ func ContainerGroupToContainer(containerID string, cg containerinstance.Containe
 
 
 	hostConfig := ToHostConfig(cc, cg)
 	hostConfig := ToHostConfig(cc, cg)
 	config := &containers.RuntimeConfig{
 	config := &containers.RuntimeConfig{
-		FQDN: fqdn(cg, region),
+		FQDN: FQDN(cg, region),
 		Env:  envVars,
 		Env:  envVars,
 	}
 	}
 
 

+ 1 - 1
api/client/compose.go

@@ -60,7 +60,7 @@ func (c *composeService) Logs(context.Context, string, compose.LogConsumer) erro
 	return errdefs.ErrNotImplemented
 	return errdefs.ErrNotImplemented
 }
 }
 
 
-func (c *composeService) Ps(context.Context, string) ([]compose.ServiceStatus, error) {
+func (c *composeService) Ps(context.Context, string) ([]compose.ContainerSummary, error) {
 	return nil, errdefs.ErrNotImplemented
 	return nil, errdefs.ErrNotImplemented
 }
 }
 
 

+ 11 - 1
api/compose/api.go

@@ -41,7 +41,7 @@ type Service interface {
 	// Logs executes the equivalent to a `compose logs`
 	// Logs executes the equivalent to a `compose logs`
 	Logs(ctx context.Context, projectName string, consumer LogConsumer) error
 	Logs(ctx context.Context, projectName string, consumer LogConsumer) error
 	// Ps executes the equivalent to a `compose ps`
 	// Ps executes the equivalent to a `compose ps`
-	Ps(ctx context.Context, projectName string) ([]ServiceStatus, error)
+	Ps(ctx context.Context, projectName string) ([]ContainerSummary, error)
 	// List executes the equivalent to a `docker stack ls`
 	// List executes the equivalent to a `docker stack ls`
 	List(ctx context.Context, projectName string) ([]Stack, error)
 	List(ctx context.Context, projectName string) ([]Stack, error)
 	// Convert translate compose model into backend's native format
 	// Convert translate compose model into backend's native format
@@ -56,6 +56,16 @@ type PortPublisher struct {
 	Protocol      string
 	Protocol      string
 }
 }
 
 
+// ContainerSummary hold high-level description of a container
+type ContainerSummary struct {
+	ID         string
+	Name       string
+	Project    string
+	Service    string
+	State      string
+	Publishers []PortPublisher
+}
+
 // ServiceStatus hold status about a service
 // ServiceStatus hold status about a service
 type ServiceStatus struct {
 type ServiceStatus struct {
 	ID         string
 	ID         string

+ 20 - 30
cli/cmd/compose/ps.go

@@ -21,12 +21,12 @@ import (
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"os"
 	"os"
+	"sort"
 	"strings"
 	"strings"
 
 
 	"github.com/spf13/cobra"
 	"github.com/spf13/cobra"
 
 
 	"github.com/docker/compose-cli/api/client"
 	"github.com/docker/compose-cli/api/client"
-	"github.com/docker/compose-cli/api/compose"
 	"github.com/docker/compose-cli/formatter"
 	"github.com/docker/compose-cli/formatter"
 )
 )
 
 
@@ -54,44 +54,34 @@ func runPs(ctx context.Context, opts composeOptions) error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	serviceList, err := c.ComposeService().Ps(ctx, projectName)
+	containers, err := c.ComposeService().Ps(ctx, projectName)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 	if opts.Quiet {
 	if opts.Quiet {
-		for _, s := range serviceList {
+		for _, s := range containers {
 			fmt.Println(s.ID)
 			fmt.Println(s.ID)
 		}
 		}
 		return nil
 		return nil
 	}
 	}
-	view := viewFromServiceStatusList(serviceList)
-	return formatter.Print(view, opts.Format, os.Stdout,
+
+	sort.Slice(containers, func(i, j int) bool {
+		return containers[i].Name < containers[j].Name
+	})
+
+	return formatter.Print(containers, opts.Format, os.Stdout,
 		func(w io.Writer) {
 		func(w io.Writer) {
-			for _, service := range view {
-				_, _ = fmt.Fprintf(w, "%s\t%s\t%d/%d\t%s\n", service.ID, service.Name, service.Replicas, service.Desired, strings.Join(service.Ports, ", "))
+			for _, container := range containers {
+				var ports []string
+				for _, p := range container.Publishers {
+					if p.URL == "" {
+						ports = append(ports, fmt.Sprintf("%d/%s", p.TargetPort, p.Protocol))
+					} else {
+						ports = append(ports, fmt.Sprintf("%s->%d/%s", p.URL, p.TargetPort, p.Protocol))
+					}
+				}
+				_, _ = fmt.Fprintf(w, "%s\t%s\t%s\n", container.Name, container.State, strings.Join(ports, ", "))
 			}
 			}
 		},
 		},
-		"ID", "NAME", "REPLICAS", "PORTS")
-}
-
-type serviceStatusView struct {
-	ID       string
-	Name     string
-	Replicas int
-	Desired  int
-	Ports    []string
-}
-
-func viewFromServiceStatusList(serviceStatusList []compose.ServiceStatus) []serviceStatusView {
-	retList := make([]serviceStatusView, len(serviceStatusList))
-	for i, s := range serviceStatusList {
-		retList[i] = serviceStatusView{
-			ID:       s.ID,
-			Name:     s.Name,
-			Replicas: s.Replicas,
-			Desired:  s.Desired,
-			Ports:    s.Ports,
-		}
-	}
-	return retList
+		"NAME", "STATE", "PORTS")
 }
 }

+ 1 - 0
ecs/aws.go

@@ -63,6 +63,7 @@ type API interface {
 	DeleteSecret(ctx context.Context, id string, recover bool) error
 	DeleteSecret(ctx context.Context, id string, recover bool) error
 	GetLogs(ctx context.Context, name string, consumer func(service, container, message string)) error
 	GetLogs(ctx context.Context, name string, consumer func(service, container, message string)) error
 	DescribeService(ctx context.Context, cluster string, arn string) (compose.ServiceStatus, error)
 	DescribeService(ctx context.Context, cluster string, arn string) (compose.ServiceStatus, error)
+	DescribeServiceTasks(ctx context.Context, cluster string, project string, service string) ([]compose.ContainerSummary, error)
 	getURLWithPortMapping(ctx context.Context, targetGroupArns []string) ([]compose.PortPublisher, error)
 	getURLWithPortMapping(ctx context.Context, targetGroupArns []string) ([]compose.PortPublisher, error)
 	ListTasks(ctx context.Context, cluster string, family string) ([]string, error)
 	ListTasks(ctx context.Context, cluster string, family string) ([]string, error)
 	GetPublicIPs(ctx context.Context, interfaces ...string) (map[string]string, error)
 	GetPublicIPs(ctx context.Context, interfaces ...string) (map[string]string, error)

+ 15 - 0
ecs/aws_mock.go

@@ -224,6 +224,21 @@ func (mr *MockAPIMockRecorder) DescribeService(arg0, arg1, arg2 interface{}) *go
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeService", reflect.TypeOf((*MockAPI)(nil).DescribeService), arg0, arg1, arg2)
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeService", reflect.TypeOf((*MockAPI)(nil).DescribeService), arg0, arg1, arg2)
 }
 }
 
 
+// DescribeServiceTasks mocks base method
+func (m *MockAPI) DescribeServiceTasks(arg0 context.Context, arg1, arg2, arg3 string) ([]compose.ContainerSummary, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DescribeServiceTasks", arg0, arg1, arg2, arg3)
+	ret0, _ := ret[0].([]compose.ContainerSummary)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DescribeServiceTasks indicates an expected call of DescribeServiceTasks
+func (mr *MockAPIMockRecorder) DescribeServiceTasks(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeServiceTasks", reflect.TypeOf((*MockAPI)(nil).DescribeServiceTasks), arg0, arg1, arg2, arg3)
+}
+
 // DescribeStackEvents mocks base method
 // DescribeStackEvents mocks base method
 func (m *MockAPI) DescribeStackEvents(arg0 context.Context, arg1 string) ([]*cloudformation.StackEvent, error) {
 func (m *MockAPI) DescribeStackEvents(arg0 context.Context, arg1 string) ([]*cloudformation.StackEvent, error) {
 	m.ctrl.T.Helper()
 	m.ctrl.T.Helper()

+ 1 - 1
ecs/local/compose.go

@@ -207,7 +207,7 @@ func (e ecsLocalSimulation) Logs(ctx context.Context, projectName string, consum
 	return cmd.Run()
 	return cmd.Run()
 }
 }
 
 
-func (e ecsLocalSimulation) Ps(ctx context.Context, projectName string) ([]compose.ServiceStatus, error) {
+func (e ecsLocalSimulation) Ps(ctx context.Context, projectName string) ([]compose.ContainerSummary, error) {
 	return nil, errors.Wrap(errdefs.ErrNotImplemented, "use docker-compose ps")
 	return nil, errors.Wrap(errdefs.ErrNotImplemented, "use docker-compose ps")
 }
 }
 func (e ecsLocalSimulation) List(ctx context.Context, projectName string) ([]compose.Stack, error) {
 func (e ecsLocalSimulation) List(ctx context.Context, projectName string) ([]compose.Stack, error) {

+ 14 - 16
ecs/ps.go

@@ -18,13 +18,11 @@ package ecs
 
 
 import (
 import (
 	"context"
 	"context"
-	"fmt"
-	"strings"
 
 
 	"github.com/docker/compose-cli/api/compose"
 	"github.com/docker/compose-cli/api/compose"
 )
 )
 
 
-func (b *ecsAPIService) Ps(ctx context.Context, project string) ([]compose.ServiceStatus, error) {
+func (b *ecsAPIService) Ps(ctx context.Context, project string) ([]compose.ContainerSummary, error) {
 	cluster, err := b.aws.GetStackClusterID(ctx, project)
 	cluster, err := b.aws.GetStackClusterID(ctx, project)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -38,23 +36,23 @@ func (b *ecsAPIService) Ps(ctx context.Context, project string) ([]compose.Servi
 		return nil, nil
 		return nil, nil
 	}
 	}
 
 
-	status := []compose.ServiceStatus{}
+	summary := []compose.ContainerSummary{}
 	for _, arn := range servicesARN {
 	for _, arn := range servicesARN {
-		state, err := b.aws.DescribeService(ctx, cluster, arn)
+		service, err := b.aws.DescribeService(ctx, cluster, arn)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
-		ports := []string{}
-		for _, lb := range state.Publishers {
-			ports = append(ports, fmt.Sprintf(
-				"%s:%d->%d/%s",
-				lb.URL,
-				lb.PublishedPort,
-				lb.TargetPort,
-				strings.ToLower(lb.Protocol)))
+
+		tasks, err := b.aws.DescribeServiceTasks(ctx, cluster, project, service.Name)
+		if err != nil {
+			return nil, err
+		}
+
+		for i, t := range tasks {
+			t.Publishers = service.Publishers
+			tasks[i] = t
 		}
 		}
-		state.Ports = ports
-		status = append(status, state)
+		summary = append(summary, tasks...)
 	}
 	}
-	return status, nil
+	return summary, nil
 }
 }

+ 65 - 2
ecs/sdk.go

@@ -819,6 +819,69 @@ func (s sdk) DescribeService(ctx context.Context, cluster string, arn string) (c
 	}, nil
 	}, nil
 }
 }
 
 
+func (s sdk) DescribeServiceTasks(ctx context.Context, cluster string, project string, service string) ([]compose.ContainerSummary, error) {
+	var summary []compose.ContainerSummary
+	familly := fmt.Sprintf("%s-%s", project, service)
+	var token *string
+	for {
+		list, err := s.ECS.ListTasks(&ecs.ListTasksInput{
+			Cluster:    aws.String(cluster),
+			Family:     aws.String(familly),
+			LaunchType: nil,
+			MaxResults: nil,
+			NextToken:  token,
+		})
+		if err != nil {
+			return nil, err
+		}
+
+		if len(list.TaskArns) == 0 {
+			break
+		}
+		tasks, err := s.ECS.DescribeTasksWithContext(ctx, &ecs.DescribeTasksInput{
+			Cluster: aws.String(cluster),
+			Include: aws.StringSlice([]string{"TAGS"}),
+			Tasks:   list.TaskArns,
+		})
+		if err != nil {
+			return nil, err
+		}
+
+		for _, t := range tasks.Tasks {
+			var project string
+			var service string
+			for _, tag := range t.Tags {
+				switch aws.StringValue(tag.Key) {
+				case compose.ProjectTag:
+					project = aws.StringValue(tag.Value)
+				case compose.ServiceTag:
+					service = aws.StringValue(tag.Value)
+				}
+			}
+
+			id, err := arn.Parse(aws.StringValue(t.TaskArn))
+			if err != nil {
+				return nil, err
+			}
+
+			summary = append(summary, compose.ContainerSummary{
+				ID:      id.String(),
+				Name:    id.Resource,
+				Project: project,
+				Service: service,
+				State:   aws.StringValue(t.LastStatus),
+			})
+		}
+
+		if list.NextToken == token {
+			break
+		}
+		token = list.NextToken
+	}
+
+	return summary, nil
+}
+
 func (s sdk) getURLWithPortMapping(ctx context.Context, targetGroupArns []string) ([]compose.PortPublisher, error) {
 func (s sdk) getURLWithPortMapping(ctx context.Context, targetGroupArns []string) ([]compose.PortPublisher, error) {
 	if len(targetGroupArns) == 0 {
 	if len(targetGroupArns) == 0 {
 		return nil, nil
 		return nil, nil
@@ -861,10 +924,10 @@ func (s sdk) getURLWithPortMapping(ctx context.Context, targetGroupArns []string
 				continue
 				continue
 			}
 			}
 			loadBalancers = append(loadBalancers, compose.PortPublisher{
 			loadBalancers = append(loadBalancers, compose.PortPublisher{
-				URL:           aws.StringValue(lb.DNSName),
+				URL:           fmt.Sprintf("%s:%d", aws.StringValue(lb.DNSName), aws.Int64Value(tg.Port)),
 				TargetPort:    int(aws.Int64Value(tg.Port)),
 				TargetPort:    int(aws.Int64Value(tg.Port)),
 				PublishedPort: int(aws.Int64Value(tg.Port)),
 				PublishedPort: int(aws.Int64Value(tg.Port)),
-				Protocol:      aws.StringValue(tg.Protocol),
+				Protocol:      strings.ToLower(aws.StringValue(tg.Protocol)),
 			})
 			})
 
 
 		}
 		}

+ 1 - 1
example/backend.go

@@ -169,7 +169,7 @@ func (cs *composeService) Down(ctx context.Context, project string) error {
 	return nil
 	return nil
 }
 }
 
 
-func (cs *composeService) Ps(ctx context.Context, project string) ([]compose.ServiceStatus, error) {
+func (cs *composeService) Ps(ctx context.Context, projectName string) ([]compose.ContainerSummary, error) {
 	return nil, errdefs.ErrNotImplemented
 	return nil, errdefs.ErrNotImplemented
 }
 }
 func (cs *composeService) List(ctx context.Context, project string) ([]compose.Stack, error) {
 func (cs *composeService) List(ctx context.Context, project string) ([]compose.Stack, error) {

+ 1 - 0
local/compose/create_test.go

@@ -0,0 +1 @@
+package compose

+ 1 - 0
local/compose/ls_test.go

@@ -0,0 +1 @@
+package compose

+ 29 - 3
local/compose/ps.go

@@ -28,8 +28,8 @@ import (
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/filters"
 )
 )
 
 
-func (s *composeService) Ps(ctx context.Context, projectName string) ([]compose.ServiceStatus, error) {
-	list, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
+func (s *composeService) Ps(ctx context.Context, projectName string) ([]compose.ContainerSummary, error) {
+	containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
 		Filters: filters.NewArgs(
 		Filters: filters.NewArgs(
 			projectFilter(projectName),
 			projectFilter(projectName),
 		),
 		),
@@ -37,7 +37,33 @@ func (s *composeService) Ps(ctx context.Context, projectName string) ([]compose.
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	return containersToServiceStatus(list)
+
+	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)
+			}
+			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:       getContainerName(c),
+			Project:    c.Labels[projectLabel],
+			Service:    c.Labels[serviceLabel],
+			State:      c.State,
+			Publishers: publishers,
+		})
+	}
+	return summary, nil
 }
 }
 
 
 func containersToServiceStatus(containers []moby.Container) ([]compose.ServiceStatus, error) {
 func containersToServiceStatus(containers []moby.Container) ([]compose.ServiceStatus, error) {

+ 4 - 3
server/proxy/compose.go

@@ -54,11 +54,12 @@ func (p *proxy) Services(ctx context.Context, request *composev1.ComposeServices
 		}
 		}
 		projectName = project.Name
 		projectName = project.Name
 	}
 	}
-	services, err := Client(ctx).ComposeService().Ps(ctx, projectName)
+	response := []*composev1.Service{}
+	_, err := Client(ctx).ComposeService().Ps(ctx, projectName)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	response := []*composev1.Service{}
+	/* FIXME need to create `docker service ls` command to re-introduce this feature
 	for _, service := range services {
 	for _, service := range services {
 		response = append(response, &composev1.Service{
 		response = append(response, &composev1.Service{
 			Id:       service.ID,
 			Id:       service.ID,
@@ -67,7 +68,7 @@ func (p *proxy) Services(ctx context.Context, request *composev1.ComposeServices
 			Desired:  uint32(service.Desired),
 			Desired:  uint32(service.Desired),
 			Ports:    service.Ports,
 			Ports:    service.Ports,
 		})
 		})
-	}
+	}*/
 	return &composev1.ComposeServicesResponse{Services: response}, nil
 	return &composev1.ComposeServicesResponse{Services: response}, nil
 }
 }
 
 

+ 3 - 3
tests/aci-e2e/e2e-aci_test.go

@@ -692,7 +692,7 @@ func TestUpUpdate(t *testing.T) {
 		for _, l := range out {
 		for _, l := range out {
 			if strings.Contains(l, serverContainer) {
 			if strings.Contains(l, serverContainer) {
 				webRunning = true
 				webRunning = true
-				strings.Contains(l, ":80->80/tcp")
+				assert.Check(t, strings.Contains(l, ":80->80/tcp"))
 			}
 			}
 		}
 		}
 		assert.Assert(t, webRunning, "web container not running ; ps:\n"+res.Stdout())
 		assert.Assert(t, webRunning, "web container not running ; ps:\n"+res.Stdout())
@@ -738,10 +738,10 @@ func TestUpUpdate(t *testing.T) {
 			switch containerID {
 			switch containerID {
 			case wordsContainer:
 			case wordsContainer:
 				wordsDisplayed = true
 				wordsDisplayed = true
-				assert.DeepEqual(t, fields, []string{containerID, "words", "1/1"})
+				assert.DeepEqual(t, fields, []string{containerID, "words", "Running"})
 			case dbContainer:
 			case dbContainer:
 				dbDisplayed = true
 				dbDisplayed = true
-				assert.DeepEqual(t, fields, []string{containerID, "db", "1/1"})
+				assert.DeepEqual(t, fields, []string{containerID, "db", "Running"})
 			case serverContainer:
 			case serverContainer:
 				webDisplayed = true
 				webDisplayed = true
 				assert.Equal(t, fields[1], "web")
 				assert.Equal(t, fields[1], "web")