Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
| ... | ... |
@@ -111,7 +111,7 @@ func New(config Config) (*Cluster, error) {
|
| 111 | 111 |
select {
|
| 112 | 112 |
case <-time.After(swarmConnectTimeout): |
| 113 | 113 |
logrus.Errorf("swarm component could not be started before timeout was reached")
|
| 114 |
- case <-n.Ready(context.Background()): |
|
| 114 |
+ case <-n.Ready(): |
|
| 115 | 115 |
case <-ctx.Done(): |
| 116 | 116 |
} |
| 117 | 117 |
if ctx.Err() != nil {
|
| ... | ... |
@@ -213,7 +213,7 @@ func (c *Cluster) startNewNode(forceNewCluster bool, listenAddr, joinAddr, secre |
| 213 | 213 |
|
| 214 | 214 |
go func() {
|
| 215 | 215 |
select {
|
| 216 |
- case <-node.Ready(context.Background()): |
|
| 216 |
+ case <-node.Ready(): |
|
| 217 | 217 |
c.Lock() |
| 218 | 218 |
c.reconnectDelay = initialReconnectDelay |
| 219 | 219 |
c.Unlock() |
| ... | ... |
@@ -273,7 +273,7 @@ func (c *Cluster) Init(req types.InitRequest) (string, error) {
|
| 273 | 273 |
c.Unlock() |
| 274 | 274 |
|
| 275 | 275 |
select {
|
| 276 |
- case <-n.Ready(context.Background()): |
|
| 276 |
+ case <-n.Ready(): |
|
| 277 | 277 |
if err := initAcceptancePolicy(n, req.Spec.AcceptancePolicy); err != nil {
|
| 278 | 278 |
return "", err |
| 279 | 279 |
} |
| ... | ... |
@@ -319,7 +319,7 @@ func (c *Cluster) Join(req types.JoinRequest) error {
|
| 319 | 319 |
return fmt.Errorf("Timeout reached before node was joined. Your cluster settings may be preventing this node from automatically joining. To accept this node into cluster run `docker node accept %v` in an existing cluster manager", nodeid)
|
| 320 | 320 |
} |
| 321 | 321 |
return ErrSwarmJoinTimeoutReached |
| 322 |
- case <-n.Ready(context.Background()): |
|
| 322 |
+ case <-n.Ready(): |
|
| 323 | 323 |
go c.reconnectOnFailure(ctx) |
| 324 | 324 |
return nil |
| 325 | 325 |
case <-ctx.Done(): |
| ... | ... |
@@ -39,7 +39,7 @@ func newContainerAdapter(b executorpkg.Backend, task *api.Task) (*containerAdapt |
| 39 | 39 |
|
| 40 | 40 |
func (c *containerAdapter) pullImage(ctx context.Context) error {
|
| 41 | 41 |
// if the image needs to be pulled, the auth config will be retrieved and updated |
| 42 |
- encodedAuthConfig := c.container.task.ServiceAnnotations.Labels[fmt.Sprintf("%v.registryauth", systemLabelPrefix)]
|
|
| 42 |
+ encodedAuthConfig := c.container.spec().RegistryAuth |
|
| 43 | 43 |
|
| 44 | 44 |
authConfig := &types.AuthConfig{}
|
| 45 | 45 |
if encodedAuthConfig != "" {
|
| ... | ... |
@@ -2,13 +2,13 @@ package container |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
- "strings" |
|
| 6 | 5 |
|
| 7 | 6 |
executorpkg "github.com/docker/docker/daemon/cluster/executor" |
| 8 | 7 |
"github.com/docker/engine-api/types" |
| 9 | 8 |
"github.com/docker/swarmkit/agent/exec" |
| 10 | 9 |
"github.com/docker/swarmkit/api" |
| 11 | 10 |
"github.com/docker/swarmkit/log" |
| 11 |
+ "github.com/pkg/errors" |
|
| 12 | 12 |
"golang.org/x/net/context" |
| 13 | 13 |
) |
| 14 | 14 |
|
| ... | ... |
@@ -84,31 +84,32 @@ func (r *controller) Prepare(ctx context.Context) error {
|
| 84 | 84 |
return err |
| 85 | 85 |
} |
| 86 | 86 |
|
| 87 |
- for {
|
|
| 88 |
- if err := r.checkClosed(); err != nil {
|
|
| 89 |
- return err |
|
| 90 |
- } |
|
| 91 |
- if err := r.adapter.create(ctx, r.backend); err != nil {
|
|
| 92 |
- if isContainerCreateNameConflict(err) {
|
|
| 93 |
- if _, err := r.adapter.inspect(ctx); err != nil {
|
|
| 94 |
- return err |
|
| 95 |
- } |
|
| 96 |
- |
|
| 97 |
- // container is already created. success! |
|
| 98 |
- return exec.ErrTaskPrepared |
|
| 99 |
- } |
|
| 87 |
+ if err := r.adapter.pullImage(ctx); err != nil {
|
|
| 88 |
+ // NOTE(stevvooe): We always try to pull the image to make sure we have |
|
| 89 |
+ // the most up to date version. This will return an error, but we only |
|
| 90 |
+ // log it. If the image truly doesn't exist, the create below will |
|
| 91 |
+ // error out. |
|
| 92 |
+ // |
|
| 93 |
+ // This gives us some nice behavior where we use up to date versions of |
|
| 94 |
+ // mutable tags, but will still run if the old image is available but a |
|
| 95 |
+ // registry is down. |
|
| 96 |
+ // |
|
| 97 |
+ // If you don't want this behavior, lock down your image to an |
|
| 98 |
+ // immutable tag or digest. |
|
| 99 |
+ log.G(ctx).WithError(err).Error("pulling image failed")
|
|
| 100 |
+ } |
|
| 100 | 101 |
|
| 101 |
- if !strings.Contains(err.Error(), "No such image") { // todo: better error detection
|
|
| 102 |
- return err |
|
| 103 |
- } |
|
| 104 |
- if err := r.adapter.pullImage(ctx); err != nil {
|
|
| 102 |
+ if err := r.adapter.create(ctx, r.backend); err != nil {
|
|
| 103 |
+ if isContainerCreateNameConflict(err) {
|
|
| 104 |
+ if _, err := r.adapter.inspect(ctx); err != nil {
|
|
| 105 | 105 |
return err |
| 106 | 106 |
} |
| 107 | 107 |
|
| 108 |
- continue // retry to create the container |
|
| 108 |
+ // container is already created. success! |
|
| 109 |
+ return exec.ErrTaskPrepared |
|
| 109 | 110 |
} |
| 110 | 111 |
|
| 111 |
- break |
|
| 112 |
+ return err |
|
| 112 | 113 |
} |
| 113 | 114 |
|
| 114 | 115 |
return nil |
| ... | ... |
@@ -135,7 +136,7 @@ func (r *controller) Start(ctx context.Context) error {
|
| 135 | 135 |
} |
| 136 | 136 |
|
| 137 | 137 |
if err := r.adapter.start(ctx); err != nil {
|
| 138 |
- return err |
|
| 138 |
+ return errors.Wrap(err, "starting container failed") |
|
| 139 | 139 |
} |
| 140 | 140 |
|
| 141 | 141 |
return nil |