diff --git a/cache/filelist.go b/cache/filelist.go index 0cb2e9b60..225a52004 100644 --- a/cache/filelist.go +++ b/cache/filelist.go @@ -35,7 +35,7 @@ func (sr *immutableRef) FileList(ctx context.Context, s session.Group) ([]string } // lazy blobs need to be pulled first - if err := sr.Extract(ctx, s); err != nil { + if err := sr.ensureLocalContentBlob(ctx, s); err != nil { return nil, err } diff --git a/cache/manager.go b/cache/manager.go index 2771f4f15..156dc59fc 100644 --- a/cache/manager.go +++ b/cache/manager.go @@ -301,7 +301,7 @@ func (cm *cacheManager) GetByBlob(ctx context.Context, desc ocispecs.Descriptor, ref := rec.ref(true, descHandlers, nil) if s := unlazySessionOf(opts...); s != nil { - if err := ref.unlazy(ctx, ref.descHandlers, ref.progress, s, true); err != nil { + if err := ref.unlazy(ctx, ref.descHandlers, ref.progress, s, true, false); err != nil { return nil, err } } diff --git a/cache/refs.go b/cache/refs.go index 94792f7c0..0d1f089ce 100644 --- a/cache/refs.go +++ b/cache/refs.go @@ -992,6 +992,14 @@ func (sr *immutableRef) Mount(ctx context.Context, readonly bool, s session.Grou return mnt, nil } +func (sr *immutableRef) ensureLocalContentBlob(ctx context.Context, s session.Group) error { + if (sr.kind() == Layer || sr.kind() == BaseLayer) && !sr.getBlobOnly() { + return nil + } + + return sr.unlazy(ctx, sr.descHandlers, sr.progress, s, true, true) +} + func (sr *immutableRef) Extract(ctx context.Context, s session.Group) (rerr error) { if (sr.kind() == Layer || sr.kind() == BaseLayer) && !sr.getBlobOnly() { return nil @@ -1002,14 +1010,14 @@ func (sr *immutableRef) Extract(ctx context.Context, s session.Group) (rerr erro if rerr = sr.prepareRemoteSnapshotsStargzMode(ctx, s); rerr != nil { return } - rerr = sr.unlazy(ctx, sr.descHandlers, sr.progress, s, true) + rerr = sr.unlazy(ctx, sr.descHandlers, sr.progress, s, true, false) }); err != nil { return err } return rerr } - return sr.unlazy(ctx, sr.descHandlers, sr.progress, s, true) + return sr.unlazy(ctx, sr.descHandlers, sr.progress, s, true, false) } func (sr *immutableRef) withRemoteSnapshotLabelsStargzMode(ctx context.Context, s session.Group, f func()) error { @@ -1149,9 +1157,12 @@ func makeTmpLabelsStargzMode(labels map[string]string, s session.Group) (fields return } -func (sr *immutableRef) unlazy(ctx context.Context, dhs DescHandlers, pg progress.Controller, s session.Group, topLevel bool) error { +func (sr *immutableRef) unlazy(ctx context.Context, dhs DescHandlers, pg progress.Controller, s session.Group, topLevel bool, ensureContentStore bool) error { _, err := g.Do(ctx, sr.ID()+"-unlazy", func(ctx context.Context) (_ struct{}, rerr error) { if _, err := sr.cm.Snapshotter.Stat(ctx, sr.getSnapshotID()); err == nil { + if !ensureContentStore { + return struct{}{}, nil + } if blob := sr.getBlob(); blob == "" { return struct{}{}, nil } @@ -1162,9 +1173,9 @@ func (sr *immutableRef) unlazy(ctx context.Context, dhs DescHandlers, pg progres switch sr.kind() { case Merge, Diff: - return struct{}{}, sr.unlazyDiffMerge(ctx, dhs, pg, s, topLevel) + return struct{}{}, sr.unlazyDiffMerge(ctx, dhs, pg, s, topLevel, ensureContentStore) case Layer, BaseLayer: - return struct{}{}, sr.unlazyLayer(ctx, dhs, pg, s) + return struct{}{}, sr.unlazyLayer(ctx, dhs, pg, s, ensureContentStore) } return struct{}{}, nil }) @@ -1172,7 +1183,7 @@ func (sr *immutableRef) unlazy(ctx context.Context, dhs DescHandlers, pg progres } // should be called within sizeG.Do call for this ref's ID -func (sr *immutableRef) unlazyDiffMerge(ctx context.Context, dhs DescHandlers, pg progress.Controller, s session.Group, topLevel bool) (rerr error) { +func (sr *immutableRef) unlazyDiffMerge(ctx context.Context, dhs DescHandlers, pg progress.Controller, s session.Group, topLevel bool, ensureContentStore bool) (rerr error) { eg, egctx := errgroup.WithContext(ctx) var diffs []snapshot.Diff sr.layerWalk(func(sr *immutableRef) { @@ -1182,13 +1193,13 @@ func (sr *immutableRef) unlazyDiffMerge(ctx context.Context, dhs DescHandlers, p if sr.diffParents.lower != nil { diff.Lower = sr.diffParents.lower.getSnapshotID() eg.Go(func() error { - return sr.diffParents.lower.unlazy(egctx, dhs, pg, s, false) + return sr.diffParents.lower.unlazy(egctx, dhs, pg, s, false, ensureContentStore) }) } if sr.diffParents.upper != nil { diff.Upper = sr.diffParents.upper.getSnapshotID() eg.Go(func() error { - return sr.diffParents.upper.unlazy(egctx, dhs, pg, s, false) + return sr.diffParents.upper.unlazy(egctx, dhs, pg, s, false, ensureContentStore) }) } case Layer: @@ -1197,7 +1208,7 @@ func (sr *immutableRef) unlazyDiffMerge(ctx context.Context, dhs DescHandlers, p case BaseLayer: diff.Upper = sr.getSnapshotID() eg.Go(func() error { - return sr.unlazy(egctx, dhs, pg, s, false) + return sr.unlazy(egctx, dhs, pg, s, false, ensureContentStore) }) } diffs = append(diffs, diff) @@ -1228,7 +1239,7 @@ func (sr *immutableRef) unlazyDiffMerge(ctx context.Context, dhs DescHandlers, p } // should be called within sizeG.Do call for this ref's ID -func (sr *immutableRef) unlazyLayer(ctx context.Context, dhs DescHandlers, pg progress.Controller, s session.Group) (rerr error) { +func (sr *immutableRef) unlazyLayer(ctx context.Context, dhs DescHandlers, pg progress.Controller, s session.Group, ensureContentStore bool) (rerr error) { if !sr.getBlobOnly() { return nil } @@ -1255,7 +1266,7 @@ func (sr *immutableRef) unlazyLayer(ctx context.Context, dhs DescHandlers, pg pr parentID := "" if sr.layerParent != nil { eg.Go(func() error { - if err := sr.layerParent.unlazy(egctx, dhs, pg, s, false); err != nil { + if err := sr.layerParent.unlazy(egctx, dhs, pg, s, false, ensureContentStore); err != nil { return err } parentID = sr.layerParent.getSnapshotID()