mirror of
https://github.com/moby/buildkit.git
synced 2026-11-06 05:16:45 +00:00
vendor: update fsutil to 91a3fc4
Brings in fix for hardlink filters. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
1 parent
2aa1bdfe9f
commit
f67b96caa3
6 files changed
+125
-5
No files matched your search
@@ -166,6 +166,7 @@ var allTests = []func(t *testing.T, sb integration.Sandbox){
|
||||
testFileOpInputSwap,
|
||||
testRelativeMountpoint,
|
||||
testLocalSourceDiffer,
|
||||
testLocalSourceWithHardlinksFilter,
|
||||
testNoTarOCIIndexMediaType,
|
||||
testOCILayoutSource,
|
||||
testOCILayoutPlatformSource,
|
||||
@@ -2042,6 +2043,57 @@ func testLocalSourceWithDiffer(t *testing.T, sb integration.Sandbox, d llb.DiffT
|
||||
}
|
||||
}
|
||||
|
||||
// moby/buildkit#4831
|
||||
func testLocalSourceWithHardlinksFilter(t *testing.T, sb integration.Sandbox) {
|
||||
requiresLinux(t)
|
||||
c, err := New(context.TODO(), sb.Address())
|
||||
require.NoError(t, err)
|
||||
defer c.Close()
|
||||
|
||||
dir := integration.Tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("bar", []byte("bar"), 0600),
|
||||
fstest.Link("bar", "foo1"),
|
||||
fstest.Link("bar", "foo2"),
|
||||
)
|
||||
|
||||
st := llb.Local("mylocal", llb.FollowPaths([]string{"foo*"}))
|
||||
|
||||
def, err := st.Marshal(context.TODO())
|
||||
require.NoError(t, err)
|
||||
|
||||
destDir := t.TempDir()
|
||||
|
||||
_, err = c.Solve(context.TODO(), def, SolveOpt{
|
||||
Exports: []ExportEntry{
|
||||
{
|
||||
Type: ExporterLocal,
|
||||
OutputDir: destDir,
|
||||
},
|
||||
},
|
||||
LocalMounts: map[string]fsutil.FS{
|
||||
"mylocal": dir,
|
||||
},
|
||||
}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = os.ReadFile(filepath.Join(destDir, "bar"))
|
||||
require.Error(t, err)
|
||||
require.True(t, os.IsNotExist(err))
|
||||
|
||||
dt, err := os.ReadFile(filepath.Join(destDir, "foo1"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []byte("bar"), dt)
|
||||
|
||||
st1, err := os.Stat(filepath.Join(destDir, "foo1"))
|
||||
require.NoError(t, err)
|
||||
|
||||
st2, err := os.Stat(filepath.Join(destDir, "foo2"))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.True(t, os.SameFile(st1, st2))
|
||||
}
|
||||
|
||||
func testOCILayoutSource(t *testing.T, sb integration.Sandbox) {
|
||||
workers.CheckFeatureCompat(t, sb, workers.FeatureOCIExporter, workers.FeatureOCILayout)
|
||||
requiresLinux(t)
|
||||
|
||||
@@ -66,7 +66,7 @@ require (
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spdx/tools-golang v0.5.3
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/tonistiigi/fsutil v0.0.0-20240418180507-497d33b008ef
|
||||
github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c
|
||||
github.com/tonistiigi/go-actions-cache v0.0.0-20240320205438-9794bdbb2fb4
|
||||
github.com/tonistiigi/go-archvariant v1.0.0
|
||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea
|
||||
|
||||
@@ -394,8 +394,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20240418180507-497d33b008ef h1:1rshiFn5ka7/H9oGYXvRnV1BzhtWls2WSQZDrNwVsCA=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20240418180507-497d33b008ef/go.mod h1:vbbYqJlnswsbJqWUcJN8fKtBhnEgldDrcagTgnBVKKM=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c h1:+6wg/4ORAbnSoGDzg2Q1i3CeMcT/jjhye/ZfnBHy7/M=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c/go.mod h1:vbbYqJlnswsbJqWUcJN8fKtBhnEgldDrcagTgnBVKKM=
|
||||
github.com/tonistiigi/go-actions-cache v0.0.0-20240320205438-9794bdbb2fb4 h1:R0lM8Jo3aZL95yjQHWQti7nszllleKBxCs9uyFbykII=
|
||||
github.com/tonistiigi/go-actions-cache v0.0.0-20240320205438-9794bdbb2fb4/go.mod h1:anhKd3mnC1shAbQj1Q4IJ+w6xqezxnyDYlx/yKa7IXM=
|
||||
github.com/tonistiigi/go-archvariant v1.0.0 h1:5LC1eDWiBNflnTF1prCiX09yfNHIxDC/aukdhCdTyb0=
|
||||
|
||||
+68
@@ -1,6 +1,9 @@
|
||||
package fsutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
gofs "io/fs"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
@@ -46,3 +49,68 @@ func (v *Hardlinks) HandleChange(kind ChangeKind, p string, fi os.FileInfo, err
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithHardlinkReset returns a FS that fixes hardlinks for FS that has been filtered
|
||||
// so that original hardlink sources might be missing
|
||||
func WithHardlinkReset(fs FS) FS {
|
||||
return &hardlinkFilter{fs: fs}
|
||||
}
|
||||
|
||||
type hardlinkFilter struct {
|
||||
fs FS
|
||||
}
|
||||
|
||||
var _ FS = &hardlinkFilter{}
|
||||
|
||||
func (r *hardlinkFilter) Walk(ctx context.Context, target string, fn gofs.WalkDirFunc) error {
|
||||
seenFiles := make(map[string]string)
|
||||
return r.fs.Walk(ctx, target, func(path string, entry gofs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fi, err := entry.Info()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if fi.IsDir() || fi.Mode()&os.ModeSymlink != 0 {
|
||||
return fn(path, entry, nil)
|
||||
}
|
||||
|
||||
stat, ok := fi.Sys().(*types.Stat)
|
||||
if !ok {
|
||||
return errors.WithStack(&os.PathError{Path: path, Err: syscall.EBADMSG, Op: "fileinfo without stat info"})
|
||||
}
|
||||
|
||||
if stat.Linkname != "" {
|
||||
if v, ok := seenFiles[stat.Linkname]; !ok {
|
||||
seenFiles[stat.Linkname] = stat.Path
|
||||
stat.Linkname = ""
|
||||
entry = &dirEntryWithStat{DirEntry: entry, stat: stat}
|
||||
} else {
|
||||
if v != stat.Path {
|
||||
stat.Linkname = v
|
||||
entry = &dirEntryWithStat{DirEntry: entry, stat: stat}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
seenFiles[path] = stat.Path
|
||||
|
||||
return fn(path, entry, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func (r *hardlinkFilter) Open(p string) (io.ReadCloser, error) {
|
||||
return r.fs.Open(p)
|
||||
}
|
||||
|
||||
type dirEntryWithStat struct {
|
||||
gofs.DirEntry
|
||||
stat *types.Stat
|
||||
}
|
||||
|
||||
func (d *dirEntryWithStat) Info() (gofs.FileInfo, error) {
|
||||
return &StatInfo{d.stat}, nil
|
||||
}
|
||||
+1
-1
@@ -29,7 +29,7 @@ type Stream interface {
|
||||
func Send(ctx context.Context, conn Stream, fs FS, progressCb func(int, bool)) error {
|
||||
s := &sender{
|
||||
conn: &syncStream{Stream: conn},
|
||||
fs: fs,
|
||||
fs: WithHardlinkReset(fs),
|
||||
files: make(map[uint32]string),
|
||||
progressCb: progressCb,
|
||||
sendpipeline: make(chan *sendHandle, 128),
|
||||
|
||||
Vendored
+1
-1
@@ -762,7 +762,7 @@ github.com/spdx/tools-golang/spdx/v2/v2_3
|
||||
## explicit; go 1.20
|
||||
github.com/stretchr/testify/assert
|
||||
github.com/stretchr/testify/require
|
||||
# github.com/tonistiigi/fsutil v0.0.0-20240418180507-497d33b008ef
|
||||
# github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c
|
||||
## explicit; go 1.20
|
||||
github.com/tonistiigi/fsutil
|
||||
github.com/tonistiigi/fsutil/copy
|
||||
|
||||
Reference in new issue
Block a user