diff --git a/src/filesystems.sh b/src/filesystems.sh index 63d05a0..47606b6 100644 --- a/src/filesystems.sh +++ b/src/filesystems.sh @@ -66,6 +66,7 @@ format_filesystems() { mkdir -p "$temp_mount" # Ensure cleanup on error + # shellcheck disable=SC2329 cleanup_temp_mount() { if mountpoint -q "$temp_mount" 2>/dev/null; then umount "$temp_mount" || log_warn "Failed to unmount temp mount: $temp_mount" diff --git a/src/packages.sh b/src/packages.sh index 667c948..912db58 100644 --- a/src/packages.sh +++ b/src/packages.sh @@ -77,8 +77,8 @@ packages_install() { log_info "Installing ${#all_packages[@]} packages (this may take several minutes)..." # Ensure repository is accessible and synchronized - # Use chroot to install packages into target system - if ! chroot "$MOUNT_ROOT" xbps-install -Syu "${all_packages[@]}"; then + # Install directly into the target root to avoid missing tooling inside chroot + if ! xbps-install -Sy -R "$MOUNT_ROOT" -y "${all_packages[@]}"; then die "Package installation failed. Check network connectivity and repository status." fi @@ -88,7 +88,7 @@ packages_install() { log_info "Verifying package installation..." local critical_packages=("base-system" "linux" "grub" "cryptsetup") for pkg in "${critical_packages[@]}"; do - if ! chroot "$MOUNT_ROOT" xbps-query "$pkg" >/dev/null 2>&1; then + if ! xbps-query -R "$MOUNT_ROOT" "$pkg" >/dev/null 2>&1; then die "Critical package not found: $pkg" fi done diff --git a/src/postinstall.sh b/src/postinstall.sh index a165e7a..eb0f574 100644 --- a/src/postinstall.sh +++ b/src/postinstall.sh @@ -65,6 +65,7 @@ postinstall_unbind_mounts() { postinstall_run() { : "${ROOT_PART:?Root partition is required}" + : "${ESP_PART:?ESP partition is required}" : "${CRYPT_NAME:?Crypt mapping name is required}" : "${MOUNT_ROOT:?Mount root is required}" : "${FS_TYPE:?Filesystem type is required}" @@ -72,15 +73,17 @@ postinstall_run() { : "${HOSTNAME:?Hostname is required}" local luks_uuid local root_uuid + local esp_uuid luks_uuid="$(cryptsetup luksUUID "$ROOT_PART")" root_uuid="$(blkid -s UUID -o value "/dev/mapper/${CRYPT_NAME}")" + esp_uuid="$(blkid -s UUID -o value "$ESP_PART")" log_info "Post-install: configuring target system in chroot" postinstall_bind_mounts trap postinstall_unbind_mounts EXIT - LUKS_UUID="$luks_uuid" ROOT_UUID="$root_uuid" FS_TYPE="$FS_TYPE" SWAP_SIZE="$SWAP_SIZE" HOSTNAME="$HOSTNAME" \ + LUKS_UUID="$luks_uuid" ROOT_UUID="$root_uuid" ESP_UUID="$esp_uuid" FS_TYPE="$FS_TYPE" SWAP_SIZE="$SWAP_SIZE" HOSTNAME="$HOSTNAME" \ chroot "$MOUNT_ROOT" /bin/bash -s <<'EOS' set -euo pipefail @@ -107,6 +110,63 @@ else printf 'add_dracutmodules+=" crypt "\n' > /etc/dracut.conf.d/10-crypt.conf fi +update_fstab_entry() { + local mount_point="$1" + local fs_type="$2" + local options="$3" + local uuid="$4" + if [[ -z "$uuid" ]]; then + echo "Missing UUID for $mount_point" >&2 + exit 1 + fi + local line="UUID=$uuid $mount_point $fs_type $options 0 0" + + if awk -v mp="$mount_point" '$2==mp {found=1} END {exit found?0:1}' /etc/fstab; then + awk -v mp="$mount_point" -v line="$line" 'BEGIN{OFS=" "} $2==mp {$0=line} {print}' /etc/fstab > /etc/fstab.tmp + mv /etc/fstab.tmp /etc/fstab + else + printf '%s\n' "$line" >> /etc/fstab + fi +} + +create_swapfile() { + local swap_size="$1" + + # Try fallocate first, fall back to dd if it fails + if ! fallocate -l "$swap_size" /swap/swapfile 2>/dev/null; then + echo "fallocate failed, using dd as fallback..." + local size_num + local size_unit + local bs="1M" + local count + + size_num="${swap_size%%[^0-9.]*}" + size_unit="${swap_size##*[0-9.]}" + + case "$size_unit" in + GiB|G|GB) count=$(awk "BEGIN {print int($size_num * 1024)}") ;; + MiB|M|MB|"") count=$(awk "BEGIN {print int($size_num)}") ;; + *) echo "Warning: unknown size unit, assuming MiB"; count=$(awk "BEGIN {print int($size_num)}") ;; + esac + + dd if=/dev/zero of=/swap/swapfile bs="$bs" count="$count" status=progress + fi +} + +touch /etc/fstab +update_fstab_entry /boot/efi vfat "defaults" "$ESP_UUID" + +if [[ "$FS_TYPE" == "btrfs" ]]; then + update_fstab_entry / "btrfs" "defaults,subvol=@" "$ROOT_UUID" + update_fstab_entry /home "btrfs" "defaults,subvol=@home" "$ROOT_UUID" + update_fstab_entry /var "btrfs" "defaults,subvol=@var" "$ROOT_UUID" + update_fstab_entry /var/log "btrfs" "defaults,subvol=@log" "$ROOT_UUID" + update_fstab_entry /.snapshots "btrfs" "defaults,subvol=@snapshots" "$ROOT_UUID" + update_fstab_entry /swap "btrfs" "defaults,subvol=@swap" "$ROOT_UUID" +else + update_fstab_entry / "ext4" "defaults" "$ROOT_UUID" +fi + # Prepare a swap file inside the encrypted root if enabled. if [[ "$SWAP_SIZE" != "0" ]]; then mkdir -p /swap @@ -119,25 +179,7 @@ if [[ "$SWAP_SIZE" != "0" ]]; then fi fi - # Try fallocate first, fall back to dd if it fails - if ! fallocate -l "$SWAP_SIZE" /swap/swapfile 2>/dev/null; then - echo "fallocate failed, using dd as fallback..." - # Extract numeric size and unit for dd - local size_num="${SWAP_SIZE%%[^0-9.]*}" - local size_unit="${SWAP_SIZE##*[0-9]}" - local bs="1M" - local count="$size_num" - - # Convert to MB count for dd - case "$size_unit" in - GiB|G|GB) count=$(awk "BEGIN {print int($size_num * 1024)}") ;; - MiB|M|MB) count=$(awk "BEGIN {print int($size_num)}") ;; - *) echo "Warning: unknown size unit, assuming MiB"; count="$size_num" ;; - esac - - dd if=/dev/zero of=/swap/swapfile bs="$bs" count="$count" status=progress - fi - + create_swapfile "$SWAP_SIZE" chmod 600 /swap/swapfile mkswap /swap/swapfile if ! grep -q '^/swap/swapfile' /etc/fstab; then @@ -145,31 +187,6 @@ if [[ "$SWAP_SIZE" != "0" ]]; then fi fi -# Ensure btrfs subvolumes are reflected in /etc/fstab. -if [[ "$FS_TYPE" == "btrfs" ]]; then - touch /etc/fstab - - update_fstab_entry() { - local mount_point="$1" - local options="$2" - local line="UUID=$ROOT_UUID $mount_point btrfs $options 0 0" - - if awk -v mp="$mount_point" '$2==mp {found=1} END {exit found?0:1}' /etc/fstab; then - awk -v mp="$mount_point" -v line="$line" 'BEGIN{OFS=" "} $2==mp {$0=line} {print}' /etc/fstab > /etc/fstab.tmp - mv /etc/fstab.tmp /etc/fstab - else - printf '%s\n' "$line" >> /etc/fstab - fi - } - - update_fstab_entry / "defaults,subvol=@" - update_fstab_entry /home "defaults,subvol=@home" - update_fstab_entry /var "defaults,subvol=@var" - update_fstab_entry /var/log "defaults,subvol=@log" - update_fstab_entry /.snapshots "defaults,subvol=@snapshots" - update_fstab_entry /swap "defaults,subvol=@swap" -fi - # Ensure GRUB unlocks the encrypted root and passes the LUKS UUID to initramfs. mkdir -p /etc/default touch /etc/default/grub