Commit 1510e36
PR26.5: source-install payload completeness (#532)
* installer: source-install payload completeness (PR26.5)
Closes the dns2 evidence finding (2026-04-30) where the source-install
path reached StateDegraded with three named assertion failures:
systemd_execstart_paths_ok (8 missing destinations)
systemd_payload_inventory_ok (6 unknown nftban-owned references)
panel_survival_ok (LoadPanelConfig directadmin not found)
Per the operator-locked PR26.5 scope (`project_pr26_5_locked.md`):
- source-install payload completeness ONLY
- no takeover/CSF binary handling (PR26.6)
- no cPanel/Plesk adapters (PR26.7+)
internal/installer/payload/payload.go (buildEntries):
- new shell-payload entries:
cli/lib/nftban/exporters/*.sh -> /usr/lib/nftban/exporters/
cli/lib/nftban/cron/*.sh -> /usr/lib/nftban/cron/
scripts/*.sh -> /usr/lib/nftban/scripts/
install/helpers/*.sh -> /usr/lib/nftban/helpers/ (joins
the existing cli/lib/nftban/helpers/ source — both flatten into
the same destination)
- new `panels` category staging the canonical panel conf.d files:
etc/nftban/conf.d/panels/<name>/main.conf -> /etc/nftban/conf.d/panels/<name>/main.conf
for all 8 first-class panels (directadmin, cpanel, plesk,
cyberpanel, cwp, interworx, vesta, generic).
policyConfigNoReplace: operator edits preserved on upgrade.
install/systemd/ (retired unit files removed):
- nftban-api.service, nftban-ui.service, nftban-ui-auth.service,
nftban-ui-auth.socket — all reference Go binaries the project
no longer builds. Operator-confirmed retired in v1.100.1b.A
(GOTH PR-D4 stage 1) and already removed by packaging on RPM/DEB
upgrade. Source-install path now matches that contract: not
shipped, not in source tree, not staged.
internal/installer/validate/assertions.go (defaultInventoryPaths):
- extended with shell-payload destinations referenced by remaining
units, so systemd_payload_inventory_ok no longer false-flags
legitimate staged shell payload as "unknown".
internal/installer/payload/payload_test.go (3 new tests):
- TestStageAll_AllUnitNftbanOwnedExecStartPathsStaged_PR26_5:
walks every install/systemd/*.service, parses every
ExecStart/Pre/Post path, asserts every nftban-owned
destination is in mock.WrittenFiles after StageAll.
- TestStageAll_AllPanelConfDStaged_PR26_5:
asserts every shipped panel's main.conf is staged at
/etc/nftban/conf.d/panels/<name>/main.conf.
- TestStageAll_PR26_5_NewShellCategoriesStaged:
regression guard pinning the four specific destinations
that failed on dns2 (exporter, cron, scripts, helpers).
Lab proof (lab2, Ubuntu 24.04, go1.22.2):
go vet payload/... validate/... cmd/nftban-installer/... clean
go test -v ./internal/installer/payload/... 3 new tests PASS, full file PASS
go test ./... 66 packages, 0 FAIL
Hard exclusions preserved: no takeover-side cleanup, no CSF binary
handling, no cPanel/Plesk adapters, no shell decommission, no
parser rewrite, no restore changes, no firewall mutation, no
destructive dns2 retry from this branch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* installer: PR26.5 — seed stub binaries in test mock for CI
Auditor flagged: TestStageAll_AllUnitNftbanOwnedExecStartPathsStaged_PR26_5
fails on CI because the runner ships a clean source checkout with no
prebuilt binaries. lab2 happened to have prebuilt binaries from prior
builds, so the test passed there. The test's intent is correct (assert
every shipped unit's nftban-owned ExecStart path is staged), but it
needs the binary source files to exist for the staging step to succeed.
Fix: per auditor option 1, add a `seedStubBuiltBinaries` helper that
populates `bin/<name>` with a stub byte-string in the test mock before
StageAll. Production payload.go is unchanged.
Helper applied to all 3 PR26.5 tests for environment consistency:
TestStageAll_AllUnitNftbanOwnedExecStartPathsStaged_PR26_5 (the failing one)
TestStageAll_AllPanelConfDStaged_PR26_5
TestStageAll_PR26_5_NewShellCategoriesStaged
Lab proof — confirmed reproducer:
rm -rf /root/nftban-src/bin && go test -count=1 -v -run PR26_5 ./...
→ all 3 PR26.5 tests PASS (was: 1 FAIL pre-fix on empty bin/)
go test ./...
→ 66 packages PASS, 0 FAIL
Production code: unchanged. The fix is fixture-only — no payload.go
edits, no validate/ edits, no buildEntries change.
Hard exclusions still preserved: no takeover preservation, no CSF
binary handling, no cPanel/Plesk adapters, no shell decommission, no
parser rewrite, no restore changes, no firewall mutation, no
destructive dns2 retry.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent bfe6eac commit 1510e36
7 files changed
Lines changed: 341 additions & 333 deletions
File tree
- install/systemd
- internal/installer
- payload
- validate
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
396 | 396 | | |
397 | 397 | | |
398 | 398 | | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
399 | 413 | | |
400 | 414 | | |
401 | 415 | | |
| |||
424 | 438 | | |
425 | 439 | | |
426 | 440 | | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
427 | 456 | | |
428 | 457 | | |
429 | 458 | | |
| |||
0 commit comments