From f8273a216ed35e22ac157dee8055393f07d4be39 Mon Sep 17 00:00:00 2001 From: Aaron Lehmann Date: Mon, 6 Mar 2017 16:05:56 -0800 Subject: [PATCH] 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 --- daemon/cluster/services.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/daemon/cluster/services.go b/daemon/cluster/services.go index ec5a58c02d..d5f6174151 100644 --- a/daemon/cluster/services.go +++ b/daemon/cluster/services.go @@ -118,6 +118,16 @@ func (c *Cluster) CreateService(s types.ServiceSpec, encodedAuth string) (*apity } else { 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}) @@ -207,6 +217,16 @@ func (c *Cluster) UpdateService(serviceIDOrName string, version uint64, spec typ } else { 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