From 06a4e9658be3d997a601d6b13987459570227901 Mon Sep 17 00:00:00 2001 From: Michael Teichgraeber Date: Sun, 10 Jun 2018 23:30:16 +0200 Subject: [PATCH] image: fix the interaction of findManifest and findConfig with walker.find MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before rev. 9027d58 findManifest and findConfig called w.walk directly, providing a walkFunc that returned errEOW in case a file has been found and processed successfully. A switch construct evaluating the error-result of w.walk then tested for the errEOW case, meaning the file has been found. Starting with rev. 9027d58 the call to w.walk in findManifest and findConfig has been replaced by w.find. Though, the function literal provided by findManifest and findConfig to w.find -- now a findFunc, not a walkFunc anymore -- still returns errEOW. As a consequence, walker.find implementations for tar and zip would treat errEOW as an error, making oci-image-tool 'validate' and 'create' stop with an error: : find failed: unable to walk: end of walk This patch adjusts tarWalker's and zipWalker's implementations of walker.find, using errEOW to stop w.walk early in case of success; there is no need for the 'done' variable anymore. Additionally, places where w.find is called, functions findManifest, unpackManifest, and findConfig, have been adapted so that their findFunc argument to w.find does not return errEOW anymore; instead nil is returned on success. Consequently, the switch constructs now test err for 'nil' instead of 'errEOW', and 'os.ErrNotExist' instead of nil. Fixes #205 Signed-off-by: Michael Teichgräber --- image/config.go | 7 ++++--- image/manifest.go | 11 +++++------ image/walker.go | 32 ++++++++++++-------------------- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/image/config.go b/image/config.go index 4571199..8f3f0fa 100644 --- a/image/config.go +++ b/image/config.go @@ -20,6 +20,7 @@ import ( "fmt" "io" "io/ioutil" + "os" "path/filepath" "strconv" "strings" @@ -48,11 +49,11 @@ func findConfig(w walker, d *v1.Descriptor) (*v1.Image, error) { return err } - return errEOW + return nil }); err { - case nil: + case os.ErrNotExist: return nil, fmt.Errorf("%s: config not found", cpath) - case errEOW: + case nil: return &c, nil default: return nil, err diff --git a/image/manifest.go b/image/manifest.go index 83bce0f..9c29212 100644 --- a/image/manifest.go +++ b/image/manifest.go @@ -53,11 +53,11 @@ func findManifest(w walker, d *v1.Descriptor) (*v1.Manifest, error) { return err } - return errEOW + return nil }); err { - case nil: + case os.ErrNotExist: return nil, fmt.Errorf("%s: manifest not found", mpath) - case errEOW: + case nil: return &m, nil default: return nil, err @@ -110,11 +110,10 @@ func unpackManifest(m *v1.Manifest, w walker, dest string) (retErr error) { return errors.Wrap(err, "unpack: error extracting layer") } - return errEOW + return nil }); err { - case nil: + case os.ErrNotExist: return fmt.Errorf("%s: layer not found", dest) - case errEOW: default: return err } diff --git a/image/walker.go b/image/walker.go index 88b01df..9ec634b 100644 --- a/image/walker.go +++ b/image/walker.go @@ -126,28 +126,24 @@ func (w *tarWalker) get(desc v1.Descriptor, dst io.Writer) (int64, error) { } func (w *tarWalker) find(path string, ff findFunc) error { - done := false - f := func(relpath string, info os.FileInfo, rdr io.Reader) error { var err error - if done { - return nil - } if filepath.Clean(relpath) == path && !info.IsDir() { if err = ff(relpath, rdr); err != nil { return err } - done = true + return errEOW } return nil } - if err := w.walk(f); err != nil { - return errors.Wrapf(err, "find failed: unable to walk") - } - if !done { + switch err := w.walk(f); err { + case nil: return os.ErrNotExist + case errEOW: + default: + return errors.Wrapf(err, "find failed: unable to walk") } return nil @@ -305,28 +301,24 @@ func (w *zipWalker) get(desc v1.Descriptor, dst io.Writer) (int64, error) { } func (w *zipWalker) find(path string, ff findFunc) error { - done := false - f := func(relpath string, info os.FileInfo, rdr io.Reader) error { var err error - if done { - return nil - } if filepath.Clean(relpath) == path && !info.IsDir() { if err = ff(relpath, rdr); err != nil { return err } - done = true + return errEOW } return nil } - if err := w.walk(f); err != nil { - return errors.Wrapf(err, "find failed: unable to walk") - } - if !done { + switch err := w.walk(f); err { + case nil: return os.ErrNotExist + case errEOW: + default: + return errors.Wrapf(err, "find failed: unable to walk") } return nil