Skip to content

Commit

Permalink
cache: don't skip unlazy without blob check
Browse files Browse the repository at this point in the history
Signed-off-by: Tonis Tiigi <[email protected]>
  • Loading branch information
tonistiigi committed Sep 9, 2023
1 parent 12bbf07 commit dfcb140
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 1 deletion.
7 changes: 6 additions & 1 deletion cache/refs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1143,7 +1143,12 @@ func makeTmpLabelsStargzMode(labels map[string]string, s session.Group) (fields
func (sr *immutableRef) unlazy(ctx context.Context, dhs DescHandlers, pg progress.Controller, s session.Group, topLevel 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 {
return struct{}{}, nil
if blob := sr.getBlob(); blob == "" {
return struct{}{}, nil
}
if _, err := sr.cm.ContentStore.Info(ctx, sr.getBlob()); err == nil {
return struct{}{}, nil
}
}

switch sr.kind() {
Expand Down
143 changes: 143 additions & 0 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ func TestIntegration(t *testing.T) {
testLLBMountPerformance,
testClientCustomGRPCOpts,
testMultipleRecordsWithSameLayersCacheImportExport,
testSnapshotWithMultipleBlobs,
testExportLocalNoPlatformSplit,
testExportLocalNoPlatformSplitOverwrite,
)
Expand Down Expand Up @@ -5494,6 +5495,148 @@ func testMultipleRecordsWithSameLayersCacheImportExport(t *testing.T, sb integra
ensurePruneAll(t, c, sb)
}

// moby/buildkit#3809
func testSnapshotWithMultipleBlobs(t *testing.T, sb integration.Sandbox) {
workers.CheckFeatureCompat(t, sb, workers.FeatureOCIExporter)
c, err := New(sb.Context(), sb.Address())
require.NoError(t, err)
defer c.Close()

// build two images with same layer but different compressed blobs

registry, err := sb.NewRegistry()
if errors.Is(err, integration.ErrRequirements) {
t.Skip(err.Error())
}
require.NoError(t, err)

now := time.Now()

st := llb.Scratch().File(llb.Copy(llb.Image("alpine"), "/", "/alpine/", llb.WithCreatedTime(now)))

def, err := st.Marshal(sb.Context())
require.NoError(t, err)

name1 := registry + "/multiblobtest1/image:latest"

_, err = c.Solve(sb.Context(), def, SolveOpt{
Exports: []ExportEntry{
{
Type: "image",
Attrs: map[string]string{
"name": name1,
"push": "true",
"compression-level": "0",
},
},
},
}, nil)
require.NoError(t, err)

ensurePruneAll(t, c, sb)

st = st.File(llb.Mkfile("test", 0600, []byte("test"))) // extra layer so we don't get a cache match based on image config rootfs only

def, err = st.Marshal(sb.Context())
require.NoError(t, err)

name2 := registry + "/multiblobtest2/image:latest"

_, err = c.Solve(sb.Context(), def, SolveOpt{
Exports: []ExportEntry{
{
Type: "image",
Attrs: map[string]string{
"name": name2,
"push": "true",
"compression-level": "9",
},
},
},
}, nil)
require.NoError(t, err)

ensurePruneAll(t, c, sb)

// first build with first image
destDir := t.TempDir()

out1 := filepath.Join(destDir, "out1.tar")
outW1, err := os.Create(out1)
require.NoError(t, err)

st = llb.Image(name1).File(llb.Mkfile("test", 0600, []byte("test1")))

def, err = st.Marshal(sb.Context())
require.NoError(t, err)

_, err = c.Solve(sb.Context(), def, SolveOpt{
Exports: []ExportEntry{
{
Type: ExporterOCI, // make sure to export so blobs need to be loaded
Output: fixedWriteCloser(outW1),
},
},
}, nil)
require.NoError(t, err)

// make sure second image does not cause any errors
out2 := filepath.Join(destDir, "out2.tar")
outW2, err := os.Create(out2)
require.NoError(t, err)

st = llb.Image(name2).File(llb.Mkfile("test", 0600, []byte("test2")))

def, err = st.Marshal(sb.Context())
require.NoError(t, err)

_, err = c.Solve(sb.Context(), def, SolveOpt{
FrontendAttrs: map[string]string{
"attest:sbom": "",
},
Exports: []ExportEntry{
{
Type: ExporterOCI, // make sure to export so blobs need to be loaded
Output: fixedWriteCloser(outW2),
},
},
}, nil)
require.NoError(t, err)

// extra validation that we did get different layer blobs
dt, err := os.ReadFile(out1)
require.NoError(t, err)

m, err := testutil.ReadTarToMap(dt, false)
require.NoError(t, err)

var index ocispecs.Index
err = json.Unmarshal(m["index.json"].Data, &index)
require.NoError(t, err)

var mfst ocispecs.Manifest
err = json.Unmarshal(m["blobs/sha256/"+index.Manifests[0].Digest.Hex()].Data, &mfst)
require.NoError(t, err)

dt, err = os.ReadFile(out2)
require.NoError(t, err)

m, err = testutil.ReadTarToMap(dt, false)
require.NoError(t, err)

err = json.Unmarshal(m["index.json"].Data, &index)
require.NoError(t, err)

err = json.Unmarshal(m["blobs/sha256/"+index.Manifests[0].Digest.Hex()].Data, &index)
require.NoError(t, err)

var mfst2 ocispecs.Manifest
err = json.Unmarshal(m["blobs/sha256/"+index.Manifests[0].Digest.Hex()].Data, &mfst2)
require.NoError(t, err)

require.NotEqual(t, mfst.Layers[0].Digest, mfst2.Layers[0].Digest)

Check failure on line 5637 in client/client_test.go

View workflow job for this annotation

GitHub Actions / test / run (containerd-rootless, ./client ./cmd/buildctl ./worker/containerd ./solver ./frontend, integr...

Failed: client/TestIntegration/TestSnapshotWithMultipleBlobs/worker=containerd-rootless

=== RUN TestIntegration/TestSnapshotWithMultipleBlobs/worker=containerd-rootless === PAUSE TestIntegration/TestSnapshotWithMultipleBlobs/worker=containerd-rootless === CONT TestIntegration/TestSnapshotWithMultipleBlobs/worker=containerd-rootless client_test.go:5637: Error Trace: /src/client/client_test.go:5637 /src/util/testutil/integration/run.go:91 /src/util/testutil/integration/run.go:205 Error: Should not be: "sha256:dda3cbbfa7e4c1cf8d02f8019eeb97262d41d52d921af9eab1294bce31599f89" Test: TestIntegration/TestSnapshotWithMultipleBlobs/worker=containerd-rootless sandbox.go:141: stdout: /usr/bin/sudo -u #1000 -i CONTAINERD_ROOTLESS_ROOTLESSKIT_STATE_DIR=/tmp/bktest_containerd2937331352/rootlesskit-containerd CONTAINERD_ROOTLESS_ROOTLESSKIT_NET=host CONTAINERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=none CONTAINERD_ROOTLESS_ROOTLESSKIT_FLAGS=--mtu=0 containerd-rootless.sh -c /tmp/bktest_containerd2937331352/config.toml sandbox.go:141: stderr: /usr/bin/sudo -u #1000 -i CONTAINERD_ROOTLESS_ROOTLESSKIT_STATE_DIR=/tmp/bktest_containerd2937331352/rootlesskit-containerd CONTAINERD_ROOTLESS_ROOTLESSKIT_NET=host CONTAINERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=none CONTAINERD_ROOTLESS_ROOTLESSKIT_FLAGS=--mtu=0 containerd-rootless.sh -c /tmp/bktest_containerd2937331352/config.toml sandbox.go:144: > StartCmd 2023-09-09 02:28:38.754677411 +0000 UTC m=+502.499770944 /usr/bin/sudo -u #1000 -i CONTAINERD_ROOTLESS_ROOTLESSKIT_STATE_DIR=/tmp/bktest_containerd2937331352/rootlesskit-containerd CONTAINERD_ROOTLESS_ROOTLESSKIT_NET=host CONTAINERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=none CONTAINERD_ROOTLESS_ROOTLESSKIT_FLAGS=--mtu=0 containerd-rootless.sh -c /tmp/bktest_containerd2937331352/config.toml sandbox.go:144: time="2023-09-09T02:28:38Z" level=warning msg="The host root filesystem is mounted as \"master:261\". Setting child propagation to \"rslave\" is not supported." sandbox.go:144: time="2023-09-09T02:28:38Z" level=warning msg="containerd config version `1` has been deprecated and will be removed in containerd v2.0, please switch to version `2`, see https:/containerd/containerd/blob/main/docs/PLUGINS.md#version-header" sandbox.go:144: time="2023-09-09T02:28:38.821030421Z" level=info msg="starting containerd" revision=0cae528dd6cb557f7201036e9f43420650207b58 version=v1.7.2 sandbox.go:144: time="2023-09-09T02:28:38.845594865Z" level=info msg="loading plugin \"io.containerd.snapshotter.v1.aufs\"..." type=io.containerd.snapshotter.v1 sandbox.go:144: time="2023-09-09T02:28:38.852837284Z" level=info msg="skip loading plugin \"io.containerd.snapshotter.v1.aufs\"..." error="aufs is not supported (modprobe aufs failed: exit status 1 \"modprobe: can't change directory to '/lib/modules': No such file or directory\\n\"): skip plugin" type=io.containerd.snapshotter.v1 sandbox.go:144: time="2023-09-09T02:28:38.852870885Z" level=info msg="loading plugin \"io.containerd.content.v1.content\"..." type=io.containerd.content.v1 sandbox.go:144: time="2023-09-09T02:28:38.852984589Z" level=info msg="loading plugin \"io.containerd.snapshotter.v1.native\"..." type=io.containerd.snapshotter.v1 sandbox.go:144: time="2023-09-09T02:28:38.853055491Z" level=info msg="loading plugin \"io.containerd.snapshotter.v1.overlayfs\"..." type=io.containerd.snapshotter.v1 sandbox.go:144: time="2023-09-09T02:28:38.853245097Z" level=info msg="loading plugin \"io.containerd.snapshotter.v1.devmapper\"..." type=io.containerd.snapshotter.v1 sandbox.go:144: time="2023-09-09T02:28:38.853260797Z" level=warning msg="failed to load plugin io.containerd.snapshotter.v1.devmapper" error="devmapper not configured" sandbox.go:144: time="2023-09-09T02:28:38.853269597Z" level=info msg="loading plugin \"io.containerd.snapshotter.v1.zfs\"..." type=io.containerd.snapshotter.v1 sandbox.go:144: time="2023-09-09T02:28:38.853601607Z" level=info msg="skip loading plugin \"io.containerd.snapshotter.v1.zfs\"..." error="path /tmp/bktest_containerd293
}

func testExportLocalNoPlatformSplit(t *testing.T, sb integration.Sandbox) {
workers.CheckFeatureCompat(t, sb, workers.FeatureOCIExporter, workers.FeatureMultiPlatform)
c, err := New(sb.Context(), sb.Address())
Expand Down

0 comments on commit dfcb140

Please sign in to comment.