|

docs: add chroot maintainer-scripts RFE

Author: Chris Tusa <chris.tusa@leafscale.com>
Date: Jul 05, 2026 17:51
Changeset: 28a389ffac52a66599a19de25a9f7d78b3bf5f78
Branch: default

Diff

diff -r 05d5f488bb24 -r 28a389ffac52 docs/coral-rfe-chroot-scripts.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/coral-rfe-chroot-scripts.md	Sun Jul 05 17:51:29 2026 -0500
@@ -0,0 +1,68 @@
+# Coral RFE: chroot maintainer scripts under `--root`
+
+**Status:** Draft — ready to file with the Coral team
+**Filed against:** Coral 0.4.2 (`reef.toml` version = "0.4.2")
+**Reporter:** Chris Tusa <chris.tusa@leafscale.com>
+**Consumer:** zyginstall (the Hammerhead system installer) — installs the OS into a
+target root via `coral install --root /mnt ...` from an ISO live environment.
+
+## Summary
+
+When `coral install --root <dir>` (and the remove/upgrade paths) run a package's
+maintainer scripts, the scripts execute against the **live host filesystem** with the
+real `/` as root. Only the file *payload* is written under `<dir>`; the scriptlets are
+not confined to it. There is no flag, config key, or env var to change this.
+
+For an OS installer that stages a target root and then installs packages into it, a
+package's `post-install.sh` that assumes it runs inside the installed system will
+instead act on the host (the ISO live environment) — silently corrupting the host or
+no-op'ing incorrectly. This makes package maintainer scripts unusable for
+`--root` installs.
+
+## Current behavior (evidence)
+
+- File placement correctly honors `--root`: `install_files` writes every file to
+  `path.join_path(root, rel_path)` (`src/core/package.reef:307`). ✅
+- Script execution does **not**: the single executor `run_script`
+  (`src/core/package.reef:508-536`) builds `zsh "<extract_dir>/.SCRIPTS/<name>.sh" <args>`
+  and hands it to `process_spawn_shell` — no `chroot`, no `cd`, and `<root>` is never
+  passed in. The hook wrappers `run_pre_install` / `run_post_install`
+  (`package.reef:539-565`) take only `(pkg_dir, version)`; `run_stored_script`
+  (`package.reef:624-651`) takes `(scripts_dir, script_name, script_args)` and the stored
+  hook wrappers (`run_stored_pre_remove` etc., `package.reef:654+`) take
+  `(scripts_dir, version)` — the target root is architecturally invisible to all of them.
+- Call sites confirm the split: scripts run with `extract_dir`, files install with
+  `install_root` (`src/commands/install.reef:443` / `:452` / `:461`).
+- No `chroot` anywhere in `src/` (only the standalone `tools/mkchroot/` helper).
+- No `$ROOT`/`$PKGROOT` env var is exported to scripts, so a script cannot even manually
+  honor the root today (only `$VERSION`/`$OLD_VERSION`/`$NEW_VERSION` are passed
+  positionally).
+
+## Requested change
+
+1. **Chroot maintainer scripts when the install root is non-`/`.** Thread the install
+   root into the hook functions (`run_pre_install`, `run_post_install`,
+   `run_pre_remove`, `run_post_remove`, `run_pre_upgrade`, `run_post_upgrade`,
+   `run_stored_*` — all currently `(pkg_dir, version)`) and have `run_script` /
+   `run_stored_script` emit `chroot "<root>" zsh /.SCRIPTS/<name> <args>`, with the
+   `.SCRIPTS` dir staged inside `<root>` so it's reachable post-chroot.
+
+2. **An explicit control** — e.g. a `--chroot-scripts` / `--no-chroot-scripts` flag or a
+   `chroot_scripts` config key — since none exists today. Define the fallback when
+   `chroot(2)` isn't permitted (non-root caller): fail loudly rather than silently
+   running against the host.
+
+3. **Until (1) ships, a safety note** in the docs that `coral install --root <dir>`
+   stages *files* under `<dir>` but runs maintainer scripts against the host, and,
+   as a stopgap, **export a `$CORAL_ROOT` env var** to scripts so a maintainer can
+   defensively prefix paths.
+
+## Impact on zyginstall (context for prioritization)
+
+Not an immediate hard blocker for the first two packages: `hammerhead-kernel` and
+`hammerhead-userland` have only one post-install script (a `svccfg import` guarded on
+`svc.configd` running) which no-ops on a Hammerhead/zyginit system. But it is a
+correctness landmine for any future package with a real post-install action, and the
+installer would otherwise have to special-case / manually re-run scripts under
+`chroot /mnt` itself. A stopgap `$CORAL_ROOT` env var (item 3) would let the installer
+proceed safely before the full chroot work lands.