Compare commits

...

2 commits

Author SHA1 Message Date
mwiegand
4aa69c2461
spec(janitorial): mark items 8, 9 resolved after on-host verification
Both items were operational verifications (not code changes) against
the deployed test host ovh.left4me (141.95.32.8).

Item 8: orphan idmap binds in PID 1's mount namespace.
  `sudo findmnt --task 1 -o TARGET | grep /var/lib/left4me/runtime/.*/idmap/`
  returned zero matches with left4me-server@{1,2}.service both active.
  Either swept earlier or never appeared on this host; nothing to umount.

Item 9: Optimized Settings (overlay 8) files-overlay sanity.
  Dir is left4me:left4me end-to-end; `sudo find /var/lib/left4me/overlays/8
  -type f -uid 981` returned empty. The invariant "files-overlays are
  populated by the web app as left4me, never through the sandbox helper"
  holds.

Remaining live janitorial items: 7 (conditional on the build-overlay-unit
refactor) and 10 (SourceMod 1.13 calendar reminder, ~late 2026).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 12:14:34 +02:00
mwiegand
8f30dd7754
docs: correct stale bubblewrap references in v1 spec + live docstring
Janitorial item 6 in 2026-05-15-janitorial-cleanup.md. The v1 sandbox
design (2026-05-08-l4d2-script-overlays-design.md) was approved
2026-05-08 and superseded the same day by the v2 systemd-only design
(2026-05-08-l4d2-script-sandbox-v2-systemd.md). The current
left4me-script-sandbox helper uses systemd-run in service-unit mode;
no bwrap binary is invoked. The v1 spec still described bubblewrap as
the engine.

- v1 spec gets a top-of-file banner pointing at v2 as the supersede.
  Body preserved; the rest of the v1 design (overlay-type unification,
  resource caps, helper auth) is still valid — only the sandbox engine
  changed.
- l4d2web/services/overlay_builders.py: ScriptBuilder docstring
  "bubblewrap + systemd-run" → "hardened systemd-run transient
  service" (the as-built reality).
- scripts/tests/test_script_sandbox.py: stray "/bwrap" in a comment
  cleaned up. Negative regression assertions (`assert "bwrap" not in
  text`) intentionally retained as the guard against accidental
  re-introduction.
- Plan docs left untouched (historical action snapshots).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 12:12:31 +02:00
4 changed files with 41 additions and 7 deletions

View file

@ -1,5 +1,14 @@
# L4D2 Script Overlays Design # L4D2 Script Overlays Design
> **Sandbox engine superseded by [`2026-05-08-l4d2-script-sandbox-v2-systemd.md`](2026-05-08-l4d2-script-sandbox-v2-systemd.md).**
> The v1 design below specifies `bubblewrap` + `systemd-run --scope` as the
> sandbox engine. The v2 design (approved 2026-05-08, same day) replaced that
> with `systemd-run` in service-unit mode and dropped `bubblewrap` entirely.
> The current implementation in `scripts/libexec/left4me-script-sandbox`
> follows v2; this v1 design is preserved for archaeology. The rest of the
> design (overlay-type unification, resource caps, helper auth model, etc.)
> still applies — only the sandbox-engine choice changed.
**Goal:** Add a single new overlay type, `script`, that lets users author arbitrary build recipes as bash and runs them inside a `bubblewrap` + `systemd-run --scope` sandbox. The new type subsumes the existing `l4d2center_maps` and `cedapug_maps` managed-globals overlay types, both of which are removed in the same change. After this work the overlay type list is exactly `workshop` (unchanged) and `script` (new). **Goal:** Add a single new overlay type, `script`, that lets users author arbitrary build recipes as bash and runs them inside a `bubblewrap` + `systemd-run --scope` sandbox. The new type subsumes the existing `l4d2center_maps` and `cedapug_maps` managed-globals overlay types, both of which are removed in the same change. After this work the overlay type list is exactly `workshop` (unchanged) and `script` (new).
**Approval status:** User-approved design direction. Implementation proceeds in lockstep with the companion plan at `docs/superpowers/plans/2026-05-08-l4d2-script-overlays.md`. **Approval status:** User-approved design direction. Implementation proceeds in lockstep with the companion plan at `docs/superpowers/plans/2026-05-08-l4d2-script-overlays.md`.

View file

@ -126,7 +126,16 @@ open decision. Three options listed there:
**Action**: pick one as part of the broader deploy-dir-rethink **Action**: pick one as part of the broader deploy-dir-rethink
work, or as an isolated decision now. work, or as an isolated decision now.
### 6. `bubblewrap` references in spec docs ### 6. `bubblewrap` references in spec docs [RESOLVED]
**Resolution**: v1 design spec (`2026-05-08-l4d2-script-overlays-design.md`)
got a top-of-file banner pointing at the v2 spec; body left as-is for
archaeology. Stale docstring in `l4d2web/services/overlay_builders.py`
corrected to "hardened systemd-run transient service." Stray "/bwrap"
in a test comment cleaned up. Plan-doc references left in place
(historical action snapshots).
**What**: `docs/superpowers/specs/2026-05-08-l4d2-script-overlays-design.md` **What**: `docs/superpowers/specs/2026-05-08-l4d2-script-overlays-design.md`
(if it still exists) describes the sandbox as using `bubblewrap`. (if it still exists) describes the sandbox as using `bubblewrap`.
@ -152,7 +161,15 @@ doc is chosen (unit fetches script from DB), the
**Action**: if that refactor lands, remove the helper function and **Action**: if that refactor lands, remove the helper function and
the dir. ckn-bw can stop creating the directory. the dir. ckn-bw can stop creating the directory.
### 8. Legacy idmap binds on un-checked instances ### 8. Legacy idmap binds on un-checked instances [RESOLVED]
**Resolution (2026-05-15)**: verified on `ovh.left4me` (141.95.32.8). The
diagnostic `sudo findmnt --task 1 -o TARGET | grep /var/lib/left4me/runtime/.*/idmap/`
returned zero matches with both `left4me-server@1.service` and
`left4me-server@2.service` active. Either the pre-`dd918ac` stragglers
were swept earlier or never appeared on this host. No umount needed.
**What**: server@2's stale idmap binds (from the idmap-on-mount **What**: server@2's stale idmap binds (from the idmap-on-mount
era) were manually cleaned during this session's verification. era) were manually cleaned during this session's verification.
@ -175,7 +192,15 @@ are gone.
Alternative: schedule a host reboot. Reboot wipes the entire mount Alternative: schedule a host reboot. Reboot wipes the entire mount
table and gets everything clean in one step. table and gets everything clean in one step.
### 9. `Optimized Settings` files-overlay verification ### 9. `Optimized Settings` files-overlay verification [RESOLVED]
**Resolution (2026-05-15)**: verified on `ovh.left4me`. Overlay 8 dir is
`left4me:left4me`-owned end-to-end; `sudo find /var/lib/left4me/overlays/8
-type f -uid 981` (the `l4d2-sandbox` uid) returned empty. The
files-overlay invariant (populated by the web app as `left4me`, never
through the sandbox helper) holds. No action needed.
**What**: overlay id 8 (`Optimized Settings`, type `files`) wasn't **What**: overlay id 8 (`Optimized Settings`, type `files`) wasn't
included in the rebuild test during the build-time-idmap included in the rebuild test during the build-time-idmap

View file

@ -366,9 +366,9 @@ def run_sandboxed_script(
class ScriptBuilder: class ScriptBuilder:
"""Run an arbitrary user-authored bash script against the overlay dir """Run an arbitrary user-authored bash script against the overlay dir
inside a bubblewrap + systemd-run sandbox. The script sees the overlay inside a hardened systemd-run transient service. The script sees the
dir as RW `/overlay` and a curated host RO mount; everything else is overlay dir as RW `/overlay` and a curated host RO mount; everything
isolated. After exit, enforce a 20 GB cap on `du -sb /overlay`.""" else is isolated. After exit, enforce a 20 GB cap on `du -sb /overlay`."""
def build( def build(
self, self,

View file

@ -166,6 +166,6 @@ def test_script_sandbox_helper_dry_run_mode(tmp_path):
# simulates `id -u l4d2-sandbox` resolving to a valid number. # simulates `id -u l4d2-sandbox` resolving to a valid number.
helper_text = SCRIPT_SANDBOX_HELPER.read_text() helper_text = SCRIPT_SANDBOX_HELPER.read_text()
# We can't actually exec this without root + a real sandbox user; just # We can't actually exec this without root + a real sandbox user; just
# verify the dry-run guard short-circuits before systemd-run / bwrap. # verify the dry-run guard short-circuits before systemd-run runs.
assert 'LEFT4ME_SCRIPT_SANDBOX_DRY_RUN' in helper_text assert 'LEFT4ME_SCRIPT_SANDBOX_DRY_RUN' in helper_text
assert 'exit 0' in helper_text assert 'exit 0' in helper_text