Skip to content

Instantly share code, notes, and snippets.

@taylorjonl
Last active March 15, 2024 02:46
Show Gist options
  • Save taylorjonl/cf2961c0386bec8d83b3ae5c22bf9a6c to your computer and use it in GitHub Desktop.
Save taylorjonl/cf2961c0386bec8d83b3ae5c22bf9a6c to your computer and use it in GitHub Desktop.
ZFS Boot Menu - Bertha

Instructions

#
# Open a root shell
# Source /etc/os-release
source /etc/os-release
export ID

# Define disk variables
export DISK1="/dev/disk/by-id/wwn-0x5000cca04a12cee8"
export DISK2="/dev/disk/by-id/wwn-0x5000cca04a13c6bc"

# Wipe partitions
for DISK in $DISK1 $DISK2; do
  sgdisk --zap-all "$DISK" && wipefs -a "$DISK"
done

# Create the partitions
for DISK in $DISK1 $DISK2; do
  sgdisk -n "1:1m:+512m" -t "1:ef00" "$DISK"
  sgdisk -n "2:0:-10m" -t "2:bf00" "$DISK"
done

# Install helpers
apt update && apt install --yes debootstrap gdisk zfsutils-linux

# Generate /etc/hostid
zgenhostid -f 0x00bab10c

# Create the zpool
zpool create -f -o ashift=12 \
 -O compression=gzip \
 -O acltype=posixacl \
 -O xattr=sa \
 -O relatime=on \
 -o autotrim=on \
 -m none zroot mirror "$DISK1-part2" "$DISK2-part2"

# Create initial file systems
zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/${ID}
zpool set bootfs=zroot/ROOT/${ID} zroot
zfs create -o canmount=off -o mountpoint=/ zroot/USERDATA
zfs create -o canmount=on -o mountpoint=/root zroot/USERDATA/root

# Export, then re-import with a temporary mountpoint of /mnt
zpool export zroot
zpool import -N -R /mnt zroot
zfs mount zroot/ROOT/${ID}
zfs mount zroot/USERDATA/root

# Update device symlinks
udevadm trigger

# Install Ubuntu
debootstrap jammy /mnt

# Copy files into the new install
cp /etc/hostid /mnt/etc
cp /etc/resolv.conf /mnt/etc

# Chroot into the new OS
mount -t proc proc /mnt/proc
mount -t sysfs sys /mnt/sys
mount -B /dev /mnt/dev
mount -t devpts pts /mnt/dev/pts
chroot /mnt /usr/bin/env DISK1=$DISK1 DISK2=$DISK2 /bin/bash

# Set a hostname
echo 'bertha' > /etc/hostname
sed -i '/127.0.0.1\slocalhost/a 127.0.1.1       bertha' /etc/hosts

# Configure the network
cat << EOF > /etc/netplan/01-netcfg.yaml
network:
  version: 2
  ethernets:
    eno3:
      dhcp4: yes
EOF
chmod 600 /etc/netplan/01-netcfg.yaml

# Configure the package sources
cat << EOF > /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu jammy main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu jammy-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu jammy-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu jammy-security main restricted universe multiverse
EOF

# Update the repository cache and system
apt update && apt upgrade

# Install additional base packages
apt install --yes --no-install-recommends linux-generic locales keyboard-configuration console-setup
apt install --yes curl nano openssh-server tmux


# Configure packages to customize local and console properties
dpkg-reconfigure locales tzdata keyboard-configuration console-setup


#
# ZFS Configuration
# Install required packages
apt install --yes dosfstools zfs-initramfs zfsutils-linux

# Enable systemd ZFS services
systemctl enable zfs.target
systemctl enable zfs-import-cache
systemctl enable zfs-mount
systemctl enable zfs-import.target

# Rebuild the initramfs
update-initramfs -c -k all

#
# Install and configure ZFSBootMenu
# Set ZFSBootMenu properties on datasets
zfs set org.zfsbootmenu:commandline="quiet" zroot/ROOT

# Create a vfat filesystem
mkfs.vfat -F32 "$DISK1-part1" && mkfs.vfat -F32 "$DISK1-part1"

# Create an fstab entry and mount
cat << EOF >> /etc/fstab
$DISK1-part1 /boot/efi vfat defaults 0 0
EOF
mkdir -p /boot/efi && mount /boot/efi

# Install ZFSBootMenu
mkdir -p /boot/efi/EFI/ZBM
curl -o /boot/efi/EFI/ZBM/VMLINUZ.EFI -L https://get.zfsbootmenu.org/efi
cp /boot/efi/EFI/ZBM/VMLINUZ.EFI /boot/efi/EFI/ZBM/VMLINUZ-BACKUP.EFI

# Configure EFI boot entries
mount -t efivarfs efivarfs /sys/firmware/efi/efivars
apt install efibootmgr
efibootmgr -c -d "$DISK1" -p "1" -L "ZFSBootMenu (Backup)" -l '\EFI\ZBM\VMLINUZ-BACKUP.EFI'
efibootmgr -c -d "$DISK1" -p "1" -L "ZFSBootMenu" -l '\EFI\ZBM\VMLINUZ.EFI'

# Set the root password
passwd

# Update ssh server to allow root login
sed -i 's/#PermitRootLogin\sprohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config

# Mount a tmpfs to /tmp
cp /usr/share/systemd/tmp.mount /etc/systemd/system/
systemctl enable tmp.mount

#
# Prepare for first boot
# Exit the chroot, unmount everything
exit
umount -n -R /mnt
# Export the zpool and reboot
zpool export zroot
reboot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment