diff options
author | Daniel J Walsh <dwalsh@redhat.com> | 2021-05-20 16:09:40 -0400 |
---|---|---|
committer | Matthew Heon <mheon@redhat.com> | 2021-05-25 15:25:02 -0400 |
commit | ba884865c58d83d7a020bfb7fe90a182ebbe1405 (patch) | |
tree | 9e7ca87227bdedd1d440767442fb0d2cb62deba9 /pkg/bindings/images/build.go | |
parent | c53638e9f61e61b1344cbf090c9766a1891c8a44 (diff) | |
download | podman-ba884865c58d83d7a020bfb7fe90a182ebbe1405.tar.gz podman-ba884865c58d83d7a020bfb7fe90a182ebbe1405.tar.bz2 podman-ba884865c58d83d7a020bfb7fe90a182ebbe1405.zip |
Handle hard links in remote builds
Fixes: https://github.com/containers/podman/issues/9893
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Diffstat (limited to 'pkg/bindings/images/build.go')
-rw-r--r-- | pkg/bindings/images/build.go | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go index f5e7c0c98..b56afbceb 100644 --- a/pkg/bindings/images/build.go +++ b/pkg/bindings/images/build.go @@ -28,6 +28,11 @@ import ( "github.com/sirupsen/logrus" ) +type devino struct { + Dev uint64 + Ino uint64 +} + var ( iidRegex = regexp.MustCompile(`^[0-9a-f]{12}`) ) @@ -402,7 +407,7 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) { defer pw.Close() defer gw.Close() defer tw.Close() - + seen := make(map[devino]string) for _, src := range sources { s, err := filepath.Abs(src) if err != nil { @@ -431,25 +436,40 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) { } if info.Mode().IsRegular() { // add file item - f, lerr := os.Open(path) - if lerr != nil { - return lerr + di, isHardLink := checkHardLink(info) + if err != nil { + return err } - hdr, lerr := tar.FileInfoHeader(info, name) - if lerr != nil { - f.Close() - return lerr + hdr, err := tar.FileInfoHeader(info, "") + if err != nil { + return err + } + orig, ok := seen[di] + if ok { + hdr.Typeflag = tar.TypeLink + hdr.Linkname = orig + hdr.Size = 0 + + return tw.WriteHeader(hdr) + } + f, err := os.Open(path) + if err != nil { + return err } + hdr.Name = name - if lerr := tw.WriteHeader(hdr); lerr != nil { + if err := tw.WriteHeader(hdr); err != nil { f.Close() - return lerr + return err } - _, cerr := io.Copy(tw, f) + _, err = io.Copy(tw, f) f.Close() - return cerr + if err == nil && isHardLink { + seen[di] = name + } + return err } else if info.Mode().IsDir() { // add folders hdr, lerr := tar.FileInfoHeader(info, name) if lerr != nil { |