From e8cf42f2f17151378574ee5b50f29904a1067bee Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Tue, 19 May 2026 18:38:39 +0200 Subject: added readme --- shield-backup | 179 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 128 insertions(+), 51 deletions(-) (limited to 'shield-backup') 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/ + +# === LaTeX caches === +.texlive*/texmf-var/ +.texlive*/texmf-cache/ + +# === Java runtime junk === +.java/ -# Browser internals -.mozilla/firefox/*/cache2/ -.mozilla/firefox/*/storage/ -.mozilla/firefox/*/datareporting/ -.mullvad-browser/*/cache2/ -.mullvad-browser/*/storage/ +# === Notmuch index (668M, rebuild with `notmuch new`) === +.local/share/mail/.notmuch/xapian/ -# Crypto node data (re-syncs) -.bitmonero/ -.shared-ringdb/ +# === Whisper.cpp models (754M, redownloadable) === +git/whisper.cpp/models/ +git/whisper.cpp/build/ -# Large reinstallable tooling -.cargo/registry -.cargo/git -.texlive2025/ +# === Reinstallable third-party software in ~/opt === +opt/tor-browser/ +opt/monero-gui-*/ +opt/Electrum-*/ -# Java runtime junk -.java/ +# === 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/ + +# === Electron / chat app caches === +.config/Signal/Cache/ +.config/Code/Cache/ +.config/Code/CachedData/ +.config/Code/logs/ + +# === 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 -- cgit v1.3