diff --git a/x86_64/airootfs/usr/local/bin/install-stormux b/x86_64/airootfs/usr/local/bin/install-stormux index 11d89ce..8b96e6f 100755 --- a/x86_64/airootfs/usr/local/bin/install-stormux +++ b/x86_64/airootfs/usr/local/bin/install-stormux @@ -11,7 +11,8 @@ mountPoint="/mnt" bootMode="" # Will be "uefi" or "bios" targetDisk="" homeDisk="" -partitionLayout="" # "single", "separate_home", "separate_disk" +partitionLayout="" # "single", "separate_home", "separate_disk", "manual_mnt" +useExistingMount=false # true when using manually mounted filesystems at /mnt hostname="" rootPassword="" declare -a userNames=() @@ -43,7 +44,7 @@ log_warning() { } log_info() { - echo "INFO: $*" | tee -a "$logFile" + echo "$*" | tee -a "$logFile" } # @@ -92,7 +93,7 @@ check_internet() { check_required_tools() { log_info "Checking for required tools..." - local tools=(parted mkfs.vfat mkfs.ext4 pacstrap arch-chroot genfstab lsblk) + local tools=(parted mkfs.vfat mkfs.ext4 pacstrap arch-chroot genfstab lsblk blkid findmnt mountpoint) local missing=() for tool in "${tools[@]}"; do @@ -164,6 +165,39 @@ select_disk() { done } +select_install_target() { + echo "Select installation target:" + + mapfile -t disks < <(list_available_disks | awk '{print $1}') + + if [[ ${#disks[@]} -gt 0 ]]; then + # Display disk information + log "Available disks:" + lsblk -dno NAME,SIZE,TYPE,MODEL | grep -E "^($(IFS='|'; echo "${disks[*]}")).*disk" || true + else + log_warning "No suitable installation disks detected" + fi + + local manualOption="Use existing /mnt (already mounted root/home/boot)" + PS3="Enter target number: " + select targetChoice in "${disks[@]}" "$manualOption" "Cancel"; do + if [[ "$targetChoice" == "Cancel" ]]; then + log_info "Target selection cancelled by user" + return 1 + elif [[ "$targetChoice" == "$manualOption" ]]; then + useExistingMount=true + partitionLayout="manual_mnt" + log_info "Selected existing mount mode at $mountPoint" + return 0 + elif [[ -n "$targetChoice" ]]; then + targetDisk="/dev/$targetChoice" + useExistingMount=false + log_info "Selected disk: $targetDisk" + return 0 + fi + done +} + confirm_disk_destruction() { local disk="$1" log "" @@ -571,6 +605,152 @@ mount_filesystems() { log_info "Filesystems mounted successfully" } +validate_existing_mountpoint() { + log_info "=== Validating Existing Mountpoint ===" + + if [[ ! -d "$mountPoint" ]]; then + log_error "Mountpoint does not exist: $mountPoint" + return 1 + fi + + if ! mountpoint -q "$mountPoint"; then + log_error "$mountPoint is not mounted" + log_error "Mount root to $mountPoint before running this installer mode" + return 1 + fi + + local rootSource + rootSource=$(findmnt -n -o SOURCE --target "$mountPoint" 2>/dev/null || true) + if [[ -z "$rootSource" ]]; then + log_error "Could not determine mounted root source for $mountPoint" + return 1 + fi + if [[ "$rootSource" != /dev/* ]]; then + log_error "Unsupported root source for manual install mode: $rootSource" + log_error "Root at $mountPoint must be backed by a /dev/* block device" + return 1 + fi + + if [[ ! -d "$mountPoint/home" ]]; then + log_error "Required directory is missing: $mountPoint/home" + log_error "Create or mount /home at $mountPoint/home before continuing" + return 1 + fi + + if [[ "$bootMode" == "uefi" ]]; then + if [[ ! -d "$mountPoint/boot" ]]; then + log_error "Required directory is missing for UEFI: $mountPoint/boot" + log_error "Mount the EFI system partition at $mountPoint/boot before continuing" + return 1 + fi + + if ! mountpoint -q "$mountPoint/boot"; then + log_error "$mountPoint/boot is not mounted" + log_error "For UEFI installs, mount EFI at $mountPoint/boot before continuing" + return 1 + fi + + local efiFsType + efiFsType=$(findmnt -n -o FSTYPE --target "$mountPoint/boot" 2>/dev/null || true) + if [[ "$efiFsType" != "vfat" && "$efiFsType" != "fat" && "$efiFsType" != "msdos" ]]; then + log_error "Unexpected EFI filesystem type at $mountPoint/boot: ${efiFsType:-unknown}" + log_error "UEFI boot partition must be FAT (vfat)" + return 1 + fi + fi + + if ! mountpoint -q "$mountPoint/home"; then + log_warning "$mountPoint/home is not a separate mountpoint" + log_warning "Continuing with /home as a directory inside root" + fi + + local writeTestFile="$mountPoint/.stormux-write-test-$$" + if ! touch "$writeTestFile" 2>/dev/null; then + log_error "$mountPoint is not writable" + return 1 + fi + rm -f "$writeTestFile" + + log "" + log "Manual mount summary (current mounts):" + log " $(findmnt -n -o SOURCE,FSTYPE,TARGET --target "$mountPoint" 2>/dev/null || echo "$mountPoint not mounted")" + + if mountpoint -q "$mountPoint/home"; then + log " $(findmnt -n -o SOURCE,FSTYPE,TARGET --target "$mountPoint/home" 2>/dev/null || echo "$mountPoint/home not mounted")" + else + log " $mountPoint/home is a directory inside root (not a separate mount)" + fi + + if [[ "$bootMode" == "uefi" ]]; then + log " $(findmnt -n -o SOURCE,FSTYPE,TARGET --target "$mountPoint/boot" 2>/dev/null || echo "$mountPoint/boot not mounted")" + fi + + echo "" + echo "Type 'YES' (in capital letters) to continue using existing mounts at $mountPoint:" + read -r manualMountConfirmation + if [[ "$manualMountConfirmation" != "YES" ]]; then + log_info "Existing mount mode not confirmed" + return 1 + fi + + log_info "Existing mountpoint validation passed" + return 0 +} + +get_root_partition_device() { + if [[ "$useExistingMount" == true ]]; then + findmnt -n -o SOURCE --target "$mountPoint" 2>/dev/null || true + else + if [[ "$bootMode" == "uefi" ]]; then + get_partition_device "$targetDisk" 2 + else + get_partition_device "$targetDisk" 1 + fi + fi +} + +get_bios_install_disk() { + if [[ "$useExistingMount" == false ]]; then + echo "$targetDisk" + return 0 + fi + + local rootPart + rootPart=$(get_root_partition_device) + if [[ -z "$rootPart" ]]; then + log_error "Could not determine root source from mounted $mountPoint" + return 1 + fi + + if [[ "$rootPart" != /dev/* ]]; then + log_error "Unsupported root source for BIOS bootloader installation: $rootPart" + return 1 + fi + + local rootType + rootType=$(lsblk -no TYPE "$rootPart" 2>/dev/null | head -n 1 || true) + + case "$rootType" in + part) + local parentDisk + parentDisk=$(lsblk -no PKNAME "$rootPart" 2>/dev/null | head -n 1 || true) + if [[ -z "$parentDisk" ]]; then + log_error "Could not determine parent disk for root partition: $rootPart" + return 1 + fi + echo "/dev/$parentDisk" + ;; + disk) + echo "$rootPart" + ;; + *) + log_error "Unsupported root device type for BIOS bootloader installation: $rootType" + log_error "Automatic disk detection only supports direct partition or disk root devices" + return 1 + ;; + esac +} + # # System information gathering # @@ -1425,9 +1605,18 @@ EOF # Get root partition UUID local rootPart - rootPart=$(get_partition_device "$targetDisk" 2) + rootPart=$(get_root_partition_device) + if [[ -z "$rootPart" ]]; then + log_error "Could not determine root partition device" + return 1 + fi + local rootUUID rootUUID=$(blkid -s UUID -o value "$rootPart") + if [[ -z "$rootUUID" ]]; then + log_error "Could not determine root partition UUID for $rootPart" + return 1 + fi # Create boot entry cat > "$mountPoint/boot/loader/entries/arch.conf" <