/be-enter

Automatically create a new zfs boot environment with zedenv or beadm and chroot it

Primary LanguageShellMIT LicenseMIT

README for be-enter

What’s this?

I made this quick little bash script because I wanted the ability to:

  • create, mount and chroot new boot environments automatically (utilizing the Linux beadm port or zedenv)
  • optionally use bind mounts
  • umount with the option to immediately activate the boot environment and reboot.

Personally, I use this script to safely automate my workflow. I typically run my personal update-gentoo script inside the chroot, and then reboot into the latest Gentoo.

Here’s a proof of concept:

root ~ # be-enter test
Boot environment doesn't exist test.

test doesn't exist! create test now? (Y or N) y
** creating boot environment "test" ...
** updating bootloader ...  # honestly the output is much noisier than this. ;)

(chroot) # ./update-gentoo  # (run my gentoo automation script)
(chroot) # rm -rf /         # run experimental command
(chroot) # exit
logout

activate and reboot into "test" NOW? (Y or N) n

root ~ # # ZFS Rocks o/
root ~ #

In the above example, had “test” already existed, it would’ve simply mounted and chrooted– no questions asked. If you provide no name at all and simply type “be-enter”, it will generate a name using the value of $BE_NAME_AUTO.

How it works

Configure three variables at the top of the script:

# beadm or zedenv to be used for create/mount ?
BE_TOOL="zedenv"

# boot environment name format used if not given explicitly via $1
BE_NAME_AUTO="GENTOO-17.1-$(date +%Y%m%d%H%M)"

# [optional] bind mounts array - specify directories to be shared between host and chroot.
# e.g if portage or ccache live on a separate datset
# BIND_MOUNTS=("/usr/portage" "/gentoo/ccache")

Requirements

be-enter is written for Linux in bash and requires a working zfs-on-root installation with zedenv and / or beadm already installed.

Compatibility

be-enter is tested with the following version of beadm: https://github.com/TemptorSent/beadm

and of course zedenv: https://github.com/johnramsden/zedenv

Tips and Tricks

Change root’s PS1 to be chroot-aware

I recommend placing the following line in root’s .bashrc to automatically see the prompt is chroot’ed.

if [ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]; then export PS1="(chroot) $PS1"; fi

Even if you don’t use zedenv

I still recommend installing it and using zedenv-grub so that you may have nicely generated menuentries for each boot environment.

How to install zedenv

There are good instructions on https://zedenv.readthedocs.io/en/latest/ and https://github.com/johnramsden/zedenv

I recommend using a legacy bios and GRUB configuration, because it is easy to install the bootloader on multiple disks that are all basically plug-and-play, making for good and simple redundancy. So I also recommend using the https://github.com/johnramsden/zedenv-grub plugin.

Depending on experience, zedenv instructions might sound complicated– this script is pretty much the way I install zedenv: https://github.com/a-schaefers/dotfiles/blob/gentoo/root-scripts/zedenv-install

Debug

  • Zedenv and beadm leave behind empty directories after unmounting.

This can cause be-enter to fail if they are not removed. be-enter tries to work around this, but doesn’t bend over backwards.

  • Beadm might have trouble mounting boot environments that were created by zedenv.

Beadm will not mount a dataset with canmount=off , and zedenv by default uses canmount=off instead of canmount=noauto while managing boot environments. There may be other issues. Rule of thumb: pick a tool and stick with it.

  • Zedenv might have trouble destroying boot environments that were created by beadm

Haven’t looked into this yet. Looks to be another edge case. Just pick a tool and stick with it…