Because /etc/schroot/schroot.conf only has a bad zfs example and i couldn't find anything useful for schroot and ZFS

AUTOMATIC SETUP / RECREATION

This script will destroy the chroot if it either doesn't find the configuration, dataset or run into any problems while doing it's thing.

   1 #!/usr/bin/env sh
   2 # shellcheck disable=SC2046,SC2091
   3 test -n "$DEBUGTHISSHIT" && set -x
   4 set -e
   5 # if those fail we are done here 
   6 zpool -V >/dev/null
   7 zfs -V >/dev/null
   8 
   9 #set -n
  10 if [ "$1" = "-h" ]; then
  11         echo "to preserve any exported SCHROOT_* vars run me directly with sudo -E"
  12         echo "or: SCHROOT_FOO=MOO .. $0"
  13         echo "Available overrides:"
  14         grep '{SCHROOT_' "$(realpath "$0")" |grep -v grep
  15         exit 0
  16 fi
  17 # don't bother...
  18 if [ $(id -u) -ne 0 ]; then
  19         #exec sudo --preserve-env=CREATECHROOTS "$0"
  20         exec sudo --preserve-env "$0"
  21 fi
  22 #
  23 # recreate if chroot older than N seconds 
  24 # 604800=7d 86400=1d ... 
  25 RECREATETIME="${SCHROOT_RECREATETIME:-604800}"
  26 # prefix - e.g. /src/chroot/$prefix/sid - defaults to schroot
  27 # # NOW THAT IS DUMB FOR SBUILD... it should be suffix -sbuild by default /รถ\
  28 PREFIX="${SCHROOT_PREFIX:-}"
  29 SUFFIX="${SCHROOT_SUFFIX:-}"
  30 # https://wiki.debian.org/ReleaseCodenames
  31 # space delimited
  32 RELEASES="${SCHROOT_RELEASES:-bullseye bookworm trixie sid}"
  33 # comma delimited
  34 COMPONENTS="${SCHROOT_COMPONENTS:-main,contrib,non-free-firmware,non-free}"
  35 # will be appended to $includes / comma delimited
  36 # make sure it's available in the release or integrate an madison.cgi check
  37 INCLUDE="${SCHROOT_INCLUDE:-dh-vim-addon,dh-consoledata,dh-cmake,dh-make,zsh,auto-apt-proxy,iproute2,less}"
  38 # poolname - defaults to 'rpool'
  39 POOL="${SCHROOT_POOL:-}"
  40 # basedataset - defaults to 'srv/chroot'
  41 BASE="${SCHROOT_BASE:-}"
  42 # variant - defaults to 'buildd'
  43 VARIANT="${SCHROOT_VARIANT:-}"
  44 # mode - defaults to 'unshare'
  45 MODE="${SCHROOT_MODE:-}"
  46 # Should i create synlinks in /etc/sbuild/chroot?
  47 # We don't want that for the $suite-$arch-sbuild default stuff!
  48 SBUILD_LINK="${SCHROOT_SBUILD_LINK:-false}"
  49 # don't break my well managed chroots just by executing this nonsense!
  50 # create fstab entries?
  51 FSTAB="${SCHROOT_FSTAB:-true}"
  52 if [ -z "${CREATECHROOTS}" ]; then
  53         echo "run export CREATECHROOTS=1 and try again"
  54         exit 1
  55 fi
  56 # way too much fiddle w/o uid=0
  57 # if [ -z "${SUDO_USER}" ]; then
  58 #       echo "Not running via sudo, please provide a username: "
  59 #       read -r SUDO_USER
  60 #       SUDO_UID=$(id -u "$SUDO_USER"); test "$SUDO_UID" -le 999 || exit 1
  61 #       SUDO_GID=$(id -g "$SUDO_USER"); test "$SUDO_GID" -le 999 || exit 1
  62 # fi
  63 # safeguards.. kinda..
  64 if [ -n "$PREFIX" ]; then
  65         PREFIX="${PREFIX##*/}"
  66 fi
  67 if [ -n "$SUFFIX" ]; then
  68         SUFFIX="${SUFFIX%%/*}"
  69 fi
  70 prefix="${PREFIX:-schroot}"
  71 suffix="${SUFFIX:-sbuild}"
  72 # install missing dependencies if needed but at least ask for ocnfirmation.
  73 if ! dpkg-query -W sbuild schroot mmdebstrap auto-apt-proxy distro-info >/dev/null 2>&1; then
  74         apt-get install schroot sbuild mmdebstrap auto-apt-proxy distro-info
  75 fi
  76 
  77 # put yourself to the sbuild group
  78 if ! $(getent group sbuild|grep -q "$SUDO_USER"); then
  79         sbuild-adduser "$SUDO_USER"
  80 fi
  81 
  82 # TABULA RASA
  83 destroy() {
  84         if grep -q systemd /proc/1/comm; then
  85                 systemctl daemon-reload
  86         fi
  87         if $(mount -l -t zfs|grep -q "${mountroot:?}/${name:?}"); then
  88                 umount -vf "${mountroot:?}/${name:?}" || :
  89         fi
  90         if zfs list -H -o name "${dataset:?}"; then
  91                 zfs destroy -rfv "${dataset:?}" || :
  92         fi
  93         if [ -d "${mountroot:?}/${name:?}" ]; then
  94                 rm -Rfv "${mountroot:?}/${name:?}" || :
  95         fi
  96         if [ -L /etc/sbuild/chroot/"${configfile##*/}" ]; then
  97                 rm /etc/sbuild/chroot/"${configfile##*/}"
  98         fi
  99         if [ -f "${configfile##*/}" ]; then
 100                 rm "${configfile##*/}"
 101         fi
 102         if ! grep -qxF -- "${fstabline:?}" /etc/fstab; then
 103                 match="$(echo "$basedataset/$release-$arch"| sed 's,\/,\\\/,g')"
 104                 sed -i '/^'"$match"'/d' /etc/fstab
 105         fi
 106 }
 107 undo() {
 108         [ $? -eq 0 ] && exit
 109         set -x
 110         destroy
 111         set +x
 112 }
 113 
 114 trap undo INT HUP
 115 
 116 includes="systemd-sysv,debhelper,eatmydata"
 117 if [ -n "$INCLUDE" ]; then
 118         includes="${includes:?},$INCLUDE"
 119 fi
 120 arch=$(dpkg --print-architecture)
 121 pool="${POOL:-rpool}"
 122 base="${pool:?}/${BASE:-srv/chroot}"
 123 variant="${VARIANT:-buildd}"
 124 mode="${MODE:-unshare}"
 125 if ! zfs list -H -o name "$base">/dev/null; then
 126         echo "Base Dataset must be created by you: ${base:?}"
 127         exit 1;
 128 fi
 129 basedataset="${base:?}/${prefix:?}"
 130 if ! [ -d '/srv/chroot' ]; then echo "mountroot not available"; exit 1; fi
 131 mountroot=/srv/chroot/"${prefix:?}"
 132 mkdir -p "${mountroot:?}"
 133 if test -z $(zfs list -H -o name "${basedataset:?}"); then
 134         zfs create -v "$basedataset"
 135 fi
 136 # be able to make snapshots w/o sudo/root
 137 zfs allow -s @schroot \
 138         allow,create,snapshot,destroy,rename,rollback,diff,clone,mount,promote,refreservation \
 139         "$basedataset"
 140 
 141 zfs allow "$SUDO_USER" @schroot "$basedataset"
 142 chown "$SUDO_UID":"$SUDO_GID" "$mountroot"
 143 # shellcheck disable=SC2086
 144 set -- $RELEASES
 145 for release in "$@"; do
 146         name="${release}-${arch}-${suffix}"
 147         dataset="$basedataset/$name"
 148         configfile=/etc/schroot/chroot.d/"$prefix"-"$name"
 149         [ "$prefix" = "schroot" ] && configfile=/etc/schroot/chroot.d/"$name"
 150         fstabline=$(printf '%s\t%s\tzfs\tnoauto\t0\t0' "$dataset" "$mountroot/$name")
 151         if [ -n "$RECREATETIME" ] && [ -n "$(zfs list -H -o name "$dataset")" ]  && [ "$(($(date +%s)-$(zfs get -H -p -o value creation "$dataset")))" -gt "$RECREATETIME" ]; then
 152                 destroy
 153         fi
 154         # bullseye doesn't know about non-free-firmware
 155         # older stuff i don't care about
 156         if [ "$release" = "bullseye" ]; then
 157                 COMPONENTS=$(echo "$COMPONENTS" |sed 's/,non-free-firmware//g')
 158         fi
 159         # check if chroot is already available and working 
 160         if schroot --chroot="source:${configfile##*/}" --directory=/ -- grep "$release" /etc/os-release >/dev/null ; then
 161                 continue
 162         else
 163                 destroy
 164         fi
 165         # just be sure nothing is lingering..
 166         schroot --chroot="source:${configfile##*/}" --end-session || :
 167         mkdir -vp "$mountroot/$name"
 168         zfs create -v -o mountpoint=legacy \
 169                 -o atime=off \
 170                 -o relatime=off \
 171                 -o com.sun:auto-snapshot=false \
 172                 "$dataset"
 173 
 174         mount -t zfs "$dataset" "$mountroot/$name"
 175         # shellcheck disable=SC2016
 176         mmdebstrap \
 177                 --variant="$variant" --include="$includes" --arch="$arch" \
 178                 --aptopt='Acquire::http {Proxy "'$(auto-apt-proxy)'"; }' \
 179                 --mode="$mode" --components="$COMPONENTS" \
 180                 --customize-hook='sed "s/^deb /deb-src /" "$1/etc/apt/sources.list" > "$1/etc/apt/sources.list.d/src.list"' \
 181                 "$release" "$mountroot/$name" || :
 182 
 183         umount "$mountroot/$name"
 184         alias="$name"
 185         if dpkg-query -W distro-info >/dev/null 2>&1; then
 186                 distribution="$(distro-info --alias="$release")"
 187                 alias="${distribution}-${arch}-${suffix}"
 188         fi
 189         cat > "$configfile" << EOF
 190 ################################################################################
 191 ## $configfile
 192 ################################################################################
 193 [${configfile##*/}]
 194 type=zfs-snapshot
 195 description=Debian ${configfile##*/} ZFS snapshot
 196 groups=sbuild,root
 197 root-users=$SUDO_USER
 198 root-groups=root,sbuild
 199 source-root-users=$SUDO_USER
 200 source-clone=true
 201 zfs-dataset=$dataset
 202 mount-options=-o atime=off,sync=disabled,relatime=off
 203 zfs-snapshot-options=-o com.sun:auto-snapshot=false
 204 command-prefix=eatmydata
 205 aliases=$alias
 206 debian.distribution=$distribution
 207 EOF
 208 
 209         if [ "$FSTAB" = "true" ]; then
 210                 if ! grep -qxF -- "$fstabline" /etc/fstab; then
 211                         printf '%s\n' "$fstabline" >> /etc/fstab
 212                         if grep -q systemd /proc/1/comm; then
 213                                 systemctl daemon-reload
 214                         fi
 215                 fi
 216         fi
 217         if [ "$SBUILD_LINK" = "true" ]; then
 218                 mkdir -p /etc/sbuild/chroot
 219                 ln -sfv "$configfile" /etc/sbuild/chroot/"${configfile##*/}"
 220         fi
 221 done
 222 # list shit?
 223 schroot --list --all-chroots --exclude-aliases |grep "$suffix"

UPDATE YOUR CHROOTS

schroot --list --all-source-chroots --exclude-aliases| while read -r chroot ; do 
  schroot --chroot="$chroot" --user=root --directory=/ -- bash -c "apt-get -q update; apt-get -qq dist-upgrade" ;
done

NOTES ABOUT AUTOMATIC SNAPSHOTS

If you use some kind of automatic recursive snapshot mechanism you will likely need to change the zfs setup script like this if you don't exclude them.

diff --git a/schroot/setup.d/05zfs b/schroot/setup.d/05zfs
index 6ecc019..aeba985 100755
--- a/schroot/setup.d/05zfs
+++ b/schroot/setup.d/05zfs
@@ -49,11 +49,11 @@ if [ "$CHROOT_TYPE" = "zfs-snapshot" ] && [ -n "$CHROOT_ZFS_CLONE_NAME" ]; then
         if zfs list "$CHROOT_ZFS_CLONE_NAME" >/dev/null 2>&1
         then
             if [ "$VERBOSE" = "verbose" ]; then
-                zfs destroy "$CHROOT_ZFS_CLONE_NAME"
-                zfs destroy "$CHROOT_ZFS_SNAPSHOT_NAME"
+                zfs destroy -vr "$CHROOT_ZFS_CLONE_NAME"
+                zfs destroy -vr "$CHROOT_ZFS_SNAPSHOT_NAME"
             else
-                zfs destroy "$CHROOT_ZFS_CLONE_NAME" > /dev/null
-                zfs destroy "$CHROOT_ZFS_SNAPSHOT_NAME" > /dev/null
+                zfs destroy -r "$CHROOT_ZFS_CLONE_NAME" > /dev/null
+                zfs destroy -r "$CHROOT_ZFS_SNAPSHOT_NAME" > /dev/null
             fi
         else
             # The dataset no longer exists, or was never created,

                     \_/
   m00h  (__)       -(_)-
      \  ~Oo~___     / \
         (..)  |\
___________|_|_|_____________
..."Have you mooed today?"...