Skip to content

Instantly share code, notes, and snippets.

@jdmonty
Last active May 8, 2023 09:50
Show Gist options
  • Save jdmonty/3c8b07d2d90f1947d9840fb7d000d3c0 to your computer and use it in GitHub Desktop.
Save jdmonty/3c8b07d2d90f1947d9840fb7d000d3c0 to your computer and use it in GitHub Desktop.
Arch Linux Setup Script
#!/bin/bash
#
# Arch Linux installation
#
# Bootable USB:
# - [Download](https://archlinux.org/download/) ISO and GPG files
# - Verify the ISO file: `$ pacman-key -v archlinux-<version>-dual.iso.sig`
# - Create a bootable USB with: `# dd if=archlinux*.iso of=/dev/sdX && sync`
#
# UEFI setup:
#
# - Set boot mode to UEFI, disable Legacy mode entirely.
# - Temporarily disable Secure Boot.
# - Make sure a strong UEFI administrator password is set.
# - Delete preloaded OEM keys for Secure Boot, allow custom ones.
# - Set SATA operation to AHCI mode.
#
# Run installation:
#
# - Connect to wifi via: `# iwctl station wlan0 connect WIFI-NETWORK`
# - Run: `# bash <(curl -sL https://github.com/jdmonty/archlinux-install)`
set -uo pipefail
trap 's=$?; echo "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR
exec 1> >(tee "stdout.log")
exec 2> >(tee "stderr.log" >&2)
export SNAP_PAC_SKIP=y
# Dialog
# MOUNT_OPTIONS "noatime,compress=zstd,ssd,commit=120";;
# KEYMAP us
# TIMEZONE America/Chicago time_zone="$(curl --fail https://ipapi.co/timezone)"
# FS "btrfs"
# DISK "/dev/nvme0n1"
# ISO='US' # mirror ISO country code
# https://gist.github.com/jdmonty/3c8b07d2d90f1947d9840fb7d000d3c0
# https://gist.githubusercontent.com/jdmonty/3c8b07d2d90f1947d9840fb7d000d3c0/raw
font="ter-v22b"
device='/dev/nvme0n1'
hostname='telos'
user='monty'
password='passwordtest'
echo -e "\n### Checking UEFI boot mode"
if [ ! -f /sys/firmware/efi/fw_platform_size ]; then
echo >&2 "You must boot in UEFI mode to continue"
exit 2
fi
echo -e "\n### Setting up clock"
timedatectl set-ntp true
hwclock --systohc --utc
echo -e "\n### Installing additional tools"
pacman -Sy --noconfirm --needed git terminus-font dialog wget curl
setfont $font
echo -e "\n### Setting up partitions"
umount -R /mnt 2> /dev/null || true
sgdisk --clear "${device}" --new 1::-551MiB "${device}" --new 2::0 --typecode 2:ef00 "${device}"
sgdisk --change-name=1:'ROOT' --change-name=2:'EFI' "${device}"
# create partitions
# partition 1 (UEFI Boot Partition)
# Boot disks for EFI-based systems require an EFI System Partition (gdisk internal code 0xEF00) formatted as FAT-32. I recommended making this partition 550 MiB.
# Some boot loaders for BIOS-based systems make use of a BIOS Boot Partition (gdisk internal code 0xEF02), in which the secondary boot loader is stored, possibly without the benefit of a filesystem. (GRUB2 may optionally use such a partition.) This partition can typically be quite small (roughly 32 to 200 KiB, although 1 MiB is more common in practice)
# If Windows is to boot from a GPT disk, a partition of type Microsoft Reserved (sgdisk internal code 0x0C01) is recommended. This partition should be about 128 MiB in size. It ordinarily follows the EFI System Partition and immediately precedes the Windows data partitions. (Note that GNU Parted creates all FAT partitions as this type, which actually makes the partition unusable for normal file storage in both Windows and Mac OS X.)
# 8300 Linux filesystem
# ef00 EFI system partition
# ef01 MBR partition scheme
# ef02 BIOS boot partition
part_root="$(ls ${device}* | grep -E "^${device}p?1$")"
part_boot="$(ls ${device}* | grep -E "^${device}p?2$")"
echo -e "\n### Formatting partitions"
mkfs.vfat -n "EFI" -F 32 "${part_boot}"
mkfs.btrfs -L ROOT ${part_root} -f
mount -t btrfs ${part_root} /mnt
echo -e "\n### Setting up BTRFS subvolumes"
mount ${part_root} /mnt
btrfs subvolume create /mnt/root
btrfs subvolume create /mnt/home
btrfs subvolume create /mnt/pkgs
btrfs subvolume create /mnt/aurbuild
btrfs subvolume create /mnt/archbuild
btrfs subvolume create /mnt/docker
btrfs subvolume create /mnt/logs
btrfs subvolume create /mnt/temp
btrfs subvolume create /mnt/swap
btrfs subvolume create /mnt/snapshots
umount /mnt
mount -o noatime,nodiratime,compress=zstd,subvol=root ${part_root} /mnt
mkdir -p /mnt/{mnt/btrfs-root,efi,home,var/{cache/pacman,log,tmp,lib/{aurbuild,archbuild,docker}},swap,.snapshots}
mount "${part_boot}" /mnt/efi
mount -o noatime,nodiratime,compress=zstd,subvol=/ ${part_root} /mnt/mnt/btrfs-root
mount -o noatime,nodiratime,compress=zstd,subvol=home ${part_root} /mnt/home
mount -o noatime,nodiratime,compress=zstd,subvol=pkgs ${part_root} /mnt/var/cache/pacman
mount -o noatime,nodiratime,compress=zstd,subvol=aurbuild ${part_root} /mnt/var/lib/aurbuild
mount -o noatime,nodiratime,compress=zstd,subvol=archbuild ${part_root} /mnt/var/lib/archbuild
mount -o noatime,nodiratime,compress=zstd,subvol=docker ${part_root} /mnt/var/lib/docker
mount -o noatime,nodiratime,compress=zstd,subvol=logs ${part_root} /mnt/var/log
mount -o noatime,nodiratime,compress=zstd,subvol=temp ${part_root} /mnt/var/tmp
mount -o noatime,nodiratime,compress=zstd,subvol=swap ${part_root} /mnt/swap
mount -o noatime,nodiratime,compress=zstd,subvol=snapshots ${part_root} /mnt/.snapshots
# Install the base packages
pacstrap /mnt base base-devel linux linux-firmware git btrfs-progs efibootmgr
# Configure the system
#echo "FONT=$font" > /mnt/etc/vconsole.conf
#genfstab -L /mnt >> /mnt/etc/fstab
#echo "${hostname}" > /mnt/etc/hostname
#echo "en_US.UTF-8 UTF-8" >> /mnt/etc/locale.gen
#arch-chroot /mnt ln -sf /usr/share/zoneinfo/America/Chicago /etc/localtime
#ln -sf /usr/share/zoneinfo/America/Chicago /mnt/etc/localtime
#arch-chroot /mnt locale-gen
#echo "LANG=en_US.UTF-8" > /mnt/etc/locale.conf
#arch-chroot /mnt mkinitcpio -P
echo "FONT=$font" > /mnt/etc/vconsole.conf
genfstab -L /mnt >> /mnt/etc/fstab
echo "${hostname}" > /mnt/etc/hostname
echo "en_US.UTF-8 UTF-8" >> /mnt/etc/locale.gen
ln -sf /usr/share/zoneinfo/America/Chicago /mnt/etc/localtime
arch-chroot /mnt locale-gen
cat << EOF > /mnt/etc/mkinitcpio.conf
MODULES=()
BINARIES=()
FILES=()
HOOKS=(base consolefont udev autodetect modconf block filesystems keyboard)
EOF
arch-chroot /mnt mkinitcpio -p linux
# Create a boot entry
arch-chroot /mnt bootctl --path=/efi install
echo "default arch" > /mnt/efi/loader/loader.conf
#echo "timeout 3" >> /mnt/efi/loader/loader.conf
#echo "editor 0" >> /mnt/efi/loader/loader.conf
# Set up the boot loader entry
echo "title Arch Linux" > /mnt/efi/loader/entries/arch.conf
echo "linux /vmlinuz-linux" >> /mnt/efi/loader/entries/arch.conf
echo "initrd /intel-ucode.img" >> /mnt/efi/loader/entries/arch.conf
echo "initrd /initramfs-linux.img" >> /mnt/efi/loader/entries/arch.conf
echo "options root=UUID=$(blkid -s UUID -o value ${part_root}) rootflags=subvol=/ rw" >> /mnt/efi/loader/entries/arch.conf
echo -e "\n### Configuring swap file"
btrfs filesystem mkswapfile --size 4G /mnt/swap/swapfile
echo "/swap/swapfile none swap defaults 0 0" >> /mnt/etc/fstab
echo -e "\n### Creating user"
arch-chroot /mnt useradd -m -s /usr/bin/zsh "$user"
for group in wheel network video input; do
arch-chroot /mnt groupadd -rf "$group"
arch-chroot /mnt gpasswd -a "$user" "$group"
done
arch-chroot /mnt chsh -s /usr/bin/zsh
echo "$user:$password" | arch-chroot /mnt chpasswd
arch-chroot /mnt passwd -dl root
# update
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment