Because the help FOODED

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 #
   4 # https://wiki.debian.org/ReleaseCodenames
   5 RELEASES="bullseye bookworm trixie sid"
   6 
   7 set -e
   8 if [ -z "$CREATECHROOTS" ]; then
   9         echo "run export CREATECHROOTS=1 and try again"
  10         exit 1
  11 fi
  12 prefix=schroot
  13 if [ $# -eq 1 ]; then
  14         prefix=/"${1##/*}"
  15 fi
  16 zpool -V >/dev/null
  17 zfs -V >/dev/null
  18 
  19 # check if packages are installed
  20 # I don't use apt-cacher-ng on localhost.
  21 if ! dpkg-query -W sbuild schroot mmdebstrap auto-apt-proxy >/dev/null 2>&1; then
  22         sudo apt-get install schroot sbuild mmdebstrap auto-apt-proxy
  23 fi
  24 
  25 # put yourself to the sbuild group
  26 if ! $(getent group sbuild|grep -q "$USER"); then
  27         sudo sbuild-adduser "$USER"
  28         newgrp sbuild
  29 fi
  30 
  31 destroy() {
  32         if $(mount -l -t zfs|grep -q "$mountroot/$release"); then
  33                 sudo umount -vf "$mountroot/$release" || :
  34         fi
  35         if zfs list -H -o name "$dataset/$release"; then
  36                 sudo zfs destroy -rfv "$dataset/$release" || :
  37         fi
  38         if [ -d "$mountroot/$release" ]; then
  39                 sudo rm -Rfv "$mountroot/$release" || :
  40         fi
  41         if [ -L /etc/sbuild/chroot/"${configfile##*/}" ]; then
  42                 sudo rm /etc/sbuild/chroot/"${configfile##*/}"
  43         fi
  44 }
  45 undo() {
  46         [ $? -eq 0 ] && exit
  47         set -x
  48         destroy
  49         set +x
  50 }
  51 
  52 trap undo EXIT
  53 
  54 pool="rpool"
  55 base="$pool/srv/chroot"
  56 if ! zfs list -H -o name "$base">/dev/null; then
  57         echo "Basedataset must be created by you: $base"
  58         exit 1;
  59 fi
  60 dataset="$base/$prefix"
  61 if ! [ -d '/srv/chroot' ]; then echo "mountroot not available"; exit 1; fi
  62 mountroot=/srv/chroot/"$prefix"; sudo mkdir -p "$mountroot"
  63 if test -z $(zfs list -H -o name "$dataset"); then
  64         sudo zfs create -v "$dataset"
  65 fi
  66 # be able to make snapshots w/o sudo/root
  67 sudo zfs allow -s @schroot \
  68         allow,create,snapshot,destroy,rename,rollback,diff,clone,mount,promote,refreservation \
  69         "$dataset"
  70 sudo zfs allow "$USER" @schroot "$dataset"
  71 sudo chown "$USER":"$GROUP" "$mountroot"
  72 # shellcheck disable=SC2086
  73 set -- $RELEASES
  74 for release in "$@"; do
  75         configfile=
  76         # if dataset already exists
  77         if zfs list -H -o name "$dataset/$release">/dev/null; then
  78                 if [ -f /etc/schroot/chroot.d/"${prefix}_${release}" ]; then
  79                         if  schroot --list --chroot="${prefix}_${release}">/dev/null ; then
  80                                 continue
  81                         else
  82                                 destroy
  83                         fi
  84                 else
  85                         destroy
  86                 fi
  87         fi
  88         mkdir -vp "$mountroot/$release"
  89         sudo zfs create -v -o mountpoint=legacy -o atime=off "$dataset/$release"
  90         sudo mount -vt zfs "$dataset/$release" "$mountroot/$release"
  91         sudo chown -v "$USER":"$GROUP" "$mountroot/$release"
  92         mmdebstrap --variant=buildd --include=systemd-sysv,debhelper,eatmydata \
  93                 --aptopt='Acquire::http {Proxy "'$(auto-apt-proxy)'"; }' \
  94                 --mode=unshare "$release" "$mountroot/$release"
  95         sudo umount -v "$mountroot/$release"
  96         alias="$release"
  97         if dpkg-query -W distro-info >/dev/null 2>&1; then
  98                 alias="$alias,$(distro-info --alias="$release")"
  99         fi
 100         configfile=/etc/schroot/chroot.d/"${prefix}"_"${release}"
 101         cat << EOF |sudo tee "$configfile" >/dev/null
 102 ################################################################################
 103 ##${configfile}
 104 ################################################################################
 105 [${configfile##*/}]
 106 type=zfs-snapshot
 107 description=Debian ${configfile##*/} ZFS snapshot
 108 groups=sbuild,root
 109 root-users=$USER
 110 root-groups=root,sbuild
 111 source-root-users=$USER
 112 source-clone=true
 113 zfs-dataset=$dataset/$release
 114 mount-options=-o atime=off,sync=disabled
 115 zfs-snapshot-options=
 116 command-prefix=eatmydata
 117 aliases=$alias
 118 EOF
 119 sudo ln -sfv "$configfile" /etc/sbuild/chroot/"${configfile##*/}"
 120 done
 121 schroot --list --all-chroots

UPDATE YOUR CHROOTS

for chroot in $(schroot --list --all-source-chroots --exclude-aliases); do schroot \
  --chroot="$chroot" --user=root --directory=/ -- \
  bash -c "apt-get -q update; apt-get -qy 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 -r "$CHROOT_ZFS_CLONE_NAME"
+                zfs destroy -r "$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,

                 (__)
         _______~(..)~
           ,----\(oo)
          /|____|,'
         * /\  /\
wWwWwWwWwWwWwWwWwWwWwWwWwWwWw
..."Have you mooed today?"...