Merge pull request #10421 from rhatdan/build

Handle hard links in remote builds
This commit is contained in:
OpenShift Merge Robot 2021-05-24 16:38:26 +02:00 committed by GitHub
commit 2311a02c38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 12 deletions

View file

@ -382,6 +382,9 @@ bin/podman.cross.%: .gopathok
.PHONY: local-cross
local-cross: $(CROSS_BUILD_TARGETS) ## Cross compile podman binary for multiple architectures
.PHONY: cross
cross: local-cross
# Update nix/nixpkgs.json its latest stable commit
.PHONY: nixpkgs
nixpkgs:

View file

@ -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 {

View file

@ -0,0 +1,16 @@
// +build !windows
package images
import (
"os"
"syscall"
)
func checkHardLink(fi os.FileInfo) (devino, bool) {
st := fi.Sys().(*syscall.Stat_t)
return devino{
Dev: uint64(st.Dev),
Ino: uint64(st.Ino),
}, st.Nlink > 1
}

View file

@ -0,0 +1,9 @@
package images
import (
"os"
)
func checkHardLink(fi os.FileInfo) (devino, bool) {
return devino{}, false
}

View file

@ -766,6 +766,26 @@ EOF
is "$output" ".*/tmp/bogus: no such file or directory"
}
@test "podman build COPY hardlinks " {
tmpdir=$PODMAN_TMPDIR/build-test
mkdir -p $tmpdir
dockerfile=$tmpdir/Dockerfile
cat >$dockerfile <<EOF
FROM $IMAGE
COPY . /test
EOF
ln $dockerfile $tmpdir/hardlink
run_podman build -t build_test $tmpdir
run_podman run --rm build_test stat -c '%i' /test/Dockerfile
dinode=$output
run_podman run --rm build_test stat -c '%i' /test/hardlink
is "$output" "$dinode" "COPY hardlinks work"
run_podman rmi -f build_test
}
function teardown() {
# A timeout or other error in 'build' can leave behind stale images
# that podman can't even see and which will cascade into subsequent