wrolpi/controller/lib
Roland 719905cb77 Moving WROLPi-managed mounts off /etc/fstab onto a drive-resident fstab.yaml.
A WROLPi drive can move between hosts and across deployment styles
(Portable, RPi, Debian).  /etc/fstab is host-specific and on the Portable
image it's part of a read-only squashfs, so persisting secondary mounts
there was both wrong-host and lost-on-reboot.  This change makes
/media/wrolpi/config/fstab.yaml the single source of truth for WROLPi-
managed mounts and introduces a new wrolpi-mounts.service that reconciles
live state to match.

Architecture:

- The Controller writes intent (fstab.yaml) but never calls mount(8) or
  umount(8) itself.  Every mutation triggers `systemctl restart
  wrolpi-mounts.service`; the Controller then verifies the outcome via
  the same MountExecutor abstraction the service uses.

- wrolpi-mounts.service runs a thin entry point that constructs a real
  Reconciler with a SubprocessMountExecutor and calls apply().  The
  reconciler mounts what's in fstab.yaml but missing from the live state,
  and unmounts paths it previously claimed that are no longer in
  fstab.yaml.  A managed-set file in /run/wrolpi-mounts/managed prevents
  the reconciler from ever touching user-mounted paths it didn't own.

- One-time migration (marker-gated) lifts both /etc/fstab WROLPi entries
  and any controller.yaml drives.mounts entries into fstab.yaml.
  /etc/fstab is backed up to /etc/fstab.wrolpi-migration.backup;
  migrated lines are commented in place with a "migrated to fstab.yaml:"
  prefix so a host admin can hand-recover.

Test approach: dependency injection in place of patching.  The
MountExecutor protocol has SubprocessMountExecutor (production) and
FakeMountExecutor (in-memory, records calls).  The Reconciler accepts an
executor in its constructor, so the 20 reconciler tests + 13 migration
tests + 18 fstab_yaml tests use real files in tmp_path with zero
mock.patch calls.  test_disks_api.py drops to mocks only for the
host-touching read helpers; the mount/unmount paths now run the real
Reconciler against the fake executor.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:44:05 -06:00
..
__init__.py Creating Controller service which will control WROLPi services, admin, SMART, disks, and status. nginx will fallback to Controller UI when React UI is unavailable (such as during upgrades). 2025-12-15 15:48:40 -07:00
admin.py Key changes: 2026-04-04 13:48:19 -06:00
config.py Add controller onboarding flow for primary drive setup 2026-03-14 16:08:40 -06:00
disks.py Adding support for mounting NTFS drives in the Controller. (#440) 2026-05-15 19:25:43 -06:00
docker_services.py Adding docker support for samba shares. 2026-03-29 11:14:38 -06:00
fstab.py Controller logs when it takes actions. 2026-03-14 10:03:11 -06:00
fstab_migration.py Moving WROLPi-managed mounts off /etc/fstab onto a drive-resident fstab.yaml. 2026-05-24 12:44:05 -06:00
fstab_yaml.py Moving WROLPi-managed mounts off /etc/fstab onto a drive-resident fstab.yaml. 2026-05-24 12:44:05 -06:00
mount_executor.py Moving WROLPi-managed mounts off /etc/fstab onto a drive-resident fstab.yaml. 2026-05-24 12:44:05 -06:00
mount_runner.py Moving WROLPi-managed mounts off /etc/fstab onto a drive-resident fstab.yaml. 2026-05-24 12:44:05 -06:00
onboarding.py Moving WROLPi-managed mounts off /etc/fstab onto a drive-resident fstab.yaml. 2026-05-24 12:44:05 -06:00
readiness.py Checking readiness of main app in Controller instead of javascript requests, which break with CORS. 2026-03-08 16:05:56 -06:00
reconciler.py Moving WROLPi-managed mounts off /etc/fstab onto a drive-resident fstab.yaml. 2026-05-24 12:44:05 -06:00
samba.py Adding docker support for samba shares. 2026-03-29 11:14:38 -06:00
scripts.py Controller logs when it takes actions. 2026-03-14 10:03:11 -06:00
smart.py Creating Controller service which will control WROLPi services, admin, SMART, disks, and status. nginx will fallback to Controller UI when React UI is unavailable (such as during upgrades). 2025-12-15 15:48:40 -07:00
status.py Rounding drive stats for similar df performance. 2026-04-09 15:32:49 -06:00
status_worker.py Controller logs when it takes actions. 2026-03-14 10:03:11 -06:00
systemd.py Controller logs when it takes actions. 2026-03-14 10:03:11 -06:00
wrol_mode.py Creating Controller service which will control WROLPi services, admin, SMART, disks, and status. nginx will fallback to Controller UI when React UI is unavailable (such as during upgrades). 2025-12-15 15:48:40 -07:00