Skip to content

Instantly share code, notes, and snippets.

@johnramsden
Last active June 6, 2024 09:43
Show Gist options
  • Save johnramsden/2128a1a8a9b100537f17b4cbb26070cb to your computer and use it in GitHub Desktop.
Save johnramsden/2128a1a8a9b100537f17b4cbb26070cb to your computer and use it in GitHub Desktop.
Install scripts for installing Arch Linux on ZFS. Not runnable, just listed commands.
#!/bin/bash
# Check before running, may need intervention
# Pass in the following to the script, or hardcode it.
# Uncomment if hardcoding input.
BOOT_PARTITION="/dev/sdg1"
DISK_1="ata-SanDisk_SDSSDXPS480G_152271401093"
DISK_2="ata-SanDisk_SDSSDXPS480G_154501401266"
POOL="vault"
# Check for zfs
modprobe zfs
# Create pool
zpool create -f -o ashift=12 ${POOL} mirror ${DISK_1} ${DISK_2}
## Properties
# Compression
zfs set compression=on ${POOL}
# Access time
zfs set atime=on ${POOL}
zfs set relatime=on ${POOL}
# Create key datasets
zfs create -o mountpoint=none "${POOL}/ROOT"
zfs create -o mountpoint=legacy "${POOL}/ROOT/default"
zfs create -o mountpoint=/home "${POOL}/home"
## Optional datasets ##
# tmp
zfs create "${POOL}/tmp" \
-o setuid=off \
-o devices=off \
-o sync=disabled \
-o mountpoint=/tmp
# Mask systemd’s automatic tmpfs-backed tmp
systemctl mask tmp.mount
# var
zfs create "${POOL}/var" \
-o xattr=sa \
-o mountpoint=legacy
# usr
zfs create "${POOL}/usr" -o mountpoint=legacy
## End Optional
# Unmount pool
zfs umount -a
# Put them in /etc/fstab
nano /etc/fstab
# <pass><file system> <dir> <type> <options> <dump>
# vault/ROOT/default / zfs rw,relatime,xattr,noacl 0 0
# vault/var /var zfs rw,relatime,xattr,noacl 0 0
# vault/usr /usr zfs rw,relatime,xattr,noacl 0 0
# set boot property
zpool set bootfs="${POOL}/ROOT/default" ${POOL}
## Setup Installation ##
# Export the pool
zpool export ${POOL}
# re-import the pool,
zpool import -d /dev/disk/by-id -R /mnt ${POOL}
# bring the zpool.cache file into your new system
mkdir -p /mnt/etc/zfs
cp /etc/zfs/zpool.cache /mnt/etc/zfs/zpool.cache
# OR, if you do not have /etc/zfs/zpool.cache, create it:
# zpool set cachefile=/etc/zfs/zpool.cache zroot
# Mount legacy zfs
mkdir /mnt/{home,var,usr,tmp,boot}
mount -t zfs "${POOL}/home" "/mnt/home"
mount -t zfs "${POOL}/var" "/mnt/var"
mount -t zfs "${POOL}/usr" "/mnt/usr"
mount -t zfs "${POOL}/tmp" "/mnt/tmp"
# Boot
mkdir -p /boot
mount "/dev/${BOOT_PARTITION}" /boot
# Generate the fstab
genfstab -U -p /mnt >> /mnt/etc/fstab
# Comment out all non-legacy datasets apart from the root dataset,
# the swap file and the boot/EFI partition.
nano /mnt/etc/fstab
# Edit mirrorlist
nano /etc/pacman.d/mirrorlist
# Install the base system
pacstrap -i /mnt base base-devel
# Edit ramdisk hooks
# If you are using a separate dataset for /usr, have the usr hook enabled after zfs
# If using a separate dataset for /var, add shutdowm hook
# HOOKS="base udev autodetect modconf block keyboard zfs usr filesystems shutdown"
nano /mnt/etc/mkinitcpio.conf
# Enter chroot
#!/bin/bash
# Run in chroot
# arch-chroot /mnt /bin/bash
# Add the Arch ZFS repository to /etc/pacman.conf
nano /etc/pacman.conf
# [archzfs]
# Server = http://archzfs.com/$repo/x86_64
# sign its key
pacman-key -r 5E1ABF240EE7A126 && pacman-key --lsign-key 5E1ABF240EE7A126
# install zfs-linux
pacman -Syyu
pacman -S zfs-linux-git
# For /tmp, mask (disable) systemd's automatic tmpfs-backed /tmp
systemctl mask tmp.mount
## Install as normal ##
nano /etc/pacman.d/mirrorlist
# set locale, uncomment en_US.UTF-8 UTF-8
nano /etc/locale.gen
# generate the new locales
locale-gen
# set locale, LANG refers to the first column of locale
nano /etc/locale.conf
# LANG=en_US.UTF-8
# timezone
ln -s /usr/share/zoneinfo/Canada/Pacific /etc/localtime
# set the time standard to UTC
hwclock --systohc --utc
## Bootloader ##
# re-generate the initramfs image
mkinitcpio -p linux
# If intel cpu, set ucode as the first initrd in the bootloader
pacman -S intel-ucode
# Install systemd-boot to wherever esp mounted
bootctl --path=/boot install
# Bootloader entry
# title Arch Linux
# linux /vmlinuz-linux
# initrd /intel-ucode.img
# initrd /initramfs-linux.img
# options zfs=vault/ROOT/default rw
nano /loader/entries/Arch.conf
## Configure the network ##
# Set the hostname to your liking:
nano /etc/hostname
## /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
# 192.168.0.2 Archon.localdomain Archon
nano /etc/hosts
# get nic
ip link
# enable internet
systemctl enable [email protected]
# root pass
passwd
# Set either shutdown hook or this
systemctl enable mkinitcpio-generate-shutdown-ramfs.service
## Install Done, Customize ##
# Make a user
pacman -S zsh sudo
useradd -m -G wheel -s /usr/bin/zsh john
passwd john
EDITOR=nano visudo
nano /etc/pacman.conf
pacman -S openssh
systemctl enable sshd
nano /etc/ssh/sshd_config
# Done!
exit
umount /mnt/boot
umount /mnt/home umount /mnt/tmp
umount /mnt/usr
umount /mnt/var
zfs umount -a
zpool export vault
## Reboot!
#!/bin/bash
## After reboot ##
zpool set cachefile=/etc/zfs/zpool.cache vault
systemctl enable zfs.target
# To write the hostid file safely you need to use a small C program:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
# int main() {
# int res;
# res = sethostid(gethostid());
# if (res != 0) {
# switch (errno) {
# case EACCES:
# fprintf(stderr, "Error! No permission to write the"
# " file used to store the host ID.\n"
# "Are you root?\n");
# break;
# case EPERM:
# fprintf(stderr, "Error! The calling process's effective"
# " user or group ID is not the same as"
# " its corresponding real ID.\n");
# break;
# default:
# fprintf(stderr, "Unknown error.\n");
# }
# return 1;
# }
# return 0;
# }
# Copy it, save it as writehostid.c and compile it with gcc -o writehostid writehostid.c, finally execute it and regenerate the initramfs image:
nano writehostid.c
gcc -o writehostid writehostid.c
chmod +x writehostid
./writehostid
mkinitcpio -p linux
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment