Repository navigation
Two ZFS-backend refinements that build on the v4.1.2.zfs.4 pointer-format groundwork.
What's new
Pointer cache extended to dockerd:// and podman://
enroot import dockerd://<image> and enroot import podman://<image> now produce the same magic-prefixed pointer file as docker:// imports and populate the layer-keyed template cache. Repeat imports hit the cache; enroot create becomes O(zfs clone) for daemon URIs too. Cache key is the daemon-reported image ID (${engine} inspect --format='{{.Id}}') — for registry-pulled daemon images this is identical in shape and meaning to the image-config-sha256 of a docker:// pull, so a daemon import of ubuntu:24.04 shares the cache with a registry import of the same reference for free.
Pointer schema gains an optional manifest-digest field — daemon-local images don't have a registry manifest digest. v1 magic line is unchanged; pointers from v4.1.2.zfs.4 still parse.
Template provenance as ZFS user properties
Each template dataset now carries:
| Property | Set on |
|---|---|
enroot:imported |
every template (RFC3339 UTC) |
enroot:last_used |
every template (refreshed each clone) |
enroot:uri |
docker / dockerd / podman templates |
enroot:manifest-digest |
docker:// templates only |
enroot:arch |
docker / dockerd / podman templates |
Templates are self-describing — zfs get -r enroot:uri tank/enroot/data/.templates shows what's cached without needing the (transient) pointer file. Properties replicate via zfs send -p, so they survive the zfs://<host>/<name> SSH transport.
Idle templates are unmounted
zfs clone <template>@pristine doesn't require the source to be mounted, so cached-but-unused templates now sit at zero mountpoints. Only active container clones (and the .templates / .ephemeral parents) appear in mount(8) output. Significant df / mount output cleanup if you have many cached images.
Inspection one-liner
zfs list -o name,enroot:uri,enroot:imported,enroot:last_used,used \
-r -d 1 ${POOL}/.templatesBehavior changes
- ZFS backend default is unchanged —
enroot import docker://,dockerd://,podman://all produce a pointer file by default. SetENROOT_ZFS_IMPORT_FORMAT=squashfs(env or config) for the legacy real-.sqshartifact, or pass--format=squashfsper invocation. dirbackend: no change.enroot:imported/enroot:uri/ etc. are populated only on freshly-installed templates. Templates cached under v4.1.2.zfs.4 stay unstamped until they cycle through the warm/cold sweep or are manually destroyed and re-imported.
Action required for existing admins
None. Existing zfs allow set (delegated in v4.1.2.zfs.3 release notes) covers everything. New optional knob (default pointer):
#ENROOT_ZFS_IMPORT_FORMAT pointer
Smoke results (spark-f2ff, OpenZFS 2.2.x, arm64)
| Check | Result |
|---|---|
enroot import dockerd://ubuntu:24.04 |
173-byte pointer; magic correct; no manifest-digest= line |
| Cache parity (dockerd:// hits docker:// template) | "Reusing cached template 3c220491de2e" |
Cache-hit enroot create from dockerd:// pointer |
0.564 s |
| Repeat-import idempotence | template count unchanged |
| Eviction recovery (destroy + create) | re-extracts from daemon, succeeds |
enroot:imported set on fresh installs |
2026-05-02T01:21:28Z ✓ |
| Idle templates not mounted | confirmed |
docker:// regression |
unchanged; still emits manifest-digest= |
Closes
Packages (aarch64 / arm64 only in this release)
| Flavor | Package |
|---|---|
| Standard | enroot_4.1.2.zfs.5-1_arm64.deb |
enroot+caps_4.1.2.zfs.5-1_arm64.deb |
|
| Hardened | enroot-hardened_4.1.2.zfs.5-1_arm64.deb |
enroot-hardened+caps_4.1.2.zfs.5-1_arm64.deb |
Plus enroot_4.1.2.zfs.5_aarch64.tar.xz (relocatable tarball) and enroot_4.1.2.zfs.5.orig.tar.xz (Debian source).
Build
git clone --recurse-submodules -b v4.1.2.zfs.5 https://github.com/zeroae/enroot.git
cd enroot
make
sudo make install setcapFor the hardened flavor: make deb PACKAGE=enroot-hardened.
See doc/zfs.md (new "Daemon URIs" subsection and "Inspecting cached templates" block) for full documentation.