diff options
| author | Craig Jennings <c@cjennings.net> | 2026-01-23 22:57:21 -0600 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-01-23 22:57:21 -0600 |
| commit | e4ee55f9706d5567f45b6b4f6f007c09709fdfea (patch) | |
| tree | 93b017f7d3b8c76c752e25b2e7c380019bc33355 | |
| parent | 4560cbdc55e6bd5abe643806e4115d67313db564 (diff) | |
| download | archangel-e4ee55f9706d5567f45b6b4f6f007c09709fdfea.tar.gz archangel-e4ee55f9706d5567f45b6b4f6f007c09709fdfea.zip | |
Phase 2.1: Implement btrfs support
- Create lib/btrfs.sh with full btrfs installation functions
- Subvolume layout matching ZFS datasets (10 subvols)
- Snapper configuration with timeline policy
- GRUB + grub-btrfs for snapshot boot menu
- Update disk.sh for filesystem-aware partition type
- Update archangel with install_btrfs() path
- Update build.sh to include lib/btrfs.sh
- Update plan with Phase 2.7 (test) and 2.8 (LUKS)
| -rwxr-xr-x | build.sh | 3 | ||||
| -rwxr-xr-x | custom/archangel | 165 | ||||
| -rw-r--r-- | custom/lib/btrfs.sh | 423 | ||||
| -rw-r--r-- | custom/lib/disk.sh | 11 | ||||
| -rw-r--r-- | docs/PLAN-archangel-btrfs.org | 34 | ||||
| -rw-r--r-- | docs/session-context.org | 101 |
6 files changed, 656 insertions, 81 deletions
@@ -417,6 +417,9 @@ if grep -q "file_permissions=" "$PROFILE_DIR/profiledef.sh"; then /)/ i\ ["/usr/local/bin/lib/zfs.sh"]="0:0:755" }' "$PROFILE_DIR/profiledef.sh" sed -i '/^file_permissions=(/,/)/ { + /)/ i\ ["/usr/local/bin/lib/btrfs.sh"]="0:0:755" + }' "$PROFILE_DIR/profiledef.sh" + sed -i '/^file_permissions=(/,/)/ { /)/ i\ ["/etc/shadow"]="0:0:400" }' "$PROFILE_DIR/profiledef.sh" fi diff --git a/custom/archangel b/custom/archangel index f9bc637..c887a4d 100755 --- a/custom/archangel +++ b/custom/archangel @@ -29,6 +29,7 @@ source "$SCRIPT_DIR/lib/common.sh" source "$SCRIPT_DIR/lib/config.sh" source "$SCRIPT_DIR/lib/disk.sh" source "$SCRIPT_DIR/lib/zfs.sh" +source "$SCRIPT_DIR/lib/btrfs.sh" ############################# # Configuration @@ -80,7 +81,15 @@ echo "" preflight_checks() { require_root - zfs_preflight +} + +# Filesystem-specific preflight (called after filesystem is selected) +filesystem_preflight() { + if [[ "$FILESYSTEM" == "zfs" ]]; then + zfs_preflight + elif [[ "$FILESYSTEM" == "btrfs" ]]; then + btrfs_preflight + fi } ############################# @@ -108,9 +117,9 @@ gather_input() { fi fi - # Btrfs not yet implemented - if [[ "$FILESYSTEM" == "btrfs" ]]; then - error "Btrfs support not yet implemented. Use FILESYSTEM=zfs" + # Validate filesystem choice + if [[ "$FILESYSTEM" != "zfs" && "$FILESYSTEM" != "btrfs" ]]; then + error "Invalid FILESYSTEM: $FILESYSTEM (must be 'zfs' or 'btrfs')" fi # Determine RAID level if not specified @@ -143,12 +152,6 @@ gather_input() { echo "" select_filesystem - - # Check for btrfs (not yet implemented) - if [[ "$FILESYSTEM" == "btrfs" ]]; then - error "Btrfs support not yet implemented. Please select ZFS." - fi - get_hostname get_timezone get_locale @@ -156,8 +159,17 @@ gather_input() { get_disks get_raid_level get_wifi - get_encryption_choice - [[ "$NO_ENCRYPT" != "yes" ]] && get_zfs_passphrase + + # Encryption handling (filesystem-specific) + if [[ "$FILESYSTEM" == "zfs" ]]; then + get_encryption_choice + [[ "$NO_ENCRYPT" != "yes" ]] && get_zfs_passphrase + elif [[ "$FILESYSTEM" == "btrfs" ]]; then + # Btrfs encryption (LUKS) not yet implemented - Phase 2.8 + info "Note: Btrfs encryption (LUKS) will be available in a future update." + NO_ENCRYPT="yes" + fi + get_root_password get_ssh_config show_summary @@ -882,6 +894,44 @@ EOF info "Base system installed." } +install_base_btrfs() { + step "Installing Base System (Btrfs)" + + info "Updating pacman keys..." + pacman-key --init + pacman-key --populate archlinux + + info "Installing base packages (this takes a while)..." + yes "" | pacstrap -K /mnt \ + base \ + base-devel \ + linux-lts \ + linux-lts-headers \ + linux-firmware \ + btrfs-progs \ + grub \ + grub-btrfs \ + efibootmgr \ + snapper \ + snap-pac \ + networkmanager \ + avahi \ + nss-mdns \ + openssh \ + git \ + vim \ + sudo \ + zsh \ + nodejs \ + npm \ + ttf-dejavu \ + fzf \ + wget \ + wireless-regdb + + info "Base system installed." +} + configure_system() { step "Configuring System" @@ -1392,6 +1442,37 @@ print_summary() { echo "" } +print_btrfs_summary() { + echo "" + echo "╔═══════════════════════════════════════════════════════════════╗" + echo "║ Installation Complete! ║" + echo "╚═══════════════════════════════════════════════════════════════╝" + echo "" + echo "System Configuration:" + echo " Hostname: $HOSTNAME" + echo " Timezone: $TIMEZONE" + echo " Filesystem: Btrfs" + echo "" + echo "Btrfs Snapshot Features:" + echo " - Boot from any snapshot via GRUB menu" + echo " - Genesis snapshot: pristine post-install state" + echo " - Pre/post pacman snapshots via snap-pac" + echo " - Timeline snapshots: 6 hourly, 7 daily, 2 weekly, 1 monthly" + echo "" + echo "GRUB Boot Menu:" + echo " - Select 'Arch Linux snapshots' submenu to boot from snapshots" + echo " - Snapshots auto-added when created by snapper" + echo "" + echo "Useful Commands:" + echo " List snapshots: snapper -c root list" + echo " Manual snapshot: snapper -c root create -d 'description'" + echo " Rollback: snapper -c root rollback <number>" + echo " Compare: snapper -c root diff <num1>..<num2>" + echo "" + info "Installation log: $LOGFILE" + echo "" +} + ############################# # Main ############################# @@ -1401,14 +1482,27 @@ main() { preflight_checks check_config gather_input + filesystem_preflight # Unattended installation begins echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo "Beginning unattended installation..." + echo "Beginning unattended installation ($FILESYSTEM)..." echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" + if [[ "$FILESYSTEM" == "zfs" ]]; then + install_zfs + elif [[ "$FILESYSTEM" == "btrfs" ]]; then + install_btrfs + fi +} + +############################# +# ZFS Installation Path +############################# + +install_zfs() { partition_disks create_zfs_pool create_datasets @@ -1429,6 +1523,51 @@ main() { print_summary } +############################# +# Btrfs Installation Path +############################# + +install_btrfs() { + # Get partition references + local root_part=$(get_root_partition "${SELECTED_DISKS[0]}") + local efi_part=$(get_efi_partition "${SELECTED_DISKS[0]}") + + # Partition and format + partition_disk "${SELECTED_DISKS[0]}" + format_efi "$efi_part" + create_btrfs_volume "$root_part" + + # Create and mount subvolumes + create_btrfs_subvolumes "$root_part" + mount_btrfs_subvolumes "$root_part" + + # Mount EFI + mkdir -p /mnt/efi + mount "$efi_part" /mnt/efi + + # Install base system + install_base_btrfs + + # Configure system + configure_system + configure_wifi + configure_ssh + generate_btrfs_fstab "$root_part" "$efi_part" + configure_btrfs_initramfs + configure_grub "$efi_part" + configure_snapper + configure_btrfs_services + configure_btrfs_pacman_hook + copy_archsetup + + # Genesis snapshot + create_btrfs_genesis_snapshot + + # Cleanup + btrfs_cleanup + print_btrfs_summary +} + trap 'error "Installation interrupted!"' INT TERM main "$@" diff --git a/custom/lib/btrfs.sh b/custom/lib/btrfs.sh new file mode 100644 index 0000000..c264fce --- /dev/null +++ b/custom/lib/btrfs.sh @@ -0,0 +1,423 @@ +#!/usr/bin/env bash +# btrfs.sh - Btrfs-specific functions for archangel installer +# Source this file after common.sh, config.sh, disk.sh + +############################# +# Btrfs Constants +############################# + +# Mount options for btrfs subvolumes +BTRFS_OPTS="noatime,compress=zstd,space_cache=v2,discard=async" + +# Subvolume layout (matches ZFS dataset structure) +# Format: "name:mountpoint:extra_opts" +BTRFS_SUBVOLS=( + "@:/::" + "@home:/home::" + "@snapshots:/.snapshots::" + "@var_log:/var/log::" + "@var_cache:/var/cache::" + "@tmp:/tmp::nosuid,nodev" + "@var_tmp:/var/tmp::nosuid,nodev" + "@media:/media::compress=no" + "@vms:/vms::nodatacow,compress=no" + "@var_lib_docker:/var/lib/docker::" +) + +############################# +# Btrfs Pre-flight +############################# + +btrfs_preflight() { + step "Checking Btrfs Requirements" + + # Check for btrfs-progs + if ! command_exists mkfs.btrfs; then + error "btrfs-progs not installed. Cannot create btrfs filesystem." + fi + info "btrfs-progs available." + + # Check for required tools + require_command btrfs + require_command grub-install + + info "Btrfs preflight checks passed." +} + +############################# +# Btrfs Volume Creation +############################# + +create_btrfs_volume() { + local partition="$1" + + step "Creating Btrfs Filesystem" + + info "Formatting $partition as btrfs..." + mkfs.btrfs -f -L "archroot" "$partition" || error "Failed to create btrfs filesystem" + + info "Btrfs filesystem created on $partition" +} + +############################# +# Subvolume Creation +############################# + +create_btrfs_subvolumes() { + local partition="$1" + + step "Creating Btrfs Subvolumes" + + # Mount the raw btrfs volume temporarily + mount "$partition" /mnt || error "Failed to mount btrfs volume" + + # Create each subvolume + for subvol_spec in "${BTRFS_SUBVOLS[@]}"; do + IFS=':' read -r name mountpoint extra <<< "$subvol_spec" + info "Creating subvolume: $name -> $mountpoint" + btrfs subvolume create "/mnt/$name" || error "Failed to create subvolume $name" + done + + # Unmount raw volume + umount /mnt + + info "Created ${#BTRFS_SUBVOLS[@]} subvolumes." +} + +############################# +# Btrfs Mount Functions +############################# + +mount_btrfs_subvolumes() { + local partition="$1" + + step "Mounting Btrfs Subvolumes" + + # Mount root subvolume first + info "Mounting @ -> /mnt" + mount -o "subvol=@,$BTRFS_OPTS" "$partition" /mnt || error "Failed to mount root subvolume" + + # Create mount points and mount remaining subvolumes + for subvol_spec in "${BTRFS_SUBVOLS[@]}"; do + IFS=':' read -r name mountpoint extra <<< "$subvol_spec" + + # Skip root, already mounted + [[ "$name" == "@" ]] && continue + + # Build mount options + local opts="subvol=$name,$BTRFS_OPTS" + + # Apply extra options (override defaults where specified) + if [[ -n "$extra" ]]; then + # Handle compress=no by removing compress from opts and not adding it + if [[ "$extra" == *"compress=no"* ]]; then + opts=$(echo "$opts" | sed 's/,compress=zstd//') + fi + # Handle nodatacow + if [[ "$extra" == *"nodatacow"* ]]; then + opts="$opts,nodatacow" + opts=$(echo "$opts" | sed 's/,compress=zstd//') + fi + # Handle nosuid,nodev for tmp + if [[ "$extra" == *"nosuid"* ]]; then + opts="$opts,nosuid,nodev" + fi + fi + + info "Mounting $name -> /mnt$mountpoint" + mkdir -p "/mnt$mountpoint" + mount -o "$opts" "$partition" "/mnt$mountpoint" || error "Failed to mount $name" + done + + # Set permissions on tmp directories + chmod 1777 /mnt/tmp /mnt/var/tmp + + info "All subvolumes mounted." +} + +############################# +# Fstab Generation +############################# + +generate_btrfs_fstab() { + local partition="$1" + local efi_partition="$2" + + step "Generating fstab" + + local uuid + uuid=$(blkid -s UUID -o value "$partition") + + # Start with header + cat > /mnt/etc/fstab << EOF +# /etc/fstab - Btrfs subvolume mounts +# IMPORTANT: Using subvol= NOT subvolid= for snapshot compatibility +# Generated by archangel installer + +EOF + + # Add each subvolume + for subvol_spec in "${BTRFS_SUBVOLS[@]}"; do + IFS=':' read -r name mountpoint extra <<< "$subvol_spec" + + # Build mount options + local opts="subvol=$name,$BTRFS_OPTS" + + # Apply extra options + if [[ -n "$extra" ]]; then + if [[ "$extra" == *"compress=no"* ]]; then + opts=$(echo "$opts" | sed 's/,compress=zstd//') + fi + if [[ "$extra" == *"nodatacow"* ]]; then + opts="$opts,nodatacow" + opts=$(echo "$opts" | sed 's/,compress=zstd//') + fi + if [[ "$extra" == *"nosuid"* ]]; then + opts="$opts,nosuid,nodev" + fi + fi + + echo "UUID=$uuid $mountpoint btrfs $opts 0 0" >> /mnt/etc/fstab + done + + # Add EFI partition + local efi_uuid + efi_uuid=$(blkid -s UUID -o value "$efi_partition") + echo "" >> /mnt/etc/fstab + echo "# EFI System Partition" >> /mnt/etc/fstab + echo "UUID=$efi_uuid /efi vfat defaults,noatime 0 2" >> /mnt/etc/fstab + + info "fstab generated with ${#BTRFS_SUBVOLS[@]} btrfs mounts + EFI" +} + +############################# +# Snapper Configuration +############################# + +configure_snapper() { + step "Configuring Snapper" + + # Snapper config for root + # Note: snapper expects /.snapshots to exist and be a subvolume + info "Creating snapper config for root..." + + arch-chroot /mnt snapper -c root create-config / || error "Failed to create snapper config" + + # Snapper creates its own .snapshots subvolume, but we already have @snapshots + # Delete snapper's and use ours + arch-chroot /mnt btrfs subvolume delete /.snapshots 2>/dev/null || true + mkdir -p /mnt/.snapshots + + # Set snapper timeline settings + # Keep: 6 hourly, 7 daily, 2 weekly, 1 monthly + info "Configuring snapshot retention policy..." + cat > /mnt/etc/snapper/configs/root << 'EOF' +# Snapper config for root filesystem +SUBVOLUME="/" +FSTYPE="btrfs" +QGROUP="" + +# Automatic timeline snapshots +TIMELINE_CREATE="yes" +TIMELINE_CLEANUP="yes" + +# Retention policy +TIMELINE_MIN_AGE="1800" +TIMELINE_LIMIT_HOURLY="6" +TIMELINE_LIMIT_DAILY="7" +TIMELINE_LIMIT_WEEKLY="2" +TIMELINE_LIMIT_MONTHLY="1" +TIMELINE_LIMIT_YEARLY="0" + +# Cleanup settings +NUMBER_CLEANUP="yes" +NUMBER_MIN_AGE="1800" +NUMBER_LIMIT="50" +NUMBER_LIMIT_IMPORTANT="10" + +# User access +ALLOW_USERS="" +ALLOW_GROUPS="" + +# Sync ACL +SYNC_ACL="no" + +# Background comparison +BACKGROUND_COMPARISON="yes" + +# Empty pre-post cleanup +EMPTY_PRE_POST_CLEANUP="yes" +EMPTY_PRE_POST_MIN_AGE="1800" +EOF + + # Enable snapper timers + arch-chroot /mnt systemctl enable snapper-timeline.timer + arch-chroot /mnt systemctl enable snapper-cleanup.timer + + info "Snapper configured with timeline snapshots enabled." +} + +############################# +# GRUB Configuration +############################# + +configure_grub() { + local efi_partition="$1" + + step "Configuring GRUB Bootloader" + + # Mount EFI partition + mkdir -p /mnt/efi + mount "$efi_partition" /mnt/efi + + # Configure GRUB defaults + info "Setting GRUB configuration..." + cat > /mnt/etc/default/grub << 'EOF' +# GRUB configuration for btrfs root with snapshots +GRUB_DEFAULT=0 +GRUB_TIMEOUT=5 +GRUB_DISTRIBUTOR="Arch" +GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet" +GRUB_CMDLINE_LINUX="" + +# Btrfs snapshot boot support +GRUB_BTRFS_GRUB_DIRNAME="/efi/grub" + +# Disable os-prober (single-boot system) +GRUB_DISABLE_OS_PROBER=true +EOF + + # Install GRUB to EFI + info "Installing GRUB to EFI partition..." + arch-chroot /mnt grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB \ + || error "GRUB installation failed" + + # Generate GRUB config + info "Generating GRUB configuration..." + arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg \ + || error "Failed to generate GRUB config" + + # Enable grub-btrfsd for automatic snapshot menu updates + info "Enabling grub-btrfs daemon..." + arch-chroot /mnt systemctl enable grub-btrfsd + + info "GRUB configured with btrfs snapshot support." +} + +############################# +# Pacman Snapshot Hook +############################# + +configure_btrfs_pacman_hook() { + step "Configuring Pacman Snapshot Hook" + + # snap-pac handles this automatically when installed + # Just verify it's set up + info "snap-pac will create pre/post snapshots for pacman transactions." + info "Snapshots visible in GRUB menu via grub-btrfs." +} + +############################# +# Genesis Snapshot +############################# + +create_btrfs_genesis_snapshot() { + step "Creating Genesis Snapshot" + + # Use snapper to create the genesis snapshot + arch-chroot /mnt snapper -c root create --description "genesis" \ + || error "Failed to create genesis snapshot" + + info "Genesis snapshot created." + info "Restore with: snapper -c root rollback <number>" + + # Show the snapshot + arch-chroot /mnt snapper -c root list +} + +############################# +# Btrfs Services +############################# + +configure_btrfs_services() { + step "Configuring System Services" + + # Enable standard services + arch-chroot /mnt systemctl enable NetworkManager + arch-chroot /mnt systemctl enable avahi-daemon + + # Snapper timers (already enabled in configure_snapper) + + # grub-btrfsd (already enabled in configure_grub) + + info "System services configured." +} + +############################# +# Btrfs Initramfs +############################# + +configure_btrfs_initramfs() { + step "Configuring Initramfs for Btrfs" + + # Backup original + cp /mnt/etc/mkinitcpio.conf /mnt/etc/mkinitcpio.conf.bak + + # Remove archiso drop-in if present + if [[ -f /mnt/etc/mkinitcpio.conf.d/archiso.conf ]]; then + info "Removing archiso drop-in config..." + rm -f /mnt/etc/mkinitcpio.conf.d/archiso.conf + fi + + # Create proper linux-lts preset + info "Creating linux-lts preset..." + cat > /mnt/etc/mkinitcpio.d/linux-lts.preset << 'EOF' +# mkinitcpio preset file for linux-lts + +PRESETS=(default fallback) + +ALL_kver="/boot/vmlinuz-linux-lts" + +default_image="/boot/initramfs-linux-lts.img" + +fallback_image="/boot/initramfs-linux-lts-fallback.img" +fallback_options="-S autodetect" +EOF + + # Configure hooks for btrfs + # btrfs module is built into kernel, but we need the btrfs hook for multi-device + sed -i 's/^HOOKS=.*/HOOKS=(base udev microcode modconf kms keyboard keymap consolefont block filesystems fsck)/' \ + /mnt/etc/mkinitcpio.conf + + # Regenerate initramfs + info "Regenerating initramfs..." + arch-chroot /mnt mkinitcpio -P + + info "Initramfs configured for btrfs." +} + +############################# +# Btrfs Cleanup +############################# + +btrfs_cleanup() { + step "Cleaning Up Btrfs" + + # Unmount in reverse order + info "Unmounting subvolumes..." + + # Unmount EFI first + umount /mnt/efi 2>/dev/null || true + + # Unmount all btrfs subvolumes (reverse order) + for ((i=${#BTRFS_SUBVOLS[@]}-1; i>=0; i--)); do + IFS=':' read -r name mountpoint extra <<< "${BTRFS_SUBVOLS[$i]}" + [[ "$name" == "@" ]] && continue + umount "/mnt$mountpoint" 2>/dev/null || true + done + + # Unmount root last + umount /mnt 2>/dev/null || true + + info "Btrfs cleanup complete." +} diff --git a/custom/lib/disk.sh b/custom/lib/disk.sh index fa3dbd2..38c6dd9 100644 --- a/custom/lib/disk.sh +++ b/custom/lib/disk.sh @@ -8,10 +8,17 @@ # Partition a single disk for ZFS/Btrfs installation # Creates: EFI partition (512M) + root partition (rest) +# Uses global FILESYSTEM variable to determine partition type partition_disk() { local disk="$1" local efi_size="${2:-512M}" + # Determine root partition type based on filesystem + local root_type="BF00" # ZFS (Solaris root) + if [[ "$FILESYSTEM" == "btrfs" ]]; then + root_type="8300" # Linux filesystem + fi + info "Partitioning $disk..." # Wipe existing partition table @@ -20,8 +27,8 @@ partition_disk() { # Create EFI partition (512M, type EF00) sgdisk -n 1:0:+${efi_size} -t 1:EF00 -c 1:"EFI" "$disk" || error "Failed to create EFI partition on $disk" - # Create root partition (rest of disk, type BF00 for ZFS or 8300 for Linux) - sgdisk -n 2:0:0 -t 2:BF00 -c 2:"ROOT" "$disk" || error "Failed to create root partition on $disk" + # Create root partition (rest of disk) + sgdisk -n 2:0:0 -t 2:$root_type -c 2:"ROOT" "$disk" || error "Failed to create root partition on $disk" # Notify kernel of partition changes partprobe "$disk" 2>/dev/null || true diff --git a/docs/PLAN-archangel-btrfs.org b/docs/PLAN-archangel-btrfs.org index ea39bf6..9d91db7 100644 --- a/docs/PLAN-archangel-btrfs.org +++ b/docs/PLAN-archangel-btrfs.org @@ -98,7 +98,14 @@ BTRFS_OPTS="noatime,compress=zstd,space_cache=v2,discard=async" - [ ] Verify appears in snapper list - [ ] Verify appears in GRUB menu -** 2.7 LUKS encryption (optional) +** 2.7 Test basic btrfs (before encryption) +- [ ] VM test: single-disk btrfs install +- [ ] Verify subvolumes created correctly +- [ ] Verify GRUB boots and shows snapshots +- [ ] Verify snapper works +- [ ] Verify genesis snapshot exists + +** 2.8 LUKS encryption (after basic btrfs works) - [ ] Add encryption prompt (yes/no) - [ ] Create LUKS container on root partition - [ ] Configure crypttab @@ -107,20 +114,31 @@ BTRFS_OPTS="noatime,compress=zstd,space_cache=v2,discard=async" * Phase 3: Multi-disk Btrfs -Goal: Mirror support for btrfs. +Goal: Full multi-disk support for btrfs (matching ZFS capabilities). -** 3.1 Btrfs RAID1 creation -- [ ] Detect multi-disk selection -- [ ] Create raid1 volume: mkfs.btrfs -d raid1 -m raid1 /dev/sdX /dev/sdY -- [ ] Handle 2+ disk configurations +** 3.1 RAID level support +- [ ] Stripe (raid0): mkfs.btrfs -d raid0 -m raid0 +- [ ] Mirror (raid1): mkfs.btrfs -d raid1 -m raid1 +- [ ] raid10: mkfs.btrfs -d raid10 -m raid10 (4+ disks) +- [ ] raid5: mkfs.btrfs -d raid5 -m raid5 (3+ disks, warn: unstable) +- [ ] raid6: mkfs.btrfs -d raid6 -m raid6 (4+ disks, warn: unstable) +- [ ] Detect multi-disk selection and offer appropriate levels +- [ ] Handle mixed disk sizes gracefully -** 3.2 EFI redundancy +** 3.2 Encryption + multi-disk +- [ ] LUKS on each disk before btrfs +- [ ] crypttab entries for all disks +- [ ] Test unlock sequence at boot +- [ ] Single passphrase unlocks all (keyfile approach) + +** 3.3 EFI redundancy - [ ] Create EFI partition on all disks - [ ] Install GRUB to all EFI partitions - [ ] Create boot entries for each disk -** 3.3 Degraded boot support +** 3.4 Degraded boot support - [ ] Add degraded mount option for emergency +- [ ] Kernel param: rootflags=degraded - [ ] Document recovery procedure * Phase 4: Testing Infrastructure diff --git a/docs/session-context.org b/docs/session-context.org index f441e89..66a1ae0 100644 --- a/docs/session-context.org +++ b/docs/session-context.org @@ -11,67 +11,52 @@ - Checked for conflicts: pwnerfly/Archangel is dead (2020, 0 stars, no license) - Name is clear for use -** Work Completed - -*** 1. Btrfs Implementation Planning -- Created docs/PLAN-archangel-btrfs.org with 6-phase implementation -- Expanded testing validation checks in research doc -- Decided: snapper for snapshots, GRUB for btrfs boot - -*** 2. Phase 1: Refactor (COMPLETE) -**** Phase 1.1: lib/ Structure -Created modular library structure: -- [X] custom/lib/common.sh - output, validation, fzf prompts, filesystem selection -- [X] custom/lib/config.sh - argument parsing, config loading -- [X] custom/lib/disk.sh - partitioning, disk selection -- [X] custom/lib/zfs.sh - ZFS pool, datasets, services - -**** Phase 1.4: Filesystem Selection -- [X] Added FILESYSTEM variable (zfs/btrfs) -- [X] Added select_filesystem() with fzf prompt -- [X] Btrfs selection shows "not yet implemented" -- [X] Config file supports FILESYSTEM option +*** Btrfs Implementation Approach +- Phase 2: Single-disk btrfs, no encryption (test first) +- Phase 2.7: Test basic btrfs before adding encryption +- Phase 2.8: LUKS encryption after basic btrfs works +- Phase 3: Multi-disk (stripe, mirror, raidX) + encrypted/unencrypted -**** Phase 1.5: Rename to archangel -- [X] Renamed install-archzfs → archangel -- [X] Updated build.sh references -- [X] Updated config example to archangel.conf.example -- [X] Updated script headers +*** Partition Type Handling +- disk.sh checks global FILESYSTEM variable +- ZFS: BF00 (Solaris root) +- Btrfs: 8300 (Linux filesystem) -*** 3. Bug Fix: set -e compatibility -Found and fixed critical bug during VM testing: -- [[ condition ]] && error pattern fails with set -e -- Fixed by converting to if/then/fi pattern - -*** 4. VM Test PASSED -Full end-to-end test: -- ISO built with lib/ structure -- Unattended install completed -- ZFSBootMenu boots correctly -- Genesis snapshots created -- System fully functional - -** Commits This Session (11 total) -- 94c2f15: Add archsetup --chroot task -- 49a8b2e: Add btrfs implementation plan -- d8eb81a: Expand testing validation checks -- 15ac415: Phase 1.1 - Create lib/ directory structure -- 498ab4d: Fix build.sh to include lib/ in ISO -- c74b1d7: Fix set -e compatibility in lib functions -- 0f56f1f: Update session context -- 7cfdc69: Phase 1.1 complete: VM test passed -- b8973f3: Phase 1.4 - Add filesystem selection prompt -- 18c07ee: Phase 1.5 - Rename to archangel - -** Phase 1 Status: COMPLETE +** Work Completed -** Next Steps (Phase 2: Btrfs Support) -1. Create lib/btrfs.sh with btrfs functions -2. Implement subvolume creation -3. Implement snapper configuration -4. Implement GRUB + grub-btrfs -5. Test btrfs installation +*** 1. Phase 1: Refactor (COMPLETE) +- [X] lib/common.sh, config.sh, disk.sh, zfs.sh created +- [X] Filesystem selection prompt +- [X] Renamed to archangel +- [X] VM test passed + +*** 2. Phase 2: Btrfs Support (IN PROGRESS) +**** Phase 2.1: lib/btrfs.sh (COMPLETE) +- [X] Created lib/btrfs.sh with full implementation +- [X] BTRFS_OPTS: noatime,compress=zstd,space_cache=v2,discard=async +- [X] 10 subvolumes matching ZFS dataset layout +- [X] Mount functions with proper options +- [X] fstab generation (subvol= NOT subvolid!) +- [X] Snapper configuration (timeline policy) +- [X] GRUB + grub-btrfs configuration +- [X] Genesis snapshot via snapper + +**** Updated Files +- [X] disk.sh - filesystem-aware partition type +- [X] archangel - sources btrfs.sh, install_btrfs() path +- [X] build.sh - includes lib/btrfs.sh permissions +- [X] PLAN-archangel-btrfs.org - added Phase 2.7/2.8 + +**** Syntax Checks +- [X] All lib/*.sh pass bash -n +- [X] archangel passes bash -n +- [X] All btrfs functions defined correctly + +** Next Steps +1. Commit Phase 2.1 implementation +2. Build ISO +3. VM test btrfs installation path ** Notes - Craig on remote console: 30 lines tall, ~145 columns wide -- Craig stepped away ~17:23, working autonomously +- Testing approach: syntax first, then full VM test |
