|
root / docs / coral-rfe-chroot-scripts.md
coral-rfe-chroot-scripts.md markdown 69 lines 3.9 KB

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.