daemon: Daemon.ContainerStart(): make validateState a regular function

There's no need for this to be a closure; let's just make it a regular
function. While moving it out, also make some minor code-changes and
add some code-comments to describe the flow / intent, which may not
be trivial for people that are not familiar with these details.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2023-08-11 20:46:53 +02:00
parent 896f246888
commit dffe634c19
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C

View file

@ -14,6 +14,30 @@ import (
"github.com/pkg/errors"
)
// validateState verifies if the container is in a non-conflicting state.
func validateState(ctr *container.Container) error {
ctr.Lock()
defer ctr.Unlock()
// Intentionally checking paused first, because a container can be
// BOTH running AND paused. To start a paused (but running) container,
// it must be thawed ("un-paused").
if ctr.Paused {
return errdefs.Conflict(errors.New("cannot start a paused container, try unpause instead"))
} else if ctr.Running {
// This is not an actual error, but produces a 304 "not modified"
// when returned through the API to indicates the container is
// already in the desired state. It's implemented as an error
// to make the code calling this function terminate early (as
// no further processing is needed).
return containerNotModifiedError{running: true}
}
if ctr.RemovalInProgress || ctr.Dead {
return errdefs.Conflict(errors.New("container is marked for removal and cannot be started"))
}
return nil
}
// ContainerStart starts a container.
func (daemon *Daemon) ContainerStart(ctx context.Context, name string, hostConfig *containertypes.HostConfig, checkpoint string, checkpointDir string) error {
daemonCfg := daemon.config()
@ -25,26 +49,7 @@ func (daemon *Daemon) ContainerStart(ctx context.Context, name string, hostConfi
if err != nil {
return err
}
validateState := func() error {
ctr.Lock()
defer ctr.Unlock()
if ctr.Paused {
return errdefs.Conflict(errors.New("cannot start a paused container, try unpause instead"))
}
if ctr.Running {
return containerNotModifiedError{running: true}
}
if ctr.RemovalInProgress || ctr.Dead {
return errdefs.Conflict(errors.New("container is marked for removal and cannot be started"))
}
return nil
}
if err := validateState(); err != nil {
if err := validateState(ctr); err != nil {
return err
}