mirror of
https://github.com/moby/buildkit.git
synced 2026-11-06 05:16:45 +00:00
errors: report build-facing paths on read failure
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> (cherry picked from commit 12bf293e5feee7393e971a1d22a191dff7f6e7f8) (cherry picked from commit 5a01794b79c7af91a961b1236b0e0661975161d7)
This commit is contained in:
1 parent
edc2718b4b
commit
71dc7cfbd6
6 files changed
+83
-22
No files matched your search
Vendored
+12
-7
@@ -23,7 +23,15 @@ type FileRange struct {
|
||||
Length int
|
||||
}
|
||||
|
||||
func ReadFile(ctx context.Context, root string, req ReadRequest) ([]byte, error) {
|
||||
func ReadFile(ctx context.Context, root string, req ReadRequest) (_ []byte, retErr error) {
|
||||
// paths below are internal to the mount, report the one that was requested
|
||||
defer func() {
|
||||
var pathErr *os.PathError
|
||||
if errors.As(retErr, &pathErr) {
|
||||
pathErr.Path = req.Filename
|
||||
}
|
||||
}()
|
||||
|
||||
fp, err := fs.RootPath(root, req.Filename)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
@@ -31,18 +39,15 @@ func ReadFile(ctx context.Context, root string, req ReadRequest) ([]byte, error)
|
||||
|
||||
f, err := openfile.Regular(fp)
|
||||
if err != nil {
|
||||
// The filename here is internal to the mount, so we can restore
|
||||
// the request base path for error reporting.
|
||||
pe := &os.PathError{}
|
||||
if errors.As(err, &pe) {
|
||||
pe.Path = req.Filename
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var rdr io.Reader = f
|
||||
if req.Range != nil {
|
||||
if req.Range.Offset < 0 || req.Range.Length < 0 {
|
||||
return nil, errors.Errorf("invalid range for %s", req.Filename)
|
||||
}
|
||||
rdr = io.NewSectionReader(f, int64(req.Range.Offset), int64(req.Range.Length))
|
||||
}
|
||||
dt, err := io.ReadAll(rdr)
|
||||
|
||||
+13
-3
@@ -3,6 +3,7 @@ package oci
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -71,8 +72,17 @@ func ParseUIDGID(str string) (uid uint32, gid uint32, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func openUserFile(root, p string) (io.ReadCloser, error) {
|
||||
p, err := fs.RootPath(root, p)
|
||||
func openUserFile(root, orig string) (_ io.ReadCloser, retErr error) {
|
||||
// paths below are daemon-side locations, report the path as the build
|
||||
// asked for it
|
||||
defer func() {
|
||||
var pathErr *os.PathError
|
||||
if errors.As(retErr, &pathErr) {
|
||||
pathErr.Path = orig
|
||||
}
|
||||
}()
|
||||
|
||||
p, err := fs.RootPath(root, orig)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
@@ -85,7 +95,7 @@ func openUserFile(root, p string) (io.ReadCloser, error) {
|
||||
return &limitedReadCloser{
|
||||
ReadCloser: f,
|
||||
r: &io.LimitedReader{R: f, N: maxUserFileBytes + 1},
|
||||
name: p,
|
||||
name: orig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/containerd/continuity/fs"
|
||||
intoto "github.com/in-toto/in-toto-golang/in_toto"
|
||||
@@ -20,7 +21,15 @@ import (
|
||||
const maxAttestationBytes int64 = 80 << 20
|
||||
|
||||
// ReadAll reads the content of an attestation.
|
||||
func ReadAll(ctx context.Context, s session.Group, att exporter.Attestation) ([]byte, error) {
|
||||
func ReadAll(ctx context.Context, s session.Group, att exporter.Attestation) (_ []byte, retErr error) {
|
||||
// paths below are daemon-side locations, report the attestation path
|
||||
defer func() {
|
||||
var pathErr *os.PathError
|
||||
if errors.As(retErr, &pathErr) {
|
||||
pathErr.Path = att.Path
|
||||
}
|
||||
}()
|
||||
|
||||
var content []byte
|
||||
if att.ContentFunc != nil {
|
||||
data, err := att.ContentFunc(ctx)
|
||||
@@ -44,7 +53,7 @@ func ReadAll(ctx context.Context, s session.Group, att exporter.Attestation) ([]
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content, err = readRegularFile(p)
|
||||
content, err = readRegularFile(p, att.Path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot read in-toto attestation")
|
||||
}
|
||||
@@ -57,14 +66,19 @@ func ReadAll(ctx context.Context, s session.Group, att exporter.Attestation) ([]
|
||||
return content, nil
|
||||
}
|
||||
|
||||
func readRegularFile(p string) ([]byte, error) {
|
||||
func readRegularFile(p, name string) ([]byte, error) {
|
||||
f, err := openfile.Regular(p)
|
||||
if err != nil {
|
||||
// the resolved path is a daemon-side location
|
||||
var pathErr *os.PathError
|
||||
if errors.As(err, &pathErr) {
|
||||
pathErr.Path = name
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
dt, err := readAllLimited(f, p, maxAttestationBytes)
|
||||
dt, err := readAllLimited(f, name, maxAttestationBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -117,28 +117,42 @@ func sort(atts []exporter.Attestation) []exporter.Attestation {
|
||||
return result
|
||||
}
|
||||
|
||||
func unbundle(root string, bundle exporter.Attestation) ([]exporter.Attestation, error) {
|
||||
func unbundle(root string, bundle exporter.Attestation) (_ []exporter.Attestation, retErr error) {
|
||||
// paths below are daemon-side locations, report the bundle path
|
||||
defer func() {
|
||||
var pathErr *os.PathError
|
||||
if errors.As(retErr, &pathErr) {
|
||||
pathErr.Path = bundle.Path
|
||||
}
|
||||
}()
|
||||
|
||||
dir, err := fs.RootPath(root, bundle.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var unbundled []exporter.Attestation
|
||||
for _, entry := range entries {
|
||||
name := path.Join(bundle.Path, entry.Name())
|
||||
p, err := fs.RootPath(dir, entry.Name())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f, err := openfile.Regular(p)
|
||||
if err != nil {
|
||||
// p is a daemon-side location, report the bundle entry
|
||||
var pathErr *os.PathError
|
||||
if errors.As(err, &pathErr) {
|
||||
pathErr.Path = name
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
var stmt intoto.Statement
|
||||
stmt, err = decodeStatement(f, p)
|
||||
stmt, err = decodeStatement(f, name)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -163,7 +177,7 @@ func unbundle(root string, bundle exporter.Attestation) ([]exporter.Attestation,
|
||||
unbundled = append(unbundled, exporter.Attestation{
|
||||
Kind: gatewaypb.AttestationKind_InToto,
|
||||
Metadata: bundle.Metadata,
|
||||
Path: path.Join(bundle.Path, entry.Name()),
|
||||
Path: name,
|
||||
ContentFunc: func(context.Context) ([]byte, error) { return predicate, nil },
|
||||
InToto: result.InTotoAttestation{
|
||||
PredicateType: stmt.PredicateType,
|
||||
|
||||
@@ -3,6 +3,7 @@ package ops
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
|
||||
"github.com/containerd/continuity/fs"
|
||||
"github.com/moby/buildkit/client/llb"
|
||||
@@ -111,6 +112,14 @@ func (b *BuildOp) Exec(ctx context.Context, job solver.JobContext, inputs []solv
|
||||
fn = override
|
||||
}
|
||||
|
||||
// paths below are daemon-side locations, report the requested filename
|
||||
defer func() {
|
||||
var pathErr *os.PathError
|
||||
if errors.As(retErr, &pathErr) {
|
||||
pathErr.Path = fn
|
||||
}
|
||||
}()
|
||||
|
||||
newfn, err := fs.RootPath(root, fn)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "working dir %s points to invalid target", fn)
|
||||
@@ -118,7 +127,7 @@ func (b *BuildOp) Exec(ctx context.Context, job solver.JobContext, inputs []solv
|
||||
|
||||
f, err := openfile.Regular(newfn)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to open %s", newfn)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
def, err := llb.ReadFrom(f)
|
||||
|
||||
@@ -119,8 +119,17 @@ func readUser(chopt *pb.ChownOpt, mu, mg snapshot.Mountable) (*copy.User, error)
|
||||
return &us, nil
|
||||
}
|
||||
|
||||
func openUserFile(root, p string) (io.ReadCloser, error) {
|
||||
p, err := fs.RootPath(root, p)
|
||||
func openUserFile(root, orig string) (_ io.ReadCloser, retErr error) {
|
||||
// paths below are daemon-side locations, report the path as the build
|
||||
// asked for it
|
||||
defer func() {
|
||||
var pathErr *os.PathError
|
||||
if errors.As(retErr, &pathErr) {
|
||||
pathErr.Path = orig
|
||||
}
|
||||
}()
|
||||
|
||||
p, err := fs.RootPath(root, orig)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
@@ -133,7 +142,7 @@ func openUserFile(root, p string) (io.ReadCloser, error) {
|
||||
return &limitedReadCloser{
|
||||
ReadCloser: f,
|
||||
r: &io.LimitedReader{R: f, N: maxUserFileBytes + 1},
|
||||
name: p,
|
||||
name: orig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user