|
@@ -2,13 +2,13 @@ package container
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
- "strings"
|
|
|
|
|
|
executorpkg "github.com/docker/docker/daemon/cluster/executor"
|
|
|
"github.com/docker/engine-api/types"
|
|
|
"github.com/docker/swarmkit/agent/exec"
|
|
|
"github.com/docker/swarmkit/api"
|
|
|
"github.com/docker/swarmkit/log"
|
|
|
+ "github.com/pkg/errors"
|
|
|
"golang.org/x/net/context"
|
|
|
)
|
|
|
|
|
@@ -84,31 +84,32 @@ func (r *controller) Prepare(ctx context.Context) error {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- for {
|
|
|
- if err := r.checkClosed(); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- if err := r.adapter.create(ctx, r.backend); err != nil {
|
|
|
- if isContainerCreateNameConflict(err) {
|
|
|
- if _, err := r.adapter.inspect(ctx); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- // container is already created. success!
|
|
|
- return exec.ErrTaskPrepared
|
|
|
- }
|
|
|
+ if err := r.adapter.pullImage(ctx); err != nil {
|
|
|
+ // NOTE(stevvooe): We always try to pull the image to make sure we have
|
|
|
+ // the most up to date version. This will return an error, but we only
|
|
|
+ // log it. If the image truly doesn't exist, the create below will
|
|
|
+ // error out.
|
|
|
+ //
|
|
|
+ // This gives us some nice behavior where we use up to date versions of
|
|
|
+ // mutable tags, but will still run if the old image is available but a
|
|
|
+ // registry is down.
|
|
|
+ //
|
|
|
+ // If you don't want this behavior, lock down your image to an
|
|
|
+ // immutable tag or digest.
|
|
|
+ log.G(ctx).WithError(err).Error("pulling image failed")
|
|
|
+ }
|
|
|
|
|
|
- if !strings.Contains(err.Error(), "No such image") { // todo: better error detection
|
|
|
- return err
|
|
|
- }
|
|
|
- if err := r.adapter.pullImage(ctx); err != nil {
|
|
|
+ if err := r.adapter.create(ctx, r.backend); err != nil {
|
|
|
+ if isContainerCreateNameConflict(err) {
|
|
|
+ if _, err := r.adapter.inspect(ctx); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- continue // retry to create the container
|
|
|
+ // container is already created. success!
|
|
|
+ return exec.ErrTaskPrepared
|
|
|
}
|
|
|
|
|
|
- break
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
return nil
|
|
@@ -135,7 +136,7 @@ func (r *controller) Start(ctx context.Context) error {
|
|
|
}
|
|
|
|
|
|
if err := r.adapter.start(ctx); err != nil {
|
|
|
- return err
|
|
|
+ return errors.Wrap(err, "starting container failed")
|
|
|
}
|
|
|
|
|
|
return nil
|