# Changelog 2026-07-12 -- DOCFIX-186: Office1 OPNsense edge build + two first-boot infra findings

**Context.** Standing up the Office1 OPNsense edge so `office1-local` has a router + DHCP
(operator: bring the edge online before the Office1 NetBox VM). First-ever OPNsense boot in
this repo -- reviewed-but-unexercised module + image chain. This records the repo changes and
the two real infrastructure findings hit on the first apply.

## Repo change
- **`opentofu/main.tf`**: `module "office1_opnsense"` instantiated (was a commented skeleton):
  `modules/opnsense-edge`, 2 vCPU / 2 GiB / 16 GiB, `pool_name = module.office1_storage.pool_name`,
  `base_volume_path` = the prepped nano qcow2, `config_iso_path` = the staged config ISO,
  `lan_network_name = module.office1_network.network_name`, `wan_network_name = "office1-wan"`.
  Validated + planned clean (first real validation of `modules/opnsense-edge`): 3 to add.

## Infrastructure created (not repo files)
- **`office1-wan`** NAT network (`172.30.1.0/24` -> `enp1s0`), created via `virsh` --
  Office1's per-site simulated-ISP uplink (operator's per-site-uplink ruling). **Logged as
  D-103 debt** to formalize into an OpenTofu module later (same class as the retained `wan`).
- OPNsense creds generated + saved 0600 to `~/vr1-office1-creds/` (jumphost-only, NEVER
  committed): SSH keypair + root password + its bcrypt hash (for `config.xml`).

## Two first-boot findings (both real, both DOCFIX-worthy)
1. **`config_iso_path` must live OUTSIDE the pool dir.** `libvirt_volume.config_seed` uses
   `create.content.url` to COPY the ISO into the pool as a volume named
   `office1-opnsense-config.iso`; if the source ISO sits at that exact pool path, libvirt
   errors "volume target path ... already exists". Fixed by staging the ISO at
   `/var/lib/libvirt/vr1/staging/` and pointing `config_iso_path` there. (The disk uses
   `backing_store` -- a reference, not a copy -- so the in-pool nano image is fine.)
   **CORRECTION 2026-07-12 (DOCFIX-189):** that parenthetical is now STALE -- DOCFIX-187
   changed the disk to a direct copy (`create.content.url`), so it no longer uses
   `backing_store`. The in-pool nano image is still fine, but for a DIFFERENT reason: the
   copy's target volume name (`<vm>-disk.qcow2`) differs from the source
   (`opnsense-26.1-nano.qcow2`), so there is no target-path collision. Same conclusion,
   different mechanism -- do not rely on the original reasoning.
2. **apparmor blocks the custom pool path `/var/lib/libvirt/vr1/`.** The domain was defined
   but failed to start: qemu (`libvirt-qemu`) got "Permission denied" on the backing image
   despite correct POSIX perms. libvirt's apparmor abstraction only whitelists
   `/var/lib/libvirt/images/**` + `.../qemu/**`, not our operator-owned `vr1/` pool tree.
   **This is foundational -- every VR1 VM lives under `/var/lib/libvirt/vr1/`.** Fix (operator,
   one-time sudo), via the abstraction's `include if exists <local/abstractions/libvirt-qemu>`:
   ```
   echo '/var/lib/libvirt/vr1/** rwk,' | sudo tee /etc/apparmor.d/local/abstractions/libvirt-qemu
   sudo systemctl reload apparmor && sudo systemctl restart libvirtd
   ```
   **PREREQ:** this belongs in the workstation/host prep (a candidate `scripts/prereqs/`
   addition + a phase-0/phase-1 runbook note) since it gates every VR1 VM boot, not just this
   edge. Not yet actioned as a prereq installer (needs sudo).

## State
- Edge build COMPLETE except the boot: image, `office1-wan`, creds, config, ISO, module
  instantiation, disk + config_seed volumes all done. Domain boot is blocked ONLY on the
  apparmor fix above (operator sudo). After it: re-apply to boot, then verify WAN (`172.30.1.2`)
  + LAN DHCP/routing on `office1-local`.

## Revert
- `git checkout opentofu/main.tf` (re-comment the module); `virsh net-destroy/undefine
  office1-wan`; `git rm` this changelog. (Live volumes: `tofu destroy` the office1_opnsense
  module resources.)
