diff --git a/pkg/lib/dir.go b/pkg/lib/dir.go index 5df8f420..6a60d30f 100644 --- a/pkg/lib/dir.go +++ b/pkg/lib/dir.go @@ -10,16 +10,6 @@ import ( "github.com/pkg/errors" ) -func IsSymlink(p string) bool { - fi, err := os.Lstat(p) - if err != nil { - // Some people can't be helped - return false - } - - return fi.Mode()&os.ModeSymlink != 0 -} - // DirCopy copies a whole directory recursively func DirCopy(dest string, source string) error { diff --git a/pkg/lib/dir_test.go b/pkg/lib/dir_test.go index c9beaf59..3d455ba0 100644 --- a/pkg/lib/dir_test.go +++ b/pkg/lib/dir_test.go @@ -19,7 +19,7 @@ func TestDir(t *testing.T) { _, err = src.Write([]byte("hello world!")) So(err, ShouldBeNil) - ok := lib.IsSymlink(src.Name()) + ok, _ := lib.IsSymlink(src.Name()) So(ok, ShouldBeFalse) }) diff --git a/pkg/lib/file.go b/pkg/lib/file.go index a8d16041..e52e5dd9 100644 --- a/pkg/lib/file.go +++ b/pkg/lib/file.go @@ -111,3 +111,26 @@ func FindFiles(base, pattern string) ([]string, error) { return paths, err } + +func IsSymlink(path string) (bool, error) { + statInfo, err := os.Lstat(path) + if err != nil { + return false, err + } + return (statInfo.Mode() & os.ModeSymlink) != 0, nil +} + +func PathExists(path string) bool { + statInfo, err := os.Stat(path) + if statInfo == nil { + isLink, err := IsSymlink(path) + if err != nil { + return false + } + return isLink + } + if err != nil && os.IsNotExist(err) { + return false + } + return true +} diff --git a/pkg/overlay/pack.go b/pkg/overlay/pack.go index a9b30fbc..1053e306 100644 --- a/pkg/overlay/pack.go +++ b/pkg/overlay/pack.go @@ -151,7 +151,7 @@ func ConvertAndOutput(config types.StackerConfig, tag, name string, layerType ty // slight hack, but this is much faster than a cp, and the // layers are the same, just in different formats - if !PathExists(overlayPath(config.RootFSDir, desc.Digest)) { + if !lib.PathExists(overlayPath(config.RootFSDir, desc.Digest)) { err = os.Symlink(overlayPath(config.RootFSDir, theLayer.Digest), overlayPath(config.RootFSDir, desc.Digest)) if err != nil { return errors.Wrapf(err, "failed to create squashfs symlink") @@ -169,29 +169,6 @@ func ConvertAndOutput(config types.StackerConfig, tag, name string, layerType ty return nil } -func IsSymlink(path string) (bool, error) { - statInfo, err := os.Lstat(path) - if err != nil { - return false, err - } - return (statInfo.Mode() & os.ModeSymlink) != 0, nil -} - -func PathExists(path string) bool { - statInfo, err := os.Stat(path) - if statInfo == nil { - isLink, err := IsSymlink(path) - if err != nil { - return false - } - return isLink - } - if err != nil && os.IsNotExist(err) { - return false - } - return true -} - func lookupManifestInDir(dir, name string) (ispec.Manifest, error) { oci, err := umoci.OpenLayout(dir) if err != nil { @@ -374,7 +351,7 @@ func stripOverlayAttrsUnder(dirPath string) error { return err } p := filepath.Join(dirPath, path) - if lib.IsSymlink(p) { + if isSymlink, _ := lib.IsSymlink(p); isSymlink { // user.* xattrs "can not" exist on symlinks return nil } diff --git a/pkg/stacker/build.go b/pkg/stacker/build.go index d51b8f9f..8d5ce707 100644 --- a/pkg/stacker/build.go +++ b/pkg/stacker/build.go @@ -340,13 +340,30 @@ func (b *Builder) build(s types.Storage, file string) error { log.Debugf("Dependency Order %v", order) var oci casext.Engine - if _, statErr := os.Stat(opts.Config.OCIDir); statErr != nil { - oci, err = umoci.CreateLayout(opts.Config.OCIDir) - } else { + ocidirstat, statErr := os.Stat(opts.Config.OCIDir) + + // if it exists, it is a directory, and it has an index.json, try openlayout + // otherwise try createlayout + + if statErr == nil { + if !ocidirstat.IsDir() { + return errors.Errorf("parameter oci-dir=%q exists but is not a directory.", opts.Config.OCIDir) + } + if !lib.PathExists(filepath.Join(opts.Config.OCIDir, "index.json")) { + return errors.Errorf("parameter oci-dir=%q exists but does not look like an OCI Layout.", opts.Config.OCIDir) + } + oci, err = umoci.OpenLayout(opts.Config.OCIDir) - } - if err != nil { - return err + if err != nil { + return errors.Wrapf(err, "could not open OCI layout at %q", opts.Config.OCIDir) + } + } else { + log.Infof("Creating new OCI Layout at %q", opts.Config.OCIDir) + oci, err = umoci.CreateLayout(opts.Config.OCIDir) + if err != nil { + return errors.Wrapf(err, "could not create layout at %q", opts.Config.OCIDir) + } + } defer oci.Close()