All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Skip-unchanged optimization (default on): the
runcommand skips datasets whose live filesystem is byte-identical to a snapshot already captured by the previous backup. Uses native ZFSwrittenproperty and snapshot creation time — no state, no extra IO. For pools of hundreds of mostly-dormant datasets this elides nearly all PBS calls. - Pre-flight clock-skew probe against the PBS HTTP
Date:header. If skew exceeds the 60s safety margin (or the probe fails), the skip-unchanged optimization is disabled for that run and the tool falls back to schedule-only behavior. Never blocks the run.
--forcecontinues to back up everything regardless of either check.- The skew check is one HTTPS HEAD per run; not user-configurable.
- Prometheus Pushgateway integration: push 6 metrics after each backup run (last run timestamp, last success timestamp, duration, successful/failed/skipped dataset counts)
ZPBS_PUSHGATEWAYenvironment variable: set to Pushgateway base URL to enable metrics; unset or empty disables (no-op)- State persistence at
/var/lib/zpbs-backup/state.json:last_success_timestamp_secondssurvives failed runs so the staleness alert reflects the true last success ZPBS_PUSHGATEWAYadded to diagnostic env-var display list
statusshowing "683 months ago" or "never" for recently backed-up datasets — PBSlistreturnslast-backupfield, notbackup-time; now checks both- Timestamp parsing handles missing, zero, or string (ISO 8601) values from PBS
- Automatically skip datasets with
canmount=offormounted=no(organizational/hierarchy-only datasets that hold no data)
run --bg/run -b: trigger backup in background via systemd, returns immediately- POSIX short options for all commands:
-n(dry-run),-f(force),-d(dataset),-j(json),-v(verbose),-b(background),-c(clear),-s(show-only),-o(orphans),-r(recursive)
- Use actual ZFS mountpoint instead of assuming
/{dataset_name}— fixes backup failures for datasets whose mountpoint differs from their name - Skip datasets with
mountpoint=noneormountpoint=legacyinstead of failing
getcommand: argument order changed toget DATASET [PROPERTY]— property defaults to showing all- CLI hides
zpbs:prefix from all user-facing output (use short names: backup, schedule, etc.) - Permission denied errors now suggest using sudo
- Helpful hint on PBS privilege separation when connection check fails
show-configcommand: display active PBS configuration, source, and connectivity check--verboseflag shows all config sources in priority order--jsonflag for machine-parseable output (suitable for automation)
send-test-notificationcommand (replacesnotify test)- New config variables aligned with PBS API token terminology:
PBS_API_TOKEN_SECRET(preferred overPBS_PASSWORD)PBS_USER,PBS_API_TOKEN_NAME,PBS_SERVER,PBS_DATASTORE(individual parts)
- Auto-composition of
PBS_REPOSITORYfrom individual parts when not set explicitly - Config source tracking: shows which file or env var provided each setting
- Per-user config file:
~/.config/zpbs-backup/pbs.conf - 40 new tests for config module
- Config file search simplified to 2 locations:
~/.config/zpbs-backup/pbs.confand/etc/zpbs-backup/pbs.conf - Removed legacy
/rootconfig file paths notify testandnotify configare now hidden deprecated aliases
notify test— usesend-test-notificationinsteadnotify config— useshow-configinstead
- Upfront PBS connectivity check in status, audit, and run commands
- 30-second timeout on all PBS query commands (prevents indefinite hangs)
- Commands no longer hang when PBS server is unreachable
- Graceful handling when non-root user lacks permission to read config files
- PBS namespace listing crash when API returns plain strings instead of objects
- Native
.deband.rpmpackage builds via nfpm - Makefile with
make packages,make deb,make rpmtargets - GitLab CI/CD pipeline for building and publishing system packages
- GitLab Releases with downloadable
.deband.rpmassets - GitHub Releases with
.deband.rpmassets (via GitLab CI mirror) - Support for both amd64 and arm64 architectures
- Version is now derived from
__init__.pyas single source of truth (pyproject.tomluses dynamic versioning via hatchling)
- Syslog support for centralized logging
- Email notification system with
notifycommand groupzpbs-backup notify test- Test notification configurationzpbs-backup notify config- Show notification settings
- Shell variable interpolation in PBS configuration files
- Hierarchical namespace creation (auto-creates parent namespaces)
--no-notifyflag forruncommand
- Configuration files now support variable interpolation (e.g.,
${PBS_USER}) - Improved error handling and logging throughout
- Initial implementation of zpbs-backup
- Auto-discovery of ZFS datasets via custom properties
- Property inheritance through dataset hierarchy
- Schedule-aware backups (daily/weekly/monthly)
- Priority-based backup ordering
- Retention policy management
- Dry-run mode for all operations
- Audit mode for orphaned backups and missed datasets
- CLI commands: status, run, audit, prune, get, set, inherit
- Systemd service and timer units
- Configuration via environment variables or config files
- PBS namespace support with auto-derivation