vendor: update buildkit to v0.14.0-rc1

Update buildkit dependency to v0.14.0-rc1. Update the tracing
infrastructure to use the new detect API which updates how the delegated
exporter is configured.

Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
This commit is contained in:
Jonathan A. Sternberg
2024-05-31 16:11:33 -05:00
parent 9b6c4103af
commit b1cb658a31
80 changed files with 2583 additions and 1597 deletions

View File

@ -111,7 +111,7 @@ func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b walkerFn, fil
if filter != nil {
filter(f2.path, &statCopy)
}
f2copy = &currentPath{path: filepath.FromSlash(f2.path), stat: &statCopy}
f2copy = &currentPath{path: f2.path, stat: &statCopy}
}
k, p := pathChange(f1, f2copy)
switch k {

View File

@ -37,6 +37,7 @@ type DiskWriter struct {
ctx context.Context
cancel func()
eg *errgroup.Group
egCtx context.Context
filter FilterFunc
dirModTimes map[string]int64
}
@ -50,13 +51,14 @@ func NewDiskWriter(ctx context.Context, dest string, opt DiskWriterOpt) (*DiskWr
}
ctx, cancel := context.WithCancel(ctx)
eg, ctx := errgroup.WithContext(ctx)
eg, egCtx := errgroup.WithContext(ctx)
return &DiskWriter{
opt: opt,
dest: dest,
eg: eg,
ctx: ctx,
egCtx: egCtx,
cancel: cancel,
filter: opt.Filter,
dirModTimes: map[string]int64{},
@ -98,7 +100,7 @@ func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, er
}
}()
destPath := filepath.Join(dw.dest, filepath.FromSlash(p))
destPath := filepath.Join(dw.dest, p)
if kind == ChangeKindDelete {
if dw.filter != nil {
@ -183,12 +185,12 @@ func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, er
}
default:
isRegularFile = true
file, err := os.OpenFile(newPath, os.O_CREATE|os.O_WRONLY, fi.Mode()) //todo: windows
file, err := os.OpenFile(newPath, os.O_CREATE|os.O_WRONLY, fi.Mode())
if err != nil {
return errors.Wrapf(err, "failed to create %s", newPath)
}
if dw.opt.SyncDataCb != nil {
if err := dw.processChange(ChangeKindAdd, p, fi, file); err != nil {
if err := dw.processChange(dw.ctx, ChangeKindAdd, p, fi, file); err != nil {
file.Close()
return err
}
@ -219,7 +221,7 @@ func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, er
dw.requestAsyncFileData(p, destPath, fi, &statCopy)
}
} else {
return dw.processChange(kind, p, fi, nil)
return dw.processChange(dw.ctx, kind, p, fi, nil)
}
return nil
@ -228,7 +230,7 @@ func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, er
func (dw *DiskWriter) requestAsyncFileData(p, dest string, fi os.FileInfo, st *types.Stat) {
// todo: limit worker threads
dw.eg.Go(func() error {
if err := dw.processChange(ChangeKindAdd, p, fi, &lazyFileWriter{
if err := dw.processChange(dw.egCtx, ChangeKindAdd, p, fi, &lazyFileWriter{
dest: dest,
}); err != nil {
return err
@ -237,7 +239,7 @@ func (dw *DiskWriter) requestAsyncFileData(p, dest string, fi os.FileInfo, st *t
})
}
func (dw *DiskWriter) processChange(kind ChangeKind, p string, fi os.FileInfo, w io.WriteCloser) error {
func (dw *DiskWriter) processChange(ctx context.Context, kind ChangeKind, p string, fi os.FileInfo, w io.WriteCloser) error {
origw := w
var hw *hashedWriter
if dw.opt.NotifyCb != nil {
@ -252,7 +254,7 @@ func (dw *DiskWriter) processChange(kind ChangeKind, p string, fi os.FileInfo, w
if fn == nil && dw.opt.AsyncDataCb != nil {
fn = dw.opt.AsyncDataCb
}
if err := fn(dw.ctx, p, w); err != nil {
if err := fn(ctx, p, w); err != nil {
return err
}
} else {
@ -313,7 +315,7 @@ type lazyFileWriter struct {
func (lfw *lazyFileWriter) Write(dt []byte) (int, error) {
if lfw.f == nil {
file, err := os.OpenFile(lfw.dest, os.O_WRONLY, 0) //todo: windows
file, err := os.OpenFile(lfw.dest, os.O_WRONLY, 0)
if os.IsPermission(err) {
// retry after chmod
fi, er := os.Stat(lfw.dest)

View File

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

View File

@ -1,10 +1,42 @@
// send.go and receive.go describe the fsutil file-transfer protocol, which
// allows transferring file trees across a network connection.
//
// The protocol operates as follows:
// - The client (the receiver) connects to the server (the sender).
// - The sender walks the target tree lexicographically and sends a series of
// STAT packets that describe each file (an empty stat indicates EOF).
// - The receiver sends a REQ packet for each file it requires the contents for,
// using the ID for the file (determined as its index in the STAT sequence).
// - The sender sends a DATA packet with byte arrays for the contents of the
// file, associated with an ID (an empty array indicates EOF).
// - Once the receiver has received all files it wants, it sends a FIN packet,
// and the file transfer is complete.
// If an error is encountered on either side, an ERR packet is sent containing
// a human-readable error.
//
// All paths transferred over the protocol are normalized to unix-style paths,
// regardless of which platforms are present on either side. These path
// conversions are performed right before sending a STAT packet (for the
// sender) or right after receiving the corresponding STAT packet (for the
// receiver); this abstraction doesn't leak into the rest of fsutil, which
// operates on native platform-specific paths.
//
// Note that in the case of cross-platform file transfers, the transfer is
// best-effort. Some filenames that are valid on a unix sender would not be
// valid on a windows receiver, so these paths are rejected as they are
// received. Additionally, file metadata, like user/group owners and xattrs do
// not have an exact correspondence on windows, and so would be discarded by
// a windows receiver.
package fsutil
import (
"context"
"io"
"os"
"path/filepath"
"sync"
"syscall"
"github.com/pkg/errors"
"github.com/tonistiigi/fsutil/types"
@ -184,13 +216,24 @@ func (r *receiver) run(ctx context.Context) error {
}
break
}
// normalize unix wire-specific paths to platform-specific paths
path := filepath.FromSlash(p.Stat.Path)
if filepath.ToSlash(path) != p.Stat.Path {
// e.g. a linux path foo/bar\baz cannot be represented on windows
return errors.WithStack(&os.PathError{Path: p.Stat.Path, Err: syscall.EINVAL, Op: "unrepresentable path"})
}
p.Stat.Path = path
p.Stat.Linkname = filepath.FromSlash(p.Stat.Linkname)
if fileCanRequestData(os.FileMode(p.Stat.Mode)) {
r.mu.Lock()
r.files[p.Stat.Path] = i
r.mu.Unlock()
}
i++
cp := &currentPath{path: p.Stat.Path, stat: p.Stat}
cp := &currentPath{path: path, stat: p.Stat}
if err := r.orderValidator.HandleChange(ChangeKindAdd, cp.path, &StatInfo{cp.stat}, nil); err != nil {
return err
}

View File

@ -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),
@ -161,6 +161,7 @@ func (s *sender) walk(ctx context.Context) error {
return errors.WithStack(&os.PathError{Path: path, Err: syscall.EBADMSG, Op: "fileinfo without stat info"})
}
stat.Path = filepath.ToSlash(stat.Path)
stat.Linkname = filepath.ToSlash(stat.Linkname)
p := &types.Packet{
Type: types.PACKET_STAT,
Stat: stat,

View File

@ -200,6 +200,7 @@ func (v *VT100) Resize(y, x int) {
v.Height = y
} else if y < v.Height {
v.Content = v.Content[:y]
v.Format = v.Format[:y]
v.Height = y
}