Last active
October 4, 2021 15:38
-
-
Save altercation/8d5bd3685f564e6e3c0c4c06f4730484 to your computer and use it in GitHub Desktop.
arch-dual drive config
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 | |
#---------------------------------------------------------------------- | |
# Arch Linux Installation Script | |
# | |
# This installs, with no intervention (other than initial edit to change | |
# RAID array drive values), Arch Linux on an encrypted btrfs raid1 array. | |
#---------------------------------------------------------------------- | |
set -eu | |
#---------------------------------------------------------------------- | |
# DRIVE & SCRIPT VALUES | |
#---------------------------------------------------------------------- | |
DRIVE1=/dev/nvme0n1 | |
DRIVE2=/dev/sdb | |
echo -e "confirm device assignments in script first\nDRIVE 1 = $DRIVE1\nDRIVE 2 = $DRIVE2\n\nlsblk:\n"; lsblk; exit | |
# script values | |
HOST=nostromo | |
USER=es | |
USERSHELL=zsh | |
MOUNT=/mnt | |
MOUNTOPTS=defaults,x-mount.mkdir | |
BTRFSOPTS=$MOUNTOPTS,ssd,noatime | |
#---------------------------------------------------------------------- | |
# preflight cleanup (close mapped encrypted devices, unmount, shutdown swap) | |
#---------------------------------------------------------------------- | |
[ -n "${SWAP:=$(swapon --noheadings --show=NAME)}" ] && swapoff $SWAP | |
umount /key || : | |
umount /mnt/boot || : | |
umount -R /mnt || : | |
for MAPPED in $(ls /dev/mapper); do [ "$MAPPED" != "control" ] && cryptsetup close /dev/mapper/$MAPPED || : ; done | |
#---------------------------------------------------------------------- | |
# optional: secure wipe of drive (takes a while) | |
#---------------------------------------------------------------------- | |
# sgdisk --zap-all /dev/device | |
# cryptsetup open --type plain /dev/device container --key-file /dev/random | |
# dd if=/dev/zero of=/dev/mapper/container status=progress | |
# cryptsetup close container | |
#---------------------------------------------------------------------- | |
# Create Partitions | |
#---------------------------------------------------------------------- | |
# NOTE: EFI partition should be at least 550MiB according to | |
# http://www.rodsbooks.com/efi-bootloaders/principles.html | |
for DRIVE in $DRIVE1 $DRIVE2 | |
do | |
sgdisk --zap-all $DRIVE | |
done | |
sgdisk --clear \ | |
--new=1:0:+2GiB --typecode=1:ef00 --change-name=1:EFI \ | |
--new=2:0:+64GiB --typecode=2:8200 --change-name=2:cryptswap \ | |
--new=3:0:0 --typecode=3:8200 --change-name=3:cryptsystem1 \ | |
$DRIVE1 | |
sgdisk --clear \ | |
--new=1:0:0 --typecode=1:8200 --change-name=1:cryptsystem2 \ | |
$DRIVE2 | |
#---------------------------------------------------------------------- | |
# | |
#---------------------------------------------------------------------- | |
# get passphrase | |
while ! ${MATCH:-false} | |
do | |
echo -en "Enter Passphrase : " | |
read -rs PASS | |
echo -en "\nConfirm Passphrase : " | |
read -rs CONF | |
[ "$PASS" = "$CONF" ] \ | |
&& { MATCH=true; echo -e "\n\nPassphrases matched.\n"; } \ | |
|| echo -e "\n\nPassphrases didn't match--try again.\n" | |
done | |
# encrypt cryptsystem* partitions with passphrases | |
for PART in cryptsystem1 cryptsystem2 | |
do | |
echo $PASS | cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/$PART | |
echo $PASS | cryptsetup open /dev/disk/by-partlabel/$PART ${PART#crypt} | |
done | |
#---------------------------------------------------------------------- | |
# Format & Mount Partitions | |
#---------------------------------------------------------------------- | |
mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI | |
# make btrfs raid | |
mkfs.btrfs --force --data raid1 --metadata raid1 --label system /dev/mapper/system1 /dev/mapper/system2 | |
# mount btrfs top-level subvolume for further subvolume creation | |
mount -t btrfs -o $BTRFSOPTS LABEL=system $MOUNT | |
btrfs subvolume create $MOUNT/root | |
btrfs subvolume create $MOUNT/home | |
btrfs subvolume create $MOUNT/snapshots | |
umount -R $MOUNT | |
# remount subvolumes | |
mount -t btrfs -o $BTRFSOPTS,subvol=root LABEL=system $MOUNT | |
mount -t btrfs -o $BTRFSOPTS,subvol=home LABEL=system $MOUNT/home | |
mount -t btrfs -o $BTRFSOPTS,subvol=snapshots LABEL=system $MOUNT/.snapshots | |
# mount EFI | |
mount -o $MOUNTOPTS LABEL=EFI $MOUNT/boot | |
# make and activate swap | |
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap | |
mkswap -L swap /dev/mapper/swap | |
swapon -L swap | |
#---------------------------------------------------------------------- | |
# Install Base System | |
#---------------------------------------------------------------------- | |
# install base system | |
pacstrap $MOUNT base base-devel btrfs-progs iw zsh vim terminus-font efibootmgr | |
# generate fstab | |
genfstab -L -p $MOUNT >> $MOUNT/etc/fstab | |
# remove the subvolume ID element of the fstab statements to | |
# allow mounting by subvolume name only (to facilitate rollbacks) | |
sed -i 's/,subvolid=[[:digit:]]*//g' $MOUNT/etc/fstab | |
# enter swap into crypttab | |
echo 'swap /dev/disk/by-partlabel/cryptswap /dev/urandom swap,cipher=aes-cbc-essiv:sha256,size=256' >> $MOUNT/etc/crypttab | |
# make sure we have a crypttab.initramfs as well | |
echo 'swap /dev/disk/by-partlabel/cryptswap /dev/urandom swap,cipher=aes-cbc-essiv:sha256,size=256' > $MOUNT/etc/crypttab.initramfs | |
# remove LABEL identifier for swap in fstab as it may/will not have a label from crypttab | |
# (TODO: could *maybe* solve this with luks.name= but I'm then using UUID) | |
sed -i 's+LABEL=swap+/dev/mapper/swap+' $MOUNT/etc/fstab | |
#---------------------------------------------------------------------- | |
# Prepare chroot script | |
#---------------------------------------------------------------------- | |
cat > $MOUNT/setup.sh <<EOFSETUP | |
#!/bin/sh | |
set -eu | |
HOST=$HOST | |
USER=$USER | |
USERSHELL=$USERSHELL | |
# get partition UUIDs (have to do this before entering chroot since lsblk won't report there) | |
CRYPTSWAP_UUID=$(lsblk --nodeps --noheadings -oUUID /dev/disk/by-partlabel/cryptswap) | |
CRYPTSYSTEM1_UUID=$(lsblk --nodeps --noheadings -oUUID /dev/disk/by-partlabel/cryptsystem1) | |
CRYPTSYSTEM2_UUID=$(lsblk --nodeps --noheadings -oUUID /dev/disk/by-partlabel/cryptsystem2) | |
EOFSETUP | |
cat >> $MOUNT/setup.sh <<'EOFSETUP' | |
setfont ter-u18n | |
echo "FONT=ter-u18n" > /etc/vconsole.conf | |
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen | |
locale-gen | |
echo "LANG=en_US.UTF-8" > /etc/locale.conf | |
export LANG=en_US.UTF-8 | |
mv /etc/localtime /etc/localtime.orig | |
ln -s /usr/share/zoneinfo/America/Los_Angeles /etc/localtime | |
hwclock --systohc --utc | |
#timedatectl set-ntp true | |
echo $HOST > /etc/hostname | |
#edit /etc/hosts the same way... see beginners guide | |
mv /etc/hosts /etc/hosts.orig | |
cat > /etc/hosts <<EOF | |
# | |
# /etc/hosts: static lookup table for host names | |
# | |
#<ip-address> <hostname.domain.org> <hostname> | |
127.0.0.1 localhost.localdomain localhost | |
::1 localhost.localdomain localhost | |
127.0.0.1 $HOST.localdomain $HOST | |
::1 $HOST.localdomain $HOST | |
# End of file | |
EOF | |
# add user, set passwords | |
useradd -m -G wheel -s $(which $USERSHELL) $USER | |
while ! ${MATCH:-false} | |
do | |
echo -en "Enter Initial Root/User Passphrase : " | |
read -rs PASS | |
echo -en "\nConfirm Passphrase : " | |
read -rs CONF | |
[ "$PASS" = "$CONF" ] \ | |
&& { MATCH=true; echo -e "\n\nPassphrases matched.\n"; } \ | |
|| echo -e "\n\nPassphrases didn't match--try again.\n" | |
done | |
for ACCOUNT in root $USER; do | |
echo "$ACCOUNT:$PASS" | chpasswd | |
done | |
# enable sudo for wheel | |
tmpfile=$(mktemp) | |
echo "%wheel ALL=(ALL) NOPASSWD: ALL" > $tmpfile | |
visudo -cf $tmpfile \ | |
&& mv $tmpfile /etc/sudoers.d/wheel \ | |
|| { echo "ERROR updating sudoers; no change made"; exit 1; } | |
# reconfigure and regenerate initrams | |
mv /etc/mkinitcpio.conf /etc/mkinitcpio.orig | |
cat > /etc/mkinitcpio.conf << EOF | |
#MODULES="nvidia nvidia_modeset nvidia_uvm nvidia_drm" | |
BINARIES="" | |
FILES="" | |
HOOKS="base systemd sd-vconsole modconf keyboard block filesystems btrfs sd-encrypt fsck" | |
EOF | |
mkinitcpio -p linux | |
# remove exiting boot entry | |
EXISTINGENTRY=$(efibootmgr | grep "Linux Boot Manager" | cut -d " " -f 1 | sed "s/[^[:digit:]]*//g" | head -n1) | |
[ -n "$EXISTINGENTRY" ] && efibootmgr -b$EXISTINGENTRY -B | |
# install bootloader ( || : to swallow error code... this seems to return one even on success?) | |
bootctl --path=/boot install || : | |
# configure loader defaults | |
cat > /boot/loader/loader.conf <<EOF | |
default arch | |
timeout 5 | |
editor 0 | |
EOF | |
# configure initial entry | |
# TODO: try PARTLABEL in lieu of UUID | |
cat > /boot/loader/entries/arch.conf <<EOF | |
title Arch Linux | |
linux /vmlinuz-linux | |
initrd /initramfs-linux.img | |
options \ | |
rd.luks.name=$CRYPTSYSTEM1_UUID=system1 \ | |
rd.luks.name=$CRYPTSYSTEM2_UUID=system2 \ | |
root=LABEL=system rootflags=subvol=/root,rw,x-systemd.device-timeout=0 | |
# nvidia-drm.modeset=1 intel_iommu=on | |
EOF | |
cat > /boot/loader/entries/arch_fallback.conf <<EOF | |
title Arch Linux Fallback | |
linux /vmlinuz-linux | |
initrd /initramfs-linux-fallback.img | |
options \ | |
rd.luks.name=$CRYPTSYSTEM1_UUID=system1 \ | |
rd.luks.name=$CRYPTSYSTEM2_UUID=system2 \ | |
root=LABEL=system rootflags=subvol=/root,rw,x-systemd.device-timeout=0 | |
# nvidia-drm.modeset=1 intel_iommu=on | |
EOF | |
echo "use efibootmgr to ensure correct entry for systemd-boot is present, active, and in bootorder" | |
# add new efi boot entry | |
NEWENTRY=$(efibootmgr | grep "Linux Boot Manager" | cut -d " " -f 1 | sed "s/[^[:digit:]]*//g" | tail -n1) | |
BOOTORDER=$(efibootmgr | grep BootOrder | cut -d " " -f 2) | |
efibootmgr -o$NEWENTRY,$BOOTORDER | |
EOFSETUP | |
#---------------------------------------------------------------------- | |
# Execute chroot script | |
#---------------------------------------------------------------------- | |
chmod +x $MOUNT/setup.sh | |
arch-chroot $MOUNT sh -c '/setup.sh' | |
#---------------------------------------------------------------------- | |
# Post reboot installation | |
#---------------------------------------------------------------------- | |
cat > $MOUNT/install.sh <<EOFINSTALL | |
#!/bin/sh | |
set -eu | |
#---------------------------------------------------------------------- | |
# Cleanup | |
#---------------------------------------------------------------------- | |
rm /setup.sh | |
#---------------------------------------------------------------------- | |
# Needs a bus, so post reboot | |
#---------------------------------------------------------------------- | |
timedatectl set-ntp true | |
#---------------------------------------------------------------------- | |
# general | |
#---------------------------------------------------------------------- | |
pacman -S git | |
#---------------------------------------------------------------------- | |
# Xorg | |
#---------------------------------------------------------------------- | |
pacman -S nvidia nvidia-utils xorg-server xorg-server-utils xorg-apps | |
pacman -S nvidia-settings xorg-server-devel opencl-nvidia | |
# based on optional dependencies for nvidia-utils | |
# nvidia-settings | |
# xorg-server-devel: nvidia-xconfig | |
# opencl-nvidia | |
# INSTALL VIDEO ACCELERATION: | |
# https://wiki.archlinux.org/index.php/Hardware_video_acceleration | |
# (env variable VDPAU_DRIVER is current in my .xinitrc and should be sufficient in conjunction with nvidia-utils | |
# Consider "gnome-themes-standard" as optional fallback icon thing for libxcursor | |
# misc xorg utils | |
pacman -S xdotool wmctrl | |
# window manager / desktop environment | |
pacman -S xmonad xmonad-contrib xmobar rxvt-unicode compton dunst feh udiskie polkit-gnome \ | |
xorg-xinit xorg-xfontsel xdg-utils networkmanager xscreensaver thunar dex xclip | |
# what about aur xinit-xsession? | |
# unclutter from aur | |
AUR unclutter-xfixes-git | |
# gtk theme | |
pacman -S gtk3 arc-solid-gtk-theme numix-gtk-theme lxappearance | |
AUR flatplat-theme-git oomox #oomox for numix changing | |
AUR xcursor-thedot | |
systemctl enable NetworkManager | |
systemctl start NetworkManager | |
# audio | |
pacman -S alsa-utils | |
# !!! Unmute master via alsamixer | |
pacman -S pulseaudio pulseaudio-alsa | |
OTHER AUR PACKAGES TO INSTALL: | |
# xsettingsd-git | |
# xcape or xcape-git | |
# xkb-switch, used to poll current keyboard config for xmobar | |
# xss-lock-git | |
# networkmanager_dmenu | |
# (I also create a symlink from /usr/bin/dmenu to /usr/bin/rofi | |
# rofi-fuzzy-git (I'm using a patched package I built with better fuzzy matching) | |
# google-chrome-beta | |
# IMPORTANT: copy over fonts | |
# acpi | |
pacman -S acpid | |
systemctl enable acpid | |
systemctl start acpid | |
mv /etc/acpi/handler.sh /etc/acpi/handler.sh.orig | |
#!!copy over handler.sh to /etc/acpi, make sure it's executable | |
#---------------------------------------------------------------------- | |
# Misc utilities | |
#---------------------------------------------------------------------- | |
# reflector | |
pacman -S reflector | |
cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak | |
reflector --country 'United States' --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist | |
#TODO: add as service | |
pacman -S mlocate | |
updatedb | |
#network utils | |
ldns #drill, etc. | |
bind-tools #dig, etc. | |
gptfdisk #sgdisk | |
youtube-dl | |
ffmpeg | |
dosfstools #mkfs.fat, etc. | |
# for xmonad: in chrome://apps, select desired chrome apps, right click on them and "add shortcuts". | |
# I find it easiest to do this to the $HOME/Desktop (or xdg equiv) folder and then rename them and move them | |
# to ~/.local/share/applications/ (though maybe I could keep them on the "Desktop"?) | |
# -------------------------------- | |
# CUPS | |
pacman -S cups cups-pdf | |
# edit /etc/cups/cups-pdf.conf to change destination of PDFs which is by default /var/spool/cups-pdf/$USER | |
systemctl enable org.cups.cupsd | |
systemctl start org.cups.cupsd | |
# for gtk3 printing as of gtk3.22 | |
pacman -S gtk3-print-backends | |
#ADD USER TO lp and sys GROUP | |
usermod -aG lp es | |
usermod -aG sys es | |
# install avahi, enable hostname resolution | |
pacman -S avahi nss-mdns | |
pacman -S pygtk python2-dbus # for avahi-discover | |
sed -i 's/resolve/mdns_minimal \[NOTFOUND=return\] resolve/' /etc/nsswitch.conf | |
systemctl enable avahi-daemon | |
systemctl start avahi-daemon | |
systemctl restart org.cups.cupsd | |
systemctl enable cups-browsed | |
systemctl start cups-browsed | |
# Avahi: Be sure to open UDP port 5353 if you're using a firewall. | |
# https://wiki.archlinux.org/index.php/Avahi#Hostname_resolution | |
# install samba? | |
# SAMBA NOTE: according to https://wiki.archlinux.org/index.php/Avahi#Samba | |
# With the Avahi daemon running on both the server and client, the file manager on the client should automatically find the server. | |
#drivers (kitchen sink approach) | |
pacman -S foomatic-db-engine foomatic-db foomatic-db-ppds foomatic-db-nonfree-ppds foomatic-db-gutenprint-ppds gutenprint ghostscript gsfonts | |
# see the https://wiki.archlinux.org/index.php/CUPS page for examples of the very useful | |
# lp* commands for adding queues, printing, etc. It's my preferred method. | |
# at this point, running 'lpinfo -v' should return list of local and network printers | |
# hplip should have extra drivers | |
pacman -S hplip | |
driverless:ipp://NPI0E6B0A.local:631/ipp/print Hewlett-Packard HP Color LaserJet MFP M277dw, driverless, cups-filters 1.13.4 | |
ipp://NPI0E6B0A.local:631/ipp/print | |
# following worked to setup my local HP printer, which was also available via driverless printing | |
lpadmin -p hpcolor -E -v ipp://NPI0E6B0A.local:631/ipp/print -m lsb/usr/HP/hp-color_laserjet_pro_mfp_m277-ps.ppd.gz | |
# I can then set it as defaul | |
lpoptions -d hpcolor | |
# and print (for example) an image to it like this: | |
cat my.jpg | lpr | |
# In my experience the following hp-setup commands aren't useful | |
# hplip provides drivers for HP DeskJet, OfficeJet, Photosmart, Business Inkjet, and some LaserJet printers, and also provides an easy to use setup tool. | |
# To run the setup tool with the GUI qt frontend: | |
hp-setup -u | |
# To run the setup tool with the command line frontend: | |
hp-setup -i | |
# To set up directly the configuration of a network connected HP printer: | |
hp-setup -i <ip address> | |
# To run systray spool manager: | |
hp-systray | |
# To generate a URI for a given ip address: | |
hp-makeuri <ip address> | |
# scanning... | |
# sane, hp-scan, python-pillow | |
# install other hplip optional packages | |
libusb python-gobject python-pillow python-pyqt5 python-reportlab rpcbind sane wget xsane xsane-gimp | |
AUR: hplip-plugin # probably not necessary... i've had this setup working before without this | |
# scanning | |
# I am not sure if I previously had run hp-setup or not, but I found that this time round I couldn't | |
# scan without first running hp-setup and adding a printer again, but then it works | |
hp-scan --mode=color | |
# STEAM | |
enable multilib in pacman.conf | |
install lib32-nvidia-utils | |
install steam | |
# ---------------------------------- | |
# production apps | |
pacman -S libreoffice-fresh | |
pacman -S gimp inkscapesed 's/resolve/mdns_minimal \[NOTFOUND=return\] resolve/' /etc/nsswitch.conf | |
# ---------------------------------- | |
# SNAPPER - as per rec on https://wiki.archlinux.org/index.php/Snapper | |
# this should be moved to the configuration stage, not provisioning | |
chmod 0750 /.snapshots | |
umount /.snapshots | |
rmdir /.snapshots | |
snapper -c root create-config / | |
mount /.snapshots | |
snapper -c home create-config /home | |
# enable backup of boot partition (ESP) on kernel update (evidently works well with snap-pac) | |
vim /usr/share/libalpm/hooks/50_bootbackup.hook | |
[Trigger] | |
Operation = Upgrade | |
Operation = Install | |
Operation = Remove | |
Type = Package | |
Target = linux | |
[Action] | |
Depends = rsync | |
Description = Backing up /boot... | |
When = PreTransaction | |
Exec = /usr/bin/rsync -avzq --delete /boot /.bootbackup | |
# install snap-pac to automatically use snapper | |
pacman -S snap-pac | |
# install a btrfs sync tool TBD | |
TBD | |
# enable snapshots on boot | |
systemctl enable snapper-boot.timer | |
# filesystem mounting of iOS devices | |
pacman -S gvfs-afc | |
EOFINSTALL |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment