Skip to content

D4rk-5ky/SnapBeforeLinkingWithOtherOS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 

Repository files navigation

SnapBeforeWatchTower

⚠️ Disclaimer / Liability Notice

This script is provided “as is”, without warranty of any kind.
By using this script, you agree that I am not liable for any data loss, system damage, service interruption, or other issues that may occur as a result of running it.

This script performs destructive operations, including but not limited to:

  • Creating ZFS snapshots
  • Destroying ZFS snapshots
  • Deleting log files (.log, .err)
  • Executing system-level commands (zfs, mail)

⚠️ Always test on a non-production system first.
⚠️ Always ensure you have verified backups.
⚠️ You are fully responsible for reviewing and understanding the code before running it.

⚠️ AI-assisted / vibe-coded experimental software. Use at your own risk.

Disclaimer

This project is AI-assisted / vibe-coded software created as a hobby project. It has not been professionally audited and may contain bugs, unsafe behavior, data-loss issues, security problems, or incorrect assumptions.

You are responsible for reviewing the code, testing it in a safe environment, making backups, and understanding what it does before using it on real data. The author is not responsible for damage, data loss, broken systems, security issues, or other problems caused by using this software.

Data Loss Warning

This application can perform destructive operations, including deleting ZFS snapshots, and backup data. Always test with dry-runs first, check the generated plans, and keep a separate working backup.


Overview

SnapBeforeWatchTower is a Python 3 utility for managing ZFS snapshots using a safe naming convention and retention policy.

It supports:

  • Creating ZFS snapshots with a configurable --name + --note
  • Pruning snapshots by age (--older-than) and/or count (--retain-count)
  • Dry-run mode (show what would be deleted)
  • Log retention cleanup using the same age/count rules
  • Optional email notifications (errors only, or errors + success)

The script must be run as root for any ZFS actions.


Key Requirements (Not Optional)

ZFS is required
A dataset file is required (--datasets-file)
A snapshot name token is required (--name)
Run as root (sudo)

If any mandatory requirement is missing or misconfigured, the script fails safely.


Features

  • ✅ ZFS snapshot creation
  • ✅ Safe snapshot deletion with strict name + timestamp matching
  • ✅ Retention rules: keep newest N, optionally delete only older than cutoff
  • ✅ Dataset-driven operation (one dataset per line)
  • ✅ Dry-run mode (no destructive changes)
  • ✅ Structured logging to .log + .err
  • ✅ Automatic writable log folder selection (script ./logs or /tmp/... fallback)
  • ✅ Optional email notifications
  • ✅ Cleans empty .err files automatically

System Requirements

Operating System

  • Linux with ZFS available

Python

  • Python 3.9+ recommended (uses modern typing)

Required Commands

The following must be available in $PATH:

  • zfs
  • mail (only required if email notifications are used)

Dataset File (Mandatory)

The dataset file must exist and contain one ZFS dataset per line.

Example datasets.txt:

tank/data
tank/docker
tank/vms
  • Blank lines are ignored
  • If a dataset is invalid or ZFS fails, the run will fail (and can send mail if enabled)

Snapshot Naming Convention

Snapshots created by this script look like:

<dataset>@<Name>_<Note>_<YYYY-MM-DD_HH_MM_SS>

Example:

tank/data@SnapBeforeWatchTower_run_2026-01-13_20_15_01

Safety matching rules (important)

When pruning, the script will only consider snapshots that:

  • Are on the target dataset, and
  • Start with @<Name>_, and
  • End with a valid timestamp _<YYYY-MM-DD_HH_MM_SS>

The <Note> token is ignored for pruning decisions (but still must exist in the snapshot name).
Anything not matching this exact pattern is never deleted.


Retention Logic (Important)

Retention is applied per dataset:

  1. The script lists snapshots for the dataset and selects only those matching the pattern above
  2. Snapshots are sorted by timestamp (newest first)
  3. The newest --retain-count snapshots are always kept
  4. Remaining snapshots are deleted depending on --older-than:
    • If --older-than is set: delete only snapshots older than the cutoff
    • If --older-than is NOT set: delete everything not retained

⚠️ Tip: If you want “keep N but don’t delete anything else”, set a very large --older-than (e.g. 9999d).


Logging Behavior

Each run generates files with the same timestamp:

  • .log → main log (INFO to console + DEBUG to file)
  • .err → errors only (removed automatically if empty)

Log location selection

The script picks a writable log folder in this order:

  1. <script_dir>/logs (preferred if writable/creatable)
  2. /tmp/<script_name>/ (fallback)

Note: Even if you run without root, logs can still be written.
However, if you are not root the script will:

  • Log the error
  • Optionally send a failure email (if --send-mail is set)
  • Exit without touching ZFS

Email Notifications

Enable mail with:

  • -m / --send-mail you@example.com

Failure mail (default)

If a run fails, it sends a mail with:

  • Latest .log
  • Latest .err only if non-empty

Success mail (optional)

If you also pass:

  • --mail-on-success

…then it will send a mail on successful completion too (same attachment rules).


Usage

Create snapshots only

sudo ./SnapBeforeWatchTower.py \
  --command create \
  --datasets-file datasets.txt \
  --name SnapBeforeWatchTower \
  --note run

Create then prune

sudo ./SnapBeforeWatchTower.py \
  --command create+delete \
  --datasets-file datasets.txt \
  --name SnapBeforeWatchTower \
  --note run \
  --older-than 7d \
  --retain-count 10

Prune only

sudo ./SnapBeforeWatchTower.py \
  --command delete-only \
  --datasets-file datasets.txt \
  --name SnapBeforeWatchTower \
  --older-than 7d \
  --retain-count 10

Dry-run prune (no changes)

sudo ./SnapBeforeWatchTower.py \
  --command dry-run \
  --datasets-file datasets.txt \
  --name SnapBeforeWatchTower \
  --older-than 7d \
  --retain-count 10

Email on failure only

sudo ./SnapBeforeWatchTower.py \
  --command create+delete \
  --datasets-file datasets.txt \
  --name SnapBeforeWatchTower \
  --older-than 7d \
  --retain-count 10 \
  --send-mail you@example.com

Email on failure + success

sudo ./SnapBeforeWatchTower.py \
  --command create+delete \
  --datasets-file datasets.txt \
  --name SnapBeforeWatchTower \
  --older-than 7d \
  --retain-count 10 \
  --send-mail you@example.com \
  --mail-on-success

Command-Line Options

Flag Description
-c, --command One of: create, create+delete, delete-only, dry-run
-d, --datasets-file Path to dataset list file (required)
-n, --name Snapshot Name token (required)
--note Snapshot Note token (default: run)
-o, --older-than Age cutoff for deletion: Nd, Nw, Nm (days/weeks/30-day months)
-r, --retain-count Always keep this many newest snapshots (default: 0)
-l, --log-prefix Prefix for log filenames (default: script filename)
-m, --send-mail EMAIL Send email report (failure by default)
-mos, --mail-on-success Also email on success (requires --send-mail)

Safety Notes

  • This script destroys ZFS snapshots
  • ❗ Must run as root for ZFS actions
  • ❗ Use --command dry-run to preview deletions
  • ❗ Prune matching is strict (name + timestamp required)
  • ❗ Retention without --older-than will delete all non-retained snapshots

License

No license is implied unless explicitly added.
Use, modify, and run this script entirely at your own risk.

About

A tool to create ZFS Snapshots before Send/Receive with delete options of its own snapshots aswell

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages