Skip to content

Commit 8fca5d6

Browse files
committed
smoke_test: guard that /work is writable by the runtime user (WebGUI)
The webgui permission bugs (#25, then its uid==0 fallback) shipped because the smoke test never wrote into /work, so CI couldn't tell that the GUI process can't create a project there. Add a webgui-only guard that does the same write fvsOL does (a dir under /work) through the entrypoint-selected user. In CI /work is root-owned and unmounted, so a non-root runtime user (the #25 fvs-on-uid-0 fallback) fails this guard; running as the mount owner (root, per #26) passes. Cluster image skips it (no fvsOL; it runs as fvs against a separately-bound cwd). Locks the permission class so a future entrypoint change can't silently reintroduce it. https://claude.ai/code/session_011C6wxKosiwHnEYvAPJfmcW
1 parent 2fd3a8d commit 8fca5d6

1 file changed

Lines changed: 17 additions & 0 deletions

File tree

scripts/smoke_test.R

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,23 @@ if (have_fvsOL) check("fvsOL/data-artifacts", {
103103
all(loads) && is.list(ep$prms) && length(ep$prms) > 0L
104104
})
105105

106+
# Guard 2c - /work writable by the runtime user (WebGUI only): fvsOL creates a new
107+
# project as a directory under the working dir (the bind-mounted /work). If the
108+
# container runs as a user that can't write /work, dir.create()/setwd() fail with
109+
# "Permission denied" the instant a forester makes a project -- the macOS bind-mount
110+
# bug. The webgui entrypoint (docker/webgui-entrypoint.sh) gosu-drops to the /work
111+
# owner to prevent that; this guard runs INSIDE that dropped process and writes
112+
# /work the way fvsOL does, so a bad entrypoint fails the build HERE. (In CI /work
113+
# is root-owned and unmounted, so the #25 "uid==0 -> non-root fvs" fallback would
114+
# fail this; running as the owner -- root -- passes.) Cluster image skips it (no
115+
# fvsOL; it runs as fvs against a separately-bound, writable cwd).
116+
if (have_fvsOL) check("webgui/work-writable", {
117+
d <- file.path("/work", paste0(".smoke_proj_", Sys.getpid()))
118+
ok <- dir.create(d, showWarnings = FALSE)
119+
if (ok) unlink(d, recursive = TRUE)
120+
isTRUE(ok)
121+
})
122+
106123
# Guard 3 - FVS engine present + version stamp: the FVS binary must be runnable
107124
# and report its build version, so a rebuild proves the engine is wired up and
108125
# records which version the WebGUI/cluster images carry (provenance + a check

0 commit comments

Comments
 (0)