From a2fc45e627befa996487cd115099c9b613d39f5b Mon Sep 17 00:00:00 2001 From: unclejack Date: Wed, 19 Mar 2014 20:37:36 +0200 Subject: [PATCH] retry to retrieve metadata on failure during pull This makes Docker retry to retrieve the JSON metadata for the layers. Docker will make 5 attempts to retrieve the metadata before failing and it will increase the delay between attempts after each failed attempt. This is a backport of PR #4387. The following changes had to be made: - img *image.Image + img *Image - img, err = image.NewImgJSON(imgJSON) + img, err = NewImgJSON(imgJSON) Docker-DCO-1.1-Signed-off-by: Cristian Staretu (github: unclejack) --- server.go | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/server.go b/server.go index c5ad24c4b..d6513d874 100644 --- a/server.go +++ b/server.go @@ -1067,16 +1067,32 @@ func (srv *Server) pullImage(r *registry.Registry, out io.Writer, imgID, endpoin if !srv.runtime.graph.Exists(id) { out.Write(sf.FormatProgress(utils.TruncateID(id), "Pulling metadata", nil)) - imgJSON, imgSize, err := r.GetRemoteImageJSON(id, endpoint, token) - if err != nil { - out.Write(sf.FormatProgress(utils.TruncateID(id), "Error pulling dependent layers", nil)) - // FIXME: Keep going in case of error? - return err - } - img, err := NewImgJSON(imgJSON) - if err != nil { - out.Write(sf.FormatProgress(utils.TruncateID(id), "Error pulling dependent layers", nil)) - return fmt.Errorf("Failed to parse json: %s", err) + var ( + imgJSON []byte + imgSize int + err error + img *Image + ) + retries := 5 + for j := 1; j <= retries; j++ { + imgJSON, imgSize, err = r.GetRemoteImageJSON(id, endpoint, token) + if err != nil && j == retries { + out.Write(sf.FormatProgress(utils.TruncateID(id), "Error pulling dependent layers", nil)) + return err + } else if err != nil { + time.Sleep(time.Duration(j) * 500 * time.Millisecond) + continue + } + img, err = NewImgJSON(imgJSON) + if err != nil && j == retries { + out.Write(sf.FormatProgress(utils.TruncateID(id), "Error pulling dependent layers", nil)) + return fmt.Errorf("Failed to parse json: %s", err) + } else if err != nil { + time.Sleep(time.Duration(j) * 500 * time.Millisecond) + continue + } else { + break + } } // Get the layer