#!/bin/bash set -euo pipefail BASEDIR="$(dirname "${0}" | sed "s|^\.|${PWD}|")" printf \ '\033[?47l\012' cat << EOF ####################################### ## ## ## $(cat "${BASEDIR}/title") Script ## ## ## ## Jean ## ## ## ####################################### ################# ## ## ## Partition ## ## ## ################# EOF source \ /etc/os-release source \ "${BASEDIR}/system.conf" if [[ ! "${DISK}" == **/dev/disk/by-id/** ]]; then if [[ "${DISK}" == **/dev/nvme** ]]; then PART3='p3' else PART3='3' fi else PART3='-part3' fi if [[ "${ID}" == 'debian' ]]; then if [[ ! "$(hostname)" == "debian-live" ]]; then cat << EOF | tee /etc/apt/sources.list.d/contrib.sources 1> /dev/null Enabled: yes Types: deb URIs: http://deb.debian.org/debian/ Suites: ${VERSION_CODENAME} Components: contrib Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg EOF fi fi if [[ -f '/usr/bin/gsettings' ]]; then gsettings \ set \ org.gnome.desktop.media-handling \ automount \ false fi if [[ "${ID}" == 'debian' ]]; then apt \ update && \ apt \ install \ --yes \ mmdebstrap \ gdisk \ zfsutils-linux \ systemd-timesyncd elif [[ "${ID}" == 'fedora' ]]; then if [[ "${VERSION_ID}" -lt '41' ]]; then dnf config-manager \ --disable \ updates else dnf config-manager \ setopt \ updates.enabled=0 fi dnf install \ -y \ https://zfsonlinux.org/fedora/zfs-release-${ZOL_FEDORA_VER}$(rpm --eval "%{dist}").noarch.rpm dnf install \ -y \ https://dl.fedoraproject.org/pub/fedora/linux/releases/${VERSION_ID}/Everything/x86_64/os/Packages/k/kernel-devel-$(uname -r).rpm dnf install \ -y \ zfs \ gdisk modprobe \ zfs fi timedatectl if [[ ! "$(hostname)" == "debian-live" ]]; then zgenhostid \ -f \ 0x00bab10c fi swapoff \ --all if [[ ! "${*}" = *--no-part* ]]; then wipefs \ -a \ ${DISK} if [[ ! "${DISK_TYPE}" == 'HDD' ]]; then blkdiscard \ -f \ ${DISK} fi sgdisk \ --zap-all \ ${DISK} sgdisk \ -n1:0:+512M \ -t1:EF00 \ -c1:EFI \ ${DISK} if [[ "${ENABLE_SWAP}" == "yes" ]]; then SWAP_SIZE="$(((($(vmstat -sS M | grep 'total memory' | sed 's/ M total memory//') / 1024) + 1) * 2))" sgdisk \ -n2:0:+${SWAP_SIZE}G \ -t2:BF02 \ -c2:swap \ ${DISK} fi sgdisk \ -n3:0:0 \ -t3:BF00 \ -c3:${ID} \ ${DISK} sleep 5 if [[ "${ENCRYPTION}" == 'yes' ]]; then ZPOOL_PASSWORD='A' ZPOOL_PASSWORD_VERIFY='B' printf \ '\033[?47h\033[2J\033[H' while [[ ! "${ZPOOL_PASSWORD}" == "${ZPOOL_PASSWORD_VERIFY}" ]] || [[ -z "${ZPOOL_PASSWORD}" ]] || [[ "${#ZPOOL_PASSWORD}" -lt '8' ]]; do printf \ "\nEnter a password to encrypt your root pool (minimum 8 characters):\n" read \ -r \ -s \ ZPOOL_PASSWORD printf \ "\nVerify the password to encrypt your root pool:\n" read \ -r \ -s \ ZPOOL_PASSWORD_VERIFY if [[ ! "${ZPOOL_PASSWORD}" == "${ZPOOL_PASSWORD_VERIFY}" ]]; then printf \ "ERROR:\tPasswords do not match!\n" elif [[ -z "${ZPOOL_PASSWORD}" ]]; then printf \ "ERROR:\tPassword is empty!\n" elif [[ "${#ZPOOL_PASSWORD}" -lt '8' ]]; then printf \ "ERROR:\tPassword is too short!\n" fi done printf \ '\033[?47l' mkdir \ -p \ /etc/zfs/keys/ printf \ "${ZPOOL_PASSWORD}\n" | tee /etc/zfs/keys/${HOSTNAME,,}.key &> /dev/null chmod \ 000 \ /etc/zfs/keys/${HOSTNAME,,}.key zpool create \ -o ashift=12 \ -o autotrim=on \ -o compatibility=openzfs-2.1-linux \ -O encryption=on \ -O keylocation=file:///etc/zfs/keys/${HOSTNAME,,}.key \ -O keyformat=passphrase \ -O acltype=posixacl \ -O xattr=sa \ -O dnodesize=auto \ -O compression=zstd-3 \ -O normalization=formD \ -O relatime=on \ -O canmount=off \ -O mountpoint=/ \ -R /mnt \ ${HOSTNAME,,} \ ${DISK}${PART3} else zpool create \ -o ashift=12 \ -o autotrim=on \ -o compatibility=openzfs-2.1-linux \ -O encryption=off \ -O acltype=posixacl \ -O xattr=sa \ -O dnodesize=auto \ -O compression=zstd-3 \ -O normalization=formD \ -O relatime=on \ -O canmount=off \ -O mountpoint=/ \ -R /mnt \ ${HOSTNAME,,} \ ${DISK}${PART3} fi zfs create \ -o canmount=off \ -o mountpoint=none \ ${HOSTNAME,,}/ROOT else zpool import \ -N \ -R \ /mnt \ ${HOSTNAME,,} zfs load-key \ -r \ -L prompt \ ${HOSTNAME,,} fi zfs create \ -o canmount=noauto \ -o mountpoint=/ \ ${HOSTNAME,,}/ROOT/${ID} zfs mount \ ${HOSTNAME,,}/ROOT/${ID} if [[ ! "${*}" = *--no-part* ]]; then zfs create \ ${HOSTNAME,,}/home zfs create \ -o mountpoint=/root \ ${HOSTNAME,,}/home/root chmod \ 700 \ /mnt/root zfs create \ -o canmount=off \ -o mountpoint=/var \ ${HOSTNAME,,}/var zfs create \ -o canmount=off \ ${HOSTNAME,,}/var/lib zfs create \ ${HOSTNAME,,}/var/log zfs create \ ${HOSTNAME,,}/var/spool zfs create \ -o com.sun:auto-snapshot=false \ ${HOSTNAME,,}/var/cache zfs create \ -o com.sun:auto-snapshot=false \ ${HOSTNAME,,}/var/lib/nfs zfs create \ -o com.sun:auto-snapshot=false \ ${HOSTNAME,,}/var/tmp chmod \ 1777 \ /mnt/var/tmp zfs create \ -o mountpoint=/srv \ ${HOSTNAME,,}/srv zfs create \ -o canmount=off \ -o mountpoint=/usr \ ${HOSTNAME,,}/usr zfs create \ ${HOSTNAME,,}/usr/local zfs create \ ${HOSTNAME,,}/var/games zfs create \ ${HOSTNAME,,}/var/lib/AccountsService zfs create \ ${HOSTNAME,,}/var/lib/NetworkManager zfs create \ ${HOSTNAME,,}/var/www zfs create \ -o com.sun:auto-snapshot=false \ -o mountpoint=/tmp \ ${HOSTNAME,,}/tmp if [[ "${ENCRYPTION}" == 'yes' ]]; then zfs create \ -o com.sun:auto-snapshot=false \ -o mountpoint=/etc/zfs/keys \ ${HOSTNAME,,}/keystore fi zpool set \ bootfs=${HOSTNAME,,}/ROOT/${ID} \ ${HOSTNAME,,} else zfs mount \ ${HOSTNAME,,}/home zfs mount \ ${HOSTNAME,,}/home/root zfs mount \ ${HOSTNAME,,}/var/log zfs mount \ ${HOSTNAME,,}/var/spool zfs mount \ ${HOSTNAME,,}/var/cache zfs mount \ ${HOSTNAME,,}/var/lib/nfs zfs mount \ ${HOSTNAME,,}/var/tmp zfs mount \ ${HOSTNAME,,}/srv zfs mount \ ${HOSTNAME,,}/usr/local zfs mount \ ${HOSTNAME,,}/var/games zfs mount \ ${HOSTNAME,,}/var/lib/AccountsService zfs mount \ ${HOSTNAME,,}/var/lib/NetworkManager zfs mount \ ${HOSTNAME,,}/var/www zfs mount \ ${HOSTNAME,,}/keystore fi if [[ "${ID}" == 'fedora' ]]; then mkdir -p /run/install if [[ "${VERSION_ID}" -lt '41' ]]; then mount /dev/mapper/live-base /run/install else mount /dev/live-base /run/install fi rsync -pogAXtlHrDx \ --stats \ --exclude=/boot/efi/* \ --exclude=/etc/machine-id \ --info=progress2 \ /run/install/ /mnt fi if [[ ! "${*}" = *--no-part* ]]; then zfs create \ ${HOSTNAME,,}/var/mail chmod \ 1777 \ /mnt/tmp else zfs mount \ ${HOSTNAME,,}/var/mail fi mkdir \ -p \ /mnt/run mount \ -t \ tmpfs \ tmpfs \ /mnt/run mkdir \ -p \ /mnt/run/lock if [[ "${ID}" == 'elementary' ]]; then mmdebstrap \ --include='' \ "${UBUNTU_VERSION_CODENAME}" \ /mnt elif [[ "${ID}" == 'debian' ]]; then mmdebstrap \ --skip=check/empty \ --components=main,non-free-firmware,contrib \ --mode=root \ --format=directory \ --include=console-setup \ --include=cryptsetup \ --include=curl \ --include=dosfstools \ --include=dpkg-dev \ --include=efibootmgr \ --include=ethtool \ --include=firmware-{ast,atheros,bnx{2,2x},brcm80211,iwlwifi,libertas,linux,realtek,zd1211} \ --include=flatpak \ --include=keyboard-configuration \ --include=linux-{headers,image}-amd64 \ --include=locales \ --include=nano \ --include=network-manager \ --include=openssh-{client,server} \ --include=popularity-contest \ --include=printer-driver-all \ --include=systemd-timesyncd \ --include=tasksel \ --include=zstd \ "${VERSION_CODENAME}" \ /mnt fi printf \ "${HOSTNAME}\n" | tee /mnt/etc/hostname &> /dev/null printf \ "127.0.1.1\t${HOSTNAME}\n" | tee --append /mnt/etc/hosts &> /dev/null if [[ "${ID}" == 'debian' ]]; then NETWORK_INTERFACE=($(ip -br addr show | sed 's| .*$||g' | grep -v '^lo' | grep -v 'tailscale' | grep -v '^wg')) shopt -s extglob for ((i = 0; i < ${#NETWORK_INTERFACE[@]}; i++)); do cat << EOF | tee /mnt/etc/network/interfaces.d/${NETWORK_INTERFACE[$i]} &> /dev/null allow-hotplug ${NETWORK_INTERFACE[$i]} iface ${NETWORK_INTERFACE[$i]} inet dhcp EOF done fi if [[ "${ID}" == 'elementary' ]]; then cat </mnt/etc/apt/sources.list deb http://archive.ubuntu.com/ubuntu/ ${UBUNTU_VERSION_CODENAME} main restricted universe multiverse deb-src http://archive.ubuntu.com/ubuntu/ ${UBUNTU_VERSION_CODENAME} main restricted universe multiverse deb http://security.ubuntu.com/ubuntu/ ${UBUNTU_VERSION_CODENAME}-security main restricted universe multiverse deb-src http://security.ubuntu.com/ubuntu/ ${UBUNTU_VERSION_CODENAME}-security main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu/ ${UBUNTU_VERSION_CODENAME}-updates main restricted universe multiverse deb-src http://archive.ubuntu.com/ubuntu/ ${UBUNTU_VERSION_CODENAME}-updates main restricted universe multiverse EOF cat </mnt/etc/apt/sources.list.d/elementary.list deb https://ppa.launchpadcontent.net/elementary-os/stable/ubuntu ${UBUNTU_VERSION_CODENAME} main deb-src https://ppa.launchpadcontent.net/elementary-os/stable/ubuntu ${UBUNTU_VERSION_CODENAME} main EOF cat </mnt/etc/apt/sources.list.d/patches.list deb https://ppa.launchpadcontent.net/elementary-os/os-patches/ubuntu ${UBUNTU_VERSION_CODENAME} main deb-src https://ppa.launchpadcontent.net/elementary-os/os-patches/ubuntu ${UBUNTU_VERSION_CODENAME} main EOF elif [[ "${ID}" == 'debian' ]]; then cat << EOF | tee /mnt/etc/apt/sources.list.d/${VERSION_CODENAME}.sources &> /dev/null # ${VERSION_CODENAME^} Enabled: yes Types: deb deb-src URIs: http://deb.debian.org/debian/ Suites: ${VERSION_CODENAME} Components: main non-free-firmware contrib Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg # ${VERSION_CODENAME^} Security Enabled: yes Types: deb deb-src URIs: http://deb.debian.org/debian-security/ Suites: ${VERSION_CODENAME}-security Components: main non-free-firmware contrib Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg # ${VERSION_CODENAME^} Updates Enabled: yes Types: deb deb-src URIs: http://deb.debian.org/debian/ Suites: ${VERSION_CODENAME}-updates Components: main non-free-firmware contrib Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg EOF rm /mnt/etc/apt/sources.list fi mount \ --rbind \ /dev \ /mnt/dev mount \ --rbind \ /proc \ /mnt/proc mount \ --rbind \ /sys \ /mnt/sys cp \ /etc/hostid \ /mnt/etc/ if [[ "${ID}" == 'fedora' ]]; then mv /mnt/etc/resolv.conf \ /mnt/etc/resolv.conf.orig cp -L \ /etc/resolv.conf \ /mnt/etc fi rsync -pogAXtlHrDx \ "${BASEDIR}" \ /mnt if [[ "${ID}" == 'elementary' ]]; then rsync -pogAXtlHrDx \ /etc/skel \ /mnt/etc fi if [[ ! "${*}" = *--no-part* ]]; then if [[ -f "/etc/zfs/keys/${HOSTNAME,,}.key" ]]; then cp \ /etc/zfs/keys/${HOSTNAME,,}.key \ /mnt/etc/zfs/keys/ fi fi if [[ "${ID}" == 'elementary' ]]; then cp \ /etc/os-release \ /mnt/etc cp \ /etc/apt/trusted.gpg.d/{elementary,patches}.key.asc \ /mnt/etc/apt/trusted.gpg.d/ fi printf \ "\nNow chrooting into /mnt...\n\n" chroot \ /mnt \ bash \ --login mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | xargs -I {} umount -Rlf {} if [[ "${ID}" == 'fedora' ]]; then umount \ -nR \ /mnt fi zpool \ export \ -a printf \ '\033[?47h\033[2J\033[H' cat <