diff --git a/go/buildstep/isolate.go b/go/buildstep/isolate.go index e431dfa..2efa739 100644 --- a/go/buildstep/isolate.go +++ b/go/buildstep/isolate.go @@ -132,13 +132,18 @@ func (iso Isolation) command(env []string, name string, args ...string) ([]strin return append(argv, args...), nil } -// cacheArgs binds the shared caches: read-write for a trunk build, otherwise read-only (S18). +// cacheArgs binds the shared warm caches (S18): for a trunk build read-write, so the next build is warm; for any other +// read-only beneath an overlay whose writes go to a tmpfs of the step's own, so the step writes as a build does and +// nothing it wrote outlives it (bubblewrap's --tmp-overlay, an overlay mount in the step's user namespace). func cacheArgs(caches []string, write bool) []string { var argv []string for _, c := range caches { - argv = append(argv, "--ro-bind", c, c) + if write { + argv = append(argv, "--bind", c, c) + continue + } + argv = append(argv, "--overlay-src", c, "--tmp-overlay", c) } - _ = write return argv } diff --git a/go/buildstep/isolate_caches_test.go b/go/buildstep/isolate_caches_test.go new file mode 100644 index 0000000..46afae5 --- /dev/null +++ b/go/buildstep/isolate_caches_test.go @@ -0,0 +1,30 @@ +package buildstep + +import "testing" + +// The shared warm caches are read under a throwaway writable layer (novox/hq ADR 0448; issue 1309): a candidate's step +// writes into them as a build does, and nothing it writes outlives it or reaches a later build; only a trunk build +// writes them. +func TestACandidatesStepWritesTheCachesOnlyIntoAThrowawayLayer(t *testing.T) { + fixedSystem(t) + iso := Isolation{Workspace: "/w", Caches: []string{"/var/cache/go-build", "/var/cache/npm"}} + argv, err := iso.Command("go", "test") + if err != nil { + t.Fatal(err) + } + for _, c := range iso.Caches { + if !holds(argv, "--overlay-src", c, "--tmp-overlay", c) { + t.Errorf("the cache %s is not under a throwaway layer: %v", c, argv) + } + if holds(argv, "--bind", c, c) { + t.Errorf("a candidate's step writes the cache %s: %v", c, argv) + } + } + iso.WriteCaches = true + argv, _ = iso.Command("go", "build") + for _, c := range iso.Caches { + if !holds(argv, "--bind", c, c) || holds(argv, "--tmp-overlay", c) { + t.Errorf("a trunk build does not write the cache %s: %v", c, argv) + } + } +}