mirror of
https://github.com/docker/compose.git
synced 2025-09-22 09:17:42 +02:00
use enum-consts for State and Health
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
1d52012b82
commit
f1efbb8322
@ -130,7 +130,7 @@ func (d *DryRunClient) ContainerInspect(ctx context.Context, container string) (
|
|||||||
ID: id,
|
ID: id,
|
||||||
Name: container,
|
Name: container,
|
||||||
State: &containerType.State{
|
State: &containerType.State{
|
||||||
Status: "running", // needed for --wait option
|
Status: containerType.StateRunning, // needed for --wait option
|
||||||
Health: &containerType.Health{
|
Health: &containerType.Health{
|
||||||
Status: containerType.Healthy, // needed for healthcheck control
|
Status: containerType.Healthy, // needed for healthcheck control
|
||||||
},
|
},
|
||||||
|
@ -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) {
|
func (s *composeService) isServiceHealthy(ctx context.Context, containers Containers, fallbackRunning bool) (bool, error) {
|
||||||
for _, c := range containers {
|
for _, c := range containers {
|
||||||
container, err := s.apiClient().ContainerInspect(ctx, c.ID)
|
ctr, err := s.apiClient().ContainerInspect(ctx, c.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
name := container.Name[1:]
|
name := ctr.Name[1:]
|
||||||
|
|
||||||
if container.State.Status == "exited" {
|
if ctr.State.Status == containerType.StateExited {
|
||||||
return false, fmt.Errorf("container %s exited (%d)", name, container.State.ExitCode)
|
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
|
// 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)
|
return false, fmt.Errorf("container %s has no healthcheck configured", name)
|
||||||
}
|
}
|
||||||
switch container.State.Health.Status {
|
switch ctr.State.Health.Status {
|
||||||
case containerType.Healthy:
|
case containerType.Healthy:
|
||||||
// Continue by checking the next container.
|
// Continue by checking the next container.
|
||||||
case containerType.Unhealthy:
|
case containerType.Unhealthy:
|
||||||
@ -854,7 +854,7 @@ func (s *composeService) isServiceHealthy(ctx context.Context, containers Contai
|
|||||||
case containerType.Starting:
|
case containerType.Starting:
|
||||||
return false, nil
|
return false, nil
|
||||||
default:
|
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
|
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) {
|
func (s *composeService) isServiceCompleted(ctx context.Context, containers Containers) (bool, int, error) {
|
||||||
for _, c := range containers {
|
for _, c := range containers {
|
||||||
container, err := s.apiClient().ContainerInspect(ctx, c.ID)
|
ctr, err := s.apiClient().ContainerInspect(ctx, c.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, 0, err
|
return false, 0, err
|
||||||
}
|
}
|
||||||
if container.State != nil && container.State.Status == "exited" {
|
if ctr.State != nil && ctr.State.Status == containerType.StateExited {
|
||||||
return true, container.State.ExitCode, nil
|
return true, ctr.State.ExitCode, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false, 0, nil
|
return false, 0, nil
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/docker/docker/api/types/container"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
"github.com/docker/compose/v2/pkg/api"
|
"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))
|
summary := make([]api.ContainerSummary, len(containers))
|
||||||
eg, ctx := errgroup.WithContext(ctx)
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
for i, container := range containers {
|
for i, ctr := range containers {
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
publishers := make([]api.PortPublisher, len(container.Ports))
|
publishers := make([]api.PortPublisher, len(ctr.Ports))
|
||||||
sort.Slice(container.Ports, func(i, j int) bool {
|
sort.Slice(ctr.Ports, func(i, j int) bool {
|
||||||
return container.Ports[i].PrivatePort < container.Ports[j].PrivatePort
|
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{
|
publishers[i] = api.PortPublisher{
|
||||||
URL: p.IP,
|
URL: p.IP,
|
||||||
TargetPort: int(p.PrivatePort),
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
health string
|
health container.HealthStatus
|
||||||
exitCode int
|
exitCode int
|
||||||
)
|
)
|
||||||
if inspect.State != nil {
|
if inspect.State != nil {
|
||||||
switch inspect.State.Status {
|
switch inspect.State.Status {
|
||||||
case "running":
|
case container.StateRunning:
|
||||||
if inspect.State.Health != nil {
|
if inspect.State.Health != nil {
|
||||||
health = inspect.State.Health.Status
|
health = inspect.State.Health.Status
|
||||||
}
|
}
|
||||||
case "exited", "dead":
|
case container.StateExited, container.StateDead:
|
||||||
exitCode = inspect.State.ExitCode
|
exitCode = inspect.State.ExitCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,7 +82,7 @@ func (s *composeService) Ps(ctx context.Context, projectName string, options api
|
|||||||
local int
|
local int
|
||||||
mounts []string
|
mounts []string
|
||||||
)
|
)
|
||||||
for _, m := range container.Mounts {
|
for _, m := range ctr.Mounts {
|
||||||
name := m.Name
|
name := m.Name
|
||||||
if name == "" {
|
if name == "" {
|
||||||
name = m.Source
|
name = m.Source
|
||||||
@ -93,26 +94,26 @@ func (s *composeService) Ps(ctx context.Context, projectName string, options api
|
|||||||
}
|
}
|
||||||
|
|
||||||
var networks []string
|
var networks []string
|
||||||
if container.NetworkSettings != nil {
|
if ctr.NetworkSettings != nil {
|
||||||
for k := range container.NetworkSettings.Networks {
|
for k := range ctr.NetworkSettings.Networks {
|
||||||
networks = append(networks, k)
|
networks = append(networks, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
summary[i] = api.ContainerSummary{
|
summary[i] = api.ContainerSummary{
|
||||||
ID: container.ID,
|
ID: ctr.ID,
|
||||||
Name: getCanonicalContainerName(container),
|
Name: getCanonicalContainerName(ctr),
|
||||||
Names: container.Names,
|
Names: ctr.Names,
|
||||||
Image: container.Image,
|
Image: ctr.Image,
|
||||||
Project: container.Labels[api.ProjectLabel],
|
Project: ctr.Labels[api.ProjectLabel],
|
||||||
Service: container.Labels[api.ServiceLabel],
|
Service: ctr.Labels[api.ServiceLabel],
|
||||||
Command: container.Command,
|
Command: ctr.Command,
|
||||||
State: container.State,
|
State: ctr.State,
|
||||||
Status: container.Status,
|
Status: ctr.Status,
|
||||||
Created: container.Created,
|
Created: ctr.Created,
|
||||||
Labels: container.Labels,
|
Labels: ctr.Labels,
|
||||||
SizeRw: container.SizeRw,
|
SizeRw: ctr.SizeRw,
|
||||||
SizeRootFs: container.SizeRootFs,
|
SizeRootFs: ctr.SizeRootFs,
|
||||||
Mounts: mounts,
|
Mounts: mounts,
|
||||||
LocalVolumes: local,
|
LocalVolumes: local,
|
||||||
Networks: networks,
|
Networks: networks,
|
||||||
|
@ -22,11 +22,11 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
containerType "github.com/docker/docker/api/types/container"
|
containerType "github.com/docker/docker/api/types/container"
|
||||||
|
"github.com/docker/docker/api/types/filters"
|
||||||
"go.uber.org/mock/gomock"
|
"go.uber.org/mock/gomock"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
|
||||||
compose "github.com/docker/compose/v2/pkg/api"
|
compose "github.com/docker/compose/v2/pkg/api"
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPs(t *testing.T) {
|
func TestPs(t *testing.T) {
|
||||||
@ -42,10 +42,10 @@ func TestPs(t *testing.T) {
|
|||||||
args := filters.NewArgs(projectFilter(strings.ToLower(testProject)), hasConfigHashLabel())
|
args := filters.NewArgs(projectFilter(strings.ToLower(testProject)), hasConfigHashLabel())
|
||||||
args.Add("label", "com.docker.compose.oneoff=False")
|
args.Add("label", "com.docker.compose.oneoff=False")
|
||||||
listOpts := containerType.ListOptions{Filters: args, All: false}
|
listOpts := containerType.ListOptions{Filters: args, All: false}
|
||||||
c1, inspect1 := containerDetails("service1", "123", "running", "healthy", 0)
|
c1, inspect1 := containerDetails("service1", "123", containerType.StateRunning, containerType.Healthy, 0)
|
||||||
c2, inspect2 := containerDetails("service1", "456", "running", "", 0)
|
c2, inspect2 := containerDetails("service1", "456", containerType.StateRunning, "", 0)
|
||||||
c2.Ports = []containerType.Port{{PublicPort: 80, PrivatePort: 90, IP: "localhost"}}
|
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().ContainerList(ctx, listOpts).Return([]containerType.Summary{c1, c2, c3}, nil)
|
||||||
api.EXPECT().ContainerInspect(anyCancellableContext(), "123").Return(inspect1, nil)
|
api.EXPECT().ContainerInspect(anyCancellableContext(), "123").Return(inspect1, nil)
|
||||||
api.EXPECT().ContainerInspect(anyCancellableContext(), "456").Return(inspect2, nil)
|
api.EXPECT().ContainerInspect(anyCancellableContext(), "456").Return(inspect2, nil)
|
||||||
@ -56,7 +56,9 @@ func TestPs(t *testing.T) {
|
|||||||
expected := []compose.ContainerSummary{
|
expected := []compose.ContainerSummary{
|
||||||
{
|
{
|
||||||
ID: "123", Name: "123", Names: []string{"/123"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service1",
|
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{
|
Labels: map[string]string{
|
||||||
compose.ProjectLabel: strings.ToLower(testProject),
|
compose.ProjectLabel: strings.ToLower(testProject),
|
||||||
compose.ConfigFilesLabel: "/src/pkg/compose/testdata/compose.yaml",
|
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",
|
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}},
|
Publishers: []compose.PortPublisher{{URL: "localhost", TargetPort: 90, PublishedPort: 80}},
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
compose.ProjectLabel: strings.ToLower(testProject),
|
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",
|
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{
|
Labels: map[string]string{
|
||||||
compose.ProjectLabel: strings.ToLower(testProject),
|
compose.ProjectLabel: strings.ToLower(testProject),
|
||||||
compose.ConfigFilesLabel: "/src/pkg/compose/testdata/compose.yaml",
|
compose.ConfigFilesLabel: "/src/pkg/compose/testdata/compose.yaml",
|
||||||
@ -90,8 +96,8 @@ func TestPs(t *testing.T) {
|
|||||||
assert.DeepEqual(t, containers, expected)
|
assert.DeepEqual(t, containers, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
func containerDetails(service string, id string, status string, health string, exitCode int) (containerType.Summary, containerType.InspectResponse) {
|
func containerDetails(service string, id string, status containerType.ContainerState, health containerType.HealthStatus, exitCode int) (containerType.Summary, containerType.InspectResponse) {
|
||||||
container := containerType.Summary{
|
ctr := containerType.Summary{
|
||||||
ID: id,
|
ID: id,
|
||||||
Names: []string{"/" + id},
|
Names: []string{"/" + id},
|
||||||
Image: "foo",
|
Image: "foo",
|
||||||
@ -107,5 +113,5 @@ func containerDetails(service string, id string, status string, health string, e
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return container, inspect
|
return ctr, inspect
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user