New prereq installer scripts/prereqs/install-apparmor-libvirt.sh, wired into install-all.sh (right after install-virtualization, since it edits libvirt's own profile directory) and reported by check-prereqs.sh. Harness extended tests/prereqs/run-tests.sh 24 -> 32 PASS. README updated.
The rule /var/lib/libvirt/vr1/** rwk, in /etc/apparmor.d/local/abstractions/libvirt-qemu gates every VR1 VM boot -- the Office1 edge, the DC edges, and every node VM. libvirt's stock abstractions/libvirt-qemu grants qemu only the DEFAULT pool path (/var/lib/libvirt/images); VR1 uses a custom pool parent, which is not in that abstraction, so AppArmor blocks qemu even with perfect POSIX permissions. The failure is nasty and non-obvious: the domain DEFINES fine, then fails to start with a bare qemu "Permission denied" and nothing in the libvirt error names AppArmor. It cost a session on 2026-07-12 (DOCFIX-186).
It had been applied BY HAND on the vcloud host and existed ONLY as host state. Nothing in the repo carried it -- so a rebuild, or a second host, walked straight back into the identical wall. This closes that gap. It was logged as a PREREQ candidate at the time and never actioned; the ledger collapse surfaced it again.
local/, not the abstraction itself. local/abstractions/libvirt-qemu is the vendor-sanctioned override include -- it survives package upgrades, which an edit to the shipped abstraction would not./var/lib/libvirt/vr1, overridable via VR1_POOL_PARENT -- per the repo's prefer-dynamic-over-hardcoded rule.tests/prereqs/run-tests.sh: 32/32 PASS (was 24/24). The new cases drive the DETECTION off a pool parent guaranteed absent from the profile, so the negative path is deterministic regardless of what the host has applied: --check must FAIL for an ungranted parent (a false OK here is the whole bug), --dry-run must plan the fix and mutate nothing, and the planned rule must be exactly <parent>/** rwk,.repo-lint: 0 fail (1 documented legacy warn).--check reports OK (rule already present), exit 0, and the profile file is unchanged -- confirming the already-satisfied path is a true no-op.git revert <this commit>
Removes the installer, its harness cases, the install-all/check-prereqs wiring, and the README rows. Reverting touches NO host state: the rule already live on vcloud was applied by hand long before this commit and is not managed by it.