#+TITLE: rsyncshot #+AUTHOR: Craig Jennings * About rsyncshot creates space-efficient backups using rsync and hard links. Each snapshot looks like a full backup, but unchanged files share disk space across all snapshots. Supports backing up to local drives (USB, NFS) or remote servers via SSH. Inspired by [[http://www.mikerubel.org/computers/rsync_snapshots/][Mike Rubel's rsync snapshots]]. * Quick Start #+begin_src sh # Download and install wget https://raw.githubusercontent.com/cjennings/rsyncshot/main/rsyncshot sudo bash ./rsyncshot setup # Or clone and install git clone https://github.com/cjennings/rsyncshot cd rsyncshot && sudo make install #+end_src After setup, edit =/etc/rsyncshot/config= to set your backup destination. * Commands | Command | Description | |----------------------------+------------------------------------------| | =rsyncshot backup= | Run an immediate one-off backup | | =rsyncshot = | Create snapshot with name and retention | | =rsyncshot setup= | Install script and configure cron jobs | | =rsyncshot status= | Show installation and environment status | | =rsyncshot list= | Show existing snapshots with sizes | | =rsyncshot dryrun = | Preview backup without making changes | | =rsyncshot help= | Show help message | ** Examples #+begin_src sh # Immediate backup (creates manual.0) sudo rsyncshot backup # Keep 24 hourly snapshots sudo rsyncshot hourly 24 # Keep 7 daily snapshots sudo rsyncshot daily 7 # Preview what would be backed up sudo rsyncshot dryrun manual 1 # Check if everything is configured correctly sudo rsyncshot status # See existing snapshots sudo rsyncshot list #+end_src * Configuration All settings live in =/etc/rsyncshot/config=. Created automatically by =rsyncshot setup=. ** Backup Modes *** Remote Mode (SSH) Back up to a remote server over SSH: #+begin_src sh REMOTE_HOST="myserver" REMOTE_PATH="/mnt/backups" #+end_src Backups go to =myserver:/mnt/backups/hostname/=. If your SSH key isn't in root's =~/.ssh/=, specify the path: #+begin_src sh SSH_IDENTITY_FILE="/home/youruser/.ssh/id_ed25519" #+end_src *** Local Mode Back up to a mounted drive (USB, NFS, etc.): #+begin_src sh REMOTE_HOST="" MOUNTDIR="/media/backup" #+end_src Backups go to =/media/backup/hostname/=. If the drive isn't mounted, rsyncshot will try to mount it. ** What Gets Backed Up Edit =/etc/rsyncshot/include.txt= - one directory per line (supports paths with spaces): #+begin_src /home /etc /usr/local/bin # Comments start with # #+end_src ** What Gets Excluded Edit =/etc/rsyncshot/exclude.txt= - one pattern per line: #+begin_src # Caches and temp files .cache *.tmp *.log # Build artifacts node_modules __pycache__ *.pyc #+end_src * Automatic Backups Setup installs a default cron schedule: | Type | Schedule | Retention | |--------+-----------------------------+-----------| | Hourly | Every hour, 1am-11pm | 22 | | Daily | Noon, Monday-Saturday | 6 | | Weekly | Noon, Sunday | 51 | Edit with =sudo crontab -e=. * How It Works 1. rsync copies your directories to =destination/latest/= 2. Oldest snapshot beyond retention count is deleted 3. Existing snapshots rotate (=hourly.0= → =hourly.1= → =hourly.2=...) 4. =latest/= is hard-linked to =hourly.0= (or whatever type you specified) Hard links mean unchanged files share disk space. A 100GB backup with 24 hourly snapshots might only use 110GB total if most files don't change. * Safeguards - *Separate by hostname* - one drive can back up multiple machines - *Lockfile* - prevents overlapping runs - *Validates sources* - checks directories exist before starting - *Validates destination* - checks mount or SSH connectivity - *Checks rsync exit code* - won't rotate if backup failed - *Read-only snapshots* - prevents accidental deletion - *Timestamped logging* - all runs logged to =/var/log/rsyncshot.log= * Requirements - bash - rsync - cron - grep - flock - ssh (for remote mode) The script checks for rsync and ssh at startup and shows install instructions if missing. * Uninstalling #+begin_src sh # If you cloned the repo sudo make uninstall # Or manually sudo rm /usr/local/bin/rsyncshot sudo rm -rf /etc/rsyncshot sudo rm /var/log/rsyncshot.log # optional sudo crontab -e # remove rsyncshot entries #+end_src * Testing An automated test suite is included in the =tests/= directory. ** Running Tests #+begin_src sh # Run all tests (requires sudo) sudo ./tests/test_rsyncshot.sh # Skip slow backup/cron tests sudo ./tests/test_rsyncshot.sh --quick # Verbose output sudo ./tests/test_rsyncshot.sh -v #+end_src ** Test Coverage | Category | Tests | Description | |-------------+-------+------------------------------------------------------| | Validation | 6 | Input validation, help command, argument checking | | Include | 5 | Path parsing, comments, empty lines, spaces in paths | | Dry-run | 4 | Preview mode doesn't modify anything | | Backup | 7 | Directory creation, file copying, rotation, retention, exclusions | | Cron | 3 | Cron job management, no duplicates, preserves existing jobs | ** Test Structure - =tests/test_rsyncshot.sh= - Main test runner - =tests/lib/test_helpers.sh= - Assertion functions and test environment setup - =tests/cases/test_validation.sh= - Input validation tests - =tests/cases/test_includes.sh= - Include file parsing tests - =tests/cases/test_dryrun.sh= - Dry-run mode tests - =tests/cases/test_backup.sh= - Backup and rotation tests - =tests/cases/test_cron.sh= - Cron job management tests * License GPL v3. See [[file:LICENSE][LICENSE]] file.