Commit 6bea6f3df8

6bea6f3df8e103d63cf091981ee3d281a54d9c96

parent: 7d675c19a7

Verified · cmc ci/build: success ci/test: success

cmc <hello@cleberg.net> · 2026-09-07 01:29 UTC

runner: mount the build home into the container

HOME in the step environment names the persistent cache directory, but
nothing mounted it, so a containerised build started with a cold Go
module cache every time. Mounted at the same path, and only that
directory: the workdir above it holds other builds' workspaces.

Ref #144

Layout: unified · split

cmd/gitbay-runner/env_test.go +11
@@ -105,3 +105,14 @@ func TestPodmanUsesCgroupfs(t *testing.T) {
105105 t.Errorf("podmanGlobal() = %v, missing the cgroupfs manager", got)
106106 }
107107}
108
109// The build home is where caches live, so the container must see it at
110// the path HOME names; otherwise every containerised build starts cold.
111func TestEnvHomeFindsHome(t *testing.T) {
112 if got := envHome([]string{"PATH=/bin", "HOME=/var/lib/gitbay-runner/work/home", "CI=true"}); got != "/var/lib/gitbay-runner/work/home" {
113 t.Errorf("envHome = %q", got)
114 }
115 if got := envHome([]string{"PATH=/bin"}); got != "" {
116 t.Errorf("envHome with no HOME = %q, want empty", got)
117 }
118}
cmd/gitbay-runner/isolate.go +16
@@ -130,6 +130,12 @@ func (r *runner) runStepsPodman(j job, dir string, env []string, sink io.Writer,
130130 "--name", name,
131131 "--env-file", envFile,
132132 "--volume", dir+":/workspace:rw",
133 // The build home holds the tool caches (Go modules, the sonar
134 // scanner) that must outlive a build; HOME in env points at it.
135 // Mounted at the same path so HOME resolves identically with and
136 // without a container. Only this directory — never the workdir
137 // above it, which holds other builds' workspaces.
138 "--volume", envHome(env)+":"+envHome(env)+":rw",
133139 "--workdir", "/workspace",
134140 "--entrypoint", "sh",
135141 image, "-c", "sleep infinity")...)
@@ -181,6 +187,16 @@ func (r *runner) podmanGlobal() []string {
181187 return []string{"--cgroup-manager=cgroupfs"}
182188}
183189
190// env_home returns the HOME the step environment carries.
191func envHome(env []string) string {
192 for _, e := range env {
193 if strings.HasPrefix(e, "HOME=") {
194 return strings.TrimPrefix(e, "HOME=")
195 }
196 }
197 return ""
198}
199
184200// podmanHome is where podman keeps its own storage: the runner's home,
185201// not a build's. The container store is the runner's business, and a
186202// build never sees this path.