Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle hard links in remote builds #10421

Merged
merged 1 commit into from
May 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
44 changes: 32 additions & 12 deletions pkg/bindings/images/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ import (
"github.com/sirupsen/logrus"
)

type devino struct {
Dev uint64
Ino uint64
}

var (
iidRegex = regexp.MustCompile(`^[0-9a-f]{12}`)
)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
16 changes: 16 additions & 0 deletions pkg/bindings/images/build_unix.go
Original file line number Diff line number Diff line change
@@ -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
}
9 changes: 9 additions & 0 deletions pkg/bindings/images/build_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package images

import (
"os"
)

func checkHardLink(fi os.FileInfo) (devino, bool) {
return devino{}, false
}
20 changes: 20 additions & 0 deletions test/system/070-build.bats
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down