Skip to content

Instantly share code, notes, and snippets.

@crpb
Last active September 10, 2022 12:42
Show Gist options
  • Save crpb/2a5fb7fd65574ef9a5906f37d93b4469 to your computer and use it in GitHub Desktop.
Save crpb/2a5fb7fd65574ef9a5906f37d93b4469 to your computer and use it in GitHub Desktop.
minimal debian installation with zfs / one or two disks.. haven't tried with two disks yet.. attention, this script will destroy your data without any question :-)
#!/bin/sh
modprobe zfs || exit
apt-get update
apt-get install ntpdate jq --yes
ntpdate-debian
#zpool export -f bpool
#zpool export -f rpool
#swapoff --all
#mount |awk '/\/mnt/ {print $3}'|xargs -n 1 umount 2>/dev/null
# shellcheck disable=SC2114
rm -Rf /mnt && mkdir -p /mnt || exit
DISKS=$(lsblk -J |jq '.[][]|select(.type == "disk")|.name' -r |grep -E "^[^ z]")
_find_id_by_dev() {
file /dev/disk/by-id/* -F\ |awk '/.*[a-z]$/' |grep "$1" |head -n 1|cut -d\ -f1
}
COUNT=$(echo "$DISKS"|wc -w)
if [ "$COUNT" -eq 1 ]; then
CBOOT="$("$(_find_id_by_dev "$DISKS")")-part3"
CROOT="$("$(_find_id_by_dev "$DISKS")")-part4"
fi
if [ "$COUNT" -eq 2 ]; then
CBOOT="raidz1 $(echo "$DISKS" |while read -r disk; do \
printf "%s " "$(_find_id_by_dev "$disk")-part3"; done)"
CROOT="raidz1 $(echo "$DISKS" |while read -r disk; do \
printf "%s " "$(_find_id_by_dev "$disk")-part4"; done)"
fi
echo "$DISKS" |while read -r dev; do
#for dev in $DISKS; do
disk=$(_find_id_by_dev "$dev")
echo "$dev: $disk"
wipefs -a "$disk"
echo 1>"/sys/block/$dev/device/rescan"
sgdisk --zap-all "$disk"
echo 1>"/sys/block/$dev/device/rescan"
sgdisk -n2:1M:+512M -t2:EF00 "$disk"
sgdisk -n3:0:+1G -t3:BF01 "$disk"
sgdisk -n4:0:0 -t4:BF00 "$disk"
echo 1>"/sys/block/$dev/device/rescan"
done
sleep 5
#exit
BOOTPOOL="zpool create -f \
-o ashift=12 \
-o autotrim=on -d \
-o cachefile=/etc/zfs/zpool.cache \
-o feature@async_destroy=enabled \
-o feature@bookmarks=enabled \
-o feature@embedded_data=enabled \
-o feature@empty_bpobj=enabled \
-o feature@enabled_txg=enabled \
-o feature@extensible_dataset=enabled \
-o feature@filesystem_limits=enabled \
-o feature@hole_birth=enabled \
-o feature@large_blocks=enabled \
-o feature@livelist=enabled \
-o feature@lz4_compress=enabled \
-o feature@spacemap_histogram=enabled \
-o feature@zpool_checkpoint=enabled \
-O devices=off \
-O acltype=posixacl -O xattr=sa \
-O compression=lz4 \
-O normalization=formD \
-O relatime=on \
-O canmount=off -O mountpoint=/boot -R /mnt \
bpool ${CBOOT}
"
$BOOTPOOL
sleep 5
ROOTPOOL="zpool create -f \
-o ashift=12 \
-o autotrim=on \
-O acltype=posixacl -O xattr=sa -O dnodesize=auto \
-O compression=lz4 \
-O normalization=formD \
-O relatime=on \
-O canmount=off -O mountpoint=/ -R /mnt \
rpool ${CROOT}
"
$ROOTPOOL
sleep 5
#exit
zfs create -o canmount=off -o mountpoint=none rpool/ROOT
zfs create -o canmount=off -o mountpoint=none bpool/BOOT
zfs create -o canmount=noauto -o mountpoint=/ rpool/ROOT/debian
zfs mount rpool/ROOT/debian
zfs create -o mountpoint=/boot bpool/BOOT/debian
zfs create rpool/home
zfs create -o mountpoint=/root rpool/home/root
chmod 700 /mnt/root
zfs create -o canmount=off rpool/var
zfs create -o canmount=off rpool/var/lib
zfs create rpool/var/log
zfs create rpool/var/spool
zfs create -o com.sun:auto-snapshot=false rpool/var/cache
zfs create -o com.sun:auto-snapshot=false rpool/var/lib/nfs
zfs create -o com.sun:auto-snapshot=false rpool/var/tmp
chmod 1777 /mnt/var/tmp
zfs create rpool/srv
zfs create -o canmount=off rpool/usr
zfs create rpool/usr/local
zfs create rpool/var/games
#zfs create rpool/var/lib/AccountsService
#zfs create rpool/var/lib/NetworkManager
#zfs create -o com.sun:auto-snapshot=false rpool/var/lib/docker
#zfs create rpool/var/mail
#zfs create rpool/var/snap
#zfs create rpool/var/www
zfs create -o com.sun:auto-snapshot=false rpool/tmp
chmod 1777 /mnt/tmp
mkdir /mnt/run
mount -t tmpfs tmpfs /mnt/run
mkdir /mnt/run/lock
if [ "$1" = "testing" ]; then
debootstrab bookworm /mnt
else
debootstrap bullseye /mnt
fi
mkdir /mnt/etc/zfs
cp /etc/zfs/zpool.cache /mnt/etc/zfs/
hostname zfs
hostname > /mnt/etc/hostname
cat << EOF > /mnt/etc/hosts
127.0.0.1 localhost
127.0.1.1 $(hostname -f) $(hostname)
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
EOF
#cat << EOF >> /mnt/etc/network/interfaces
#auto /e*/1=eth
#iface eth inet dhcp
#EOF
#Use Systemd-Networking
cat << EOF > /mnt/etc/systemd/network/80-dhcp.network
[Match]
Name=e*
[Network]
DHCP=yes
UseDomains=true
[DHCPv4]
ClientIdentifier=mac
EOF
if [ "$1" = "testing" ]; then
cat << EOF > /mnt/etc/apt/sources.list.d/bookworm.sources
Types: deb
URIs: http://deb.debian.org/debian-security
Suites:
bookworm-security
Components: main contrib non-free
Types: deb deb-src
URIs: http://deb.debian.org/debian
Suites:
bookworm
bookworm-updates
bookworm-proposed-updates
bookworm-backports
Components: main contrib non-free
EOF
else
cat << EOF > /mnt/etc/apt/sources.list.d/bullseye.sources
Types: deb
URIs: http://deb.debian.org/debian-security
Suites:
bullseye-security
Components: main contrib non-free
Types: deb deb-src
URIs: http://deb.debian.org/debian
Suites:
bullseye
bullseye-updates
bullseye-proposed-updates
bullseye-backports
Components: main contrib non-free
EOF
fi
rm /mnt/etc/apt/sources.list
mount --make-private --rbind /dev /mnt/dev
mount --make-private --rbind /proc /mnt/proc
mount --make-private --rbind /sys /mnt/sys
_chr() {
DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true \
LC_ALL=C LANGUAGE=C LANG=C chroot /mnt "${@}"
}
_apt() {
DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true \
LC_ALL=C LANGUAGE=C LANG=C \
chroot /mnt apt-get install -qqq --yes "${@}"
}
_chr ln -s /proc/self/mounts /etc/mtab
rm /mnt/etc/timezone /mnt/etc/localtime
echo 'Europe/Berlin' > /mnt/etc/timezone
_chr ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime
_chr dpkg-reconfigure -f noninteractive tzdata
_chr apt-get update
_apt console-setup locales
cat << EOF > /mnt/etc/default/keyboard
# KEYBOARD CONFIGURATION FILE
# Consult the keyboard(5) manual page.
XKBMODEL="pc104"
XKBLAYOUT="us"
XKBVARIANT="euro"
XKBOPTIONS="terminate:ctrl_alt_bksp"
BACKSPACE="guess"
EOF
_apt tzdata keyboard-configuration console-setup
sed -i '/en_US.UTF-8/s/^# //g' /mnt/etc/locale.gen
sed -i '/de_DE.UTF-8/s/^# //g' /mnt/etc/locale.gen
_chr locale-gen
_chr systemctl enable systemd-netword.service
_apt dpkg-dev linux-headers-generic linux-image-generic zfs-initramfs
echo REMAKE_INITRD=yes > /mnt/etc/dkms/zfs.conf
#_apt grub-pc
BOOTP="$(_find_id_by_dev "$(echo "$DISKS" |head -n 1)")-part2"
_chr apt install dosfstools
_chr mkdosfs -F 32 -s 1 -n EFI "$BOOTP"
mkdir /mnt/boot/efi
# shellcheck disable=SC2046
echo /dev/disk/by-uuid/$(blkid -s UUID -o value "$BOOTP") \
/boot/efi vfat defaults 0 0 | tee -a /mnt/etc/fstab
_chr mount /boot/efi
_apt grub-efi-amd64 shim-signed
#_chr apt-get purge --yes os-prober
echo root:INSERTCOINHERE |_chr chpasswd
cat << EOF > /mnt/etc/systemd/system/zfs-import-bpool.service
[Unit]
DefaultDependencies=no
Before=zfs-import-scan.service
Before=zfs-import-cache.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/zpool import -N -o cachefile=none bpool
# Work-around to preserve zpool cache:
ExecStartPre=-/bin/mv /etc/zfs/zpool.cache /etc/zfs/preboot_zpool.cache
ExecStartPost=-/bin/mv /etc/zfs/preboot_zpool.cache /etc/zfs/zpool.cache
[Install]
WantedBy=zfs-import.target
EOF
_chr systemctl enable zfs-import-bpool.service
_chr grub-probe /boot
_chr update-initramfs -c -k all
sed -i 's/GRUB_CMDLINE_LINUX=.*$/GRUB_CMDLINE_LINUX="root=ZFS=rpool\/ROOT\/debian"/g' /mnt/etc/default/grub
echo "GRUB_TERMINAL=console" >> /mnt/etc/default/grub
_chr update-grub
#YES MBR AND EFI BOTH... FOR NOW....
echo "$DISKS" |while read -r dev; do
_chr grub-install "/dev/$dev"
done
_chr grub-install --target=x86_64-efi --efi-directory=/boot/efi \
--bootloader-id=debian --recheck --no-floppy
_chr zfs snapshot -r bpool@install
_chr zfs snapshot -r rpool@install
#WE WANT MAC!!!
echo "send dhcp-client-identifier = hardware;" >>/mnt/etc/dhcp/dhclient.conf
rm /mnt/var/lib/dhcp/*
#MINIMAL SETUP
_apt vim-nox zsh wget curl screen tmux openssh-server
_chr chsh -s /bin/zsh
#VMWARE-TOOLS
_apt open-vm-tools
#GRMLGRMLGRMLGRMLGRML!!!!!
wget -O /mnt/root/.screenrc https://grml.org/console/screenrc
wget -O /mnt/root/.tmux.conf https://grml.org/console/tmux.conf
wget -O /mnt/root/.vimrc https://grml.org/console/vimrc
wget -O /mnt/root/.zshrc https://grml.org/console/zshrc
mkdir /mnt/etc/zfs/zfs-list.cache
touch /mnt/etc/zfs/zfs-list.cache/bpool
touch /mnt/etc/zfs/zfs-list.cache/rpool
_chr zed -F &
sleep 5
_chr zfs set canmount=on bpool/BOOT/debian
_chr zfs set canmount=noauto rpool/ROOT/debian
while true; do
if [ "$(wc -l /mnt/etc/zfs/zfs-list.cache/bpool|cut -d\ -f1)" -gt 2 ] && [ "$(wc -l /mnt/etc/zfs/zfs-list.cache/rpool|cut -d\ -f1)" -gt 5 ]; then
_chr pkill -9 zed
break
fi
done
sed -Ei "s|/mnt/?|/|" /mnt/etc/zfs/zfs-list.cache/*
awk '{print $1}' /mnt/etc/zfs/zfs-list.cache/bpool /mnt/etc/zfs/zfs-list.cache/rpool
#TESTING-PURPOSES....
sed -i 's/^#PermitRootLogin.*$/PermitRootLogin yes/g' /mnt/etc/ssh/sshd_config
cat << EOF > /mnt/etc/update-motd.d/99-sshd
#!/bin/sh
echo "########################################################"
echo "!!!!Disable PermitRootLogin in /etc/ssh/sshd_config!!!!!"
echo "########################################################"
EOF
chmod +x /mnt/etc/update-motd.d/99-sshd
#/TESTING-PURPOSES.....
_chr zfs snapshot -r rpool@"$(date +%Y%m%d-%H%M)"
#DEBUG...
echo "TIME TO UMOUNT...."
mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | xargs -I{} umount -lf {}
sleep 10
zpool export -a -f
#/DEBUG
echo "---------------------------------------------"
echo "TIME TO REBOOT?!"
echo "---------------------------------------------"
echo "In initramfs: \`zpool import -f rpool\`"
echo "after Import <Ctrl><Alt><Del> - don't exit..."
echo "---------------------------------------------"
echo "Don't forget to edit /etc/ssh/sshd_config!!!!"
ps axo pid,ruid,comm |tac |awk '/z_/ { print $1}' |while read -r pid; do
kill -9 "$pid"
done
zpool export -a
zpool list
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment