├── 18.04 manual walkthrough.md ├── README.md └── rpooler.sh /18.04 manual walkthrough.md: -------------------------------------------------------------------------------- 1 | # HOWTO install Ubuntu 18.04 to a Whole Disk Native ZFS Root Filesystem using Ubiquity GUI installer 2 | 3 | (Copied from https://github.com/zfsonlinux/pkg-zfs/wiki/HOWTO-install-Ubuntu-18.04-to-a-Whole-Disk-Native-ZFS-Root-Filesystem-using-Ubiquity-GUI-installer 5/15/2018) 4 | 5 | Currently, the Ubiquity installer in 18.04 does not support the ZFS filesystem, nor does the LiveCD environment have zfs tools preinstalled. This WIKI explains how to make the LiveCD environment ZFS capable, how to install Ubuntu to a ZFS zvol formatted as ext4, then concludes as if you are migrating an existing installation to ZFS. This method is unique to other methods because it utilizes ZFS whole disk formatting and does not require multiple hard drives. It is designed to be a guide showing the minimum effort needed to have a system JUST WORK. 6 | 7 | # System Requirements 8 | 9 | * 64-bit Ubuntu 18.04 full desktop install media (not server, netboot, or alternative) 10 | * 16Gb+ drive that is or can be completely wiped 11 | * Internet connection usable by LiveCD 12 | * 4GB memory recommended 13 | 14 | 15 | 16 | # Strategy 17 | 18 | The Ubiquity installer for 18.04 does not recognize the ZFS filesystem as a usable target, however it can be installed to a ZFS zvol then manually copied to the ZFS filesystem. 19 | 20 | It is best practice, to use devices found in "/dev/disk/by-id/", not "/dev/" when creating pools. Some prefer to use "wwn-" devices listed in this directory, however not all devices have these identifiers. Please inventory what you have in your system and use your device names in the following commands. In the examples below, we'll use a single disk "/dev/disk/by-id/ata-ST9999999999_10000000". Additionally, the ZFS pool name in this guide is "alexandria", however feel free to use any name you wish. 21 | 22 | 23 | # The Process 24 | ## Install ZFS packages to the install environment 25 | 26 | Initially, Ubuntu 18.04 LiveCD media is not ZFS aware. As you start the media, Select "Try Ubuntu", then open the terminal. First, install the zfs tools, then create a pool and a ZVOL within that pool. The example below is a single disk pool. Feel free to create mirror(s) or raidz(x) configurations if you wish. Doing so is beyond the scope of this wiki. The ZVOL is a block device that can be used just as a physical drive. Finally, we execute the Ubiquity installer. 27 | 28 | ``` 29 | Open Terminal (Ctrl+Alt+T) 30 | $ sudo su 31 | # apt install -y zfsutils 32 | # zpool create -f -o ashift=12 -O atime=off -O compression=lz4 -O normalization=formD -O recordsize=1M -O xattr=sa alexandria /dev/disk/by-id/ata-ST9999999999_10000000 33 | # zfs create -V 10G alexandria/ubuntu-temp 34 | # ubiquity --no-bootloader 35 | ``` 36 | 37 | ## Configuring the Ubiquity Installer 38 | 1. Choose any options you wish until you get to the 'Installation Type' screen. 39 | 2. Select 'Erase disk and install Ubuntu' and click 'Continue'. 40 | 3. Change the 'Select drive:' dropdown to '/dev/zd0 - 10.7 GB Unknown' and click 'Install Now'. 41 | 4. A popup summarizes your choices and asks 'Write the changes to disks?". Click 'Continue'. 42 | 5. At this point continue through the installer normally. 43 | 6. Finally, a message comes up 'Installation Complete'. Click the 'Continue Testing'. 44 | 45 | ## Copy your Ubuntu image to the ZFS filesystem 46 | 47 | In 18.04, Ubiquity does not unmount the ZVOL after it completes because it also uses it for swap space. We'll take advantage of this and continue to use its mountpoint "/target". We need to create your ZFS OS filesystem, then rsync your Ubuntu install from the ZVOL to the ZFS OS filesystem. This example shows how to contain all contents of your system in a single filesystem. If you wish to have additional filesystems, for example /home or /var, you can create them and set their mountpoints before the rsync, but this is beyond the scope of this wiki. 48 | 49 | Continuing in the terminal: 50 | ```` 51 | # zfs create alexandria/ROOT 52 | # zfs create alexandria/ROOT/ubuntu-1 53 | # rsync -avPX /target/. /alexandria/ROOT/ubuntu-1/. 54 | ```` 55 | ## Prepare your ZFS filesystem copy of Ubuntu to be ZFS aware 56 | 57 | Your ZFS filesystem needs to have ZFS support added so it can understand itself after reboot. We connect the active /proc, /dev, and /sys mounts to the ZFS filesystem copy and chroot into it. We give it a nameserver, update the repositories, and install zfs binaries. Next, we remove the root filesystem and /swapfile entries from fstab. ZFS does this mounting for us and the swapfile does not work on a filesystem that "appears to have holes." If you wish to have swap, you can create a ZVOL for swap and reference that in the fstab, however that is beyond the scope of this wiki. Finally, we remove the unused "/swapfile". 58 | ```` 59 | # for d in proc sys dev; do mount --bind /$d /alexandria/ROOT/ubuntu-1/$d; done 60 | # chroot /alexandria/ROOT/ubuntu-1 61 | # echo "nameserver 8.8.8.8" | tee -a /etc/resolv.conf 62 | # apt update 63 | # apt install -y zfs-initramfs 64 | # nano /etc/fstab ## comment out the lines for the mountpoint "/" and "/swapfile" and exit 65 | # rm /swapfile 66 | ```` 67 | 68 | ## Create a BIOS Grub partition and install Grub 69 | 70 | ZFS whole disk formatting uses GPT partitioning. In order to boot a GPT disk, you need to EFI boot with an EFI partition present, or legacy (MBR) boot with a GRUB BIOS partition present. The structure automatically created by ZFS whole disk formatting will only allow for the latter to be done. In this section, we create a tiny GRUB BIOS partition in an unused section at the beginning of the drive, then update and install grub to the disk. If you created a multi-disk pool, this should be repeat the "sgdisk" commands for all the disks in the pool, then "update-grub", followed by "grub-install" against all your disks, so they are all capable of being a boot drive. 71 | ```` 72 | # sgdisk -a1 -n2:512:2047 -t2:EF02 /dev/disk/by-id/ata-ST9999999999_10000000 73 | # update-grub 74 | # grub-install /dev/disk/by-id/ata-ST9999999999_10000000 75 | ```` 76 | ## Set Mountpoint and reboot 77 | We now exit the chroot, unmount the /dev, /sys, and /proc from /alexandria/ROOT/ubuntu-1, as well as /alexandria/ROOT/ubuntu-1 itself. We set our ZFS filesystem's mountpoint variable to /, snapshot our filesystem (optional), turn off swapfile (holds the /target mountpoint open), unmount the zvol, export our pool, then finally reboot. 78 | 79 | ```` 80 | # exit 81 | # umount -R /alexandria/ROOT/ubuntu-1 82 | # zfs set mountpoint=/ alexandria/ROOT/ubuntu-1 83 | # zfs snapshot alexandria/ROOT/ubuntu-1@pre-reboot 84 | # swapoff -a 85 | # umount /target 86 | # zpool export alexandria 87 | # shutdown -r 0 88 | ```` 89 | ## Finish installation 90 | 91 | Congratulations, you should have successfully booted Ubuntu 18.04 using ZFS as a root filesystem. Sometimes the system hangs at the Ubuntu logo screen on first boot, but it boots the second time. The remaining steps are all optional. We will do a post install snapshot, destroy the ZVOL used during the installation, and run ubuntu updates. 92 | 93 | ```` 94 | Open Terminal (Ctrl+Alt+T) 95 | $ sudo zfs snapshot alexandria/ROOT/ubuntu-1@post-reboot 96 | $ sudo zfs destroy alexandria/ubuntu-temp 97 | $ sudo apt update 98 | $ sudo apt dist-upgrade -y 99 | $ sudo zfs snapshot alexandria/ROOT/ubuntu-1@post-reboot-updates 100 | ```` 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rpooler 2 | ## A ZFS rpool wrapper for the Ubuntu 18.04 Ubiquity Installer 3 | This is a wrapper that automates the creation of a fully bootable zfs root pool with Ubuntu 18.04 installed. It was crafted off the step-by-step [HOWTO install Ubuntu 18.04 to a Whole Disk Native ZFS Root Filesystem using Ubiquity GUI installer](https://github.com/zfsonlinux/pkg-zfs/wiki/HOWTO-install-Ubuntu-18.04-to-a-Whole-Disk-Native-ZFS-Root-Filesystem-using-Ubiquity-GUI-installer). The goals are to further simplfy the installation process and encourage best practices through the guided process. 4 | 5 | Instructions: 6 | 1) Boot Ubuntu 18.04 Desktop Live CD 7 | 2) Select "Try Ubuntu" 8 | 3) Open terminal (Ctrl+Alt+t) 9 | 4) `wget https://raw.github.com/ghfields/rpooler/master/rpooler.sh` 10 | 5) `sudo bash rpooler.sh` 11 | 12 | 13 | ## What to expect when running script 14 | ``` 15 | Installer script for ZFS whole disk installation using Ubuntu GUI (Ubiquity) 16 | ---------------------------------------------------------------------------- 17 | What do you want to name your pool? 18 | rpool 19 | 20 | These are the drives on your system: 21 | /dev/disk/by-id/ata-VBOX_CD-ROM_VB2-01700376 22 | /dev/disk/by-id/ata-VBOX_HARDDISK_VB9c4c6292-31c83b83 23 | What vdev layout do you want to use? (hint: tab completion works): 24 | /dev/disk/by-id/ata-VBOX_HARDDISK_VB9c4c6292-31c83b83 25 | 26 | Which zpool & zfs options do you wish to set at creation? 27 | -o feature@multi_vdev_crash_dump=disabled -o feature@large_dnode=disabled -o feature@sha512=disabled -o feature@skein=disabled -o feature@edonr=disabled -o ashift=12 -O atime=off -O compression=lz4 -O normalization=formD -O recordsize=1M -O xattr=sa 28 | 29 | Zpool would create 'rpool' with the following layout: 30 | 31 | rpool 32 | ata-VBOX_HARDDISK_VB9c4c6292-31c83b83 33 | 34 | Does this look correct (y/n): 35 | y 36 | 37 | The Ubiquity made swapfile will not function and will be removed. 38 | Based on your system's 3.85 GB of RAM, Ubuntu suggests a swap of 2 GB. 39 | What size, in GB, should the created swap zvol be? (0 for none): 40 | 2 41 | Zvol swap size: 2 GB 42 | Is this correct (y/n): 43 | y 44 | 45 | Configuring the Ubiquity Installer 46 | ---------------------------------- 47 | 1) Choose any options you wish until you get to the 'Installation Type' screen. 48 | 2) Select 'Erase disk and install Ubuntu' and click 'Continue'. 49 | 3) Change the 'Select drive:' dropdown to '/dev/zd0 - 10.7 GB Unknown' and click 'Install Now'. 50 | 4) A popup summarizes your choices and asks 'Write the changes to disks?'. Click 'Continue'. 51 | 5) At this point continue through the installer normally. 52 | 6) Finally, a message comes up 'Installation Complete'. Click the 'Continue Testing'. 53 | This install script will continue. 54 | 55 | Press any key to launch Ubiquity. These instructions will remain visible in the terminal window. 56 | 57 | 58 | ====== 59 | Ubiquity Launches 60 | ====== 61 | 62 | (Rsync output truncated) 63 | 64 | Setting up zfs-initramfs (0.7.5-1ubuntu16.2) ... 65 | Processing triggers for libc-bin (2.27-3ubuntu1) ... 66 | Processing triggers for initramfs-tools (0.130ubuntu3.1) ... 67 | update-initramfs: Generating /boot/initrd.img-4.15.0-29-generic 68 | cp: memory exhausted 69 | Generating grub configuration file ... 70 | Found linux image: /boot/vmlinuz-4.15.0-29-generic 71 | Found initrd image: /boot/initrd.img-4.15.0-29-generic 72 | Found memtest86+ image: /ROOT/ubuntu-1@/boot/memtest86+.elf 73 | Found memtest86+ image: /ROOT/ubuntu-1@/boot/memtest86+.bin 74 | done 75 | Warning: The kernel is still using the old partition table. 76 | The new table will be used at the next reboot or after you 77 | run partprobe(8) or kpartx(8) 78 | The operation has completed successfully. 79 | Installing for i386-pc platform. 80 | Installation finished. No error reported. 81 | Would you like to create a snapshot before rebooting? : 82 | y 83 | 84 | Script complete. Please reboot your computer to boot into your installation. 85 | If first boot hangs, reset computer and try boot again. 86 | 87 | Do you want to restart now? 88 | n 89 | ``` 90 | -------------------------------------------------------------------------------- /rpooler.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | green='\e[92m' 3 | nocolor='\e[0m' 4 | echo "" 5 | echo "Installer script for ZFS whole disk installation using Ubuntu GUI (Ubiquity)" 6 | echo "----------------------------------------------------------------------------" 7 | 8 | distver=$(lsb_release -cs) 9 | if [ "$distver" != "bionic" ]; then 10 | echo "This script requires Ubuntu 18.04 to run." 11 | exit 1 12 | fi 13 | 14 | if [[ $EUID -ne 0 ]]; then 15 | echo "This script must be run as root" 16 | exit 1 17 | fi 18 | 19 | if !(apt update &> /dev/null && apt install -y zfsutils &> /dev/null); then 20 | echo "Error installing zfsutils from the internet. Please check your connection." 21 | exit 1 22 | fi 23 | 24 | while [[ $exitpoolselect == "" ]]; do 25 | echo -e $green "What do you want to name your pool? " $nocolor 26 | read -i "rpool" -e pool 27 | echo "" 28 | echo "These are the drives on your system:" 29 | for i in $(ls /dev/disk/by-id/ -a |grep -v part |awk '{if(NR>2)print}');do echo -e ' \t' "/dev/disk/by-id/"$i;done 30 | echo -e $green "What vdev layout do you want to use? (hint: tab completion works): " $nocolor 31 | read -e layout 32 | echo "" 33 | echo -e $green "Which zpool & zfs options do you wish to set at creation? " $nocolor 34 | read -i "-o feature@multi_vdev_crash_dump=disabled -o feature@large_dnode=disabled -o feature@sha512=disabled -o feature@skein=disabled -o feature@edonr=disabled -o ashift=12 -O atime=off -O compression=lz4 -O normalization=formD -O recordsize=1M -O xattr=sa" -e options 35 | echo "" 36 | echo -n "Zpool " 37 | if (zpool create -nf $options $pool $layout); then 38 | echo "" 39 | while true; do 40 | echo -e $green "Does this look correct (y/n):" $nocolor 41 | read -i "y" -e yn 42 | case $yn in 43 | [Yy]* ) exitpoolselect="1"; break;; 44 | [Nn]* ) break;; 45 | * ) echo "Please answer yes or no.";; 46 | esac 47 | done 48 | else 49 | echo "" 50 | echo "Your selections formed an invalid "zpool create" commmand. Please try again." 51 | fi 52 | done 53 | 54 | 55 | systemramk=$(free -m | awk '/^Mem:/{print $2}') 56 | systemramg=$(echo "scale=2; $systemramk/1024" | bc) 57 | suggestswap=$(printf %.$2f $(echo "scale=2; sqrt($systemramk/1024)" | bc)) 58 | 59 | while [[ $exitfilesystemselect == "" ]]; do 60 | echo "" 61 | echo "The Ubiquity made swapfile will not function and will be removed." 62 | echo "Based on your system's $systemramg GB of RAM, Ubuntu suggests a swap of $suggestswap GB." 63 | echo -e $green "What size, in GB, should the created swap zvol be? (0 for none): " $nocolor 64 | read -e -i $suggestswap swapzvol 65 | echo "Zvol swap size: $swapzvol GB" 66 | while true; do 67 | echo -e $green "Is this correct (y/n):" $nocolor 68 | read -i "y" -e yn 69 | case $yn in 70 | [Yy]* ) exitfilesystemselect="1"; break;; 71 | [Nn]* ) break;; 72 | * ) echo "Please answer yes or no.";; 73 | esac 74 | done 75 | done 76 | 77 | if !(zpool create -f $options $pool $layout); then 78 | echo "Error creating zpool. Terminating Script." 79 | exit 1 80 | fi 81 | 82 | if !(zfs create -V 10G $pool/ubuntu-temp); then 83 | echo "Error creating ZVOL. Terminating Script." 84 | exit 1 85 | fi 86 | 87 | echo "" 88 | echo "Configuring the Ubiquity Installer" 89 | echo "----------------------------------" 90 | echo -e ' \t' "1) Choose any options you wish until you get to the 'Installation Type' screen." 91 | echo -e ' \t' "2) Select 'Erase disk and install Ubuntu' and click 'Continue'." 92 | echo -e ' \t' "3) Change the 'Select drive:' dropdown to '/dev/zd0 - 10.7 GB Unknown' and click 'Install Now'." 93 | echo -e ' \t' "4) A popup summarizes your choices and asks 'Write the changes to disks?'. Click 'Continue'." 94 | echo -e ' \t' "5) At this point continue through the installer normally." 95 | echo -e ' \t' "6) Finally, a message comes up 'Installation Complete'. Click the 'Continue Testing'." 96 | echo -e ' \t' "This install script will continue." 97 | echo "" 98 | read -p "Press any key to launch Ubiquity. These instructions will remain visible in the terminal window." 99 | 100 | if !(ubiquity --no-bootloader); then 101 | echo "Ubiquity Installer failed to complete. Terminating Script." 102 | exit 1 103 | fi 104 | 105 | while [[ $exitrootselect == "" ]]; do 106 | echo -e $green "Where on your pool do you want your root dataset? " $nocolor 107 | echo -e "$pool\c" 108 | read -i "/ROOT/ubuntu-1" -e root 109 | echo "" 110 | while true; do 111 | echo -e $green "Create root dataset at $pool$root." $nocolor 112 | echo -e $green "Is this correct (y/n):" $nocolor 113 | read -i "y" -e yn 114 | case $yn in 115 | [Yy]* ) exitrootselect="1"; break;; 116 | [Nn]* ) break;; 117 | * ) echo "Please answer yes or no.";; 118 | esac 119 | done 120 | done 121 | 122 | zfs create -p $pool$root 123 | 124 | if !(rsync -avPX --exclude '/swapfile' /target/. /$pool$root/.); then 125 | echo "Rsync failed to complete. Terminating Script." 126 | exit 1 127 | fi 128 | 129 | for d in proc sys dev; do mount --bind /$d /$pool$root/$d; done 130 | 131 | cp /etc/resolv.conf /$pool$root/etc/resolv.conf 132 | sed -e '/\s\/\s/ s/^#*/#/' -i /$pool$root/etc/fstab #My take at comment out / line. 133 | sed -e '/\sswap\s/ s/^#*/#/' -i /$pool$root/etc/fstab #My take at comment out swap line. 134 | 135 | if [[ $swapzvol -ne 0 ]]; then 136 | zfs create -V "$swapzvol"G -b $(getconf PAGESIZE) -o compression=zle \ 137 | -o logbias=throughput -o sync=always \ 138 | -o primarycache=metadata -o secondarycache=none \ 139 | -o com.sun:auto-snapshot=false $pool/swap 140 | mkswap -f /dev/zvol/$pool/swap 141 | echo RESUME=none > /$pool$root/etc/initramfs-tools/conf.d/resume 142 | echo /dev/zvol/$pool/swap none swap defaults 0 0 >> /$pool$root/etc/fstab 143 | fi 144 | 145 | chroot /$pool$root apt update 146 | chroot /$pool$root apt install -y zfs-initramfs 147 | chroot /$pool$root update-grub 148 | drives="$(echo $layout | sed 's/\S*\(mirror\|raidz\|log\|spare\|cache\)\S*//g')" 149 | for i in $drives; do 150 | chroot /$pool$root sgdisk -a1 -n2:512:2047 -t2:EF02 $i 151 | chroot /$pool$root grub-install $i 152 | done 153 | 154 | umount -R /$pool$root 155 | zfs set mountpoint=/ $pool$root 156 | 157 | while true; do 158 | echo -e $green 'Would you like to create a snapshot before rebooting? : ' $nocolor 159 | read -i "y" -e yn 160 | case $yn in 161 | [Yy]* ) zfs snapshot $pool$root@install-pre-reboot; break;; 162 | [Nn]* ) break;; 163 | * ) echo "Please answer yes or no.";; 164 | esac 165 | 166 | done 167 | swapoff -a 168 | umount /target 169 | zfs destroy $pool/ubuntu-temp 170 | zpool export $pool 171 | echo "" 172 | echo "Script complete. Please reboot your computer to boot into your installation." 173 | echo "If first boot hangs, reset computer and try boot again." 174 | echo "" 175 | 176 | while true; do 177 | echo -e $green 'Do you want to restart now? ' $nocolor 178 | read -i "y" -e yn 179 | case $yn in 180 | [Yy]* ) shutdown -r 0; break;; 181 | [Nn]* ) break;; 182 | * ) echo "Please answer yes or no.";; 183 | esac 184 | 185 | done 186 | exit 0 187 | --------------------------------------------------------------------------------