12 Commits

Author SHA1 Message Date
Stefan Strobl
98aebc5f09 fix(postinstall): improve error handling and user feedback
Add three critical improvements to post-install phase:

1. Cleanup trap for bind mounts: Ensure /dev, /proc, /sys, /run
   are unmounted even if chroot script fails. Prevents orphaned
   mounts blocking cleanup.

2. Fallocate fallback: Use dd as fallback if fallocate fails
   (can happen on some filesystems or with insufficient space).
   Includes intelligent size conversion and progress display.

3. Progress messages: Add informative echo statements before
   long-running operations (xbps-reconfigure, grub-install,
   grub-mkconfig) so users know the system is working.

Decision: Use trap EXIT instead of manual cleanup to guarantee
execution on both success and error paths. Remove redundant
explicit cleanup call.

Trade-offs: dd fallback is slower but ensures swap file creation
succeeds. Progress messages add noise but significantly improve
UX during multi-minute operations.
2025-12-24 15:27:14 +01:00
Stefan Strobl
551cb98a9d fix(installer): verify mounts after installer completion
Add verification that critical mounts (root and ESP) are still
intact after void-installer exits. Catches cases where installer
accidentally reformats filesystems despite instructions.

Fail fast with clear error message if mounts disappeared, rather
than proceeding to post-install and encountering cryptic errors.

Decision: Check mounts immediately after installer rather than
during post-install to provide clear failure point and message.

Alternative considered: Monitor installer process to prevent
reformatting, rejected as too invasive and complex.
2025-12-24 15:25:42 +01:00
Stefan Strobl
c303a75192 fix(filesystems): add cleanup trap for temp btrfs mount
Add trap to ensure temp mount is cleaned up if btrfs subvolume
creation fails. Without this, failures leave mounted filesystems
and orphaned directories, blocking retry attempts.

Use mountpoint -q for robust mount detection before cleanup.

Decision: Use local trap within format_filesystems to avoid
interfering with main error handler. Reset trap after successful
completion to prevent double cleanup.

Trade-off: Slightly more complex code vs guaranteed cleanup on
error paths.
2025-12-24 15:24:29 +01:00
Stefan Strobl
c9fbc5486c fix(config): add size validation and improve swap normalization
Add validate_size() function to check format of user-provided
size inputs (ESP_SIZE, ROOT_END, SWAP_SIZE) before they reach
partitioning tools. Prevents cryptic parted errors from invalid
formats like "abc" or "1X".

Improve SWAP_SIZE normalization to handle all zero variants
(0, 0G, 0GB, 0GiB, 0M, 0MB, 0MiB) consistently.

Decision: Validate at config phase rather than partition phase
to provide early, clear feedback. Use regex pattern that matches
parted's expected format (number + optional unit or percentage).

Alternative considered: Let parted handle validation, rejected
because error messages would be less user-friendly.
2025-12-24 15:22:50 +01:00
Stefan Strobl
4e0d9573e6 fix(partitioning): export partition variables for module access
Export ESP_PART and ROOT_PART variables to ensure they are
available in all subsequent modules (encryption, filesystems,
postinstall). While sourcing makes them accessible, explicit
exports clarify the sharing model and prevent potential issues
in different shell contexts.

Decision: Use explicit export instead of relying on implicit
variable propagation through source to make dependencies clear.
2025-12-24 15:22:10 +01:00
Stefan Strobl
051485cede Relax partition refresh dependency 2025-12-24 14:57:05 +01:00
Stefan Strobl
a6e5399572 Implement wrapper workflow and btrfs layout 2025-12-24 14:36:53 +01:00
Stefan Strobl
1fc9fa0f5f feat(support): add phase 1 narrative for logging and rollback
Add literate programming phase 1 documentation for:
- logging.sh: transparency and auditability during operations
- rollback.sh: cleanup strategy after failures

Decision: Plain text logs for readability over structured JSON.
Log destination is /tmp/void-wrapper-YYYY-MM-DD-HHMMSS.log to
avoid conflicts in multi-run sessions. Logs remain ephemeral
in live environment, not copied to target system.

Decision: Three log levels (INFO, WARN, ERROR) with clear
separation between stdout (user-facing) and log file (detailed
trace). Secret masking prevents passphrase exposure.

Decision: Best-effort rollback limited to reversible operations.
Unmount filesystems and close LUKS mappings, but never revert
partitioning or formatting (irreversible without data loss).
Only cleanup after explicit user confirmation.

Rationale: Full automatic rollback rejected due to complexity
and risk. Partial cleanup with clear manual recovery instructions
is safer and more transparent. Track failed phase to provide
targeted recovery advice.

Open questions for phase 2:
- Support verbose/debug mode beyond standard levels?
- Display log path at end for manual review?
- Handle log rotation in multi-run sessions?
2025-12-24 09:52:49 +01:00
Stefan Strobl
a1fdbdaf6b feat(install): add phase 1 narrative for installer integration
Add literate programming phase 1 documentation for:
- installer.sh: handoff to official Void installer
- postinstall.sh: boot configuration for encrypted system

Decision: Keep official installer in the loop rather than
full automation. The installer handles package selection and
system configuration choices better than a custom script would.
Reduces maintenance burden significantly.

Decision: GRUB as default bootloader for wide Void support
without systemd dependencies. systemd-boot and rEFInd rejected
due to availability constraints. EFISTUB rejected due to manual
UEFI entry management overhead.

Technical details documented for post-install phase:
- dracut crypt module enables LUKS unlock in initramfs
- /etc/crypttab uses UUID references for device stability
- GRUB_ENABLE_CRYPTODISK=y enables GRUB LUKS unlock
- rd.luks.uuid kernel parameter tells dracut which container
- grub-install embeds cryptodisk, grub-mkconfig updates menu

Open questions preserved for phase 2 implementation:
- Should rescue initramfs be generated?
- Verify GRUB LUKS2 support before reboot?
- Document kernel update process for users?
2025-12-24 09:52:06 +01:00
Stefan Strobl
0d29a9ae62 feat(disk): add phase 1 narrative for disk preparation modules
Add literate programming phase 1 documentation for:
- partitioning.sh: UEFI layout with ESP and encrypted root
- encryption.sh: LUKS encryption strategy and key handling
- filesystems.sh: filesystem choices and swap configuration
- mounts.sh: mount tree preparation for installer handoff

Decision: Swap file instead of swap partition for automatic
encryption and flexibility. Swap partition would require either
a second LUKS container (two passphrases at boot), unencrypted
swap (security risk), or LVM (out of scope).

Decision: /boot inside encrypted root for simplicity. GRUB
unlocks LUKS once, kernel and initramfs are protected. ESP
remains unencrypted per UEFI requirements.

Decision: Default to btrfs with explicit ext4 opt-in. Btrfs
provides snapshots and flexibility. Swap file on btrfs requires
No-COW subvolume to avoid corruption.

Trade-off: LUKS2 vs LUKS1. LUKS2 provides better security
features and tooling, but GRUB <2.06 may have incomplete
support. Users informed of potential boot issues with clear
recovery path rather than silent downgrade.
2025-12-24 09:51:25 +01:00
Stefan Strobl
d6be456c39 feat(core): add phase 1 narrative for core orchestration modules
Add literate programming phase 1 documentation for:
- main.sh: wrapper orchestration and user journey
- config.sh: configuration management and defaults
- sanity.sh: preflight safety checks

Decision: UEFI-only support to reduce complexity. BIOS would
require separate /boot partition and additional testing burden
disproportionate to modern hardware usage.

Decision: LUKS2 as default encryption for improved security
tooling, with clear guidance for LUKS1 fallback if GRUB boot
fails. Auto-detection rejected due to version fragmentation.

Decision: Interactive configuration as default. Presets are
out of scope for phase 1 to keep the flow understandable.

The user journey documents the complete end-to-end flow from
live medium boot to first encrypted boot, establishing clear
handoff points between wrapper and installer.
2025-12-24 09:50:14 +01:00
Stefan Strobl
dbf40c30d8 docs: add literate programming guidelines and project notes
Add comprehensive documentation for literate programming approach:
- Phase 1 guidelines focusing on why/what without implementation
- General literate programming principles for code documentation
- Project notes explaining wrapper script concept and strategy

Decision: Follow literate programming to make the wrapper
maintainable and educational. Comments tell the story, code
implements it. This foundation enables better collaboration
and knowledge transfer.

The notes.md establishes the core concept: a reproducible
wrapper around the Void installer that automates error-prone
LUKS encryption setup while keeping user control over system
configuration choices.
2025-12-24 09:50:00 +01:00