mirror of
https://github.com/docker/compose.git
synced 2025-09-13 21:08:14 +02:00
pkg/compose: use state consts from moby API
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
02ffe2ac6c
commit
f217207876
@ -20,23 +20,17 @@ import (
|
||||
"io"
|
||||
|
||||
moby "github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
)
|
||||
|
||||
const (
|
||||
// ContainerCreated created status
|
||||
ContainerCreated = "created"
|
||||
// ContainerRestarting restarting status
|
||||
ContainerRestarting = "restarting"
|
||||
// ContainerRunning running status
|
||||
ContainerRunning = "running"
|
||||
// ContainerRemoving removing status
|
||||
ContainerRemoving = "removing"
|
||||
// ContainerPaused paused status
|
||||
ContainerPaused = "paused"
|
||||
// ContainerExited exited status
|
||||
ContainerExited = "exited"
|
||||
// ContainerDead dead status
|
||||
ContainerDead = "dead"
|
||||
ContainerCreated = container.StateCreated // StateCreated indicates the container is created, but not (yet) started.
|
||||
ContainerRunning = container.StateRunning // StateRunning indicates that the container is running.
|
||||
ContainerPaused = container.StatePaused // StatePaused indicates that the container's current state is paused.
|
||||
ContainerRestarting = container.StateRestarting // StateRestarting indicates that the container is currently restarting.
|
||||
ContainerRemoving = container.StateRemoving // StateRemoving indicates that the container is being removed.
|
||||
ContainerExited = container.StateExited // StateExited indicates that the container exited.
|
||||
ContainerDead = container.StateDead // StateDead indicates that the container failed to be deleted. Containers in this state are attempted to be cleaned up when the daemon restarts.
|
||||
)
|
||||
|
||||
var _ io.ReadCloser = ContainerStdout{}
|
||||
|
@ -135,7 +135,7 @@ func isOrphaned(project *types.Project) containerPredicate {
|
||||
// One-off container
|
||||
v, ok := c.Labels[api.OneoffLabel]
|
||||
if ok && v == "True" {
|
||||
return c.State == ContainerExited || c.State == ContainerDead
|
||||
return c.State == container.StateExited || c.State == container.StateDead
|
||||
}
|
||||
// Service that is not defined in the compose model
|
||||
service := c.Labels[api.ServiceLabel]
|
||||
|
@ -30,7 +30,7 @@ import (
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
"github.com/containerd/platforms"
|
||||
containerType "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
mmount "github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
@ -152,19 +152,19 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
|
||||
})
|
||||
|
||||
slices.Reverse(containers)
|
||||
for i, container := range containers {
|
||||
for i, ctr := range containers {
|
||||
if i >= expected {
|
||||
// Scale Down
|
||||
// As we sorted containers, obsolete ones and/or highest number will be removed
|
||||
container := container
|
||||
traceOpts := append(tracing.ServiceOptions(service), tracing.ContainerOptions(container)...)
|
||||
ctr := ctr
|
||||
traceOpts := append(tracing.ServiceOptions(service), tracing.ContainerOptions(ctr)...)
|
||||
eg.Go(tracing.SpanWrapFuncForErrGroup(ctx, "service/scale/down", traceOpts, func(ctx context.Context) error {
|
||||
return c.service.stopAndRemoveContainer(ctx, container, &service, timeout, false)
|
||||
return c.service.stopAndRemoveContainer(ctx, ctr, &service, timeout, false)
|
||||
}))
|
||||
continue
|
||||
}
|
||||
|
||||
mustRecreate, err := c.mustRecreate(service, container, recreate)
|
||||
mustRecreate, err := c.mustRecreate(service, ctr, recreate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -174,9 +174,9 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
|
||||
return err
|
||||
}
|
||||
|
||||
i, container := i, container
|
||||
eg.Go(tracing.SpanWrapFuncForErrGroup(ctx, "container/recreate", tracing.ContainerOptions(container), func(ctx context.Context) error {
|
||||
recreated, err := c.service.recreateContainer(ctx, project, service, container, inherit, timeout)
|
||||
i, ctr := i, ctr
|
||||
eg.Go(tracing.SpanWrapFuncForErrGroup(ctx, "container/recreate", tracing.ContainerOptions(ctr), func(ctx context.Context) error {
|
||||
recreated, err := c.service.recreateContainer(ctx, project, service, ctr, inherit, timeout)
|
||||
updated[i] = recreated
|
||||
return err
|
||||
}))
|
||||
@ -185,20 +185,20 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
|
||||
|
||||
// Enforce non-diverged containers are running
|
||||
w := progress.ContextWriter(ctx)
|
||||
name := getContainerProgressName(container)
|
||||
switch container.State {
|
||||
case ContainerRunning:
|
||||
name := getContainerProgressName(ctr)
|
||||
switch ctr.State {
|
||||
case container.StateRunning:
|
||||
w.Event(progress.RunningEvent(name))
|
||||
case ContainerCreated:
|
||||
case ContainerRestarting:
|
||||
case ContainerExited:
|
||||
case container.StateCreated:
|
||||
case container.StateRestarting:
|
||||
case container.StateExited:
|
||||
default:
|
||||
container := container
|
||||
eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "service/start", tracing.ContainerOptions(container), func(ctx context.Context) error {
|
||||
return c.service.startContainer(ctx, container)
|
||||
ctr := ctr
|
||||
eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "service/start", tracing.ContainerOptions(ctr), func(ctx context.Context) error {
|
||||
return c.service.startContainer(ctx, ctr)
|
||||
}))
|
||||
}
|
||||
updated[i] = container
|
||||
updated[i] = ctr
|
||||
}
|
||||
|
||||
next := nextContainerNumber(containers)
|
||||
@ -214,8 +214,8 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
|
||||
UseNetworkAliases: true,
|
||||
Labels: mergeLabels(service.Labels, service.CustomLabels),
|
||||
}
|
||||
container, err := c.service.createContainer(ctx, project, service, name, number, opts)
|
||||
updated[actual+i] = container
|
||||
ctr, err := c.service.createContainer(ctx, project, service, name, number, opts)
|
||||
updated[actual+i] = ctr
|
||||
return err
|
||||
}))
|
||||
continue
|
||||
@ -245,7 +245,7 @@ func (c *convergence) stopDependentContainers(ctx context.Context, project *type
|
||||
for _, name := range dependents {
|
||||
dependentStates := c.getObservedState(name)
|
||||
for i, dependent := range dependentStates {
|
||||
dependent.State = ContainerExited
|
||||
dependent.State = container.StateExited
|
||||
dependentStates[i] = dependent
|
||||
}
|
||||
c.setObservedState(name, dependentStates)
|
||||
@ -328,7 +328,7 @@ func (c *convergence) resolveSharedNamespaces(service *types.ServiceConfig) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *convergence) mustRecreate(expected types.ServiceConfig, actual containerType.Summary, policy string) (bool, error) {
|
||||
func (c *convergence) mustRecreate(expected types.ServiceConfig, actual container.Summary, policy string) (bool, error) {
|
||||
if policy == api.RecreateNever {
|
||||
return false, nil
|
||||
}
|
||||
@ -360,7 +360,7 @@ func (c *convergence) mustRecreate(expected types.ServiceConfig, actual containe
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func checkExpectedNetworks(expected types.ServiceConfig, actual containerType.Summary, networks map[string]string) bool {
|
||||
func checkExpectedNetworks(expected types.ServiceConfig, actual container.Summary, networks map[string]string) bool {
|
||||
// check the networks container is connected to are the expected ones
|
||||
for net := range expected.Networks {
|
||||
id := networks[net]
|
||||
@ -383,7 +383,7 @@ func checkExpectedNetworks(expected types.ServiceConfig, actual containerType.Su
|
||||
return false
|
||||
}
|
||||
|
||||
func checkExpectedVolumes(expected types.ServiceConfig, actual containerType.Summary, volumes map[string]string) bool {
|
||||
func checkExpectedVolumes(expected types.ServiceConfig, actual container.Summary, volumes map[string]string) bool {
|
||||
// check container's volume mounts and search for the expected ones
|
||||
for _, vol := range expected.Volumes {
|
||||
if vol.Type != string(mmount.TypeVolume) {
|
||||
@ -423,7 +423,7 @@ func getDefaultContainerName(projectName, serviceName, index string) string {
|
||||
return strings.Join([]string{projectName, serviceName, index}, api.Separator)
|
||||
}
|
||||
|
||||
func getContainerProgressName(ctr containerType.Summary) string {
|
||||
func getContainerProgressName(ctr container.Summary) string {
|
||||
return "Container " + getCanonicalContainerName(ctr)
|
||||
}
|
||||
|
||||
@ -571,7 +571,7 @@ func shouldWaitForDependency(serviceName string, dependencyConfig types.ServiceD
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func nextContainerNumber(containers []containerType.Summary) int {
|
||||
func nextContainerNumber(containers []container.Summary) int {
|
||||
maxNumber := 0
|
||||
for _, c := range containers {
|
||||
s, ok := c.Labels[api.ContainerNumberLabel]
|
||||
@ -592,7 +592,7 @@ func nextContainerNumber(containers []containerType.Summary) int {
|
||||
|
||||
func (s *composeService) createContainer(ctx context.Context, project *types.Project, service types.ServiceConfig,
|
||||
name string, number int, opts createOptions,
|
||||
) (ctr containerType.Summary, err error) {
|
||||
) (ctr container.Summary, err error) {
|
||||
w := progress.ContextWriter(ctx)
|
||||
eventName := "Container " + name
|
||||
w.Event(progress.CreatingEvent(eventName))
|
||||
@ -612,8 +612,8 @@ func (s *composeService) createContainer(ctx context.Context, project *types.Pro
|
||||
}
|
||||
|
||||
func (s *composeService) recreateContainer(ctx context.Context, project *types.Project, service types.ServiceConfig,
|
||||
replaced containerType.Summary, inherit bool, timeout *time.Duration,
|
||||
) (created containerType.Summary, err error) {
|
||||
replaced container.Summary, inherit bool, timeout *time.Duration,
|
||||
) (created container.Summary, err error) {
|
||||
w := progress.ContextWriter(ctx)
|
||||
eventName := getContainerProgressName(replaced)
|
||||
w.Event(progress.NewEvent(eventName, progress.Working, "Recreate"))
|
||||
@ -632,7 +632,7 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P
|
||||
return created, err
|
||||
}
|
||||
|
||||
var inherited *containerType.Summary
|
||||
var inherited *container.Summary
|
||||
if inherit {
|
||||
inherited = &replaced
|
||||
}
|
||||
@ -655,12 +655,12 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P
|
||||
}
|
||||
|
||||
timeoutInSecond := utils.DurationSecondToInt(timeout)
|
||||
err = s.apiClient().ContainerStop(ctx, replaced.ID, containerType.StopOptions{Timeout: timeoutInSecond})
|
||||
err = s.apiClient().ContainerStop(ctx, replaced.ID, container.StopOptions{Timeout: timeoutInSecond})
|
||||
if err != nil {
|
||||
return created, err
|
||||
}
|
||||
|
||||
err = s.apiClient().ContainerRemove(ctx, replaced.ID, containerType.RemoveOptions{})
|
||||
err = s.apiClient().ContainerRemove(ctx, replaced.ID, container.RemoveOptions{})
|
||||
if err != nil {
|
||||
return created, err
|
||||
}
|
||||
@ -677,12 +677,12 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P
|
||||
// force sequential calls to ContainerStart to prevent race condition in engine assigning ports from ranges
|
||||
var startMx sync.Mutex
|
||||
|
||||
func (s *composeService) startContainer(ctx context.Context, ctr containerType.Summary) error {
|
||||
func (s *composeService) startContainer(ctx context.Context, ctr container.Summary) error {
|
||||
w := progress.ContextWriter(ctx)
|
||||
w.Event(progress.NewEvent(getContainerProgressName(ctr), progress.Working, "Restart"))
|
||||
startMx.Lock()
|
||||
defer startMx.Unlock()
|
||||
err := s.apiClient().ContainerStart(ctx, ctr.ID, containerType.StartOptions{})
|
||||
err := s.apiClient().ContainerStart(ctx, ctr.ID, container.StartOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -695,11 +695,11 @@ func (s *composeService) createMobyContainer(ctx context.Context,
|
||||
service types.ServiceConfig,
|
||||
name string,
|
||||
number int,
|
||||
inherit *containerType.Summary,
|
||||
inherit *container.Summary,
|
||||
opts createOptions,
|
||||
w progress.Writer,
|
||||
) (containerType.Summary, error) {
|
||||
var created containerType.Summary
|
||||
) (container.Summary, error) {
|
||||
var created container.Summary
|
||||
cfgs, err := s.getCreateConfigs(ctx, project, service, number, inherit, opts)
|
||||
if err != nil {
|
||||
return created, err
|
||||
@ -733,11 +733,11 @@ func (s *composeService) createMobyContainer(ctx context.Context,
|
||||
if err != nil {
|
||||
return created, err
|
||||
}
|
||||
created = containerType.Summary{
|
||||
created = container.Summary{
|
||||
ID: inspectedContainer.ID,
|
||||
Labels: inspectedContainer.Config.Labels,
|
||||
Names: []string{inspectedContainer.Name},
|
||||
NetworkSettings: &containerType.NetworkSettingsSummary{
|
||||
NetworkSettings: &container.NetworkSettingsSummary{
|
||||
Networks: inspectedContainer.NetworkSettings.Networks,
|
||||
},
|
||||
}
|
||||
@ -834,24 +834,24 @@ func (s *composeService) isServiceHealthy(ctx context.Context, containers Contai
|
||||
}
|
||||
name := ctr.Name[1:]
|
||||
|
||||
if ctr.State.Status == containerType.StateExited {
|
||||
if ctr.State.Status == container.StateExited {
|
||||
return false, fmt.Errorf("container %s exited (%d)", name, ctr.State.ExitCode)
|
||||
}
|
||||
|
||||
if ctr.Config.Healthcheck == nil && fallbackRunning {
|
||||
// Container does not define a health check, but we can fall back to "running" state
|
||||
return ctr.State != nil && ctr.State.Status == containerType.StateRunning, nil
|
||||
return ctr.State != nil && ctr.State.Status == container.StateRunning, nil
|
||||
}
|
||||
|
||||
if ctr.State == nil || ctr.State.Health == nil {
|
||||
return false, fmt.Errorf("container %s has no healthcheck configured", name)
|
||||
}
|
||||
switch ctr.State.Health.Status {
|
||||
case containerType.Healthy:
|
||||
case container.Healthy:
|
||||
// Continue by checking the next container.
|
||||
case containerType.Unhealthy:
|
||||
case container.Unhealthy:
|
||||
return false, fmt.Errorf("container %s is unhealthy", name)
|
||||
case containerType.Starting:
|
||||
case container.Starting:
|
||||
return false, nil
|
||||
default:
|
||||
return false, fmt.Errorf("container %s had unexpected health status %q", name, ctr.State.Health.Status)
|
||||
@ -866,7 +866,7 @@ func (s *composeService) isServiceCompleted(ctx context.Context, containers Cont
|
||||
if err != nil {
|
||||
return false, 0, err
|
||||
}
|
||||
if ctr.State != nil && ctr.State.Status == containerType.StateExited {
|
||||
if ctr.State != nil && ctr.State.Status == container.StateExited {
|
||||
return true, ctr.State.ExitCode, nil
|
||||
}
|
||||
}
|
||||
@ -896,7 +896,7 @@ func (s *composeService) startService(ctx context.Context,
|
||||
|
||||
w := progress.ContextWriter(ctx)
|
||||
for _, ctr := range containers.filter(isService(service.Name)) {
|
||||
if ctr.State == ContainerRunning {
|
||||
if ctr.State == container.StateRunning {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -912,7 +912,7 @@ func (s *composeService) startService(ctx context.Context,
|
||||
|
||||
eventName := getContainerProgressName(ctr)
|
||||
w.Event(progress.StartingEvent(eventName))
|
||||
err = s.apiClient().ContainerStart(ctx, ctr.ID, containerType.StartOptions{})
|
||||
err = s.apiClient().ContainerStart(ctx, ctr.ID, container.StartOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ func testContainer(service string, id string, oneOff bool) container.Summary {
|
||||
ID: id,
|
||||
Names: []string{name},
|
||||
Labels: containerLabels(service, oneOff),
|
||||
State: ContainerExited,
|
||||
State: container.StateExited,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user