diff --git a/pkg/api/dryrunclient.go b/pkg/api/dryrunclient.go index b5ffc8ae6..83d214b5b 100644 --- a/pkg/api/dryrunclient.go +++ b/pkg/api/dryrunclient.go @@ -130,7 +130,7 @@ func (d *DryRunClient) ContainerInspect(ctx context.Context, container string) ( ID: id, Name: container, State: &containerType.State{ - Status: "running", // needed for --wait option + Status: containerType.StateRunning, // needed for --wait option Health: &containerType.Health{ Status: containerType.Healthy, // needed for healthcheck control }, diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index ec90ae544..1fd6ec898 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -828,25 +828,25 @@ func (s *composeService) getLinks(ctx context.Context, projectName string, servi func (s *composeService) isServiceHealthy(ctx context.Context, containers Containers, fallbackRunning bool) (bool, error) { for _, c := range containers { - container, err := s.apiClient().ContainerInspect(ctx, c.ID) + ctr, err := s.apiClient().ContainerInspect(ctx, c.ID) if err != nil { return false, err } - name := container.Name[1:] + name := ctr.Name[1:] - if container.State.Status == "exited" { - return false, fmt.Errorf("container %s exited (%d)", name, container.State.ExitCode) + if ctr.State.Status == containerType.StateExited { + return false, fmt.Errorf("container %s exited (%d)", name, ctr.State.ExitCode) } - if container.Config.Healthcheck == nil && fallbackRunning { + if ctr.Config.Healthcheck == nil && fallbackRunning { // Container does not define a health check, but we can fall back to "running" state - return container.State != nil && container.State.Status == "running", nil + return ctr.State != nil && ctr.State.Status == containerType.StateRunning, nil } - if container.State == nil || container.State.Health == nil { + if ctr.State == nil || ctr.State.Health == nil { return false, fmt.Errorf("container %s has no healthcheck configured", name) } - switch container.State.Health.Status { + switch ctr.State.Health.Status { case containerType.Healthy: // Continue by checking the next container. case containerType.Unhealthy: @@ -854,7 +854,7 @@ func (s *composeService) isServiceHealthy(ctx context.Context, containers Contai case containerType.Starting: return false, nil default: - return false, fmt.Errorf("container %s had unexpected health status %q", name, container.State.Health.Status) + return false, fmt.Errorf("container %s had unexpected health status %q", name, ctr.State.Health.Status) } } return true, nil @@ -862,12 +862,12 @@ func (s *composeService) isServiceHealthy(ctx context.Context, containers Contai func (s *composeService) isServiceCompleted(ctx context.Context, containers Containers) (bool, int, error) { for _, c := range containers { - container, err := s.apiClient().ContainerInspect(ctx, c.ID) + ctr, err := s.apiClient().ContainerInspect(ctx, c.ID) if err != nil { return false, 0, err } - if container.State != nil && container.State.Status == "exited" { - return true, container.State.ExitCode, nil + if ctr.State != nil && ctr.State.Status == containerType.StateExited { + return true, ctr.State.ExitCode, nil } } return false, 0, nil diff --git a/pkg/compose/ps.go b/pkg/compose/ps.go index 72b47e30f..42dfd272b 100644 --- a/pkg/compose/ps.go +++ b/pkg/compose/ps.go @@ -21,6 +21,7 @@ import ( "sort" "strings" + "github.com/docker/docker/api/types/container" "golang.org/x/sync/errgroup" "github.com/docker/compose/v2/pkg/api" @@ -42,13 +43,13 @@ func (s *composeService) Ps(ctx context.Context, projectName string, options api } summary := make([]api.ContainerSummary, len(containers)) eg, ctx := errgroup.WithContext(ctx) - for i, container := range containers { + for i, ctr := range containers { eg.Go(func() error { - publishers := make([]api.PortPublisher, len(container.Ports)) - sort.Slice(container.Ports, func(i, j int) bool { - return container.Ports[i].PrivatePort < container.Ports[j].PrivatePort + publishers := make([]api.PortPublisher, len(ctr.Ports)) + sort.Slice(ctr.Ports, func(i, j int) bool { + return ctr.Ports[i].PrivatePort < ctr.Ports[j].PrivatePort }) - for i, p := range container.Ports { + for i, p := range ctr.Ports { publishers[i] = api.PortPublisher{ URL: p.IP, TargetPort: int(p.PrivatePort), @@ -57,22 +58,22 @@ func (s *composeService) Ps(ctx context.Context, projectName string, options api } } - inspect, err := s.apiClient().ContainerInspect(ctx, container.ID) + inspect, err := s.apiClient().ContainerInspect(ctx, ctr.ID) if err != nil { return err } var ( - health string + health container.HealthStatus exitCode int ) if inspect.State != nil { switch inspect.State.Status { - case "running": + case container.StateRunning: if inspect.State.Health != nil { health = inspect.State.Health.Status } - case "exited", "dead": + case container.StateExited, container.StateDead: exitCode = inspect.State.ExitCode } } @@ -81,7 +82,7 @@ func (s *composeService) Ps(ctx context.Context, projectName string, options api local int mounts []string ) - for _, m := range container.Mounts { + for _, m := range ctr.Mounts { name := m.Name if name == "" { name = m.Source @@ -93,26 +94,26 @@ func (s *composeService) Ps(ctx context.Context, projectName string, options api } var networks []string - if container.NetworkSettings != nil { - for k := range container.NetworkSettings.Networks { + if ctr.NetworkSettings != nil { + for k := range ctr.NetworkSettings.Networks { networks = append(networks, k) } } summary[i] = api.ContainerSummary{ - ID: container.ID, - Name: getCanonicalContainerName(container), - Names: container.Names, - Image: container.Image, - Project: container.Labels[api.ProjectLabel], - Service: container.Labels[api.ServiceLabel], - Command: container.Command, - State: container.State, - Status: container.Status, - Created: container.Created, - Labels: container.Labels, - SizeRw: container.SizeRw, - SizeRootFs: container.SizeRootFs, + ID: ctr.ID, + Name: getCanonicalContainerName(ctr), + Names: ctr.Names, + Image: ctr.Image, + Project: ctr.Labels[api.ProjectLabel], + Service: ctr.Labels[api.ServiceLabel], + Command: ctr.Command, + State: ctr.State, + Status: ctr.Status, + Created: ctr.Created, + Labels: ctr.Labels, + SizeRw: ctr.SizeRw, + SizeRootFs: ctr.SizeRootFs, Mounts: mounts, LocalVolumes: local, Networks: networks, diff --git a/pkg/compose/ps_test.go b/pkg/compose/ps_test.go index 41cd807e3..ac2230e4d 100644 --- a/pkg/compose/ps_test.go +++ b/pkg/compose/ps_test.go @@ -22,11 +22,11 @@ import ( "testing" containerType "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/filters" "go.uber.org/mock/gomock" "gotest.tools/v3/assert" compose "github.com/docker/compose/v2/pkg/api" - "github.com/docker/docker/api/types/filters" ) func TestPs(t *testing.T) { @@ -42,10 +42,10 @@ func TestPs(t *testing.T) { args := filters.NewArgs(projectFilter(strings.ToLower(testProject)), hasConfigHashLabel()) args.Add("label", "com.docker.compose.oneoff=False") listOpts := containerType.ListOptions{Filters: args, All: false} - c1, inspect1 := containerDetails("service1", "123", "running", "healthy", 0) - c2, inspect2 := containerDetails("service1", "456", "running", "", 0) + c1, inspect1 := containerDetails("service1", "123", containerType.StateRunning, containerType.Healthy, 0) + c2, inspect2 := containerDetails("service1", "456", containerType.StateRunning, "", 0) c2.Ports = []containerType.Port{{PublicPort: 80, PrivatePort: 90, IP: "localhost"}} - c3, inspect3 := containerDetails("service2", "789", "exited", "", 130) + c3, inspect3 := containerDetails("service2", "789", containerType.StateExited, "", 130) api.EXPECT().ContainerList(ctx, listOpts).Return([]containerType.Summary{c1, c2, c3}, nil) api.EXPECT().ContainerInspect(anyCancellableContext(), "123").Return(inspect1, nil) api.EXPECT().ContainerInspect(anyCancellableContext(), "456").Return(inspect2, nil) @@ -56,7 +56,9 @@ func TestPs(t *testing.T) { expected := []compose.ContainerSummary{ { ID: "123", Name: "123", Names: []string{"/123"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service1", - State: "running", Health: "healthy", Publishers: []compose.PortPublisher{}, + State: containerType.StateRunning, + Health: containerType.Healthy, + Publishers: []compose.PortPublisher{}, Labels: map[string]string{ compose.ProjectLabel: strings.ToLower(testProject), compose.ConfigFilesLabel: "/src/pkg/compose/testdata/compose.yaml", @@ -66,7 +68,8 @@ func TestPs(t *testing.T) { }, { ID: "456", Name: "456", Names: []string{"/456"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service1", - State: "running", Health: "", + State: containerType.StateRunning, + Health: "", Publishers: []compose.PortPublisher{{URL: "localhost", TargetPort: 90, PublishedPort: 80}}, Labels: map[string]string{ compose.ProjectLabel: strings.ToLower(testProject), @@ -77,7 +80,10 @@ func TestPs(t *testing.T) { }, { ID: "789", Name: "789", Names: []string{"/789"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service2", - State: "exited", Health: "", ExitCode: 130, Publishers: []compose.PortPublisher{}, + State: containerType.StateExited, + Health: "", + ExitCode: 130, + Publishers: []compose.PortPublisher{}, Labels: map[string]string{ compose.ProjectLabel: strings.ToLower(testProject), compose.ConfigFilesLabel: "/src/pkg/compose/testdata/compose.yaml", @@ -90,8 +96,8 @@ func TestPs(t *testing.T) { assert.DeepEqual(t, containers, expected) } -func containerDetails(service string, id string, status string, health string, exitCode int) (containerType.Summary, containerType.InspectResponse) { - container := containerType.Summary{ +func containerDetails(service string, id string, status containerType.ContainerState, health containerType.HealthStatus, exitCode int) (containerType.Summary, containerType.InspectResponse) { + ctr := containerType.Summary{ ID: id, Names: []string{"/" + id}, Image: "foo", @@ -107,5 +113,5 @@ func containerDetails(service string, id string, status string, health string, e }, }, } - return container, inspect + return ctr, inspect }