|
@@ -28,7 +28,6 @@ import (
|
|
|
"github.com/containerd/containerd/platforms"
|
|
"github.com/containerd/containerd/platforms"
|
|
|
moby "github.com/docker/docker/api/types"
|
|
moby "github.com/docker/docker/api/types"
|
|
|
containerType "github.com/docker/docker/api/types/container"
|
|
containerType "github.com/docker/docker/api/types/container"
|
|
|
- "github.com/docker/docker/api/types/filters"
|
|
|
|
|
"github.com/docker/docker/api/types/network"
|
|
"github.com/docker/docker/api/types/network"
|
|
|
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
|
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
|
|
"github.com/pkg/errors"
|
|
"github.com/pkg/errors"
|
|
@@ -281,7 +280,7 @@ func containerEvents(containers Containers, eventFunc func(string) progress.Even
|
|
|
// ServiceConditionRunningOrHealthy is a service condition on status running or healthy
|
|
// ServiceConditionRunningOrHealthy is a service condition on status running or healthy
|
|
|
const ServiceConditionRunningOrHealthy = "running_or_healthy"
|
|
const ServiceConditionRunningOrHealthy = "running_or_healthy"
|
|
|
|
|
|
|
|
-func (s *composeService) waitDependencies(ctx context.Context, project *types.Project, dependencies types.DependsOnConfig) error {
|
|
|
|
|
|
|
+func (s *composeService) waitDependencies(ctx context.Context, project *types.Project, dependencies types.DependsOnConfig, containers Containers) error {
|
|
|
eg, _ := errgroup.WithContext(ctx)
|
|
eg, _ := errgroup.WithContext(ctx)
|
|
|
w := progress.ContextWriter(ctx)
|
|
w := progress.ContextWriter(ctx)
|
|
|
for dep, config := range dependencies {
|
|
for dep, config := range dependencies {
|
|
@@ -291,10 +290,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- containers, err := s.getContainers(ctx, project.Name, oneOffExclude, false, dep)
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- return err
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ containers = containers.filter(isService(dep))
|
|
|
w.Events(containerEvents(containers, progress.Waiting))
|
|
w.Events(containerEvents(containers, progress.Waiting))
|
|
|
|
|
|
|
|
dep, config := dep, config
|
|
dep, config := dep, config
|
|
@@ -305,7 +301,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
|
|
|
<-ticker.C
|
|
<-ticker.C
|
|
|
switch config.Condition {
|
|
switch config.Condition {
|
|
|
case ServiceConditionRunningOrHealthy:
|
|
case ServiceConditionRunningOrHealthy:
|
|
|
- healthy, err := s.isServiceHealthy(ctx, project, dep, true)
|
|
|
|
|
|
|
+ healthy, err := s.isServiceHealthy(ctx, containers, dep, true)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
@@ -314,7 +310,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
case types.ServiceConditionHealthy:
|
|
case types.ServiceConditionHealthy:
|
|
|
- healthy, err := s.isServiceHealthy(ctx, project, dep, false)
|
|
|
|
|
|
|
+ healthy, err := s.isServiceHealthy(ctx, containers, dep, false)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
w.Events(containerEvents(containers, progress.ErrorEvent))
|
|
w.Events(containerEvents(containers, progress.ErrorEvent))
|
|
|
return errors.Wrap(err, "dependency failed to start")
|
|
return errors.Wrap(err, "dependency failed to start")
|
|
@@ -324,7 +320,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
case types.ServiceConditionCompletedSuccessfully:
|
|
case types.ServiceConditionCompletedSuccessfully:
|
|
|
- exited, code, err := s.isServiceCompleted(ctx, project, dep)
|
|
|
|
|
|
|
+ exited, code, err := s.isServiceCompleted(ctx, containers, dep)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
@@ -650,12 +646,7 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Project, service string, fallbackRunning bool) (bool, error) {
|
|
|
|
|
- containers, err := s.getContainers(ctx, project.Name, oneOffExclude, true, service)
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- return false, err
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+func (s *composeService) isServiceHealthy(ctx context.Context, containers Containers, service string, fallbackRunning bool) (bool, error) {
|
|
|
if len(containers) == 0 {
|
|
if len(containers) == 0 {
|
|
|
return false, nil
|
|
return false, nil
|
|
|
}
|
|
}
|
|
@@ -690,11 +681,7 @@ func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Pr
|
|
|
return true, nil
|
|
return true, nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (s *composeService) isServiceCompleted(ctx context.Context, project *types.Project, dep string) (bool, int, error) {
|
|
|
|
|
- containers, err := s.getContainers(ctx, project.Name, oneOffExclude, true, dep)
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- return false, 0, err
|
|
|
|
|
- }
|
|
|
|
|
|
|
+func (s *composeService) isServiceCompleted(ctx context.Context, containers Containers, dep string) (bool, int, error) {
|
|
|
for _, c := range containers {
|
|
for _, c := range containers {
|
|
|
container, err := s.apiClient().ContainerInspect(ctx, c.ID)
|
|
container, err := s.apiClient().ContainerInspect(ctx, c.ID)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -707,23 +694,12 @@ func (s *composeService) isServiceCompleted(ctx context.Context, project *types.
|
|
|
return false, 0, nil
|
|
return false, 0, nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (s *composeService) startService(ctx context.Context, project *types.Project, service types.ServiceConfig) error {
|
|
|
|
|
|
|
+func (s *composeService) startService(ctx context.Context, project *types.Project, service types.ServiceConfig, containers Containers) error {
|
|
|
if service.Deploy != nil && service.Deploy.Replicas != nil && *service.Deploy.Replicas == 0 {
|
|
if service.Deploy != nil && service.Deploy.Replicas != nil && *service.Deploy.Replicas == 0 {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- err := s.waitDependencies(ctx, project, service.DependsOn)
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- return err
|
|
|
|
|
- }
|
|
|
|
|
- containers, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
|
|
|
|
|
- Filters: filters.NewArgs(
|
|
|
|
|
- projectFilter(project.Name),
|
|
|
|
|
- serviceFilter(service.Name),
|
|
|
|
|
- oneOffFilter(false),
|
|
|
|
|
- ),
|
|
|
|
|
- All: true,
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ err := s.waitDependencies(ctx, project, service.DependsOn, containers)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|