aboutsummaryrefslogtreecommitdiff
path: root/shield-backup
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-05-19 18:38:39 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-05-19 18:38:39 +0200
commite8cf42f2f17151378574ee5b50f29904a1067bee (patch)
tree86b4db80971ecf9818ad769bd8b7fa337d218731 /shield-backup
parentc3bfa44d1b6da88c184fc3312944cf47d1dfd7f2 (diff)
downloadbin-e8cf42f2f17151378574ee5b50f29904a1067bee.tar.gz
bin-e8cf42f2f17151378574ee5b50f29904a1067bee.zip
added readmeHEADmain
Diffstat (limited to 'shield-backup')
-rwxr-xr-xshield-backup175
1 files changed, 126 insertions, 49 deletions
diff --git a/shield-backup b/shield-backup
index ccaff5b..1c95a5d 100755
--- a/shield-backup
+++ b/shield-backup
@@ -2,7 +2,7 @@
set -euo pipefail
export PATH="/usr/sbin:/sbin:/usr/bin:/bin:$PATH"
-RCLONE_CONFIG="$HOME/.config/rclone/rclone.conf"
+
#################### CONFIG – EDIT THESE ####################
# LUKS2 block device
@@ -23,59 +23,141 @@ BACKUP_ITEMS=(
# Machine identifier (destination subdir on the LUKS volume)
MACHINE_DIR="T480"
-#################### INTERNALS – NO NEED TO EDIT ############
-
-RSYNC_EXCLUDES_FILE="/tmp/rsync_excludes_$$.txt"
-
-cat > "${RSYNC_EXCLUDES_FILE}" <<'EOF'
+# rsync exclude patterns (passed via stdin to --exclude-from=-)
+# Paths are relative to each rsync source root (i.e. $HOME for the home backup).
+read -r -d '' RSYNC_EXCLUDES <<'EOF' || true
+# === Top-level junk ===
downloads/
-# Caches & regenerable state
+Downloads/
+tmp/
+.tmp/
+
+# === All caches (3.9G in .cache alone) ===
.cache/
+
+# === Browsers (rebuilt on next launch) ===
+.mozilla/
+.mullvad-browser/
+
+# === Shell / history / runtime state ===
.fasd
.viminfo
-.zcompdump
+.zcompdump*
+.lesshst
.sqlite_history
+.python_history
+.node_repl_history
.wget-hsts
-.dbus/
+.xsession-errors*
.Xauthority
+.ICEauthority
+.dbus/
.pki/
-tmp/
+.gvfs/
+
+# === Trash ===
+.local/share/Trash/
+.Trash-*/
+
+# === Claude Code old versions (884M, current one re-fetches) ===
+.local/share/claude/versions/
+
+# === Haskell / cabal (1.9G total, fully regenerable) ===
+.cache/cabal/
+.local/state/cabal/
+
+# === Rust / cargo registry (152M, regenerable from Cargo.lock) ===
+.cargo/registry/
+.cargo/git/
+
+# === Python: venvs, caches, bytecode (anywhere in tree) ===
+__pycache__/
+*.pyc
+*.pyo
+.mypy_cache/
+.pytest_cache/
+.ruff_cache/
+.tox/
+.venv/
+venv/
+.virtualenvs/
+.local/share/pipx/
+
+# === Node / JS ===
+node_modules/
+.npm/
+.yarn/cache/
+.pnpm-store/
+
+# === Build artifacts in repos ===
+build/
+dist/
+target/
+.gradle/
+.m2/repository/
-# Browser internals
-.mozilla/firefox/*/cache2/
-.mozilla/firefox/*/storage/
-.mozilla/firefox/*/datareporting/
-.mullvad-browser/*/cache2/
-.mullvad-browser/*/storage/
+# === LaTeX caches ===
+.texlive*/texmf-var/
+.texlive*/texmf-cache/
-# Crypto node data (re-syncs)
+# === Java runtime junk ===
+.java/
+
+# === Notmuch index (668M, rebuild with `notmuch new`) ===
+.local/share/mail/.notmuch/xapian/
+
+# === Whisper.cpp models (754M, redownloadable) ===
+git/whisper.cpp/models/
+git/whisper.cpp/build/
+
+# === Reinstallable third-party software in ~/opt ===
+opt/tor-browser/
+opt/monero-gui-*/
+opt/Electrum-*/
+
+# === Themes (509M, reinstall from upstream) ===
+.themes/gruvbox-gtk-theme/
+
+# === Crypto node chain data (re-syncs) ===
.bitmonero/
.shared-ringdb/
+.ethereum/geth/chaindata/
+.bitcoin/blocks/
+.bitcoin/chainstate/
-# Large reinstallable tooling
-.cargo/registry
-.cargo/git
-.texlive2025/
+# === Electron / chat app caches ===
+.config/Signal/Cache/
+.config/Code/Cache/
+.config/Code/CachedData/
+.config/Code/logs/
-# Java runtime junk
-.java/
+# === Flatpak / Snap caches ===
+.var/app/*/cache/
+snap/*/common/.cache/
+
+# === OS junk ===
+.DS_Store
+Thumbs.db
+*.swp
+*.swo
+*~
+core
+core.*
EOF
+#################### INTERNALS – NO NEED TO EDIT ############
+
need_cmd() { command -v "$1" >/dev/null 2>&1 || { echo "ERROR: missing command: $1" >&2; exit 1; }; }
cleanup() {
echo
echo ">>> Cleaning up..."
- rm -f "${RSYNC_EXCLUDES_FILE}"
-
- # Try to unmount, if mounted
if mountpoint -q "${LUKS_MOUNTPOINT}"; then
echo ">>> Unmounting ${LUKS_MOUNTPOINT}..."
sudo umount "${LUKS_MOUNTPOINT}" || true
fi
- # Close LUKS mapping if it exists
if [ -e "/dev/mapper/${LUKS_NAME}" ]; then
echo ">>> Closing LUKS mapping ${LUKS_NAME}..."
sudo cryptsetup close "${LUKS_NAME}" || true
@@ -84,17 +166,15 @@ cleanup() {
trap cleanup EXIT
need_cmd cryptsetup
-need_cmd rclone
need_cmd rsync
need_cmd mountpoint
-# Cache sudo credentials early to avoid surprises mid-run
+# Cache sudo credentials early
sudo -v
echo ">>> Ensuring mountpoint exists: ${LUKS_MOUNTPOINT}"
sudo mkdir -p "${LUKS_MOUNTPOINT}"
-# Check if already open
if [ -e "/dev/mapper/${LUKS_NAME}" ]; then
echo ">>> WARNING: /dev/mapper/${LUKS_NAME} already exists, assuming already open."
else
@@ -102,13 +182,11 @@ else
sudo cryptsetup open "${LUKS_DEVICE}" "${LUKS_NAME}"
fi
-# At this point /dev/mapper/${LUKS_NAME} must exist
if [ ! -e "/dev/mapper/${LUKS_NAME}" ]; then
echo "ERROR: /dev/mapper/${LUKS_NAME} not found after cryptsetup open." >&2
exit 1
fi
-# Mount if not already mounted
if mountpoint -q "${LUKS_MOUNTPOINT}"; then
echo ">>> WARNING: ${LUKS_MOUNTPOINT} already mounted."
else
@@ -118,21 +196,8 @@ fi
echo ">>> LUKS volume mounted at ${LUKS_MOUNTPOINT}"
-# Ensure SharePoint destinations exist in root of shield
-sudo mkdir -p \
- "${LUKS_MOUNTPOINT}/SP_Administration" \
- "${LUKS_MOUNTPOINT}/SP_Operations" \
- "${LUKS_MOUNTPOINT}/SP_Skyscale"
-
-echo ">>> Starting rclone syncs (SharePoint -> ${LUKS_MOUNTPOINT}/SP_*)..."
-rclone --config "$RCLONE_CONFIG" sync 'SP_Administration:' "${LUKS_MOUNTPOINT}/SP_Administration" --create-empty-src-dirs --fast-list --progress
-rclone --config "$RCLONE_CONFIG" sync 'SP_Operations:' "${LUKS_MOUNTPOINT}/SP_Operations" --create-empty-src-dirs --fast-list --progress
-rclone --config "$RCLONE_CONFIG" sync 'SP_SkyscaleCommerce:' "${LUKS_MOUNTPOINT}/SP_Skyscale" --create-empty-src-dirs --fast-list --progress
-echo ">>> All rclone syncs finished."
-
echo ">>> Starting rsync backups of local folders -> ${LUKS_MOUNTPOINT}/${MACHINE_DIR}/..."
-# Ensure machine root exists
sudo mkdir -p "${LUKS_MOUNTPOINT}/${MACHINE_DIR}"
for SRC in "${BACKUP_ITEMS[@]}"; do
@@ -158,12 +223,24 @@ for SRC in "${BACKUP_ITEMS[@]}"; do
sudo mkdir -p "${DEST}"
echo ">>> rsync: ${SRC} -> ${DEST}"
- rsync -a --delete --progress \
- --exclude-from="${RSYNC_EXCLUDES_FILE}" \
+ set +e
+ sudo rsync -a --delete --progress \
+ --exclude-from=- \
"${SRC%/}/" \
- "${DEST}/"
+ "${DEST}/" <<< "${RSYNC_EXCLUDES}"
+ RSYNC_RC=$?
+ set -e
+ case "${RSYNC_RC}" in
+ 0) ;;
+ 23|24)
+ echo ">>> rsync finished with code ${RSYNC_RC} (some files skipped/vanished); continuing."
+ ;;
+ *)
+ echo "ERROR: rsync failed with code ${RSYNC_RC} on ${SRC}" >&2
+ exit "${RSYNC_RC}"
+ ;;
+ esac
done
echo ">>> All rsync backups finished."
echo ">>> Unmounting and closing LUKS (via trap)..."
-# cleanup() will run automatically on script exit