From 2cfcf42d50b469abfb0e13245726371d445b76e4 Mon Sep 17 00:00:00 2001 From: unclejack Date: Fri, 28 Feb 2014 18:42:20 +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. 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 d6a4036faf..4876f31bae 100644 --- a/server.go +++ b/server.go @@ -1086,16 +1086,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 := image.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.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 = image.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