diff --git a/image/config.go b/image/config.go index 944a921aa..857f6c82e 100644 --- a/image/config.go +++ b/image/config.go @@ -53,9 +53,9 @@ func findConfig(w walker, d *descriptor) (*config, error) { var c config cpath := filepath.Join("blobs", d.normalizeDigest()) - if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { + switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { if info.IsDir() || filepath.Clean(path) != cpath { - return fmt.Errorf("%s: config not found", cpath) + return nil } buf, err := ioutil.ReadAll(r) if err != nil { @@ -69,12 +69,15 @@ func findConfig(w walker, d *descriptor) (*config, error) { if err := json.Unmarshal(buf, &c); err != nil { return err } - - return nil - }); err != nil { + return errEOW + }); err { + case nil: + return nil, fmt.Errorf("%s: config not found", cpath) + case errEOW: + return &c, nil + default: return nil, err } - return &c, nil } func (c *config) runtimeSpec(rootfs string) (*specs.Spec, error) { diff --git a/image/descriptor.go b/image/descriptor.go index 8ecba38c3..d1e5d601f 100644 --- a/image/descriptor.go +++ b/image/descriptor.go @@ -41,44 +41,49 @@ func findDescriptor(w walker, name string) (*descriptor, error) { var d descriptor dpath := filepath.Join("refs", name) - if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { + switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { if info.IsDir() || filepath.Clean(path) != dpath { - return fmt.Errorf("%s: descriptor not found", dpath) + return nil } if err := json.NewDecoder(r).Decode(&d); err != nil { return err } - return nil - }); err != nil { + return errEOW + }); err { + case nil: + return nil, fmt.Errorf("%s: descriptor not found", dpath) + case errEOW: + return &d, nil + default: return nil, err } - - return &d, nil } func (d *descriptor) validate(w walker) error { - if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { + switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { if info.IsDir() { - return fmt.Errorf("%s: not found", d.normalizeDigest()) + return nil } digest, err := filepath.Rel("blobs", filepath.Clean(path)) if err != nil || d.normalizeDigest() != digest { - return fmt.Errorf("%s: not found", d.normalizeDigest()) + return nil } if err := d.validateContent(r); err != nil { return err } - + return errEOW + }); err { + case nil: + return fmt.Errorf("%s: not found", d.normalizeDigest()) + case errEOW: return nil - }); err != nil { + default: return errors.Wrapf(err, "%s: validation failed", d.normalizeDigest()) } - - return nil } func (d *descriptor) validateContent(r io.Reader) error { diff --git a/image/manifest.go b/image/manifest.go index 7af8a0922..227b24a03 100644 --- a/image/manifest.go +++ b/image/manifest.go @@ -40,9 +40,9 @@ func findManifest(w walker, d *descriptor) (*manifest, error) { var m manifest mpath := filepath.Join("blobs", d.normalizeDigest()) - if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { + switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { if info.IsDir() || filepath.Clean(path) != mpath { - return fmt.Errorf("%s: manifest not found", mpath) + return nil } buf, err := ioutil.ReadAll(r) @@ -62,12 +62,15 @@ func findManifest(w walker, d *descriptor) (*manifest, error) { return fmt.Errorf("%s: no layers found", path) } - return nil - }); err != nil { + return errEOW + }); err { + case nil: + return nil, fmt.Errorf("%s: manifest not found", mpath) + case errEOW: + return &m, nil + default: return nil, err } - - return &m, nil } func (m *manifest) validate(w walker) error { @@ -90,26 +93,30 @@ func (m *manifest) unpack(w walker, dest string) error { continue } - if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { + switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { if info.IsDir() { - return fmt.Errorf("%s: blob digest not found", d.normalizeDigest()) + return nil } dd, err := filepath.Rel("blobs", filepath.Clean(path)) if err != nil || d.normalizeDigest() != dd { - return fmt.Errorf("%s: blob digest not found", d.normalizeDigest()) + return nil } if err := unpackLayer(dest, r); err != nil { return errors.Wrap(err, "error extracting layer") } + return errEOW + }); err { + case nil: + return fmt.Errorf("%s: layer not found", dest) + case errEOW: return nil - }); err != nil { + default: return err } } - return nil } diff --git a/image/walker.go b/image/walker.go index 74c0aae52..777bce7d5 100644 --- a/image/walker.go +++ b/image/walker.go @@ -16,6 +16,7 @@ package image import ( "archive/tar" + "fmt" "io" "os" "path/filepath" @@ -23,6 +24,10 @@ import ( "github.com/pkg/errors" ) +var ( + errEOW = fmt.Errorf("end of walk") // error to signal stop walking +) + // walkFunc is a function type that gets called for each file or directory visited by the Walker. type walkFunc func(path string, _ os.FileInfo, _ io.Reader) error