From eb942eae5b8cae5215ea94e1b8a7284a8827d783 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Fri, 5 Apr 2024 16:24:40 -0700 Subject: [PATCH] unify ReadAt to ReadCloser conversion Also removes dependency from pkg/ioutils Signed-off-by: Tonis Tiigi --- solver/llbsolver/history.go | 20 ++++--------- source/containerimage/ocilayout.go | 18 ++---------- util/compression/compression.go | 2 +- util/compression/uncompressed.go | 4 +-- util/iohelper/helper.go | 45 ++++++++++++++++++++++++------ 5 files changed, 46 insertions(+), 43 deletions(-) diff --git a/solver/llbsolver/history.go b/solver/llbsolver/history.go index fc4a8ecdb..13aed089d 100644 --- a/solver/llbsolver/history.go +++ b/solver/llbsolver/history.go @@ -21,6 +21,7 @@ import ( "github.com/moby/buildkit/cmd/buildkitd/config" "github.com/moby/buildkit/identity" containerdsnapshot "github.com/moby/buildkit/snapshot/containerd" + "github.com/moby/buildkit/util/iohelper" "github.com/moby/buildkit/util/leaseutil" digest "github.com/opencontainers/go-digest" ocispecs "github.com/opencontainers/image-spec/specs-go/v1" @@ -254,7 +255,7 @@ func (h *HistoryQueue) migrateBlobV2(ctx context.Context, id string, detectSkipL return false, nil // allow skipping } defer ra.Close() - if err := content.Copy(ctx, w, &reader{ReaderAt: ra}, 0, dgst, content.WithLabels(labels)); err != nil { + if err := content.Copy(ctx, w, iohelper.ReadCloser(ra), 0, dgst, content.WithLabels(labels)); err != nil { return false, err } @@ -460,9 +461,11 @@ func (h *HistoryQueue) Status(ctx context.Context, ref string, st chan<- *client if err != nil { return err } - defer ra.Close() - brdr := bufio.NewReader(&reader{ReaderAt: ra}) + rc := iohelper.ReadCloser(ra) + defer rc.Close() + + brdr := bufio.NewReader(rc) buf := make([]byte, 32*1024) @@ -906,14 +909,3 @@ func (p *channel[T]) close() { close(p.done) }) } - -type reader struct { - io.ReaderAt - pos int64 -} - -func (r *reader) Read(p []byte) (int, error) { - n, err := r.ReaderAt.ReadAt(p, r.pos) - r.pos += int64(len(p)) - return n, err -} diff --git a/source/containerimage/ocilayout.go b/source/containerimage/ocilayout.go index 7ade6af55..820dacfbe 100644 --- a/source/containerimage/ocilayout.go +++ b/source/containerimage/ocilayout.go @@ -12,6 +12,7 @@ import ( "github.com/moby/buildkit/session" sessioncontent "github.com/moby/buildkit/session/content" "github.com/moby/buildkit/util/imageutil" + "github.com/moby/buildkit/util/iohelper" ocispecs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -51,7 +52,7 @@ func (r *ociLayoutResolver) Fetch(ctx context.Context, desc ocispecs.Descriptor) if err != nil { return err } - rc = &readerAtWrapper{readerAt: readerAt} + rc = iohelper.ReadCloser(readerAt) return nil }) return rc, err @@ -137,18 +138,3 @@ func (r *ociLayoutResolver) withCaller(ctx context.Context, f func(context.Conte return f(ctx, caller) }) } - -// readerAtWrapper wraps a ReaderAt to give a Reader -type readerAtWrapper struct { - offset int64 - readerAt content.ReaderAt -} - -func (r *readerAtWrapper) Read(p []byte) (n int, err error) { - n, err = r.readerAt.ReadAt(p, r.offset) - r.offset += int64(n) - return -} -func (r *readerAtWrapper) Close() error { - return r.readerAt.Close() -} diff --git a/util/compression/compression.go b/util/compression/compression.go index 2155db4d5..9569cf6fe 100644 --- a/util/compression/compression.go +++ b/util/compression/compression.go @@ -251,5 +251,5 @@ func decompress(ctx context.Context, cs content.Store, desc ocispecs.Descriptor) return nil, err } } - return &iohelper.ReadCloser{ReadCloser: r, CloseFunc: ra.Close}, nil + return iohelper.WithCloser(r, ra.Close), nil } diff --git a/util/compression/uncompressed.go b/util/compression/uncompressed.go index 924215485..a232e58d0 100644 --- a/util/compression/uncompressed.go +++ b/util/compression/uncompressed.go @@ -6,7 +6,6 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/images" - "github.com/docker/docker/pkg/ioutils" "github.com/moby/buildkit/util/iohelper" ocispecs "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -22,8 +21,7 @@ func (c uncompressedType) Decompress(ctx context.Context, cs content.Store, desc if err != nil { return nil, err } - rdr := io.NewSectionReader(ra, 0, ra.Size()) - return ioutils.NewReadCloserWrapper(rdr, ra.Close), nil + return iohelper.ReadCloser(ra), nil } func (c uncompressedType) NeedsConversion(ctx context.Context, cs content.Store, desc ocispecs.Descriptor) (bool, error) { diff --git a/util/iohelper/helper.go b/util/iohelper/helper.go index e0ebaf9bb..e910c3246 100644 --- a/util/iohelper/helper.go +++ b/util/iohelper/helper.go @@ -15,18 +15,26 @@ func (w *NopWriteCloser) Close() error { return nil } -type ReadCloser struct { - io.ReadCloser - CloseFunc func() error +type closeFunc func() error + +func (c closeFunc) Close() error { + return c() } -func (rc *ReadCloser) Close() error { - err1 := rc.ReadCloser.Close() - err2 := rc.CloseFunc() - if err1 != nil { - return errors.Wrapf(err1, "failed to close: %v", err2) +// WithCloser returns a ReadCloser with additional closer function. +func WithCloser(r io.ReadCloser, closer func() error) io.ReadCloser { + var f closeFunc = func() error { + err1 := r.Close() + err2 := closer() + if err1 != nil { + return errors.Wrapf(err1, "failed to close: %v", err2) + } + return err2 + } + return &readCloser{ + Reader: r, + Closer: f, } - return err2 } type WriteCloser struct { @@ -61,3 +69,22 @@ func (c *Counter) Size() (n int64) { c.mu.Unlock() return } + +type ReaderAtCloser interface { + io.ReaderAt + io.Closer + Size() int64 +} + +// ReadCloser returns a ReadCloser from ReaderAtCloser. +func ReadCloser(in ReaderAtCloser) io.ReadCloser { + return &readCloser{ + Reader: io.NewSectionReader(in, 0, in.Size()), + Closer: in, + } +} + +type readCloser struct { + io.Reader + io.Closer +}