Merge pull request #50495 from thaJeztah/move_back_StateStatus_take2

api/types/container: move StateStatus, NewStateStatus internal again
This commit is contained in:
Sebastiaan van Stijn
2025-07-28 17:30:48 +02:00
committed by GitHub
9 changed files with 50 additions and 72 deletions

View File

@@ -34,31 +34,3 @@ func ValidateContainerState(s ContainerState) error {
return errInvalidParameter{error: fmt.Errorf("invalid value for state (%s): must be one of %s", s, strings.Join(validStates, ", "))}
}
}
// StateStatus is used to return container wait results.
// Implements exec.ExitCode interface.
// This type is needed as State include a sync.Mutex field which make
// copying it unsafe.
type StateStatus struct {
exitCode int
err error
}
// ExitCode returns current exitcode for the state.
func (s StateStatus) ExitCode() int {
return s.exitCode
}
// Err returns current error for the state. Returns nil if the container had
// exited on its own.
func (s StateStatus) Err() error {
return s.err
}
// NewStateStatus returns a new StateStatus with the given exit code and error.
func NewStateStatus(exitCode int, err error) StateStatus {
return StateStatus{
exitCode: exitCode,
err: err,
}
}

View File

@@ -8,6 +8,7 @@ import (
"context"
"io"
containerpkg "github.com/docker/docker/daemon/container"
"github.com/docker/docker/daemon/internal/image"
"github.com/docker/docker/daemon/internal/layer"
"github.com/docker/docker/daemon/server/backend"
@@ -65,7 +66,7 @@ type ExecBackend interface {
// ContainerStart starts a new container
ContainerStart(ctx context.Context, containerID string, checkpoint string, checkpointDir string) error
// ContainerWait stops processing until the given container is stopped.
ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan container.StateStatus, error)
ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan containerpkg.StateStatus, error)
}
// Result is the output produced by a Builder

View File

@@ -7,6 +7,7 @@ import (
"runtime"
"github.com/docker/docker/daemon/builder"
containerpkg "github.com/docker/docker/daemon/container"
"github.com/docker/docker/daemon/internal/image"
"github.com/docker/docker/daemon/internal/layer"
"github.com/docker/docker/daemon/server/backend"
@@ -49,7 +50,7 @@ func (m *MockBackend) ContainerStart(ctx context.Context, containerID string, ch
return nil
}
func (m *MockBackend) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.StateStatus, error) {
func (m *MockBackend) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan containerpkg.StateStatus, error) {
return nil, nil
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/distribution/reference"
"github.com/docker/distribution"
clustertypes "github.com/docker/docker/daemon/cluster/provider"
containerpkg "github.com/docker/docker/daemon/container"
"github.com/docker/docker/daemon/internal/image"
"github.com/docker/docker/daemon/libnetwork"
"github.com/docker/docker/daemon/libnetwork/cluster"
@@ -44,7 +45,7 @@ type Backend interface {
DeactivateContainerServiceBinding(containerName string) error
UpdateContainerServiceConfig(containerName string, serviceConfig *clustertypes.ServiceConfig) error
ContainerInspect(ctx context.Context, name string, options backend.ContainerInspectOptions) (*container.InspectResponse, error)
ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan container.StateStatus, error)
ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan containerpkg.StateStatus, error)
ContainerRm(name string, config *backend.ContainerRmConfig) error
ContainerKill(name string, sig string) error
SetContainerDependencyStore(name string, store exec.DependencyGetter) error

View File

@@ -16,6 +16,7 @@ import (
"github.com/docker/docker/daemon"
"github.com/docker/docker/daemon/cluster/convert"
executorpkg "github.com/docker/docker/daemon/cluster/executor"
containerpkg "github.com/docker/docker/daemon/container"
"github.com/docker/docker/daemon/libnetwork"
networkSettings "github.com/docker/docker/daemon/network"
"github.com/docker/docker/daemon/server/backend"
@@ -415,7 +416,7 @@ func (c *containerAdapter) events(ctx context.Context) <-chan events.Message {
return eventsq
}
func (c *containerAdapter) wait(ctx context.Context) (<-chan containertypes.StateStatus, error) {
func (c *containerAdapter) wait(ctx context.Context) (<-chan containerpkg.StateStatus, error) {
return c.backend.ContainerWait(ctx, c.container.nameOrID(), containertypes.WaitConditionNotRunning)
}

View File

@@ -46,8 +46,8 @@ type State struct {
Health *Health
Removed bool `json:"-"`
stopWaiters []chan<- container.StateStatus
removeOnlyWaiters []chan<- container.StateStatus
stopWaiters []chan<- StateStatus
removeOnlyWaiters []chan<- StateStatus
// The libcontainerd reference fields are unexported to force consumers
// to access them through the getter methods with multi-valued returns
@@ -58,6 +58,26 @@ type State struct {
task libcontainerdtypes.Task
}
// StateStatus is used to return container wait results.
// Implements exec.ExitCode interface.
// This type is needed as State include a sync.Mutex field which make
// copying it unsafe.
type StateStatus struct {
exitCode int
err error
}
// ExitCode returns current exitcode for the state.
func (s StateStatus) ExitCode() int {
return s.exitCode
}
// Err returns current error for the state. Returns nil if the container had
// exited on its own.
func (s StateStatus) Err() error {
return s.err
}
// NewState creates a default state object.
func NewState() *State {
return &State{}
@@ -138,20 +158,23 @@ func (s *State) StateString() container.ContainerState {
// be nil and its ExitCode() method will return the container's exit code,
// otherwise, the results Err() method will return an error indicating why the
// wait operation failed.
func (s *State) Wait(ctx context.Context, condition container.WaitCondition) <-chan container.StateStatus {
func (s *State) Wait(ctx context.Context, condition container.WaitCondition) <-chan StateStatus {
s.Lock()
defer s.Unlock()
// Buffer so we can put status and finish even nobody receives it.
resultC := make(chan container.StateStatus, 1)
resultC := make(chan StateStatus, 1)
if s.conditionAlreadyMet(condition) {
resultC <- container.NewStateStatus(s.ExitCode(), s.Err())
resultC <- StateStatus{
exitCode: s.ExitCodeValue,
err: s.Err(),
}
return resultC
}
waitC := make(chan container.StateStatus, 1)
waitC := make(chan StateStatus, 1)
// Removal wakes up both removeOnlyWaiters and stopWaiters
// Container could be removed while still in "created" state
@@ -166,8 +189,10 @@ func (s *State) Wait(ctx context.Context, condition container.WaitCondition) <-c
select {
case <-ctx.Done():
// Context timeout or cancellation.
resultC <- container.NewStateStatus(-1, ctx.Err())
resultC <- StateStatus{
exitCode: -1,
err: ctx.Err(),
}
return
case status := <-waitC:
resultC <- status
@@ -397,8 +422,11 @@ func (s *State) Err() error {
return nil
}
func (s *State) notifyAndClear(waiters *[]chan<- container.StateStatus) {
result := container.NewStateStatus(s.ExitCodeValue, s.Err())
func (s *State) notifyAndClear(waiters *[]chan<- StateStatus) {
result := StateStatus{
exitCode: s.ExitCodeValue,
err: s.Err(),
}
for _, c := range *waiters {
c <- result

View File

@@ -4,6 +4,7 @@ import (
"context"
"io"
containerpkg "github.com/docker/docker/daemon/container"
"github.com/docker/docker/daemon/server/backend"
"github.com/moby/go-archive"
"github.com/moby/moby/api/types/container"
@@ -40,7 +41,7 @@ type stateBackend interface {
ContainerStop(ctx context.Context, name string, options container.StopOptions) error
ContainerUnpause(name string) error
ContainerUpdate(name string, hostConfig *container.HostConfig) (container.UpdateResponse, error)
ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan container.StateStatus, error)
ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan containerpkg.StateStatus, error)
}
// monitorBackend includes functions to implement to provide containers monitoring functionality.

View File

@@ -3,6 +3,7 @@ package daemon
import (
"context"
"github.com/docker/docker/daemon/container"
containertypes "github.com/moby/moby/api/types/container"
)
@@ -13,7 +14,7 @@ import (
// condition is met or if an error occurs waiting for the container (such as a
// context timeout or cancellation). On a successful wait, the exit code of the
// container is returned in the status with a non-nil Err() value.
func (daemon *Daemon) ContainerWait(ctx context.Context, name string, condition containertypes.WaitCondition) (<-chan containertypes.StateStatus, error) {
func (daemon *Daemon) ContainerWait(ctx context.Context, name string, condition containertypes.WaitCondition) (<-chan container.StateStatus, error) {
cntr, err := daemon.GetContainer(name)
if err != nil {
return nil, err

View File

@@ -34,31 +34,3 @@ func ValidateContainerState(s ContainerState) error {
return errInvalidParameter{error: fmt.Errorf("invalid value for state (%s): must be one of %s", s, strings.Join(validStates, ", "))}
}
}
// StateStatus is used to return container wait results.
// Implements exec.ExitCode interface.
// This type is needed as State include a sync.Mutex field which make
// copying it unsafe.
type StateStatus struct {
exitCode int
err error
}
// ExitCode returns current exitcode for the state.
func (s StateStatus) ExitCode() int {
return s.exitCode
}
// Err returns current error for the state. Returns nil if the container had
// exited on its own.
func (s StateStatus) Err() error {
return s.err
}
// NewStateStatus returns a new StateStatus with the given exit code and error.
func NewStateStatus(exitCode int, err error) StateStatus {
return StateStatus{
exitCode: exitCode,
err: err,
}
}