ZFS snapshot operations, made legible

zfstui

A comfortable terminal UI for browsing pools, creating snapshots, defining GFS-retention schedules, installing managed cron jobs, and restoring datasets safely.

Go 1.22+LinuxOpenZFSBubble Tea

Overview

zfstui keeps YAML configuration as the source of truth and treats crontab as a derived artifact. It has no daemon: scheduled jobs run the CLI through plain cron.

BrowseInspect pools, datasets, filesystems, volumes, and snapshots.
ScheduleCreate named jobs with cron expressions and tiered retention.
RestoreRollback in place or clone to a new dataset, with typed confirmation.
PreviewUse global dry-run or toggle session dry-run with D.

Install

Build from a checkout with Go and a host that has zfs available. Dry-run mode explores the UI without mutating ZFS or crontab.

make build
# → bin/zfstui
zfstui
zfstui --config ~/.config/zfstui/config.yaml --dry-run

For a system-wide install, run sudo make install. Tests use fake ZFS clients and do not require real pools.

TUI guide

KeyAction
↑/k, ↓/jMove through a list
enterOpen or select
escGo back
DToggle session dry-run
?Open help overlay
qQuit

Snapshots use c to create, d to destroy with typed confirmation, and r for the restore wizard. Schedules use a/e/x to add, edit, and delete; space toggles enabled; r runs the selected job.

Schedules & retention

A schedule names one or more datasets, a cron expression, a snapshot prefix, and a retention policy. Multi-dataset jobs share a snapshot name and run targets sequentially. Enabled jobs cannot overlap, including recursive ancestors.

version: 1
defaults:
snapshot_prefix: zfstui
recursive: false
schedules:
- name: nightly-data
dataset: tank/data
cron: "30 2 * * *"
retention:
daily: 7
weekly: 4
monthly: 12

Retention keeps one snapshot per UTC hour/day/ISO week/month/year for the newest configured periods. retention.total can cap the final selected set; all zeros means no prune.

Recursive note: recursive creation snapshots descendants, but pruning is scoped to explicitly selected roots.

Restore & safety

Rollback

Rollback returns the original dataset to a selected snapshot. Newer snapshots and their deltas may be destroyed; zfstui lists them and requires typing the dataset name.

Clone

Clone creates a new dataset path and leaves the source intact. Keep promote set to No for exploration. Promotion is not a rollback of live data.

Safe default: use --dry-run or press D before destroy, rollback, or cron installation.

Managed cron

Enabled schedules render into a managed user-crontab block or /etc/cron.d/zfstui for system installs. Reinstalling regenerates entries from YAML and removes stale managed entries.

zfstui cron status
zfstui cron install
zfstui cron uninstall
sudo zfstui cron install --system

CLI reference

CommandPurpose
versionPrint build version
run --schedule NAMECreate and prune one schedule
snapshot --dataset DOne-shot snapshot
prune --schedule NAMEApply retention only
cron install|uninstall|statusManage derived cron entries
zfstui run --schedule hourly-home
zfstui snapshot --dataset tank/home --prefix zfstui
zfstui prune --schedule hourly-home
zfstui --dry-run run --schedule hourly-home

Architecture

The application is layered so ZFS and scheduling logic remain testable without real pools.

cmd/zfstuiEntry point, flags, and version.
internal/uiBubble Tea screens, styles, and keymaps.
internal/configYAML schema, defaults, validation, atomic save.
internal/scheduleCron validation and retention evaluation.
internal/zfsThin wrapper around zfs and zpool.
internal/restoreRollback, clone, and promote orchestration.

A project section of the CapeRadar Homelab Wiki. Keep the README and this guide aligned when behavior changes.