Files
arch-installer/install.sh
T

275 lines
7.1 KiB
Bash
Executable File

#!/bin/sh
# User inputs
HOSTNAME=""
ROOT_PASSWORD=""
USERNAME=""
USER_PASSWORD=""
install_deps() {
echo "You will need commands like mkfs.ext4, sgisk and pacstrap."
printf "Try to install them with pacman (if you are on arch linux)? [Y/n] "
read CONFIRMATION
case "$CONFIRMATION" in
"n" | "N")
echo "Operation canceled."
return
;;
"" | "y" | "Y")
echo "Installing dependencies"
sudo pacman -S --needed --noconfirm dosfstools gptfdisk arch-install-scripts
echo ""
;;
*)
echo "Invalid input. Defaulting to 'No'."
exit 0
;;
esac
}
send_status_message() {
term_width=$(tput cols 2>/dev/null || echo 80)
msg="$1"
edge=$(printf '%*s' "$term_width" '' | tr ' ' '=')
printf "\n%s\n" "$edge"
printf "%*s\n" $(((${#msg} + term_width) / 2)) "$msg"
printf "%s\n\n" "$edge"
}
get_config_inputs() {
send_status_message "CONFIGURATION: Getting user inputs"
while [ -z "$HOSTNAME" ]; do
printf "Enter hostname: "
read HOSTNAME
if [ -z "$HOSTNAME" ]; then
echo "Hostname cannot be empty."
continue
fi
break
done
echo ""
while [ -z "$ROOT_PASSWORD" ]; do
printf "Enter root password: "
read -s ROOT_PASSWORD
printf "\nConfirm root password: "
read -s CONFIRM_ROOT_PASSWORD
if [ "$ROOT_PASSWORD" != "$CONFIRM_ROOT_PASSWORD" ]; then
echo "Root passwords do not match."
ROOT_PASSWORD=""
CONFIRM_ROOT_PASSWORD=""
continue
fi
break
done
echo ""
echo ""
while [ -z "$USERNAME" ]; do
printf "Enter username: "
read USERNAME
if [ -z "$USERNAME" ]; then
echo "Username cannot be empty."
continue
fi
break
done
echo ""
while [ -z "$USER_PASSWORD" ]; do
printf "Enter user password: "
read -s USER_PASSWORD
printf "\nConfirm user password: "
read -s CONFIRM_USER_PASSWORD
if [ "$USER_PASSWORD" != "$CONFIRM_USER_PASSWORD" ]; then
echo "User passwords do not match."
USER_PASSWORD=""
CONFIRM_USER_PASSWORD=""
continue
fi
break
done
}
# Function to get drive name
DISK=""
get_drive() {
send_status_message "DRIVE SETUP: Selecting and confirming target drive"
lsblk
printf "\nEnter the drive name (e.g., sda, sdb, vda, nvme0n1): "
read DISK
if [ -z "${DISK}" ]; then
echo "No drive name entered. Exiting."
exit 1
fi
DISK="/dev/${DISK}"
PART_PREFIX="$DISK"
case "$DISK" in
*nvme*n*) PART_PREFIX="${DISK}p" ;; # nvme devices need a 'p' before partition number
*) PART_PREFIX="${DISK}" ;;
esac
printf "WARNING: All data on %s will be erased. Are you sure? [Y/n] " "${DISK}"
read CONFIRMATION
case "$CONFIRMATION" in
"n" | "N")
echo "Operation canceled."
exit 0
;;
"" | "y" | "Y")
echo "Proceeding with the operation on ${DISK}."
printf "Wiping drive in "
for i in 3 2 1; do
printf '%d...' $i
sleep 1
done
echo ""
;;
*)
echo "Invalid input. Defaulting to 'No'."
exit 0
;;
esac
echo "Drive ${DISK} confirmed for installation."
}
setup_partitions() {
send_status_message "PARTITIONING: Creating partitions and filesystems"
if [ ! -d "/sys/firmware/efi" ]; then # Checking for BIOS system
echo "BIOS systems are not supported."
fi
umount -A -R /mnt # make sure everything is unmounted before we start
sgdisk -Z ${DISK} # zap all on disk
sgdisk -a 2048 -o ${DISK} # new GPT disk 2048 alignment
# Create partitions
sgdisk -n 1::+1G --typecode=1:ef00 --change-name=1:"BOOT" ${DISK} # partition 1 (UEFI boot partition)
sgdisk -n 2::+4G --typecode=2:8200 --change-name=2:"SWAP" ${DISK} # partition 2 (Swap partition)
sgdisk -n 3::-0 --typecode=3:8300 --change-name=3:"ROOT" ${DISK} # partition 3 (Root), default start, remaining
partprobe ${DISK} # reread partition table to ensure it is correct
# Create filesystems
mkfs.fat -F32 -n "BOOT" ${PART_PREFIX}1
mkswap -f ${PART_PREFIX}2
mkfs.ext4 -F -L "ROOT" ${PART_PREFIX}3
# Mount
mount ${PART_PREFIX}3 /mnt
if [ $? -ne 0 ]; then
echo "Failed to mount the ROOT partition."
exit 2 # Exit if mounting ROOT partition fails
fi
mount --mkdir ${PART_PREFIX}1 /mnt/boot
if [ $? -ne 0 ]; then
echo "Failed to mount the BOOT partition."
exit 2 # Exit if mounting BOOT partition fails
fi
swapon ${PART_PREFIX}2
}
# Setup systemdboot as the bootloader
setup_bootloader() {
send_status_message "BOOTLOADER: Installing and configuring systemd-boot"
# Run bootctl inside chroot
arch-chroot /mnt bootctl install
if [ $? -ne 0 ]; then
echo "Error: Failed to install systemd-boot."
exit 3
fi
BOOTLOADER_ENTRY="/mnt/boot/loader/entries/arch.conf"
ARCH_ENTRY_TEMPLATE="/mnt/usr/share/systemd/bootctl/arch.conf"
# Get PARTUUID for the root partition
PARTUUID=$(blkid | grep "${PART_PREFIX}3" | awk -F= '{print $NF}' | tr -d '\"')
if [ -z "$PARTUUID" ]; then
echo "Error: Unable to find PARTUUID for ${DISK}3."
exit 3
fi
# Create a new entry based on the template and PARTUUID
echo "Creating bootloader entry with PARTUUID=$PARTUUID"
sed "s/^options.*/options root=PARTUUID=$PARTUUID rw splash/" "$ARCH_ENTRY_TEMPLATE" >"$BOOTLOADER_ENTRY"
if [ $? -eq 0 ]; then
echo "Successfully created bootloader entry: $BOOTLOADER_ENTRY"
else
echo "Error: Failed to create the bootloader entry."
exit 3
fi
}
# >------ Main execution flow ------<
# Install dependencies on the host
install_deps
echo ""
# Ask for hostname, username, user and root passwords
get_config_inputs
echo ""
# Ask for the drive to install on
get_drive
echo ""
# Partition, create filesystems and mount
setup_partitions
# Then install the kernel and some required packages
send_status_message "BASE INSTALLATION: Installing base system with pacstrap"
pacstrap -K /mnt base linux linux-firmware networkmanager lemurs sudo
if [ $? -ne 0 ]; then
echo "Error: Failed to install base system."
exit 4
fi
send_status_message "SYSTEM CONFIG: Generating fstab"
genfstab -U /mnt >>/mnt/etc/fstab
# Setup base locales
send_status_message "SYSTEM CONFIG: Setting timezone, locales, and hostname"
ln -sf /usr/share/zoneinfo/Europe/Paris /mnt/etc/localtime
echo 'en_US.UTF-8 UTF-8' >>/mnt/etc/locale.gen
arch-chroot /mnt locale-gen
echo LANG=en_US.UTF-8 >/mnt/etc/locale.conf
echo $HOSTNAME >/mnt/etc/hostname
send_status_message "USER SETUP: Creating user and setting passwords"
# Set root password
arch-chroot /mnt bash -c "echo 'root:$ROOT_PASSWORD' | chpasswd"
# Create user and set password
arch-chroot /mnt useradd -m $USERNAME
arch-chroot /mnt bash -c "echo '$USERNAME:$USER_PASSWORD' | chpasswd"
# Setup wheel group
arch-chroot /mnt usermod -aG wheel $USERNAME
arch-chroot /mnt bash -c "echo '%wheel ALL=(ALL) ALL' | EDITOR='tee -a' visudo"
send_status_message "SERVICES: Enabling NetworkManager and lemurs"
# Setup services and display manager
arch-chroot /mnt systemctl enable NetworkManager lemurs
setup_bootloader
send_status_message "CLEANUP: Unmounting all filesystems"
umount -A -R /mnt # Unmount everything for safety
send_status_message "Installation finished. Reboot now."