Created
August 20, 2019 19:10
-
-
Save xunil154/e7292db25428a26cdfca4d683a9bcb8d to your computer and use it in GitHub Desktop.
ArchLinux install script with ZFS as the root, all sitting on LUKS encryption, using systemd-boot for UEFI (ArchLinux with ZFS Root on LUKS with UEFI)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
SWAPSIZE=3 # IN GB | |
SYSTEM_NAME=aerozine # Hostname and used in ZFS structure (zroot/sys/${SYSTEM_NAME}/ROOT/default) | |
USER=xunil # Initial admin user for the system | |
# Archlinux on ZFS Root on LUKS setup script (v1.0) | |
# | |
# USAGE: ./ArchLinux_ZFS_LUKS_Setup.sh /dev/sda | |
# | |
# Author: Chris Campbell (https://gist.github.com/xunil154) | |
# | |
# With LOTS of help from online docs: | |
# ZFS Guide: https://ramsdenj.com/2016/06/23/arch-linux-on-zfs-part-2-installation.html | |
# https://wiki.archlinux.org/index.php/Installing_Arch_Linux_on_ZFS#Configure_the_root_filesystem | |
# https://aur.archlinux.org/packages/mkinitcpio-sd-zfs/ | |
# https://wiki.archlinux.org/index.php/Dm-crypt/Encrypting_an_entire_system | |
# | |
# The key to making this all work was 'mkinitcpio-sd-zfs' and the 'root=zfs:zroot/sys/${SYSTEM_NAME}/ROOT/default' | |
# line in the systemd-boot options. Wiki's say to use just 'zfs=zroot/sys/${SYSTEM_NAME}/ROOT/default' which | |
# is not honnored through sd-zfs | |
# | |
# This script will auto-partition the disk with [ /boot 1GiB FAT ][ LUKS for the rest of the disk ] | |
if [ $# -ne 1 ] | |
then | |
echo "Usage: $0 <device>" | |
echo "Where <device> is sdX" | |
echo "Example: $0 sda" | |
echo "do NOT use the /dev/disk/by-id/.... the script will find that automatically" | |
exit 1 | |
fi | |
#### START SCRIPT CODE #### | |
ee(){ | |
if [ $1 -ne 0 ] | |
then | |
echo "[ERROR] ${2}" | |
exit $1 | |
fi | |
} | |
HOOKS="base systemd autodetect keyboard sd-vconsole modconf block sd-encrypt sd-zfs usr filesystems shutdown" | |
echo "############# Disk Configuration #################" | |
userdev=$(basename "$1") | |
DISK=$(find /dev/disk/by-id -type l -printf "%f:%l\n" | grep -E "${userdev}$" | cut -d':' -f 1) | |
if [ -z "${DISK}" ] | |
then | |
ee 1 "Could not lookup disk by id... are you sure '${userdev}' is correct?" | |
fi | |
DISKDEV="/dev/disk/by-id/${DISK}" | |
echo "USING DISK: ${DISKDEV}" | |
echo "If this is wrong, press Ctrl^C within 15 seconds" | |
sleep 5 | |
echo "10s" | |
sleep 5 | |
echo "5s" | |
sleep 5 | |
echo "Destroying existing partitions" | |
sgdisk --zap-all ${DISKDEV} | |
sgdisk -p ${DISKDEV} | |
echo "Creating the following partition scheme" | |
echo "[ EFI BOOT 1G ][ LUKS * ]" | |
#parted --script "$DISKDEV" mklabel gpt mkpart primary fat32 1MiB 2GiB set 1 esp on name 1 efi mkpart primary 2GiB 100% name 2 sys | |
sgdisk --new=0:1M:1G "${DISKDEV}" | |
sgdisk --new=0:0:0 ${DISKDEV} | |
sgdisk --typecode=1:EF00 ${DISKDEV} | |
sgdisk --typecode=2:8309 ${DISKDEV} | |
sgdisk --change-name=1:efi | |
sgdisk --change-name=2:sys | |
sgdisk -p ${DISKDEV} | |
echo "Partitions created, reloading table on ${DISKDEV}" | |
partprobe ${DISKDEV} | |
sleep 2 | |
BOOT="${DISK}-part1" | |
BOOTDEV=/dev/disk/by-id/$BOOT | |
CRYPT="${DISK}-part2" | |
CRYPTDEV=/dev/disk/by-id/$CRYPT | |
BOOTUUID=$(blkid -o export $BOOTDEV | grep -E '^UUID' | cut -d'=' -f2) | |
echo "Creating FAT32 FS on ${BOOTDEV}" | |
ls -l "${BOOTDEV}" | |
mkfs.fat -F32 ${BOOTDEV} | |
ee $? "Failed to format boot partition ${BOOTDEV}" | |
echo "############# LUKS Setup ##############" | |
echo "Using $CRYPTDEV as LUKS partition" | |
echo "Done, you have 10s to review and cancel..." | |
sleep 5 | |
echo "5s" | |
sleep 2 | |
echo "3s" | |
sleep 3 | |
modprobe dm-crypt | |
modprobe dm-mod | |
cryptsetup luksFormat -v --cipher aes-xts-plain64 -s 512 -h sha512 --iter-time 3000 --use-random $CRYPTDEV | |
ee $? "Failed to create LUKS" | |
echo "Mounting $CRYPTDEV... you will need to enter the passphrase again" | |
cryptsetup open $CRYPTDEV luks_zfs | |
ee $? "ERROR: Failed to decrypt luks" | |
echo "############## ZFS Setup #################" | |
ZFSDISK=$(ls /dev/disk/by-id | grep CRYPT) | |
ZFSDISKDEV=/dev/disk/by-id/$ZFSDISK | |
modprobe zfs | |
ee $? "Failed to load ZFS module" | |
echo "Creating zroot pool" | |
zpool create -o ashift=12 -f zroot -o altroot=/mnt -m none $ZFSDISKDEV | |
ee $? "Failed to create 'zroot' zpool" | |
zfs set compression=on zroot | |
zfs set atime=on zroot | |
zfs set relatime=on zroot | |
SYS_ROOT=zroot/sys | |
zfs create -o mountpoint=none -p ${SYS_ROOT}/${SYSTEM_NAME} | |
zfs create -o mountpoint=none ${SYS_ROOT}/${SYSTEM_NAME}/ROOT | |
zfs create -o mountpoint=/ ${SYS_ROOT}/${SYSTEM_NAME}/ROOT/default | |
zpool set bootfs=${SYS_ROOT}/${SYSTEM_NAME}/ROOT/default | |
zfs create -o mountpoint=legacy ${SYS_ROOT}/${SYSTEM_NAME}/home | |
zfs create -V ${SWAPSIZE}G -b $(getconf PAGESIZE) -o logbias=throughput -o sync=always -o primarycache=metadata -o com.sun:auto-snapshot=false zroot/swap | |
mkswap -f /dev/zvol/zroot/swap | |
ee $? "Failed to create SWAP" | |
zfs create -o canmount=off -o mountpoint=/var -o xattr=sa ${SYS_ROOT}/${SYSTEM_NAME}/var | |
zfs create -o canmount=off -o mountpoint=/var/lib ${SYS_ROOT}/${SYSTEM_NAME}/var/lib | |
zfs create -o canmount=off -o mountpoint=/var/lib/systemd ${SYS_ROOT}/${SYSTEM_NAME}/var/lib/systemd | |
zfs create -o canmount=off -o mountpoint=/usr ${SYS_ROOT}/${SYSTEM_NAME}/usr | |
SYSTEM_DATASETS='var/lib/systemd/coredump var/log var/log/journal var/lib/lxc var/lib/lxd var/lib/machines var/lib/libvirt var/cache usr/local' | |
for ds in ${SYSTEM_DATASETS}; do zfs create -o mountpoint=legacy ${SYS_ROOT}/${SYSTEM_NAME}/${ds}; done | |
zfs create -o mountpoint=legacy -o acltype=posixacl ${SYS_ROOT}/${SYSTEM_NAME}/var/log/journal | |
echo "All datasets created.... unmounting for instillation" | |
zfs umount -a | |
ee $? "Failed to unmount ZFS filesystmes" | |
zpool export zroot | |
ee $? "Failed to export zroot" | |
echo "################### Instillation Preparation ###########################" | |
echo "Importing zpool" | |
zpool import -d $ZFSDISKDEV -R /mnt zroot | |
ee $? "Failed to import zroot pool" | |
mkdir -p /etc/zfs | |
mkdir -p /mnt/etc/zfs | |
zpool set cachefile=/etc/zfs/zpool.cache zroot | |
mv /etc/zfs/zpool.cache /mnt/etc/zfs/zpool.cache | |
ln -s /mnt/etc/zfs/zpool.cache /etc/zfs/zpool.cache | |
echo "KEYMAP=us" > /mnt/etc/vconsole.conf | |
mkdir -p /mnt/boot | |
mount $BOOTDEV /mnt/boot | |
ee $? "Failed to mount ${BOOTDEV} to /mnt/boot" | |
DIRS='/home /var/lib/systemd/coredump /var/log /var/log/journal /var/lib/lxc /var/lib/machines /var/lib/libvert /var/cache /usr/local' | |
for d in ${DIRS}; do mkdir -p "/mnt${d}"; mount -t zfs ${SYS_ROOT}/${SYSTEM_NAME}${d} /mnt${d}; done | |
genfstab -U -p /mnt >> /mnt/etc/fstab | |
echo "/dev/zvol/zroot/swap none swap discard 0 0" >> /mnt/etc/fstab | |
repo='$repo' | |
echo "#################### INSTILLATION #########################" | |
pacstrap -i /mnt base base-devel | |
ee $? "Failed to pacstrap" | |
echo "Installing systemd-boot" | |
bootctl --path=/mnt/boot install | |
ee $? "Failed to install systemd-boot" | |
CRYPTUUID=$(blkid -o export $CRYPTDEV | grep -E '^UUID' | cut -d'=' -f2) | |
mkdir -p /mnt/boot/loader/entries | |
cat <<EOF > /mnt/boot/loader/entries/arch.conf | |
title Arch Linux | |
linux /vmlinuz-linux | |
initrd /initramfs-linux.img | |
options rd.luks.uuid=${CRYPTUUID} rd.luks.name=${CRYPTUUID}=luks_zfs rd.luks.options=timeout=20s,cipher=aes-xts-plain64:sha512,size=512 root=zfs:zroot/sys/${SYSTEM_NAME}/ROOT/default rw | |
EOF | |
echo "Configuring/generating setup scripts (/mnt/chroot_install.sh /mnt/post_install.sh)" | |
cat <<EOF >> /mnt/etc/pacman.conf | |
[archzfs] | |
Server = http://archzfs.com/$repo/x86_64 | |
EOF | |
sed -i -e "s/^HOOKS=(.*$/HOOKS=(${HOOKS})/" /mnt/etc/mkinitcpio.conf | |
echo "/etc/mkinitcpio.conf HOOKS config..." | |
grep -E '^HOOKS=' /mnt/etc/mkinitcpio.conf | |
echo '%wheel ALL=(ALL) ALL' > /mnt/etc/sudoers.d/wheel | |
cat <<EOF >> /mnt/chroot_install.sh | |
#!/bin/sh | |
pacman-key -r F75D9D76 | |
pacman-key --lsign-key F75D9D76 | |
pacman --noconfirm -Sy zfs-linux sudo vim wget curl | |
cd /tmp | |
wget https://aur.archlinux.org/cgit/aur.git/snapshot/mkinitcpio-sd-zfs.tar.gz | |
tar -xzf mkinitcpio-sd-zfs.tar.gz | |
chown nobody:nobody mkinitcpio-sd-zfs | |
cd mkinitcpio-sd-zfs | |
sudo -u nobody makepkg | |
pacman --noconfirm -U *.xz | |
mkinitcpio -p linux | |
ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime | |
hwclock --systohc | |
sed -i -e 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen | |
locale-gen | |
echo 'LANG=en_US.UTF-8' >> /etc/locale.conf | |
echo $SYSTEM_NAME > /etc/hostname | |
echo '127.0.0.1 localhost' > /etc/hosts | |
echo '::1 localhost' >> /etc/hosts | |
echo "127.0.0.1 ${SYSTEM_NAME}.localdomain ${SYSTEM_NAME}" >> /etc/hosts | |
loadkeys us | |
localectl set-keymap --no-convert us | |
#echo "Setting the root password" | |
#passwd | |
echo "Creating user $USER" | |
useradd -m -g users -G wheel,storage,power -s /bin/bash $USER | |
echo "Set password for $USER" | |
passwd $USER | |
echo "Done, do whatever you want then Ctrl+D" | |
EOF | |
chmod +x /mnt/chroot_install.sh | |
cat <<EOF > /mnt/post_install.sh | |
#!/bin/sh | |
zpool set cachefile=/etc/zfs/zpool.cache zroot | |
systemctl enable zfs.target | |
systemctl enable zfs-import-cache | |
systemctl enable zfs-mount | |
systemctl enable zfs-import.target | |
zgenhostid $(hostid) | |
mkinitcpio -p linux | |
EOF | |
chmod +x /mnt/post_install.sh | |
echo "##### DONE #####" | |
echo "Running /mnt/chroot_install.sh" | |
arch-chroot /mnt /chroot_install.sh | |
echo "Done... dropping into arch-chroot" | |
arch-chroot /mnt /bin/bash | |
#echo "##### IMPORTANT #####" | |
#echo "remember to 'umount /mnt/boot' and 'zfs umount -a' and 'zpool export zroot' OR" | |
#echo "cat unmount.txt | xargs unmount; zfs unmount -a; zpool export zroot" | |
cat <<EOF > unmount.txt | |
/mnt/boot | |
/mnt/usr/local | |
/mnt/var/cache | |
/mnt/home | |
/mnt/var/lib/systemd/coredump | |
/mnt/var/log/journal | |
/mnt/var/log | |
/mnt/var/lib/lxc | |
/mnt/var/lib/machines | |
/mnt | |
EOF | |
echo "UNMOUNTING AND EXPORING POOL" | |
cat unmount.txt | xargs umount | |
zfs unmount -a | |
zpool export zroot | |
echo "Done, reboot into the new system! (hopefully)" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment