Sfoglia il codice sorgente

cluster: Renew the context after communicating with the registry

When pinning by digest, the registry might be slow or unresponsive. This
could cause the context to already be expired by the time UpdateService
or CreateService is called. We want digest pinning to be a best-effort
operation, so it's problematic if a slow or misbehaving registry
prevents the service operation from completing. Replace the context
after communicating with the registry, so we have a fresh timeout for
the gRPC call.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Aaron Lehmann 8 anni fa
parent
commit
f8273a216e
1 ha cambiato i file con 20 aggiunte e 0 eliminazioni
  1. 20 0
      daemon/cluster/services.go

+ 20 - 0
daemon/cluster/services.go

@@ -118,6 +118,16 @@ func (c *Cluster) CreateService(s types.ServiceSpec, encodedAuth string) (*apity
 			} else {
 			} else {
 				logrus.Debugf("creating service using supplied digest reference %s", ctnr.Image)
 				logrus.Debugf("creating service using supplied digest reference %s", ctnr.Image)
 			}
 			}
+
+			// Replace the context with a fresh one.
+			// If we timed out while communicating with the
+			// registry, then "ctx" will already be expired, which
+			// would cause UpdateService below to fail. Reusing
+			// "ctx" could make it impossible to create a service
+			// if the registry is slow or unresponsive.
+			var cancel func()
+			ctx, cancel = c.getRequestContext()
+			defer cancel()
 		}
 		}
 
 
 		r, err := state.controlClient.CreateService(ctx, &swarmapi.CreateServiceRequest{Spec: &serviceSpec})
 		r, err := state.controlClient.CreateService(ctx, &swarmapi.CreateServiceRequest{Spec: &serviceSpec})
@@ -207,6 +217,16 @@ func (c *Cluster) UpdateService(serviceIDOrName string, version uint64, spec typ
 			} else {
 			} else {
 				logrus.Debugf("updating service using supplied digest reference %s", newCtnr.Image)
 				logrus.Debugf("updating service using supplied digest reference %s", newCtnr.Image)
 			}
 			}
+
+			// Replace the context with a fresh one.
+			// If we timed out while communicating with the
+			// registry, then "ctx" will already be expired, which
+			// would cause UpdateService below to fail. Reusing
+			// "ctx" could make it impossible to update a service
+			// if the registry is slow or unresponsive.
+			var cancel func()
+			ctx, cancel = c.getRequestContext()
+			defer cancel()
 		}
 		}
 
 
 		var rollback swarmapi.UpdateServiceRequest_Rollback
 		var rollback swarmapi.UpdateServiceRequest_Rollback