Add code to return message field of returned registry errors

Docker registries return errors in a know format so this change now checks for these
errors and returns the message field. If the error is not in the expected format fall
back to the original behaviour.

https://github.com/containerd/containerd/issues/3076

Signed-off-by: Jack Baines <jack.baines@uk.ibm.com>
This commit is contained in:
Jack Baines
2019-03-19 15:30:37 +00:00
parent 5840ecc3d8
commit 908b771086
5 changed files with 526 additions and 1 deletions

View File

@@ -18,6 +18,7 @@ package docker
import (
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
@@ -25,6 +26,8 @@ import (
"path"
"strings"
"github.com/docker/distribution/registry/api/errcode"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/log"
@@ -102,10 +105,18 @@ func (r dockerFetcher) open(ctx context.Context, u, mediatype string, offset int
// can discard the bytes, hiding the seek behavior from the
// implementation.
resp.Body.Close()
defer resp.Body.Close()
if resp.StatusCode == http.StatusNotFound {
return nil, errors.Wrapf(errdefs.ErrNotFound, "content at %v not found", u)
}
body, err := ioutil.ReadAll(resp.Body)
if err == nil {
dockerErr := errcode.Errors{}
err := json.Unmarshal(body, &dockerErr)
if err == nil && dockerErr.Len() > 0 {
return nil, errors.Errorf("unexpected status code %v: %s - Server message: %s", u, resp.Status, dockerErr.Error())
}
}
return nil, errors.Errorf("unexpected status code %v: %v", u, resp.Status)
}
if offset > 0 {