#! /bin/bash
echo ""
echo "Updating local packages..."
errors = ` apt-add-repository universe >/dev/null 2>/dev/null && apt update 2>& 1 >/dev/null`
if [ " $? " = "0" ] ; then
echo "Done."
else
echo " Failed to add universal repository, update apt repository - $errors "
exit 1
fi
echo ""
echo "Installing required setup configuration utilities..."
apt install -y dialog net-tools gdisk zfs-initramfs debootstrap >/dev/null 2>/dev/null
if [ " $? " = "0" ] ; then
echo "Done."
else
echo "Failed to install net-tools, gdisk, zfs-initramfs, or debootstrap."
exit 2
fi
#calculate width and height of console
width = ` tput cols`
height = ` tput lines`
window = $(( height - 5 ))
# gather input at the start
devices = "" ; for device in $( ls /dev/disk/by-id | grep -v part) ; do devices = " $devices $device off " ; done
disks = ` dialog --separate-output --no-cancel --no-items --title "Root devices" --checklist "Select boot drives" $height $width ${ window } $devices 2>& 1 1>/dev/tty`
raidtype = ` dialog --no-items --no-cancel --title "Root pool ZFS RAID" --radiolist "Select root pool ZFS RAID type" 12 35 5 raidz off raidz2 off raidz3 off mirror off none off 2>& 1 1>/dev/tty`
hostname = "" ; while [ -z " $hostname " ] ; do hostname = ` dialog --no-cancel --inputbox "Host name/Server name" 8 100 2>& 1 >/dev/tty` ; done
nicdevices = "" ; for nic in $( ip -o link show | awk -F': ' '{print $2}' | grep -v '^lo' ) ; do nicdevices = " $nicdevices $nic off " ; done
nics = ` dialog --separate-output --no-cancel --no-items --title "Network devices for bridge" --checklist "Select the network devices to be bridged" $height $width ${ window } $nicdevices 2>& 1 1>/dev/tty`
rootpassword = ` dialog --no-cancel --title "Root password" --insecure --passwordbox "Enter root password" $height $width 2>& 1 1>/dev/tty`
timezone = ` dialog --no-cancel --title "Timezone" --inputbox "Enter time zone" $height $width "America/Los_Angeles" 2>& 1 1>/dev/tty`
admin = "" ; while [ -z " $admin " ] ; do admin = ` dialog --no-cancel --inputbox "Admin account/first user (with sudo capability)" 8 100 2>& 1 >/dev/tty` ; done
for disk in ` echo " $disks " ` ; do
echo ""
echo " Partitioning disk $disk ... "
errors = ` sgdisk --zap-all /dev/disk/by-id/$disk 2>& 1 1>/dev/null && sgdisk -n2:1M:+512M -t2:EF00 /dev/disk/by-id/$disk 2>& 1 1>/dev/null && sgdisk -n3:0:+512M -t3:BF01 /dev/disk/by-id/$disk 2>& 1 1>/dev/null && sgdisk -n4:0:0 -t4:BF01 /dev/disk/by-id/$disk 2>& 1 1>/dev/null`
if ! [ " $? " = "0" ] ; then
echo " Failed to partition disk $disk - $errors "
exit 3
fi
echo "Done."
done
# create boot mirror list
bootmirror = "" ; rootraidz = "" ; for disk in ` echo " $disks " ` ; do bootmirror = " $bootmirror /dev/disk/by-id/ ${ disk } -part3 " ; rootraidz = " $rootraidz /dev/disk/by-id/ ${ disk } -part4 " ; done
# refresh drives or there are missing partitions
partprobe 2>/dev/null 1>/dev/null
echo ""
echo "Creating boot zpool..."
errors = ` zpool create -f -o ashift = 12 -d -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@lz4_compress= enabled -o feature@spacemap_histogram= enabled -o feature@userobj_accounting= enabled -O acltype = posixacl -O canmount = off -O compression = lz4 -O devices = off -O normalization = formD -O relatime = on -O xattr = sa -O mountpoint = / -R /mnt bpool mirror$bootmirror 2>& 1 1>/dev/null`
if ! [ " $? " = "0" ] ; then
echo " Failed to create boot pool - $errors "
exit 4
fi
echo "Done."
# special exception for none raid - this just operates the disks like a stripe, for 1 or more disk - *not* recommended
if [ " $raidtype " = "none" ] ; then
raidtype = ""
else
raidtype = " $raidtype "
fi
echo ""
echo "Creating main zpool..."
error = ` zpool create -f -o ashift = 12 -O acltype = posixacl -O canmount = off -O compression = lz4 -O dnodesize = auto -O normalization = formD -O relatime = on -O xattr = sa -O mountpoint = / -R /mnt rpool${ raidtype } ${ rootraidz } 2>& 1 1>/dev/null`
if ! [ " $? " = "0" ] ; then
echo " Failed to create main pool - $errors "
exit 5
fi
echo "Done."
echo ""
echo "Setting up main zpool dataset configuration..."
errors = ` zfs create -o canmount = off -o mountpoint = none rpool/ROOT 2>& 1 1>/dev/null && zfs create -o canmount = off -o mountpoint = none bpool/BOOT 2>& 1 1>/dev/null && zfs create -o canmount = noauto -o mountpoint = / rpool/ROOT/ubuntu 2>& 1 1>/dev/null && zfs mount rpool/ROOT/ubuntu 2>& 1 1>/dev/null && zfs create -o canmount = noauto -o mountpoint = /boot bpool/BOOT/ubuntu 2>& 1 1>/dev/null && zfs mount bpool/BOOT/ubuntu 2>& 1 1>/dev/null && zfs create rpool/home 2>& 1 1>/dev/null && zfs create -o mountpoint = /root rpool/home/root 2>& 1 1>/dev/null && zfs create -o canmount = off rpool/var 2>& 1 1>/dev/null && zfs create -o canmount = off rpool/var/lib 2>& 1 1>/dev/null && zfs create rpool/var/log 2>& 1 1>/dev/null && zfs create rpool/var/spool 2>& 1 1>/dev/null && zfs create -o com.sun:auto-snapshot= false rpool/var/cache 2>& 1 1>/dev/null && zfs create -o com.sun:auto-snapshot= false rpool/var/tmp 2>& 1 1>/dev/null && chmod 1777 /mnt/var/tmp 2>& 1 1>/dev/null && zfs create rpool/opt 2>& 1 1>/dev/null && zfs create rpool/srv 2>& 1 1>/dev/null && zfs create -o canmount = off rpool/usr 2>& 1 1>/dev/null && zfs create rpool/usr/local 2>& 1 1>/dev/null && zfs create rpool/var/mail 2>& 1 1>/dev/null && zfs create -o com.sun:auto-snapshot= false rpool/var/lib/docker 2>& 1 1>/dev/null && zfs create -o com.sun:auto-snapshot= false rpool/var/lib/nfs 2>& 1 1>/dev/null && zfs create -o com.sun:auto-snapshot= false rpool/tmp 2>& 1 1>/dev/null && chmod 1777 /mnt/tmp 2>& 1 1>/dev/null`
if ! [ " $? " = "0" ] ; then
echo " Error setting up ZFS settings - $errors "
exit 5
fi
echo "Done."
echo ""
echo "Starting debian bootstrap - this can take some time..."
debootstrap bionic /mnt
#errors=`debootstrap bionic /mnt 2>&1 1>/dev/null`
if ! [ " $? " = "0" ] ; then
echo " Failed to bootstrap root - $errors "
exit 6
fi
echo "Done."
echo ""
echo "Disabling ZFS devices..."
errors = ` zfs set devices = off rpool 2>& 1 1>/dev/null`
if ! [ " $? " = "0" ] ; then
echo " Failed to set devices=off for root pool- $errors "
exit 7
fi
echo "Done."
echo ""
echo "Setting hostname..."
echo " $hostname " > /mnt/etc/hostname
echo " 127.0.1.1 $hostname " >> /mnt/etc/hosts
echo "Done."
echo ""
echo "Setting default apt repositories"
echo "deb http://archive.ubuntu.com/ubuntu bionic main universe" > /mnt/etc/apt/sources.list
echo "deb-src http://archive.ubuntu.com/ubuntu bionic main universe" >> /mnt/etc/apt/sources.list
echo "deb http://security.ubuntu.com/ubuntu bionic-security main universe" >> /mnt/etc/apt/sources.list
echo "deb-src http://security.ubuntu.com/ubuntu bionic-security main universe" >> /mnt/etc/apt/sources.list
echo "deb http://archive.ubuntu.com/ubuntu bionic-updates main universe" >> /mnt/etc/apt/sources.list
echo "deb-src http://archive.ubuntu.com/ubuntu bionic-updates main universe" >> /mnt/etc/apt/sources.list
echo "Done."
# network configuration should have optional static configuration - not just DHCP, it's very important
echo ""
echo "Writing netplan file"
macaddr = $( echo $hostname | md5sum| sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' )
echo "network:" > /mnt/etc/netplan/bridge.yaml
echo " version: 2" >> /mnt/etc/netplan/bridge.yaml
echo " renderer: networkd" >> /mnt/etc/netplan/bridge.yaml
echo " ethernets:" >> /mnt/etc/netplan/bridge.yaml
for nic in " $nics " ; do
echo " ${ nic } : " >> /mnt/etc/netplan/bridge.yaml
echo " dhcp4: no" >> /mnt/etc/netplan/bridge.yaml
done
echo " bridges:" >> /mnt/etc/netplan/bridge.yaml
echo " br0:" >> /mnt/etc/netplan/bridge.yaml
echo " macaddress: ${ macaddr } " >> /mnt/etc/netplan/bridge.yaml
echo " dhcp4: yes" >> /mnt/etc/netplan/bridge.yaml
echo " parameters:" >> /mnt/etc/netplan/bridge.yaml
echo " stp: true" >> /mnt/etc/netplan/bridge.yaml
echo " interfaces:" >> /mnt/etc/netplan/bridge.yaml
for nic in ` echo " $nics " ` ; do
echo " - ${ nic } " >> /mnt/etc/netplan/bridge.yaml
done
echo "Done."
echo ""
echo "Setting up bpoo import service"
echo "[Unit]\n DefaultDependencies=no" > /mnt/etc/systemd/system/zfs-import-bpool.service
echo " Before=zfs-import-scan.service" >> /mnt/etc/systemd/system/zfs-import-bpool.service
echo " Before=zfs-import-cache.service" >> /mnt/etc/systemd/system/zfs-import-bpool.service
echo "" >> /mnt/etc/systemd/system/zfs-import-bpool.service
echo "[Service]" >> /mnt/etc/systemd/system/zfs-import-bpool.service
echo " Type=oneshot" >> /mnt/etc/systemd/system/zfs-import-bpool.service
echo " RemainAfterExit=yes" >> /mnt/etc/systemd/system/zfs-import-bpool.service
echo " ExecStart=/sbin/zpool import -N -o cachefile=none bpool" >> /mnt/etc/systemd/system/zfs-import-bpool.service
echo "[Install]" >> /mnt/etc/systemd/system/zfs-import-bpool.service
echo " WantedBy=zfs-import.target " >> /mnt/etc/systemd/system/zfs-import-bpool.service
chmod +x /mnt/etc/systemd/system/zfs-import-bpool.service
echo "Done."
echo ""
echo "Mounting chroot mounts..."
mount --rbind /dev /mnt/dev
mount --rbind /proc /mnt/proc
mount --rbind /sys /mnt/sys
echo "Done."
echo "Entering chroot..."
echo "#! /bin/bash" > /mnt/setup-chroot.sh
echo "echo \"\"" >> /mnt/setup-chroot.sh
echo "echo \"Mounting /proc/self/mounts...\"" >> /mnt/setup-chroot.sh
echo "ln -s /proc/self/mounts /etc/mtab" >> /mnt/setup-chroot.sh
echo "echo \"Done.\"" >> /mnt/setup-chroot.sh
echo "echo \"\"" >> /mnt/setup-chroot.sh
echo "echo \"Updating apt repositories inside chroot...\"" >> /mnt/setup-chroot.sh
echo "apt update" >> /mnt/setup-chroot.sh
#echo "errors=`apt update 2>&1 1>/dev/null`" >> /mnt/setup-chroot.sh
echo 'if ! [ "$?" = "0" ]; then ' >> /mnt/setup-chroot.sh
echo " echo \"Failed to update apt repositories inside chroot - \$errors\"" >> /mnt/setup-chroot.sh
#echo " exit 1">> /mnt/setup-chroot.sh
echo "fi" >> /mnt/setup-chroot.sh
echo "echo \"Done.\"" >> /mnt/setup-chroot.sh
echo "echo \"\"" >> /mnt/setup-chroot.sh
echo "echo \"Setting locale...\"" >> /mnt/setup-chroot.sh
echo "locale-gen en_US.UTF-8" >> /mnt/setup-chroot.sh
#echo "echo 'LANG=\"en_US.UTF-8\"' > /etc/default/locale" >> /mnt/setup-chroot.sh
#echo "echo 'LANGUAGE=\"en_US:en\"' >> /etc/default/locale">> /mnt/setup-chroot.sh
echo "echo \"Done.\"" >> /mnt/setup-chroot.sh
echo " cp /usr/share/zoneinfo/ $timezone /etc/localtime " >> /mnt/setup-chroot.sh
echo "apt install -y --no-install-recommends linux-image-generic" >> /mnt/setup-chroot.sh
echo "apt install -y vim bash screen tmux zfs-initramfs dosfstools openssh-server" >> /mnt/setup-chroot.sh
echo "i=\"0\"" >> /mnt/setup-chroot.sh
echo "for disk in \"\$disks\"; do" >> /mnt/setup-chroot.sh
echo " echo \"mkdosfs -F 32 -s 1 -n EFI /dev/disk/by-id/ ${ disk } -part2\" " >> /mnt/setup-chroot.sh
echo " echo \"mkdir /boot/efi\${i}\"" >> /mnt/setup-chroot.sh
echo " echo \"echo PARTUUID= $( blkid -s PARTUUID -o value /dev/disk/by-id/\$ { disk} -part2) /boot/efi\${i} vfat nofail,x-systemd.device-timeout=0 0 1 >> /etc/fstab\" " >> /mnt/setup-chroot.sh
echo " echo \"mount /boot/efi\${i}\"" >> /mnt/setup-chroot.sh
echo " i= $(( i + 1 )) " >> /mnt/setup-chroot.sh
echo "done" >> /mnt/setup-chroot.sh
echo "apt install -y grub-efi-amd64-signed shim-signed" >> /mnt/setup-chroot.sh
echo " echo 'root: ${ rootpassword } ' | chpasswd " >> /mnt/setup-chroot.sh
echo "systemctl enable zfs-import-bpool.service" >> /mnt/setup-chroot.sh
echo "exit 0" >> /mnt/setup-chroot.sh
#cp /usr/sharesystemd/tmp.mount /etc/systemd/system/
#systemctl enable tmp.mount
#addgroup --system lpadmin
#addgroup --system sambashare
echo "echo \"Checking ZFS root...\"" >> /mnt/setup-chroot.sh
echo "zfscheck=`grub-probe /boot 2>&1 1>/dev/null`" >> /mnt/setup-chroot.sh
echo "if ! [ \"\$?\" = \"0\" ]; then echo \"grub-probe check failed - \$zfscheck\"; exit 2; fi" >> /mnt/setup-chroot.sh
echo "echo \"Success.\"" >> /mnt/setup-chroot.sh
echo "update-initramfs -u -k all" >> /mnt/setup-chroot.sh
# you need sed to do this right!
# GRUB_CMDLINE_LINUX="root=ZFS=rpool/ROOT/ubuntu" <--- replace this
echo "update-grub" >> /mnt/setup-chroot.sh
echo "i=\"0\"" >> /mnt/setup-chroot.sh
echo " for f in \" $disks \"; do " >> /mnt/setup-chroot.sh
echo " grub-install --target=x86_64-efi --efi-directory=/boot/efi ${ i } --botloader-id=ubuntu --recheck --no-floppy " >> /mnt/setup-chroot.sh
echo " umount /boot/efi ${ i } " >> /mnt/setup-chroot.sh
echo " i= $(( i + 1 )) " >> /mnt/setup-chroot.sh
echo "done" >> /mnt/setup-chroot.sh
echo "zfs set mountpoint=legacy bpool/BOOT/ubuntu" >> /mnt/setup-chroot.sh
echo "echo \"bpool/BOOT/ubuntu /boot zfs nodev,relatime,x-systemd.requires=zfs-import-bpool.service 0 0\" >> /etc/fstab" >> /mnt/setup-chroot.sh
echo "zfs set mountpoint=legacy rpool/var/log" >> /mnt/setup-chroot.sh
echo "echo \"rpool/var/log /var/log zfs nodev,relatime 0 0\" >> /etc/fstab" >> /mnt/setup-chroot.sh
echo "zfs set mountpoint=legacy rpool/var/spool" >> /mnt/setup-chroot.sh
echo "echo \"rpool/var/spool /var/spool zfs nodev,relatime 0 0\" >> /etc/fstab" >> /mnt/setup-chroot.sh
echo "zfs set mountpoint=legacy rpool/var/tmp" >> /mnt/setup-chroot.sh
echo "echo \"rpool/var/tmp /var/tmp zfs nodev,relatime 0 0\" >> /etc/fstab" >> /mnt/setup-chroot.sh
echo "zfs set mountpoint=legacy rpool/tmp" >> /mnt/setup-chroot.sh
echo "echo \"rpool/tmp /tmp zfs nodev,relatime 0 0\" >> /etc/fstab" >> /mnt/setup-chroot.sh
echo "systemctl enable ssh" >> /mnt/setup-chroot.sh
# create parker user automated way
echo " zfs create rpool/home/ $admin " >> /mnt/setup-chroot.sh
echo " useradd $admin " >> /mnt/setup-chroot.sh
echo " cp -a /etc/skel/.[!.]* /home/ $admin " >> /mnt/setup-chroot.sh
echo " chown -R ${ admin } : ${ admin } /home/ $admin " >> /mnt/setup-chroot.sh
echo " usermod -a -G adm,cdrom,dip,plugdev,sudo $admin " >> /mnt/setup-chroot.sh
echo " echo ' ${ admin } : ${ rootpassword } ' | chpasswd " >> /mnt/setup-chroot.sh
#create swap space, too if necessary
#exit 0
chmod +x /mnt/setup-chroot.sh
echo "Done."
chroot /mnt /setup-chroot.sh
#--login
#echo ""
#echo "Clearing chroot configuration script..."
#rm /mnt/setup-chroot.sh
#echo "Done."
#echo ""
#echo "Unmounting chroot mounts..."
#mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | xargs -i{} umount -lf {}
#echo "Done."
#echo ""
#echo "Exporting zpools..."
#errors=`zpool export -a 2>&1 1>/dev/null`
#if ! [ "$?" = "0" ]; then
# echo "Couldn't export mounted zpools - $errors"
# exit 8
#fi
#echo "Done."
#echo "Please reboot - and set your boot device in the BIOS"
exit 0