Repository navigation
fix(packaging): postinst fails loud when nodogsplash was orphan-removed - #715
Conversation
Amperstrand
left a comment
There was a problem hiding this comment.
Review (PR-REVIEW.md pass) — disposition: land (one author-side fix: convert the changelog edit to a fragment).
Author-side review, with the verification record: the husk check sits before the swallowed restart || true, names both mints of failure (binary + init script) and the remediation; build-purity 3/3 on the branch; battery 15/16 with the one red pre-existing and root-caused elsewhere; the fork-PR #110 coordination and the #707-duplicate closure are both on record. The rc1-sequencing rationale (fail-loud must precede the bench upgrade/rollback pass) is documented on #707/#665.
One fix before merge: this PR edits CHANGELOG.md directly, but the fragment convention (changelog.d/, "do not edit CHANGELOG.md in the same PR") landed before this branch was pushed — convert the entry to changelog.d/715-postinst-nds-husk.fixed.md so the release fold doesn't hit a conflict with the fragment flow. Same note applies to #717 and #727 (I'll convert all three as author).
Cross-family review —
|
|
🏷️ Next action — approved Approved; rebase (17 behind) + one physical router install/reinstall before merge. |
|
rc4 evidence: the fail-loud contract is not observable on the opkg lane — the install over a husked portal proceeds into the network re-architecture instead. Venue: PRTA local virtual lab (OpenWrt 24.10 x86_64, QEMU), Repro —
Observed: no fail-loud refusal naming the husk. The postinst proceeded — and moved eth0 off br-lan onto br-private mid-install (kernel log: Caveat, stated plainly: the observation channel died mid-install, so this proves no observable refusal + the re-architecture ran over a dead portal; it cannot prove or disprove opkg's final exit code. A serial-console-captured repro on hardware would close that. Full capture, serial excerpt, and venue notes: OpenTollGate/physical-router-test-automation |
|
Follow-up (same day, better venue): the caveat is closed — rc4's postinst reports SUCCESS over a husked portal, full capture, A second run on an overlay whose uci has no private network (there the br-private move degrades to a warning — With (The two runs together also scope the network behavior: on a config where the private network exists, the same install severs the LAN mid-flight — previous comment; on a config without it, the install sails through. Either way the portal's death stops nothing.) Repro: PRTA |
Gate-1 review — APPROVED @
|
Review: APPROVE (code sound; two citation errors to fix)Reviewed cold at head What it adds (+23/-0, 2 files): a fail-loud check in if [ ! -s /usr/bin/nodogsplash ] || [ ! -s /etc/init.d/nodogsplash ]; then
echo "ERROR: nodogsplash binary or init script is empty (zero bytes) —" >&2
...
exit 1
fi
/etc/init.d/nodogsplash restart 2>/dev/null || trueThe guard logic is correct — I exercised all five cases (extracted predicate, healthy vs
Two citation errors — please fix the comment.
Neither weakens the guard: the failure mode it describes (an aborted opkg transaction Not hardware-tested. The change is a postinst shell guard; I verified its predicate logic Labels: not applied — this account has FULL_REVIEW: ~/reports/reviews/tollgate-module-basic-go-pr715-kimi.md |
|
Evidence for the merge-campaign tracker (#965) — offline verification of PR #715 (branch Diff shape: exactly 2 files — Merge hygiene vs fresh main: Static gates:
Behavior simulation (offline, sandboxed): the postinst with its two absolute husk paths redirected into a sandbox (documented sed substitution; every earlier restart line is already
Fund-safety: none — install-time shell guard; no wallet/payment path. Queue-ready from my side; only the approving click remains. |
Local CI gate — PR #715: fix(packaging): postinst fails loud when nodogsplash was orphan-removedRun of
Verdict: 4 leg(s) RED — 2 green. What this gate does not run (no vacuous green)
failing-leg log tailspackaging-sequential — tailshell-suites — tailpackaging-concurrent — tailgo-battery — tail |
c03rad0r
left a comment
There was a problem hiding this comment.
Technical review — requesting changes. Head b3f5bf1. The fix is right; it is applied to a file that does not ship.
The failure mode and the guard are both correct: an aborted opkg transaction that orphan-removes nodogsplash and leaves zero-byte husks should fail the install loudly, and [ ! -s /usr/bin/nodogsplash ] is the right test. But this change edits packaging/postinst, and per this repo's own packaging/README.md that file is not the shipping postinst:
packaging/README.md: the feed Makefile is the shipping package; this repo'spackaging/Makefilebuilds for test/reproducibility lanes only;packaging/postinstis consumed bypackaging/local-build-ipk.shand is already on the decommission list.
I verified the live paths on current main and on the feed:
FreedomTechFeed/packages/net/tollgate-wrt/Makefile(the shipping package),Package/tollgate-wrt/postinst, line ~1010:/etc/init.d/nodogsplash restart 2>/dev/null || true— no zero-byte guard.OpenTollGate/tollgate-module-basic-gopackaging/Makefile,Package/$(PKG_NAME)/postinst, line ~187: the same line, same gap.packaging/postinst(this PR): patched.
So as written, a router installed from the feed still reports success over a dead portal — the changelog's "The package postinst now fails loudly" is not true of the shipped package.
Also note the two copies have already drifted: the Makefile copy carries the default-route-preserve block and the gate-last uci-defaults ordering; packaging/postinst does not. Patching only the test-lane copy makes the divergence worse.
What I need before approving:
- Port the guard into
packaging/Makefile's inline postinst (with$$escaping) so the test/repro lane and the feed copy stay identical. - Open the corresponding change against
FreedomTechFeed/packages(or state explicitly that a companion PR exists) — that is the one that protects shipped routers. - Reword the changelog fragment to say which lane it protects until the feed PR lands.
Keep the packaging/postinst hunk: it keeps the local build honest. The review is about reach, not correctness.
Disposition: request-changes.
…ed (#715) The guard now ships in both live copies: the module Makefile inline postinst (test/repro lane) and packaging/postinst, plus the feed recipe (separate PR). A zero-byte nodogsplash binary/init refuses the install.
b3f5bf1 to
236992a
Compare
|
Fixes pushed. The guard now lands in the copies that actually ship:
The guard refuses a zero-byte Verified: |
c03rad0r
left a comment
There was a problem hiding this comment.
Re-review — the guard now lands in the shipping copies. Approving.
packaging/Makefileinline postinst (the body the feed recipe was copied from) andpackaging/postinstboth refuse a zero-byte/usr/bin/nodogsplashor/etc/init.d/nodogsplashbefore restarting the daemon, with the remediation andexit 1.- FreedomTechFeed/packages#96 carries the same guard in
net/tollgate-wrt/Makefile, the copy routers actually install. - The fragment records the feed companion.
bash -n packaging/postinstclean; the guard is present at both module call sites.
This closes the original finding ("the fix protects a file nobody ships"): all three copies now agree, and the shipping lane is the one that matters.
Disposition: land.
…e husk (#96) An aborted transaction can orphan-remove runtime deps and leave the nodogsplash binary/init empty; the old 'restart || true' reported success over a dead portal. The postinst now fails with the remediation. Companion to OpenTollGate/tollgate-module-basic-go#715 (which adds the same guard to the module's own postinst copies). Co-authored-by: Your Name <you@example.com>
What
Upstream relay of fork Amperstrand#110 (tracked as #707) for rc1 inclusion: after an aborted opkg transaction orphan-removes runtime deps and leaves zero-byte husks (nodogsplash binary/init — fork #109, the fork #93 class), the postinst's
restart 2>/dev/null || truereported success over a dead captive portal. The postinst now refuses to claim success when the nodogsplash binary or init script is empty (! -s), prints the remediation (opkg update+ reinstall), and exits non-zero — so the damage surfaces at install time instead of as opaque downstream product symptoms.Cherry-picked from the fork branch with author credit preserved (
-xfooter records the source commit); closes #707.Why now
Per #707: the rc1 bench upgrade+rollback tests are only meaningful with fail-loud in the image — a postinst that reports success over a husked portal makes every upgrade test vacuously green. Pairs with PRTA's deploy-side hardening (opkg update before install + an NDS health gate).
Verification
tests/contract/build-purity.sh: 3/3 PASS on this branch.make go-battery: 16 modules; 15 green, 1 red that is pre-existing on the base and unrelated —TestLateReceiveOutcomeIsRecordedWhenReceiveCompletesAfterTheDeadline(from fix(merchant): the business-transaction record — an ambiguous or interrupted payment converges to service or spendable value (#502) #700) fails identically on clean68ad514(current main) and cleane5e7945with no involvement from this packaging-only diff (one file,packaging/postinst, +12 lines). Reported separately on v0.6.0 pre-tag readiness — test plan, approved-idle PRs, and owed decisions #665 — flagging here so the lane output is not mistaken for a regression from this PR.Changelog
Entry added under
[Unreleased] → Fixedin the follow-up commit.