These types used to be internal to the container package, but were
moved to the API in 100102108b2f096cd43165e4522a6314bc16f07c.
However, the `StateStatus` type is only used internally; it's used
as an intermediate type because [`container.State`] contains a sync.Mutex
field which would make copying it unsafe (see [moby@2998945]).
This moves the type and re-introduces an internal type
in the original location, effectively reverting
100102108b2f096cd43165e4522a6314bc16f07c
[`container.State`]: https://github.com/moby/moby/blob/19e79906cb347ab12deaade16bf9d82c41d777c4/container/state.go#L15-L23
[moby@2998945]: https://github.com/moby/moby/commit/2998945a54577e24a6414d576bc861e58fa87359
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -34,31 +34,3 @@ func ValidateContainerState(s ContainerState) error {
|
| 34 | 34 |
return errInvalidParameter{error: fmt.Errorf("invalid value for state (%s): must be one of %s", s, strings.Join(validStates, ", "))}
|
| 35 | 35 |
} |
| 36 | 36 |
} |
| 37 |
- |
|
| 38 |
-// StateStatus is used to return container wait results. |
|
| 39 |
-// Implements exec.ExitCode interface. |
|
| 40 |
-// This type is needed as State include a sync.Mutex field which make |
|
| 41 |
-// copying it unsafe. |
|
| 42 |
-type StateStatus struct {
|
|
| 43 |
- exitCode int |
|
| 44 |
- err error |
|
| 45 |
-} |
|
| 46 |
- |
|
| 47 |
-// ExitCode returns current exitcode for the state. |
|
| 48 |
-func (s StateStatus) ExitCode() int {
|
|
| 49 |
- return s.exitCode |
|
| 50 |
-} |
|
| 51 |
- |
|
| 52 |
-// Err returns current error for the state. Returns nil if the container had |
|
| 53 |
-// exited on its own. |
|
| 54 |
-func (s StateStatus) Err() error {
|
|
| 55 |
- return s.err |
|
| 56 |
-} |
|
| 57 |
- |
|
| 58 |
-// NewStateStatus returns a new StateStatus with the given exit code and error. |
|
| 59 |
-func NewStateStatus(exitCode int, err error) StateStatus {
|
|
| 60 |
- return StateStatus{
|
|
| 61 |
- exitCode: exitCode, |
|
| 62 |
- err: err, |
|
| 63 |
- } |
|
| 64 |
-} |
| ... | ... |
@@ -8,6 +8,7 @@ import ( |
| 8 | 8 |
"context" |
| 9 | 9 |
"io" |
| 10 | 10 |
|
| 11 |
+ containerpkg "github.com/docker/docker/daemon/container" |
|
| 11 | 12 |
"github.com/docker/docker/daemon/internal/image" |
| 12 | 13 |
"github.com/docker/docker/daemon/internal/layer" |
| 13 | 14 |
"github.com/docker/docker/daemon/server/backend" |
| ... | ... |
@@ -65,7 +66,7 @@ type ExecBackend interface {
|
| 65 | 65 |
// ContainerStart starts a new container |
| 66 | 66 |
ContainerStart(ctx context.Context, containerID string, checkpoint string, checkpointDir string) error |
| 67 | 67 |
// ContainerWait stops processing until the given container is stopped. |
| 68 |
- ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan container.StateStatus, error) |
|
| 68 |
+ ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan containerpkg.StateStatus, error) |
|
| 69 | 69 |
} |
| 70 | 70 |
|
| 71 | 71 |
// Result is the output produced by a Builder |
| ... | ... |
@@ -7,6 +7,7 @@ import ( |
| 7 | 7 |
"runtime" |
| 8 | 8 |
|
| 9 | 9 |
"github.com/docker/docker/daemon/builder" |
| 10 |
+ containerpkg "github.com/docker/docker/daemon/container" |
|
| 10 | 11 |
"github.com/docker/docker/daemon/internal/image" |
| 11 | 12 |
"github.com/docker/docker/daemon/internal/layer" |
| 12 | 13 |
"github.com/docker/docker/daemon/server/backend" |
| ... | ... |
@@ -49,7 +50,7 @@ func (m *MockBackend) ContainerStart(ctx context.Context, containerID string, ch |
| 49 | 49 |
return nil |
| 50 | 50 |
} |
| 51 | 51 |
|
| 52 |
-func (m *MockBackend) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.StateStatus, error) {
|
|
| 52 |
+func (m *MockBackend) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan containerpkg.StateStatus, error) {
|
|
| 53 | 53 |
return nil, nil |
| 54 | 54 |
} |
| 55 | 55 |
|
| ... | ... |
@@ -8,6 +8,7 @@ import ( |
| 8 | 8 |
"github.com/distribution/reference" |
| 9 | 9 |
"github.com/docker/distribution" |
| 10 | 10 |
clustertypes "github.com/docker/docker/daemon/cluster/provider" |
| 11 |
+ containerpkg "github.com/docker/docker/daemon/container" |
|
| 11 | 12 |
"github.com/docker/docker/daemon/internal/image" |
| 12 | 13 |
"github.com/docker/docker/daemon/libnetwork" |
| 13 | 14 |
"github.com/docker/docker/daemon/libnetwork/cluster" |
| ... | ... |
@@ -44,7 +45,7 @@ type Backend interface {
|
| 44 | 44 |
DeactivateContainerServiceBinding(containerName string) error |
| 45 | 45 |
UpdateContainerServiceConfig(containerName string, serviceConfig *clustertypes.ServiceConfig) error |
| 46 | 46 |
ContainerInspect(ctx context.Context, name string, options backend.ContainerInspectOptions) (*container.InspectResponse, error) |
| 47 |
- ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan container.StateStatus, error) |
|
| 47 |
+ ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan containerpkg.StateStatus, error) |
|
| 48 | 48 |
ContainerRm(name string, config *backend.ContainerRmConfig) error |
| 49 | 49 |
ContainerKill(name string, sig string) error |
| 50 | 50 |
SetContainerDependencyStore(name string, store exec.DependencyGetter) error |
| ... | ... |
@@ -16,6 +16,7 @@ import ( |
| 16 | 16 |
"github.com/docker/docker/daemon" |
| 17 | 17 |
"github.com/docker/docker/daemon/cluster/convert" |
| 18 | 18 |
executorpkg "github.com/docker/docker/daemon/cluster/executor" |
| 19 |
+ containerpkg "github.com/docker/docker/daemon/container" |
|
| 19 | 20 |
"github.com/docker/docker/daemon/libnetwork" |
| 20 | 21 |
networkSettings "github.com/docker/docker/daemon/network" |
| 21 | 22 |
"github.com/docker/docker/daemon/server/backend" |
| ... | ... |
@@ -415,7 +416,7 @@ func (c *containerAdapter) events(ctx context.Context) <-chan events.Message {
|
| 415 | 415 |
return eventsq |
| 416 | 416 |
} |
| 417 | 417 |
|
| 418 |
-func (c *containerAdapter) wait(ctx context.Context) (<-chan containertypes.StateStatus, error) {
|
|
| 418 |
+func (c *containerAdapter) wait(ctx context.Context) (<-chan containerpkg.StateStatus, error) {
|
|
| 419 | 419 |
return c.backend.ContainerWait(ctx, c.container.nameOrID(), containertypes.WaitConditionNotRunning) |
| 420 | 420 |
} |
| 421 | 421 |
|
| ... | ... |
@@ -46,8 +46,8 @@ type State struct {
|
| 46 | 46 |
Health *Health |
| 47 | 47 |
Removed bool `json:"-"` |
| 48 | 48 |
|
| 49 |
- stopWaiters []chan<- container.StateStatus |
|
| 50 |
- removeOnlyWaiters []chan<- container.StateStatus |
|
| 49 |
+ stopWaiters []chan<- StateStatus |
|
| 50 |
+ removeOnlyWaiters []chan<- StateStatus |
|
| 51 | 51 |
|
| 52 | 52 |
// The libcontainerd reference fields are unexported to force consumers |
| 53 | 53 |
// to access them through the getter methods with multi-valued returns |
| ... | ... |
@@ -58,6 +58,26 @@ type State struct {
|
| 58 | 58 |
task libcontainerdtypes.Task |
| 59 | 59 |
} |
| 60 | 60 |
|
| 61 |
+// StateStatus is used to return container wait results. |
|
| 62 |
+// Implements exec.ExitCode interface. |
|
| 63 |
+// This type is needed as State include a sync.Mutex field which make |
|
| 64 |
+// copying it unsafe. |
|
| 65 |
+type StateStatus struct {
|
|
| 66 |
+ exitCode int |
|
| 67 |
+ err error |
|
| 68 |
+} |
|
| 69 |
+ |
|
| 70 |
+// ExitCode returns current exitcode for the state. |
|
| 71 |
+func (s StateStatus) ExitCode() int {
|
|
| 72 |
+ return s.exitCode |
|
| 73 |
+} |
|
| 74 |
+ |
|
| 75 |
+// Err returns current error for the state. Returns nil if the container had |
|
| 76 |
+// exited on its own. |
|
| 77 |
+func (s StateStatus) Err() error {
|
|
| 78 |
+ return s.err |
|
| 79 |
+} |
|
| 80 |
+ |
|
| 61 | 81 |
// NewState creates a default state object. |
| 62 | 82 |
func NewState() *State {
|
| 63 | 83 |
return &State{}
|
| ... | ... |
@@ -138,20 +158,23 @@ func (s *State) StateString() container.ContainerState {
|
| 138 | 138 |
// be nil and its ExitCode() method will return the container's exit code, |
| 139 | 139 |
// otherwise, the results Err() method will return an error indicating why the |
| 140 | 140 |
// wait operation failed. |
| 141 |
-func (s *State) Wait(ctx context.Context, condition container.WaitCondition) <-chan container.StateStatus {
|
|
| 141 |
+func (s *State) Wait(ctx context.Context, condition container.WaitCondition) <-chan StateStatus {
|
|
| 142 | 142 |
s.Lock() |
| 143 | 143 |
defer s.Unlock() |
| 144 | 144 |
|
| 145 | 145 |
// Buffer so we can put status and finish even nobody receives it. |
| 146 |
- resultC := make(chan container.StateStatus, 1) |
|
| 146 |
+ resultC := make(chan StateStatus, 1) |
|
| 147 | 147 |
|
| 148 | 148 |
if s.conditionAlreadyMet(condition) {
|
| 149 |
- resultC <- container.NewStateStatus(s.ExitCode(), s.Err()) |
|
| 149 |
+ resultC <- StateStatus{
|
|
| 150 |
+ exitCode: s.ExitCodeValue, |
|
| 151 |
+ err: s.Err(), |
|
| 152 |
+ } |
|
| 150 | 153 |
|
| 151 | 154 |
return resultC |
| 152 | 155 |
} |
| 153 | 156 |
|
| 154 |
- waitC := make(chan container.StateStatus, 1) |
|
| 157 |
+ waitC := make(chan StateStatus, 1) |
|
| 155 | 158 |
|
| 156 | 159 |
// Removal wakes up both removeOnlyWaiters and stopWaiters |
| 157 | 160 |
// Container could be removed while still in "created" state |
| ... | ... |
@@ -166,8 +189,10 @@ func (s *State) Wait(ctx context.Context, condition container.WaitCondition) <-c |
| 166 | 166 |
select {
|
| 167 | 167 |
case <-ctx.Done(): |
| 168 | 168 |
// Context timeout or cancellation. |
| 169 |
- resultC <- container.NewStateStatus(-1, ctx.Err()) |
|
| 170 |
- |
|
| 169 |
+ resultC <- StateStatus{
|
|
| 170 |
+ exitCode: -1, |
|
| 171 |
+ err: ctx.Err(), |
|
| 172 |
+ } |
|
| 171 | 173 |
return |
| 172 | 174 |
case status := <-waitC: |
| 173 | 175 |
resultC <- status |
| ... | ... |
@@ -397,8 +422,11 @@ func (s *State) Err() error {
|
| 397 | 397 |
return nil |
| 398 | 398 |
} |
| 399 | 399 |
|
| 400 |
-func (s *State) notifyAndClear(waiters *[]chan<- container.StateStatus) {
|
|
| 401 |
- result := container.NewStateStatus(s.ExitCodeValue, s.Err()) |
|
| 400 |
+func (s *State) notifyAndClear(waiters *[]chan<- StateStatus) {
|
|
| 401 |
+ result := StateStatus{
|
|
| 402 |
+ exitCode: s.ExitCodeValue, |
|
| 403 |
+ err: s.Err(), |
|
| 404 |
+ } |
|
| 402 | 405 |
|
| 403 | 406 |
for _, c := range *waiters {
|
| 404 | 407 |
c <- result |
| ... | ... |
@@ -4,6 +4,7 @@ import ( |
| 4 | 4 |
"context" |
| 5 | 5 |
"io" |
| 6 | 6 |
|
| 7 |
+ containerpkg "github.com/docker/docker/daemon/container" |
|
| 7 | 8 |
"github.com/docker/docker/daemon/server/backend" |
| 8 | 9 |
"github.com/moby/go-archive" |
| 9 | 10 |
"github.com/moby/moby/api/types/container" |
| ... | ... |
@@ -40,7 +41,7 @@ type stateBackend interface {
|
| 40 | 40 |
ContainerStop(ctx context.Context, name string, options container.StopOptions) error |
| 41 | 41 |
ContainerUnpause(name string) error |
| 42 | 42 |
ContainerUpdate(name string, hostConfig *container.HostConfig) (container.UpdateResponse, error) |
| 43 |
- ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan container.StateStatus, error) |
|
| 43 |
+ ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan containerpkg.StateStatus, error) |
|
| 44 | 44 |
} |
| 45 | 45 |
|
| 46 | 46 |
// monitorBackend includes functions to implement to provide containers monitoring functionality. |
| ... | ... |
@@ -3,6 +3,7 @@ package daemon |
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 | 5 |
|
| 6 |
+ "github.com/docker/docker/daemon/container" |
|
| 6 | 7 |
containertypes "github.com/moby/moby/api/types/container" |
| 7 | 8 |
) |
| 8 | 9 |
|
| ... | ... |
@@ -13,7 +14,7 @@ import ( |
| 13 | 13 |
// condition is met or if an error occurs waiting for the container (such as a |
| 14 | 14 |
// context timeout or cancellation). On a successful wait, the exit code of the |
| 15 | 15 |
// container is returned in the status with a non-nil Err() value. |
| 16 |
-func (daemon *Daemon) ContainerWait(ctx context.Context, name string, condition containertypes.WaitCondition) (<-chan containertypes.StateStatus, error) {
|
|
| 16 |
+func (daemon *Daemon) ContainerWait(ctx context.Context, name string, condition containertypes.WaitCondition) (<-chan container.StateStatus, error) {
|
|
| 17 | 17 |
cntr, err := daemon.GetContainer(name) |
| 18 | 18 |
if err != nil {
|
| 19 | 19 |
return nil, err |
| ... | ... |
@@ -34,31 +34,3 @@ func ValidateContainerState(s ContainerState) error {
|
| 34 | 34 |
return errInvalidParameter{error: fmt.Errorf("invalid value for state (%s): must be one of %s", s, strings.Join(validStates, ", "))}
|
| 35 | 35 |
} |
| 36 | 36 |
} |
| 37 |
- |
|
| 38 |
-// StateStatus is used to return container wait results. |
|
| 39 |
-// Implements exec.ExitCode interface. |
|
| 40 |
-// This type is needed as State include a sync.Mutex field which make |
|
| 41 |
-// copying it unsafe. |
|
| 42 |
-type StateStatus struct {
|
|
| 43 |
- exitCode int |
|
| 44 |
- err error |
|
| 45 |
-} |
|
| 46 |
- |
|
| 47 |
-// ExitCode returns current exitcode for the state. |
|
| 48 |
-func (s StateStatus) ExitCode() int {
|
|
| 49 |
- return s.exitCode |
|
| 50 |
-} |
|
| 51 |
- |
|
| 52 |
-// Err returns current error for the state. Returns nil if the container had |
|
| 53 |
-// exited on its own. |
|
| 54 |
-func (s StateStatus) Err() error {
|
|
| 55 |
- return s.err |
|
| 56 |
-} |
|
| 57 |
- |
|
| 58 |
-// NewStateStatus returns a new StateStatus with the given exit code and error. |
|
| 59 |
-func NewStateStatus(exitCode int, err error) StateStatus {
|
|
| 60 |
- return StateStatus{
|
|
| 61 |
- exitCode: exitCode, |
|
| 62 |
- err: err, |
|
| 63 |
- } |
|
| 64 |
-} |