aboutsummaryrefslogtreecommitdiff
path: root/installer/lib/disk.sh
blob: b548b4f85b39d7d6525fb790d86c1871bb5a8c33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env bash
# disk.sh - Disk partitioning functions for archangel installer
# Source this file after common.sh

#############################
# Partition Disks
#############################

# Partition a single disk for ZFS or Btrfs installation. Wipes
# non-GPT signatures (LVM, mdadm, ext) with wipefs, zaps the GPT
# with sgdisk, then lays down a 512M EFI partition plus a root
# partition that fills the rest. Root partition type code is
# selected from FILESYSTEM (BF00 for ZFS, 8300 for Btrfs).
partition_disk() {
    local disk="$1"
    local efi_size="${2:-512M}"

    local root_type="BF00"
    if [[ "$FILESYSTEM" == "btrfs" ]]; then
        root_type="8300"
    fi

    info "Partitioning $disk..."

    wipefs -af "$disk" || error "Failed to wipe signatures on $disk"
    sgdisk --zap-all "$disk" || error "Failed to zap GPT on $disk"
    sgdisk -n 1:0:+${efi_size} -t 1:EF00 -c 1:"EFI" "$disk" || error "Failed to create EFI partition on $disk"
    sgdisk -n 2:0:0 -t 2:$root_type -c 2:"ROOT" "$disk" || error "Failed to create root partition on $disk"

    partprobe "$disk" 2>/dev/null || true
    sleep 1

    info "Partitioned $disk: EFI=${efi_size}, ROOT=remainder"
}

# Partition every disk in SELECTED_DISKS, format each EFI partition,
# and populate the EFI_PARTS + ROOT_PARTS arrays for downstream
# callers (create_zfs_pool, btrfs_open_encryption,
# sync_efi_partitions, fstab generation).
#
# EFI labels are EFI0, EFI1, ... in selection order so multi-disk
# layouts get a stable, distinguishable scheme that lsblk -f can
# show. Errors out if SELECTED_DISKS is empty so a misconfigured
# install can't silently skip partitioning.
partition_disks() {
    if [[ ${#SELECTED_DISKS[@]} -eq 0 ]]; then
        error "partition_disks: SELECTED_DISKS is empty"
    fi

    step "Partitioning ${#SELECTED_DISKS[@]} disk(s)"

    EFI_PARTS=()
    ROOT_PARTS=()

    for disk in "${SELECTED_DISKS[@]}"; do
        partition_disk "$disk"
        EFI_PARTS+=("$(get_efi_partition "$disk")")
        ROOT_PARTS+=("$(get_root_partition "$disk")")
    done

    sleep 2

    for i in "${!EFI_PARTS[@]}"; do
        info "Formatting EFI partition ${EFI_PARTS[$i]}..."
        mkfs.fat -F32 -n "EFI$i" "${EFI_PARTS[$i]}" || error "Failed to format ${EFI_PARTS[$i]}"
    done

    info "Partitioning complete. Created ${#EFI_PARTS[@]} EFI and ${#ROOT_PARTS[@]} ROOT partitions."
}

#############################
# Partition Helpers
#############################

# Get EFI partition path for a disk
get_efi_partition() {
    local disk="$1"
    if [[ "$disk" =~ nvme ]]; then
        echo "${disk}p1"
    else
        echo "${disk}1"
    fi
}

# Get root partition path for a disk
get_root_partition() {
    local disk="$1"
    if [[ "$disk" =~ nvme ]]; then
        echo "${disk}p2"
    else
        echo "${disk}2"
    fi
}

#############################
# Disk Selection (Interactive)
#############################

# Interactive disk selection using fzf
select_disks() {
    local available
    available=$(list_available_disks)

    if [[ -z "$available" ]]; then
        error "No available disks found"
    fi

    step "Select installation disk(s)"
    prompt "Use Tab to select multiple disks for RAID, Enter to confirm"

    local selected
    if has_fzf; then
        selected=$(echo "$available" | fzf --multi --prompt="Select disk(s): " --height=15 --reverse)
    else
        echo "$available"
        read -rp "Enter disk path(s) separated by space: " selected
    fi

    if [[ -z "$selected" ]]; then
        error "No disk selected"
    fi

    # Extract just the device paths (remove size/model info)
    SELECTED_DISKS=()
    while IFS= read -r line; do
        local disk
        disk=$(echo "$line" | cut -d' ' -f1)
        SELECTED_DISKS+=("$disk")
    done <<< "$selected"

    info "Selected disks: ${SELECTED_DISKS[*]}"
}