| Commit message (Collapse) | Author | Age | Files | Lines |
| | |
|
| |
|
|
|
|
|
|
| |
rsyncshot now acquires an exclusive, non-blocking lock (fd 200) before the backup phase, so a slow backup can't overlap the next cron tick. Only real backups lock. Help, list, status, and dryrun don't, so they're never blocked.
The lock file defaults to /run/lock/rsyncshot.lock, a root-only directory that avoids the symlink-truncation risk of a predictable name in world-writable /tmp. It falls back to /var/lock then /tmp, and is configurable via LOCKFILE. It's deliberately a different file from the old /tmp/rsyncshot.lock cron wrappers, so existing wrapped crontabs keep working until the wrapper is removed.
setup() no longer wraps cron entries in flock, since the script locks itself.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Refuse to run when REMOTE_PATH or MOUNTDIR is empty or non-absolute. A blank config value otherwise resolves the destination to the filesystem root, where rotation runs rm -rf and --delete.
Run the rotation cp/mv/rm as bare command names in remote mode, resolved by the remote PATH, instead of hardcoded /usr/bin paths that broke on remotes whose binaries live elsewhere. Resolve the real binary via command -v in local mode.
Pass rsync -R so each source is stored under its full path. Two includes sharing a basename (/usr/local/bin and /usr/bin) previously both mapped to latest/bin, and the second sync's --delete wiped the first. This changes the stored layout: /usr/local/bin now lives at latest/usr/local/bin instead of latest/bin. /home and /etc are unchanged.
Add rsync --numeric-ids so /etc and /home ownership survives a restore when the destination has a different passwd/group database.
Match mount points exactly via is_mounted() instead of a substring grep of /proc/mounts, so /media/backup no longer matches /media/backup2, paths compare literally, and mount points with spaces work.
Reject a retention count below 1, which previously still created one snapshot. Drop the grep "|| echo 0" that emitted a stray second line, assemble ssh options as arrays, and quote the RSYNC_RSH identity path.
Extract derive_paths() and is_mounted() as sourceable functions and add unit, rsync-flag, and gated remote-mode test suites. The suite now runs 36 tests, and shellcheck is clean across the script and tests.
|
| |
|
|
|
| |
Per claude-templates c36fd14. Claude tooling moves to hidden .ai/;
project-level docs/ reserved for real documentation.
|
| |
|
|
|
|
| |
Files vanishing during transfer (exit 24) is normal — temp files,
editor swap files, etc. get cleaned up while the backup runs. Log a
warning instead of aborting snapshot rotation.
|
| |
|
|
|
|
|
|
|
|
|
| |
Snapshots with read-only permissions (from chmod -w at creation) and
internal dirs with restrictive modes (e.g. /etc at 555) prevented
rm -rf from deleting old snapshots during rotation. This caused
cascading mv failures and silent rotation breakage.
- Add chmod -R u+w before rm -rf of oldest snapshot
- Clean up orphan snapshots beyond retention count
- Add error checking on rm, mv, and cp -al operations
|
| |
|
|
|
| |
Add .gitignore for docs/ and inbox/. Increase rsync --timeout from
300s to 600s for slower connections.
|
| |
|
|
|
|
|
|
| |
Adds --timeout=300 to rsync commands to handle network interruptions
gracefully, especially over WiFi. Without this, SSH connection drops
could leave rsync hanging indefinitely.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
| | |
|
| |
|
|
|
|
| |
- Add make deps to Quick Start instructions
- Add Development section with all make targets table
- Move Testing as subsection under Development
|
| |
|
|
|
|
| |
- Make INSTALLHOME, SCRIPTLOC, LOGFILE overridable via env vars
- Add RSYNCSHOT_SKIP_MOUNT_CHECK for testing without mount points
- Use CP, MV, RM variables in run_cmd to avoid shell alias issues
|
| |
|
|
|
|
|
|
|
| |
- Add help target showing all available commands
- Add test targets: test, test-quick, test-verbose
- Add lint target for shellcheck static analysis
- Add check target combining lint and test
- Add deps target with cross-platform package manager support
(apt, dnf, yum, pacman, zypper, apk, brew)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Add remote mode for SSH-based backups to servers like TrueNAS
- Add SSH_IDENTITY_FILE config for non-root SSH keys
- Add new commands: backup, status, list, dryrun
- Add dependency checks for rsync, ssh, flock
- Add timestamped logging
- Fix: duplicate cron jobs on repeated setup
- Fix: use mktemp for temp files
- Fix: use portable sed instead of grep -oP
- Fix: strengthen input validation with regex anchors
- Fix: handle paths with spaces (newline-separated includes)
- Change license from MIT to GPL v3
- Add automated test suite (25 tests)
- Update README with new features and testing docs
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
| |
- printf instead of echo
- make script executable after install
- make TYPE case insensitive earlier for HELP
- validate destination directory exists
- validate destination is a mounted drive, if not attempt a mount.
|
| | |
|
| |
|
|
| |
Comments coming back in once I get org properties working as expected.
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|