| 1 | # shellcheck shell=bash |
| 2 | # Base system from the Arch ISO: disk, Arch, GRUB, user, then (unless --base) the desktop part |
| 3 | # inside the new system's chroot. Sourced by install.sh, runs as root. |
| 4 | # |
| 5 | # Every question comes first and nothing is touched until the summary is confirmed |
| 6 | # (except cfdisk in manual mode, which only writes when you tell it to). |
| 7 | # After that it runs unattended. |
| 8 | |
| 9 | LOG=/tmp/aurora-install.log |
| 10 | CRYPT_NAME=cryptroot |
| 11 | |
| 12 | ############## |
| 13 | ## Preflight ## |
| 14 | ############## |
| 15 | if [[ $EUID -ne 0 || ! -d /run/archiso ]]; then |
| 16 | log ERROR "The full install (and --base) only runs from the Arch ISO, as root." |
| 17 | log INFO "On an installed system use: ./install.sh --desktop" |
| 18 | exit 1 |
| 19 | fi |
| 20 | |
| 21 | if [[ "$(cat /sys/firmware/efi/fw_platform_size 2>/dev/null)" != 64 ]]; then |
| 22 | log ERROR "The ISO isn't booted in 64-bit UEFI mode. Legacy BIOS isn't supported." |
| 23 | exit 1 |
| 24 | fi |
| 25 | |
| 26 | if ! curl -fsI --max-time 10 https://archlinux.org >/dev/null; then |
| 27 | log ERROR "No network." |
| 28 | cat >&2 <<'EOF' |
| 29 | Ethernet should just work. Wi-Fi: |
| 30 | iwctl device list |
| 31 | iwctl station <device> get-networks |
| 32 | iwctl station <device> connect <SSID> |
| 33 | (Wi-Fi networks you connect to here are carried over to the new system.) |
| 34 | EOF |
| 35 | exit 1 |
| 36 | fi |
| 37 | |
| 38 | log INFO "Preparing the live system" |
| 39 | timedatectl set-ntp true |
| 40 | # the ISO fills its keyring at boot: wait for that before using pacman |
| 41 | for _ in {1..60}; do |
| 42 | systemctl is-active -q pacman-init.service && break |
| 43 | sleep 1 |
| 44 | done |
| 45 | sed -i 's/^#\?ParallelDownloads.*/ParallelDownloads = 15/' /etc/pacman.conf |
| 46 | pacman -Sy --needed --noconfirm archlinux-keyring gum || exit 1 |
| 47 | |
| 48 | |
| 49 | ############## |
| 50 | ## Helpers ## |
| 51 | ############## |
| 52 | abort() { |
| 53 | log WARN "Aborted, nothing was changed." |
| 54 | exit 1 |
| 55 | } |
| 56 | |
| 57 | # ask VAR "Prompt" [default] |
| 58 | ask() { |
| 59 | local -n _out="$1" |
| 60 | _out="$(gum input --prompt "$2: " --value "${3:-}")" || abort |
| 61 | } |
| 62 | |
| 63 | # ask_secret VAR "Label" [allow_empty] |
| 64 | ask_secret() { |
| 65 | local -n _out="$1" |
| 66 | local a b |
| 67 | while :; do |
| 68 | a="$(gum input --password --prompt "$2: ")" || abort |
| 69 | if [[ -z "$a" ]]; then |
| 70 | if ((${3:-0})); then _out=""; return; fi |
| 71 | gum_warn "Can't be empty" >&2 |
| 72 | continue |
| 73 | fi |
| 74 | b="$(gum input --password --prompt "$2 (again): ")" || abort |
| 75 | [[ "$a" == "$b" ]] && { _out="$a"; return; } |
| 76 | gum_warn "They don't match, try again" >&2 |
| 77 | done |
| 78 | } |
| 79 | |
| 80 | # yes/no question, VAR=1/0. ask_yn VAR "Question" default(yes|no) |
| 81 | ask_yn() { |
| 82 | local -n _out="$1" |
| 83 | local rc |
| 84 | gum confirm --default="$([[ $3 == yes ]] && echo true || echo false)" "$2" |
| 85 | rc=$? |
| 86 | ((rc > 1)) && abort # ctrl+c / esc |
| 87 | ((rc == 0)) && _out=1 || _out=0 |
| 88 | } |
| 89 | |
| 90 | # One lsblk column of one device, without padding |
| 91 | field() { |
| 92 | lsblk -dno "$1" "$2" | sed 's/^ *//; s/ *$//' |
| 93 | } |
| 94 | |
| 95 | # The disk the ISO itself was booted from (a USB stick): never offered |
| 96 | iso_disk="$(lsblk -no PKNAME "$(findmnt -no SOURCE /run/archiso/bootmnt 2>/dev/null)" 2>/dev/null | head -1)" |
| 97 | |
| 98 | disk_lines() { |
| 99 | local name type |
| 100 | while read -r name type; do |
| 101 | [[ "$type" == disk && "$name" != /dev/zram* && "$name" != "/dev/$iso_disk" ]] || continue |
| 102 | printf '%-16s %8s %s\n' "$name" "$(field SIZE "$name")" "$(field MODEL "$name")" |
| 103 | done < <(lsblk -dpno NAME,TYPE) |
| 104 | } |
| 105 | |
| 106 | part_lines() { |
| 107 | local name type |
| 108 | while read -r name type; do |
| 109 | [[ "$type" == part ]] || continue |
| 110 | [[ -n "$iso_disk" && "$(field PKNAME "$name")" == "$iso_disk" ]] && continue |
| 111 | [[ " $* " == *" $name "* ]] && continue # already picked |
| 112 | printf '%-16s %8s %-11s %s\n' "$name" "$(field SIZE "$name")" \ |
| 113 | "$(field FSTYPE "$name")" "$(field PARTTYPENAME "$name")" |
| 114 | done < <(lsblk -lpno NAME,TYPE) |
| 115 | } |
| 116 | |
| 117 | # pick VAR "Header" < <(lines): the first column of the chosen line. |
| 118 | # Not in a pipe: VAR would only be set in the pipe's subshell. |
| 119 | pick() { |
| 120 | local -n _out="$1" |
| 121 | local lines line |
| 122 | lines="$(cat)" |
| 123 | [[ -n "$lines" ]] || { log ERROR "Nothing to choose from: $2"; exit 1; } |
| 124 | line="$(gum choose --header "$2" <<< "$lines")" || abort |
| 125 | _out="${line%% *}" |
| 126 | } |
| 127 | |
| 128 | # Run a command on a pseudo-terminal: the output goes through tee into the log, and |
| 129 | # pacman/paru only draw their progress bars on a terminal (silent for minutes otherwise) |
| 130 | with_tty() { |
| 131 | script -qefc "$(printf '%q ' "$@")" /dev/null |
| 132 | } |
| 133 | |
| 134 | STEP="" |
| 135 | step() { |
| 136 | STEP="$1" |
| 137 | log INFO "== $1" |
| 138 | } |
| 139 | |
| 140 | |
| 141 | ############### |
| 142 | ## Questions ## |
| 143 | ############### |
| 144 | gum style --border double --border-foreground 196 --padding "1 2" --bold \ |
| 145 | "⚠️ aurora: full install |
| 146 | |
| 147 | This installs Arch Linux + MY desktop (Hyprland + aurora), built for MY machine |
| 148 | (Lenovo Legion, Intel + NVIDIA hybrid, linux-zen). It is NOT general purpose. |
| 149 | |
| 150 | It will ERASE the disk you pick (or format the partitions you pick). |
| 151 | Nothing happens until you confirm the summary at the end. |
| 152 | |
| 153 | Provided AS IS, WITHOUT ANY WARRANTY. Proceed at your OWN RISK." |
| 154 | |
| 155 | ## Disk ## |
| 156 | DISK_MODE="$(gum choose --header "Partitioning" \ |
| 157 | "auto erase a whole disk: 1 GiB EFI + the rest for Arch" \ |
| 158 | "manual partition yourself (cfdisk), then pick the partitions")" || abort |
| 159 | DISK_MODE="${DISK_MODE%% *}" |
| 160 | |
| 161 | DISK="" ESP="" ROOT="" FORMAT_ESP=1 |
| 162 | if [[ "$DISK_MODE" == auto ]]; then |
| 163 | pick DISK "Disk to ERASE" < <(disk_lines) |
| 164 | else |
| 165 | cfdisk_disk="" |
| 166 | pick cfdisk_disk "Run cfdisk on" < <(disk_lines; echo "skip (already partitioned)") |
| 167 | if [[ "$cfdisk_disk" != skip ]]; then |
| 168 | cfdisk "$cfdisk_disk" |
| 169 | partprobe "$cfdisk_disk" 2>/dev/null |
| 170 | udevadm settle |
| 171 | fi |
| 172 | |
| 173 | pick ESP "EFI system partition (mounted at /boot)" < <(part_lines) |
| 174 | if (( $(lsblk -bdno SIZE "$ESP") < 500 * 1024 * 1024 )); then |
| 175 | gum_warn "$ESP is smaller than 500 MiB. /boot holds two kernels + initramfs (~300 MiB)." >&2 |
| 176 | gum confirm --default=false "Use it anyway?" || abort |
| 177 | fi |
| 178 | if [[ "$(field FSTYPE "$ESP")" == vfat ]]; then |
| 179 | # an existing ESP probably boots another OS too: keep it unless asked |
| 180 | ask_yn FORMAT_ESP "$ESP is already FAT. Format it? (No keeps other systems' boot loaders)" no |
| 181 | else |
| 182 | log INFO "$ESP isn't FAT yet, it will be formatted" |
| 183 | fi |
| 184 | |
| 185 | pick ROOT "Root partition (will be FORMATTED)" < <(part_lines "$ESP") |
| 186 | fi |
| 187 | |
| 188 | ## Encryption ## |
| 189 | ask_yn LUKS "Encrypt the system with LUKS2? (asks for the passphrase at every boot)" yes |
| 190 | LUKS_PASS="" |
| 191 | ((LUKS)) && ask_secret LUKS_PASS "Encryption passphrase" |
| 192 | |
| 193 | ## Host and user ## |
| 194 | while :; do |
| 195 | ask HOSTNAME_NEW "Hostname" "arch" |
| 196 | [[ "$HOSTNAME_NEW" =~ ^[a-z0-9][a-z0-9-]{0,62}$ ]] && break |
| 197 | gum_warn "Lowercase letters, digits and '-' only" >&2 |
| 198 | done |
| 199 | while :; do |
| 200 | ask USERNAME_NEW "Username" |
| 201 | [[ "$USERNAME_NEW" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]] && break |
| 202 | gum_warn "Lowercase letters, digits, '_' and '-', starting with a letter" >&2 |
| 203 | done |
| 204 | ask_secret USER_PASS "Password for $USERNAME_NEW" |
| 205 | ask_secret ROOT_PASS "Root password (empty: root login disabled, use sudo)" 1 |
| 206 | |
| 207 | ## Locale ## |
| 208 | TIMEZONE="Asia/Kolkata" |
| 209 | ask_yn tz_ok "Timezone $TIMEZONE?" yes |
| 210 | if ! ((tz_ok)); then |
| 211 | TIMEZONE="$(timedatectl list-timezones | gum filter --header "Timezone")" || abort |
| 212 | fi |
| 213 | while :; do |
| 214 | ask LOCALE "Locale" "en_US.UTF-8" |
| 215 | grep -q "^#\?${LOCALE//./\\.} " /etc/locale.gen && break |
| 216 | gum_warn "Not in /etc/locale.gen" >&2 |
| 217 | done |
| 218 | while :; do |
| 219 | ask KEYMAP "Console keymap" "us" |
| 220 | localectl list-keymaps | grep -qx "$KEYMAP" && break |
| 221 | gum_warn "Unknown keymap" >&2 |
| 222 | done |
| 223 | |
| 224 | ## GRUB ## |
| 225 | ask_yn GRUB_HIDDEN "Skip the GRUB menu at boot? (hold Shift/Esc to see it)" yes |
| 226 | ask_yn OS_PROBER "Add other installed systems (Windows, ...) to GRUB? (os-prober)" no |
| 227 | |
| 228 | ## Desktop packages ## |
| 229 | SELECTED_PKGS=() |
| 230 | [[ "$MODE" == full ]] && pick_packages |
| 231 | |
| 232 | ## Summary ## |
| 233 | case "$(grep -m1 -o 'GenuineIntel\|AuthenticAMD' /proc/cpuinfo)" in |
| 234 | GenuineIntel) UCODE=(intel-ucode) ;; |
| 235 | AuthenticAMD) UCODE=(amd-ucode) ;; |
| 236 | *) UCODE=() ;; |
| 237 | esac |
| 238 | |
| 239 | if [[ "$DISK_MODE" == auto ]]; then |
| 240 | disk_desc="$DISK ($(field SIZE "$DISK") $(field MODEL "$DISK")): ERASED, 1 GiB EFI + Arch" |
| 241 | CONFIRM_TARGET="$DISK" |
| 242 | else |
| 243 | disk_desc="EFI $ESP ($( ((FORMAT_ESP)) && echo formatted || echo kept)), Arch on $ROOT (formatted)" |
| 244 | CONFIRM_TARGET="$ROOT" |
| 245 | fi |
| 246 | if [[ "$MODE" == full ]]; then |
| 247 | desktop_desc="Hyprland + aurora, $(read_list desktop | wc -l) base + ${#SELECTED_PKGS[@]} picked packages" |
| 248 | else |
| 249 | desktop_desc="none (--base), run ./install.sh --desktop later" |
| 250 | fi |
| 251 | |
| 252 | gum style --border rounded --padding "1 2" \ |
| 253 | "Summary |
| 254 | |
| 255 | Disk: $disk_desc |
| 256 | Encryption: $( ((LUKS)) && echo "LUKS2" || echo "none") |
| 257 | System: $(read_list base | grep -c .) packages (linux-zen + linux) ${UCODE[*]}, GRUB, zram swap |
| 258 | Host/user: $HOSTNAME_NEW / $USERNAME_NEW (sudo), root login $( [[ -n $ROOT_PASS ]] && echo enabled || echo disabled) |
| 259 | Locale: $TIMEZONE, $LOCALE, keymap $KEYMAP |
| 260 | GRUB: menu $( ((GRUB_HIDDEN)) && echo hidden || echo shown), os-prober $( ((OS_PROBER)) && echo on || echo off) |
| 261 | Desktop: $desktop_desc" |
| 262 | |
| 263 | answer="$(gum input --placeholder "$CONFIRM_TARGET" \ |
| 264 | --header "Type $CONFIRM_TARGET to FORMAT it and start the install")" || abort |
| 265 | [[ "$answer" == "$CONFIRM_TARGET" ]] || abort |
| 266 | |
| 267 | |
| 268 | ################## |
| 269 | ## Installation ## |
| 270 | ################## |
| 271 | # From here on: unattended, logged, stop at the first error |
| 272 | exec 3>&1 4>&2 |
| 273 | exec > >(tee -a "$LOG") 2>&1 |
| 274 | set -Eeuo pipefail |
| 275 | trap 'log ERROR "Failed: $STEP (line $LINENO). Log: $LOG. /mnt is still mounted for a look around."' ERR |
| 276 | trap 'rm -f /mnt/etc/sudoers.d/99-aurora-install' EXIT |
| 277 | |
| 278 | # A previous attempt may have left things mounted/open |
| 279 | if mountpoint -q /mnt; then umount -R /mnt; fi |
| 280 | if [[ -e "/dev/mapper/$CRYPT_NAME" ]]; then cryptsetup close "$CRYPT_NAME"; fi |
| 281 | |
| 282 | if [[ "$DISK_MODE" == auto ]]; then |
| 283 | step "Partitioning $DISK" |
| 284 | # old signatures (LUKS headers, filesystems) first, then the partition table |
| 285 | for p in $(lsblk -lpno NAME,TYPE "$DISK" | awk '$2 == "part" { print $1 }'); do |
| 286 | wipefs -af "$p" |
| 287 | done |
| 288 | wipefs -af "$DISK" |
| 289 | sgdisk --zap-all "$DISK" |
| 290 | sgdisk -n1:0:+1G -t1:ef00 -c1:EFI \ |
| 291 | -n2:0:0 -t2:"$( ((LUKS)) && echo 8309 || echo 8304)" -c2:arch "$DISK" |
| 292 | partprobe "$DISK" || true |
| 293 | udevadm settle |
| 294 | # partition paths from lsblk: nvme0n1p1 and sda1 alike |
| 295 | mapfile -t parts < <(lsblk -lpno NAME,TYPE "$DISK" | awk '$2 == "part" { print $1 }') |
| 296 | ESP="${parts[0]}" |
| 297 | ROOT="${parts[1]}" |
| 298 | fi |
| 299 | |
| 300 | ROOT_DEV="$ROOT" |
| 301 | if ((LUKS)); then |
| 302 | step "Encrypting $ROOT" |
| 303 | printf '%s' "$LUKS_PASS" | cryptsetup luksFormat --type luks2 --batch-mode --key-file=- "$ROOT" |
| 304 | printf '%s' "$LUKS_PASS" | cryptsetup open --key-file=- "$ROOT" "$CRYPT_NAME" |
| 305 | ROOT_DEV="/dev/mapper/$CRYPT_NAME" |
| 306 | LUKS_UUID="$(blkid -s UUID -o value "$ROOT")" |
| 307 | fi |
| 308 | |
| 309 | step "Formatting and mounting" |
| 310 | ((FORMAT_ESP)) && mkfs.fat -F32 -n EFI "$ESP" |
| 311 | mkfs.ext4 -F -L arch "$ROOT_DEV" |
| 312 | mount "$ROOT_DEV" /mnt |
| 313 | mount --mkdir -o umask=0077 "$ESP" /mnt/boot |
| 314 | |
| 315 | step "Installing the base system (pacstrap)" |
| 316 | mapfile -t base_pkgs < <(read_list base) |
| 317 | with_tty pacstrap -K /mnt "${base_pkgs[@]}" "${UCODE[@]}" |
| 318 | genfstab -U /mnt >> /mnt/etc/fstab |
| 319 | |
| 320 | step "Configuring the system" |
| 321 | ln -sf "/usr/share/zoneinfo/$TIMEZONE" /mnt/etc/localtime |
| 322 | arch-chroot /mnt hwclock --systohc |
| 323 | sed -i "s/^#\(${LOCALE//./\\.} \)/\1/" /mnt/etc/locale.gen |
| 324 | arch-chroot /mnt locale-gen |
| 325 | echo "LANG=$LOCALE" > /mnt/etc/locale.conf |
| 326 | echo "KEYMAP=$KEYMAP" > /mnt/etc/vconsole.conf |
| 327 | echo "$HOSTNAME_NEW" > /mnt/etc/hostname |
| 328 | cat > /mnt/etc/hosts <<EOF |
| 329 | 127.0.0.1 localhost |
| 330 | ::1 localhost |
| 331 | 127.0.1.1 $HOSTNAME_NEW.localdomain $HOSTNAME_NEW |
| 332 | EOF |
| 333 | sed -i 's/^#\?ParallelDownloads.*/ParallelDownloads = 15/; s/^#Color$/Color/' /mnt/etc/pacman.conf |
| 334 | # swap in compressed RAM instead of a partition/file (no hibernation anyway) |
| 335 | cat > /mnt/etc/systemd/zram-generator.conf <<'EOF' |
| 336 | [zram0] |
| 337 | zram-size = min(ram / 2, 8192) |
| 338 | compression-algorithm = zstd |
| 339 | EOF |
| 340 | |
| 341 | CMDLINE="" |
| 342 | if ((LUKS)); then |
| 343 | step "initramfs with LUKS" |
| 344 | # Use whatever hooks the installed mkinitcpio defaults to: systemd-based or busybox |
| 345 | hooks="$(grep '^HOOKS=' /mnt/etc/mkinitcpio.conf)" |
| 346 | if [[ " ${hooks//[()=]/ } " == *" systemd "* ]]; then |
| 347 | sed -i '/^HOOKS=/ s/ filesystems/ sd-encrypt filesystems/' /mnt/etc/mkinitcpio.conf |
| 348 | CMDLINE="rd.luks.name=$LUKS_UUID=$CRYPT_NAME root=/dev/mapper/$CRYPT_NAME" |
| 349 | else |
| 350 | sed -i '/^HOOKS=/ s/ filesystems/ encrypt filesystems/' /mnt/etc/mkinitcpio.conf |
| 351 | CMDLINE="cryptdevice=UUID=$LUKS_UUID:$CRYPT_NAME root=/dev/mapper/$CRYPT_NAME" |
| 352 | fi |
| 353 | grep -q '^HOOKS=.*encrypt filesystems' /mnt/etc/mkinitcpio.conf |
| 354 | arch-chroot /mnt mkinitcpio -P |
| 355 | fi |
| 356 | |
| 357 | step "Users" |
| 358 | arch-chroot /mnt useradd -m -G wheel -s /usr/bin/zsh "$USERNAME_NEW" |
| 359 | printf '%s:%s\n' "$USERNAME_NEW" "$USER_PASS" | arch-chroot /mnt chpasswd |
| 360 | if [[ -n "$ROOT_PASS" ]]; then |
| 361 | printf 'root:%s\n' "$ROOT_PASS" | arch-chroot /mnt chpasswd |
| 362 | else |
| 363 | arch-chroot /mnt passwd -l root |
| 364 | fi |
| 365 | echo '%wheel ALL=(ALL:ALL) ALL' > /mnt/etc/sudoers.d/10-wheel |
| 366 | chmod 0440 /mnt/etc/sudoers.d/10-wheel |
| 367 | arch-chroot /mnt visudo -cf /etc/sudoers.d/10-wheel |
| 368 | |
| 369 | step "GRUB" |
| 370 | arch-chroot /mnt grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=arch |
| 371 | # also EFI/BOOT/BOOTX64.EFI, for firmware that forgets its boot entries; only on a disk that's all ours |
| 372 | [[ "$DISK_MODE" == auto ]] && arch-chroot /mnt grub-install --target=x86_64-efi --efi-directory=/boot --removable |
| 373 | g=/mnt/etc/default/grub |
| 374 | [[ -n "$CMDLINE" ]] && sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 $CMDLINE\"|" "$g" |
| 375 | # zen is the default entry, plain linux stays as the fallback |
| 376 | [[ -f /mnt/boot/vmlinuz-linux-zen ]] && echo 'GRUB_TOP_LEVEL="/boot/vmlinuz-linux-zen"' >> "$g" |
| 377 | if ((GRUB_HIDDEN)); then |
| 378 | sed -i 's/^GRUB_TIMEOUT=.*/GRUB_TIMEOUT=0/; s/^#\?GRUB_TIMEOUT_STYLE=.*/GRUB_TIMEOUT_STYLE=hidden/' "$g" |
| 379 | fi |
| 380 | ((OS_PROBER)) && sed -i 's/^#\?GRUB_DISABLE_OS_PROBER=.*/GRUB_DISABLE_OS_PROBER=false/' "$g" |
| 381 | arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg |
| 382 | |
| 383 | step "Services" |
| 384 | arch-chroot /mnt systemctl enable NetworkManager.service systemd-timesyncd.service fstrim.timer |
| 385 | |
| 386 | # Wi-Fi networks joined with iwctl on the ISO -> NetworkManager, so the first boot is online |
| 387 | for psk in /var/lib/iwd/*.psk; do |
| 388 | [[ -f "$psk" ]] || continue |
| 389 | ssid="$(basename "$psk" .psk)" |
| 390 | # iwd hex-encodes names with special characters as =<hex> |
| 391 | [[ "$ssid" == =* ]] && ssid="$(printf '%b' "$(sed 's/../\\x&/g' <<< "${ssid#=}")")" |
| 392 | key="$(sed -n 's/^Passphrase=//p' "$psk")" |
| 393 | [[ -n "$key" ]] || key="$(sed -n 's/^PreSharedKey=//p' "$psk")" |
| 394 | [[ -n "$key" ]] || continue |
| 395 | mkdir -p /mnt/etc/NetworkManager/system-connections |
| 396 | conn="/mnt/etc/NetworkManager/system-connections/${ssid//[^A-Za-z0-9._-]/_}.nmconnection" |
| 397 | cat > "$conn" <<EOF |
| 398 | [connection] |
| 399 | id=$ssid |
| 400 | uuid=$(cat /proc/sys/kernel/random/uuid) |
| 401 | type=wifi |
| 402 | |
| 403 | [wifi] |
| 404 | mode=infrastructure |
| 405 | ssid=$ssid |
| 406 | |
| 407 | [wifi-security] |
| 408 | key-mgmt=wpa-psk |
| 409 | psk=$key |
| 410 | |
| 411 | [ipv4] |
| 412 | method=auto |
| 413 | |
| 414 | [ipv6] |
| 415 | method=auto |
| 416 | EOF |
| 417 | chmod 0600 "$conn" |
| 418 | log INFO "Wi-Fi \"$ssid\" carried over" |
| 419 | done |
| 420 | |
| 421 | step "Copying aurora to /home/$USERNAME_NEW/aurora" |
| 422 | cp -a "$currentDir" "/mnt/home/$USERNAME_NEW/aurora" |
| 423 | arch-chroot /mnt chown -R "$USERNAME_NEW:$USERNAME_NEW" "/home/$USERNAME_NEW/aurora" |
| 424 | |
| 425 | DESKTOP_OK=1 |
| 426 | if [[ "$MODE" == full ]]; then |
| 427 | step "Desktop (install.sh --desktop inside the new system)" |
| 428 | # makepkg/paru call sudo: no password while this runs, the EXIT trap removes it again |
| 429 | echo "$USERNAME_NEW ALL=(ALL) NOPASSWD: ALL" > /mnt/etc/sudoers.d/99-aurora-install |
| 430 | chmod 0440 /mnt/etc/sudoers.d/99-aurora-install |
| 431 | picks="/home/$USERNAME_NEW/.aurora-picks" |
| 432 | printf '%s\n' "${SELECTED_PKGS[@]}" > "/mnt$picks" |
| 433 | if ! with_tty arch-chroot /mnt runuser -u "$USERNAME_NEW" -- \ |
| 434 | env HOME="/home/$USERNAME_NEW" USER="$USERNAME_NEW" LOGNAME="$USERNAME_NEW" \ |
| 435 | SHELL=/usr/bin/zsh AURORA_CHROOT=1 \ |
| 436 | bash "/home/$USERNAME_NEW/aurora/install.sh" --desktop --yes --picks "$picks"; then |
| 437 | DESKTOP_OK=0 |
| 438 | log ERROR "The desktop part failed. After the reboot, log in and run: ~/aurora/install.sh --desktop" |
| 439 | fi |
| 440 | rm -f "/mnt$picks" /mnt/etc/sudoers.d/99-aurora-install |
| 441 | fi |
| 442 | |
| 443 | step "Finishing" |
| 444 | trap - ERR |
| 445 | set +Eeuo pipefail |
| 446 | exec 1>&3 2>&4 3>&- 4>&- |
| 447 | sleep 1 # let tee write the last lines |
| 448 | install -m 0600 "$LOG" /mnt/var/log/aurora-install.log |
| 449 | umount -R /mnt |
| 450 | ((LUKS)) && cryptsetup close "$CRYPT_NAME" |
| 451 | |
| 452 | if ((DESKTOP_OK)); then |
| 453 | gum style --border rounded --border-foreground 42 --padding "1 2" --bold \ |
| 454 | "✔ Arch$([[ "$MODE" == full ]] && echo " + aurora") installed. |
| 455 | |
| 456 | Remove the install medium and reboot.$([[ "$MODE" == full ]] && echo " |
| 457 | Log in on tty1 as $USERNAME_NEW: Hyprland and aurora start by themselves." || echo " |
| 458 | For the desktop, log in and run: ~/aurora/install.sh --desktop") |
| 459 | The install log is in /var/log/aurora-install.log." |
| 460 | else |
| 461 | gum style --border rounded --border-foreground 220 --padding "1 2" --bold \ |
| 462 | "⚠ Arch is installed, the desktop part failed. |
| 463 | |
| 464 | Reboot, log in as $USERNAME_NEW and run: ~/aurora/install.sh --desktop |
| 465 | The install log is in /var/log/aurora-install.log." |
| 466 | fi |
| 467 | |
| 468 | gum confirm "Reboot now?" && reboot |
| 469 | exit 0 |