diff --git a/internal/compose/compose.go b/internal/compose/compose.go index cf8f8a24a..80f9a4291 100644 --- a/internal/compose/compose.go +++ b/internal/compose/compose.go @@ -369,35 +369,26 @@ func (p *Project) WaitForHealthy(ctx context.Context, opts CommandOptions) error return err } - for _, containerDescription := range descriptions { - + for _, d := range descriptions { + switch { // No healthcheck defined for service - if containerDescription.State.Status == "running" && containerDescription.State.Health == nil { - logger.Debugf("Container %s status: %s (no health status)", containerDescription.ID, containerDescription.State.Status) - continue - } - - // Service is up and running and it's healthy - if containerDescription.State.Status == "running" && containerDescription.State.Health.Status == "healthy" { - logger.Debugf("Container %s status: %s (health: %s)", containerDescription.ID, containerDescription.State.Status, containerDescription.State.Health.Status) - continue - } - - // Container started and finished with exit code 0 - if containerDescription.State.Status == "exited" && containerDescription.State.ExitCode == 0 { - logger.Debugf("Container %s status: %s (exit code: %d)", containerDescription.ID, containerDescription.State.Status, containerDescription.State.ExitCode) - continue - } - - // Container exited with code > 0 - if containerDescription.State.Status == "exited" && containerDescription.State.ExitCode > 0 { - logger.Debugf("Container %s status: %s (exit code: %d)", containerDescription.ID, containerDescription.State.Status, containerDescription.State.ExitCode) - return fmt.Errorf("container (ID: %s) exited with code %d", containerDescription.ID, containerDescription.State.ExitCode) - } - + case d.State.Status == "running" && d.State.Health == nil: + logger.Debugf("Container %s (%s) status: %s (no health status)", d.Config.Labels.ComposeService, d.ID, d.State.Status) + // Service is up and running and it's healthy + case d.State.Status == "running" && d.State.Health.Status == "healthy": + logger.Debugf("Container %s (%s) status: %s (health: %s)", d.Config.Labels.ComposeService, d.ID, d.State.Status, d.State.Health.Status) + // Container started and finished with exit code 0 + case d.State.Status == "exited" && d.State.ExitCode == 0: + logger.Debugf("Container %s (%s) status: %s (exit code: %d)", d.Config.Labels.ComposeService, d.ID, d.State.Status, d.State.ExitCode) + // Container exited with code > 0 + case d.State.Status == "exited" && d.State.ExitCode > 0: + logger.Debugf("Container %s (%s) status: %s (exit code: %d)", d.Config.Labels.ComposeService, d.ID, d.State.Status, d.State.ExitCode) + return fmt.Errorf("container (ID: %s) exited with code %d", d.ID, d.State.ExitCode) // Any different status is considered unhealthy - logger.Debugf("Container %s status: unhealthy", containerDescription.ID) - healthy = false + default: + logger.Debugf("Container %s (%s) status: unhealthy", d.Config.Labels.ComposeService, d.ID) + healthy = false + } } // end loop before timeout if healthy diff --git a/internal/docker/docker.go b/internal/docker/docker.go index 0350ef4b7..fedfe3a15 100644 --- a/internal/docker/docker.go +++ b/internal/docker/docker.go @@ -27,7 +27,7 @@ type NetworkDescription struct { type ContainerDescription struct { Config struct { Image string - Labels map[string]string + Labels ConfigLabels } ID string State struct { @@ -44,6 +44,13 @@ type ContainerDescription struct { } } +// ConfigLabels are the labels included in the config in container descriptions. +type ConfigLabels struct { + ComposeProject string `json:"com.docker.compose.project"` + ComposeService string `json:"com.docker.compose.service"` + ComposeVersion string `json:"com.docker.compose.version"` +} + // String function dumps string representation of the container description. func (c *ContainerDescription) String() string { b, err := json.Marshal(c) diff --git a/internal/stack/compose.go b/internal/stack/compose.go index edc31e32e..a0afa8b85 100644 --- a/internal/stack/compose.go +++ b/internal/stack/compose.go @@ -23,8 +23,6 @@ type ServiceStatus struct { const readyServicesSuffix = "is_ready" const ( - // serviceLabelDockerCompose is the label with the service name created by docker-compose - serviceLabelDockerCompose = "com.docker.compose.service" // projectLabelDockerCompose is the label with the project name created by docker-compose projectLabelDockerCompose = "com.docker.compose.project" ) @@ -213,7 +211,7 @@ func dockerComposeStatus(ctx context.Context, options Options) ([]ServiceStatus, func newServiceStatus(description *docker.ContainerDescription) (*ServiceStatus, error) { service := ServiceStatus{ - Name: description.Config.Labels[serviceLabelDockerCompose], + Name: description.Config.Labels.ComposeService, Status: description.State.Status, Version: getVersionFromDockerImage(description.Config.Image), } diff --git a/internal/stack/compose_test.go b/internal/stack/compose_test.go index 5ad495b1b..96be46942 100644 --- a/internal/stack/compose_test.go +++ b/internal/stack/compose_test.go @@ -42,10 +42,10 @@ func TestNewServiceStatus(t *testing.T) { description: docker.ContainerDescription{ Config: struct { Image string - Labels map[string]string + Labels docker.ConfigLabels }{ Image: "docker.test:1.42.0", - Labels: map[string]string{"com.docker.compose.service": "myservice", "foo": "bar"}, + Labels: docker.ConfigLabels{ComposeService: "myservice"}, }, ID: "123456789ab", State: struct { @@ -85,10 +85,10 @@ func TestNewServiceStatus(t *testing.T) { description: docker.ContainerDescription{ Config: struct { Image string - Labels map[string]string + Labels docker.ConfigLabels }{ Image: "docker.test:1.42.0", - Labels: map[string]string{"com.docker.compose.service": "myservice", "foo": "bar"}, + Labels: docker.ConfigLabels{ComposeService: "myservice"}, }, ID: "123456789ab", State: struct { @@ -119,10 +119,10 @@ func TestNewServiceStatus(t *testing.T) { description: docker.ContainerDescription{ Config: struct { Image string - Labels map[string]string + Labels docker.ConfigLabels }{ Image: "docker.test:1.42.0", - Labels: map[string]string{"com.docker.compose.service": "myservice", "foo": "bar"}, + Labels: docker.ConfigLabels{ComposeService: "myservice"}, }, ID: "123456789ab", State: struct { diff --git a/internal/stack/serverless.go b/internal/stack/serverless.go index 83646de7f..b90f1b071 100644 --- a/internal/stack/serverless.go +++ b/internal/stack/serverless.go @@ -489,7 +489,7 @@ func (sp *serverlessProvider) localAgentStatus() ([]ServiceStatus, error) { func localServiceNames(project string) ([]string, error) { services := []string{} serviceFunc := func(description docker.ContainerDescription) error { - services = append(services, description.Config.Labels[serviceLabelDockerCompose]) + services = append(services, description.Config.Labels.ComposeService) return nil } @@ -518,7 +518,7 @@ func runOnLocalServices(project string, serviceFunc func(docker.ContainerDescrip } for _, containerDescription := range containerDescriptions { - serviceName := containerDescription.Config.Labels[serviceLabelDockerCompose] + serviceName := containerDescription.Config.Labels.ComposeService if strings.HasSuffix(serviceName, readyServicesSuffix) { continue }