From 2c0538444f0071a20b6b50403caca6c0a52239d2 Mon Sep 17 00:00:00 2001 From: joelazar Date: Thu, 23 Jul 2026 11:37:36 +0200 Subject: [PATCH] :sparkles: replace backup script with restic-backup and restic-maintain - add restic-backup: backs up dotfiles and configs to $RESTIC_REPOSITORY - add restic-maintain: prunes old snapshots with keep-within policies - drop old backup script targeting Google Drive - update README script table - refresh wireshark preferences (4.6.7, column and capture filter changes) --- README.md | 3 +- dot_config/wireshark/preferences | 10 ++-- private_dot_local/bin/executable_backup | 52 ------------------ .../bin/executable_restic-backup | 54 +++++++++++++++++++ .../bin/executable_restic-maintain | 32 +++++++++++ 5 files changed, 93 insertions(+), 58 deletions(-) delete mode 100644 private_dot_local/bin/executable_backup create mode 100644 private_dot_local/bin/executable_restic-backup create mode 100644 private_dot_local/bin/executable_restic-maintain diff --git a/README.md b/README.md index 8f30fabf..cb8f89f1 100644 --- a/README.md +++ b/README.md @@ -273,7 +273,6 @@ Most of the personal helpers live in [`private_dot_local/bin/`](private_dot_loca | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | | [`agent-md`](private_dot_local/bin/executable_agent-md) | Creates or fixes `AGENTS.md` / `CLAUDE.md` files for coding-agent projects | | [`ai-update`](private_dot_local/bin/executable_ai-update) | Updates Claude Code, Codex, Pi, and Pi local packages | -| [`backup`](private_dot_local/bin/executable_backup) | Encrypted backups with `restic` and `age` | | [`chatterbox`](private_dot_local/bin/executable_chatterbox) | Local text-to-speech via the Chatterbox TTS model | | [`cht`](private_dot_local/bin/executable_cht) | Quick cheat-sheet lookup via cht.sh | | [`claude-private`](private_dot_local/bin/executable_claude-private) | Launches the Claude desktop app with the default profile | @@ -292,6 +291,8 @@ Most of the personal helpers live in [`private_dot_local/bin/`](private_dot_loca | [`obsidian-update`](private_dot_local/bin/executable_obsidian-update) | Triggers Obsidian plugin and theme updates across vaults | | [`pi`](private_dot_local/bin/executable_pi) | Runs the Pi agent CLI through the mise-managed Node 24 runtime | | [`pr-create`](private_dot_local/bin/executable_pr-create) | Creates pull requests with a guided interactive prompt | +| [`restic-backup`](private_dot_local/bin/executable_restic-backup) | Backs up selected dotfiles and configs to `$RESTIC_REPOSITORY` via restic | +| [`restic-maintain`](private_dot_local/bin/executable_restic-maintain) | Prunes old snapshots from the restic backup repo | | [`skills-invocation`](private_dot_local/bin/executable_skills-invocation) | Re-applies the skill invocation policy after `skills update` | | [`switch-main-display`](private_dot_local/bin/executable_switch-main-display) | Changes the primary display on multi-monitor setups | | [`transcribe`](private_dot_local/bin/executable_transcribe) | Offline audio/video transcription via whisper.cpp | diff --git a/dot_config/wireshark/preferences b/dot_config/wireshark/preferences index 284c4eb1..af2ab24e 100644 --- a/dot_config/wireshark/preferences +++ b/dot_config/wireshark/preferences @@ -1,4 +1,4 @@ -# Configuration file for Wireshark 4.6.6. +# Configuration file for Wireshark 4.6.7. # # This file is regenerated each time preferences are saved within # Wireshark. Making manual changes should be safe, however. @@ -304,7 +304,7 @@ gui.color_filter_bg.deprecated: e0af68 # Packet list hidden columns # List all column indices (1-indexed) to hide in the packet list. -gui.column.hide: 7,8,10,11,12,13,14,15,16,17,20,21,22,23,24,25,26,27,28,30 +gui.column.hide: 7,8,10,11,12,13,14,15,16,17,19,20,21,22,23,24,25,26,27,30 # Packet list hidden column formats (deprecated) # List all column formats to hide in the packet list. Deprecated in favor of the index-based preference. @@ -331,7 +331,6 @@ gui.column.format: "TEID/GRE Key", "%Cus:gtpv2.f_teid_gre_key:0:U", "Destination Port", "%Cus:tcp.dstport:0:U", "MCC", "%Cus:e212.cgi.mcc || e212.rai.mcc || e212.ecgi.mcc || e212.tai.mcc || e212.mcc:0:U", - "MNC", "%Cus:e212.cgi.mnc || e212.rai.mnc || e212.ecgi.mnc || e212.tai.mnc || e212.mnc:0:U", "NAS EPS session management messages", "%Cus:nas-eps.nas_msg_esm_type:0:R", "Release cause", "%Cus:lte-rrc.releaseCause:0:R", "Character Set", "%Cus:gsm_sms.tp-dcs:0:U", @@ -341,6 +340,7 @@ gui.column.format: "Uplink (AMBR / Max bit rate)", "%Cus:gtpv2.ambr_up || diameter.Max-Requested-Bandwidth-UL || gtp.qos_max_ul || gsm_map.qos.max_brate_ulink:0:U", "This TSN is a retransmission of one in frame", "%Cus:sctp.retransmission:0:U", "APN", "%Cus:gsm_a.gm.sm.apn:0:U", + "MNC", "%Cus:e212.cgi.mnc || e212.rai.mnc || e212.ecgi.mnc || e212.tai.mnc || e212.mnc:0:U", "Association IMSI", "%Cus:e212.assoc.imsi:0:U", "localValue", "%Cus:gsm_old.localValue:0:U", "Info", "%i" @@ -630,7 +630,7 @@ capture.devices_pmode: ap1(1),en0(1),awdl0(1),utun0(1),utun1(1),utun2(1),utun3(1 # Remote capture filter # A string -#extcap.ciscodump.remotefilter: deny tcp host 10.2.0.2 any eq 22, deny tcp any eq 22 host 10.2.0.2, deny tcp host fd7a:115c:a1e0::c01:8c04 any eq 22, deny tcp any eq 22 host fd7a:115c:a1e0::c01:8c04, deny tcp host 100.115.140.4 any eq 22, deny tcp any eq 22 host 100.115.140.4, deny tcp host fe80::5859:cc7b:b4dc:a9ed any eq 22, deny tcp any eq 22 host fe80::5859:cc7b:b4dc:a9ed, deny tcp host fe80::16c8:3415:fe1e:3b0e any eq 22, deny tcp any eq 22 host fe80::16c8:3415:fe1e:3b0e, deny tcp host fe80::cb78:e994:7a5b:5642 any eq 22, deny tcp any eq 22 host fe80::cb78:e994:7a5b:5642, deny tcp host fe80::ce81:b1c:bd2c:69e any eq 22, deny tcp any eq 22 host fe80::ce81:b1c:bd2c:69e, deny tcp host fe80::ce0b:dc60:1d9f:38c0 any eq 22, deny tcp any eq 22 host fe80::ce0b:dc60:1d9f:38c0, deny tcp host fe80::902a:89:2d49:a33a any eq 22, deny tcp any eq 22 host fe80::902a:89:2d49:a33a, deny tcp host fe80::f91a:6177:5136:1dca any eq 22, deny tcp any eq 22 host fe80::f91a:6177:5136:1dca, deny tcp host fe80::cc23:86ff:fe26:30a7 any eq 22, deny tcp any eq 22 host fe80::cc23:86ff:fe26:30a7, deny tcp host fe80::cc23:86ff:fe26:30a7 any eq 22, deny tcp any eq 22 host fe80::cc23:86ff:fe26:30a7, deny tcp host 2a02:ab88:11:ab80:850a:684b:f550:d3a8 any eq 22, deny tcp any eq 22 host 2a02:ab88:11:ab80:850a:684b:f550:d3a8, deny tcp host 2a02:ab88:11:ab80:8fa:dbb3:5fff:6020 any eq 22, deny tcp any eq 22 host 2a02:ab88:11:ab80:8fa:dbb3:5fff:6020, deny tcp host 192.168.0.17 any eq 22, deny tcp any eq 22 host 192.168.0.17, deny tcp host fe80::1867:cceb:729d:be90 any eq 22, deny tcp any eq 22 host fe80::1867:cceb:729d:be90, deny tcp host fe80::1 any eq 22, deny tcp any eq 22 host fe80::1, permit ip any any +#extcap.ciscodump.remotefilter: deny tcp host fe80::7d3:4fe2:e466:492d any eq 22, deny tcp any eq 22 host fe80::7d3:4fe2:e466:492d, deny tcp host fe80::7d84:6126:93dd:2112 any eq 22, deny tcp any eq 22 host fe80::7d84:6126:93dd:2112, deny tcp host fdba:61f6:fb94:76e1:1475:8e2a:59d4:3541 any eq 22, deny tcp any eq 22 host fdba:61f6:fb94:76e1:1475:8e2a:59d4:3541, deny tcp host fe80::842f:57ff:fea2:fe64 any eq 22, deny tcp any eq 22 host fe80::842f:57ff:fea2:fe64, deny tcp host 192.168.64.1 any eq 22, deny tcp any eq 22 host 192.168.64.1, deny tcp host 10.2.0.2 any eq 22, deny tcp any eq 22 host 10.2.0.2, deny tcp host fd7a:115c:a1e0::c01:8c04 any eq 22, deny tcp any eq 22 host fd7a:115c:a1e0::c01:8c04, deny tcp host 100.115.140.4 any eq 22, deny tcp any eq 22 host 100.115.140.4, deny tcp host fe80::5859:cc7b:b4dc:a9ed any eq 22, deny tcp any eq 22 host fe80::5859:cc7b:b4dc:a9ed, deny tcp host fe80::cb91:b289:1264:b993 any eq 22, deny tcp any eq 22 host fe80::cb91:b289:1264:b993, deny tcp host fe80::9223:a387:abc1:7696 any eq 22, deny tcp any eq 22 host fe80::9223:a387:abc1:7696, deny tcp host fe80::ce81:b1c:bd2c:69e any eq 22, deny tcp any eq 22 host fe80::ce81:b1c:bd2c:69e, deny tcp host fe80::e3c9:63bd:b890:988c any eq 22, deny tcp any eq 22 host fe80::e3c9:63bd:b890:988c, deny tcp host fe80::3d3:56:7d:b0b5 any eq 22, deny tcp any eq 22 host fe80::3d3:56:7d:b0b5, deny tcp host fe80::e1da:1b8d:581e:5deb any eq 22, deny tcp any eq 22 host fe80::e1da:1b8d:581e:5deb, deny tcp host fe80::245d:beff:fe8c:a863 any eq 22, deny tcp any eq 22 host fe80::245d:beff:fe8c:a863, deny tcp host fe80::245d:beff:fe8c:a863 any eq 22, deny tcp any eq 22 host fe80::245d:beff:fe8c:a863, deny tcp host 192.168.40.51 any eq 22, deny tcp any eq 22 host 192.168.40.51, deny tcp host fe80::1843:6401:4e75:c26 any eq 22, deny tcp any eq 22 host fe80::1843:6401:4e75:c26, deny tcp host fe80::1 any eq 22, deny tcp any eq 22 host fe80::1, permit ip any any # Packets to capture # A string @@ -718,7 +718,7 @@ capture.devices_pmode: ap1(1),en0(1),awdl0(1),utun0(1),utun1(1),utun2(1),utun3(1 # Remote capture filter # A string -#extcap.sshdump.remotefilter: not ((host 10.2.0.2 or host fd7a:115c:a1e0::c01:8c04 or host 100.115.140.4 or host fe80::5859:cc7b:b4dc:a9ed or host fe80::16c8:3415:fe1e:3b0e or host fe80::cb78:e994:7a5b:5642 or host fe80::ce81:b1c:bd2c:69e or host fe80::ce0b:dc60:1d9f:38c0 or host fe80::902a:89:2d49:a33a or host fe80::f91a:6177:5136:1dca or host fe80::cc23:86ff:fe26:30a7 or host fe80::cc23:86ff:fe26:30a7 or host 2a02:ab88:11:ab80:850a:684b:f550:d3a8 or host 2a02:ab88:11:ab80:8fa:dbb3:5fff:6020 or host 192.168.0.17 or host fe80::1867:cceb:729d:be90 or host fe80::1) and port 22) +#extcap.sshdump.remotefilter: not ((host fe80::7d3:4fe2:e466:492d or host fe80::7d84:6126:93dd:2112 or host fdba:61f6:fb94:76e1:1475:8e2a:59d4:3541 or host fe80::842f:57ff:fea2:fe64 or host 192.168.64.1 or host 10.2.0.2 or host fd7a:115c:a1e0::c01:8c04 or host 100.115.140.4 or host fe80::5859:cc7b:b4dc:a9ed or host fe80::cb91:b289:1264:b993 or host fe80::9223:a387:abc1:7696 or host fe80::ce81:b1c:bd2c:69e or host fe80::e3c9:63bd:b890:988c or host fe80::3d3:56:7d:b0b5 or host fe80::e1da:1b8d:581e:5deb or host fe80::245d:beff:fe8c:a863 or host fe80::245d:beff:fe8c:a863 or host 192.168.40.51 or host fe80::1843:6401:4e75:c26 or host fe80::1) and port 22) # Packets to capture # A string diff --git a/private_dot_local/bin/executable_backup b/private_dot_local/bin/executable_backup deleted file mode 100644 index d93881e3..00000000 --- a/private_dot_local/bin/executable_backup +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash -# -# Backup script for my home directory -# - -BACKUPDIR="$HOME/Google Drive/My Drive/Backup/" -REPO=(--repo "$BACKUPDIR") -INCLUDE=( - "$HOME/.ssh" - "$HOME/.config/fish/.local.fish" - "$HOME/.local/share/fish/fish_history" -) -EXCLUDE=( - "$HOME/.ssh/work" -) - -function print_help() { - echo "Usage: backup {init|do|list|prune|forget|help}" - echo "Commands:" - echo " init - Initialize the backup repository" - echo " do - Perform the backup" - echo " list - List all snapshots in the backup repository" - echo " prune - Remove old snapshots from the backup repository" - echo " forget - Only keep the last snapshot" - echo " help - Print this help message" -} - -case "$1" in -"init") - restic "${REPO[@]}" init - ;; -"do") - restic "${REPO[@]}" backup "${INCLUDE[@]}" "${EXCLUDE[@]/#/--exclude=}" - ;; -"list") - restic "${REPO[@]}" snapshots - ;; -"prune") - restic "${REPO[@]}" prune - ;; -"forget") - restic "${REPO[@]}" forget --keep-last 1 - ;; -"help") - print_help - ;; -*) - echo "Invalid command: $1" - print_help - exit 1 - ;; -esac diff --git a/private_dot_local/bin/executable_restic-backup b/private_dot_local/bin/executable_restic-backup new file mode 100644 index 00000000..177ae980 --- /dev/null +++ b/private_dot_local/bin/executable_restic-backup @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# +# Back up selected dotfiles and configs to the restic repo in $RESTIC_REPOSITORY. +# +set -Eeuo pipefail + +if [[ -z "${RESTIC_REPOSITORY:-}" ]]; then + echo '❌ RESTIC_REPOSITORY is not set' >&2 + exit 1 +fi + +INCLUDE=( + "$HOME/.agents" + "$HOME/.aws" + "$HOME/.claude" + "$HOME/.claude-work" + "$HOME/.claude.json" + "$HOME/.config" + "$HOME/.docker/config.json" + "$HOME/.gemini" + "$HOME/.gnupg" + "$HOME/.kube" + "$HOME/.npmrc" + "$HOME/.obsidian-headless" + "$HOME/.pi" + "$HOME/.ssh" + "$HOME/.local/share/fish/fish_history" +) + +ensure_repository_ready() { + local volume + volume="$(dirname "$RESTIC_REPOSITORY")" + if [[ ! -d "$volume" ]]; then + printf '❌ Backup volume "%s" is not mounted\n' "$volume" >&2 + exit 1 + fi + if ! restic cat config >/dev/null 2>&1; then + printf '📦 Initializing new restic repository at "%s"\n' "$RESTIC_REPOSITORY" + restic init + fi +} + +run_backup() { + printf '💾 Backing up to "%s"\n' "$RESTIC_REPOSITORY" + restic unlock + restic backup "${INCLUDE[@]}" \ + --retry-lock 3h \ + --compression max \ + --exclude-caches \ + "$@" +} + +ensure_repository_ready +run_backup "$@" diff --git a/private_dot_local/bin/executable_restic-maintain b/private_dot_local/bin/executable_restic-maintain new file mode 100644 index 00000000..0871ea8e --- /dev/null +++ b/private_dot_local/bin/executable_restic-maintain @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# +# Prune old snapshots from the restic repo in $RESTIC_REPOSITORY. +# +set -Eeuo pipefail + +if [[ -z "${RESTIC_REPOSITORY:-}" ]]; then + echo '❌ RESTIC_REPOSITORY is not set' >&2 + exit 1 +fi + +ensure_repository_ready() { + if ! restic cat config >/dev/null 2>&1; then + printf '❌ No restic repository found at "%s"\n' "$RESTIC_REPOSITORY" >&2 + exit 1 + fi +} + +forget_old_snapshots() { + printf '🧠 Forgetting extra backups in "%s"\n' "$RESTIC_REPOSITORY" + restic unlock + restic forget \ + --retry-lock 3h \ + --keep-within-daily 7d \ + --keep-within-weekly 1m \ + --keep-within-monthly 1y \ + --keep-within-yearly 100y \ + --prune +} + +ensure_repository_ready +forget_old_snapshots -- 2.51.2