aboutsummaryrefslogtreecommitdiff
path: root/straper/lint-db.sh
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukasz.kasprzak@pm.me>2026-03-19 17:26:34 +0100
committerLukasz Kasprzak <lukasz.kasprzak@pm.me>2026-03-19 17:26:34 +0100
commit0ad332db7e3ea4f0fce0f4db332193883ebec254 (patch)
tree967e6ea58cd1109ca3216fb395281018bee16bd8 /straper/lint-db.sh
parentb1844d805a8f190af00faf3f6e5bed7d997ecaae (diff)
downloadbin-0ad332db7e3ea4f0fce0f4db332193883ebec254.tar.gz
bin-0ad332db7e3ea4f0fce0f4db332193883ebec254.zip
modified sorter and added lint-db to compare it against the db
Diffstat (limited to 'straper/lint-db.sh')
-rwxr-xr-xstraper/lint-db.sh175
1 files changed, 175 insertions, 0 deletions
diff --git a/straper/lint-db.sh b/straper/lint-db.sh
new file mode 100755
index 0000000..dc0de37
--- /dev/null
+++ b/straper/lint-db.sh
@@ -0,0 +1,175 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+SCRIPT_DIR="$(cd -- "$(dirname -- "$0")" && pwd)"
+# shellcheck disable=SC1091
+source "${SCRIPT_DIR}/common.sh"
+
+SCRIPT_NAME="lint-db.sh"
+ISSUES=0
+
+usage() {
+ cat <<'USAGE'
+Usage: sudo ./lint-db.sh [options]
+
+Purpose:
+ Non-destructively lint a rebuild DB for structural problems that can pollute
+ restore results.
+
+Checks:
+ - backup directories captured into DB (e.g. *.bak.*)
+ - nested duplicate service roots (e.g. nginx/nginx, i2pd/i2pd)
+ - overlapping category roots (e.g. etc-i2pd plus sibling tunnels.d)
+ - duplicate canonical files at two depths within the same category
+
+Options:
+ --db-dir PATH
+ --verbose
+ --help
+USAGE
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --db-dir) DB_DIR="$2"; PUBLIC_DIR="${DB_DIR}/db/public"; SECRET_DIR="${DB_DIR}/db/secret"; shift ;;
+ --verbose) VERBOSE=true ;;
+ --help) usage; exit 0 ;;
+ *) die "unknown option: $1" ;;
+ esac
+ shift
+done
+
+load_optional_config
+ensure_runtime_dirs
+
+[[ -d "${PUBLIC_DIR}" ]] || die "public DB not found: ${PUBLIC_DIR}"
+
+say() { printf '%s\n' "$*"; }
+warnx() { printf 'WARN | %s\n' "$*"; ISSUES=1; }
+okx() { printf 'OK | %s\n' "$*"; }
+
+emit_section() {
+ printf '\n%s\n' "$1"
+}
+
+find_matches() {
+ local base="$1" pattern="$2"
+ find "$base" -path "$pattern" -print 2>/dev/null | sort || true
+}
+
+check_backup_dirs() {
+ local hits
+ hits="$(find "${PUBLIC_DIR}" "${SECRET_DIR}" \
+ -type d -name '*.bak.*' -print 2>/dev/null | sort || true)"
+
+ if [[ -n "${hits}" ]]; then
+ warnx "captured backup directories found"
+ printf '%s\n' "${hits}"
+ else
+ okx "no captured backup directories found"
+ fi
+}
+
+check_nested_duplicate_roots() {
+ local name hits
+ local names=(nginx i2pd grafana loki prometheus alloy tor postfix prosody mysql docker)
+
+ for name in "${names[@]}"; do
+ hits="$(find "${PUBLIC_DIR}" "${SECRET_DIR}" \
+ -type d -path "*/${name}/${name}" -print 2>/dev/null | sort || true)"
+ if [[ -n "${hits}" ]]; then
+ warnx "nested duplicate root '${name}/${name}' found"
+ printf '%s\n' "${hits}"
+ fi
+ done
+}
+
+check_overlapping_i2pd_capture() {
+ local has_root=false has_tunnels=false has_tunnels_conf=false
+
+ [[ -d "${PUBLIC_DIR}/i2pd/etc-i2pd" ]] && has_root=true
+ [[ -e "${PUBLIC_DIR}/i2pd/tunnels.d" ]] && has_tunnels=true
+ [[ -e "${PUBLIC_DIR}/i2pd/tunnels.conf" ]] && has_tunnels_conf=true
+
+ if [[ "${has_root}" == true && ( "${has_tunnels}" == true || "${has_tunnels_conf}" == true ) ]]; then
+ warnx "overlapping i2pd capture roots found (etc-i2pd plus sibling tunnels paths)"
+ [[ -d "${PUBLIC_DIR}/i2pd/etc-i2pd" ]] && printf '%s\n' "${PUBLIC_DIR}/i2pd/etc-i2pd"
+ [[ -e "${PUBLIC_DIR}/i2pd/tunnels.conf" ]] && printf '%s\n' "${PUBLIC_DIR}/i2pd/tunnels.conf"
+ [[ -e "${PUBLIC_DIR}/i2pd/tunnels.d" ]] && printf '%s\n' "${PUBLIC_DIR}/i2pd/tunnels.d"
+ else
+ okx "no overlapping i2pd capture roots found"
+ fi
+}
+
+check_duplicate_canonical_files() {
+ emit_section "Duplicate canonical file checks"
+
+ check_dup_pair() {
+ local a="$1" b="$2" label="$3"
+ local ha=false hb=false
+ [[ -e "${a}" ]] && ha=true
+ [[ -e "${b}" ]] && hb=true
+
+ if [[ "${ha}" == true && "${hb}" == true ]]; then
+ warnx "${label} exists at two depths"
+ printf '%s\n%s\n' "${a}" "${b}"
+ else
+ okx "${label} not duplicated across checked depths"
+ fi
+ }
+
+ check_dup_pair \
+ "${PUBLIC_DIR}/prometheus/etc-prometheus/prometheus.yml" \
+ "${PUBLIC_DIR}/prometheus/etc-prometheus/prometheus/prometheus.yml" \
+ "prometheus.yml"
+
+ check_dup_pair \
+ "${PUBLIC_DIR}/loki/etc-loki/config.yml" \
+ "${PUBLIC_DIR}/loki/etc-loki/loki/config.yml" \
+ "loki config.yml"
+
+ check_dup_pair \
+ "${PUBLIC_DIR}/grafana/etc-grafana/grafana.ini" \
+ "${PUBLIC_DIR}/grafana/etc-grafana/grafana/grafana.ini" \
+ "grafana.ini"
+
+ check_dup_pair \
+ "${SECRET_DIR}/alloy/etc-alloy/config.alloy" \
+ "${SECRET_DIR}/alloy/etc-alloy/alloy/config.alloy" \
+ "alloy config.alloy"
+
+ check_dup_pair \
+ "${PUBLIC_DIR}/i2pd/etc-i2pd/i2pd.conf" \
+ "${PUBLIC_DIR}/i2pd/etc-i2pd/i2pd/i2pd.conf" \
+ "i2pd.conf"
+
+ check_dup_pair \
+ "${PUBLIC_DIR}/nginx/etc-nginx/nginx.conf" \
+ "${PUBLIC_DIR}/nginx/etc-nginx/nginx/nginx.conf" \
+ "nginx.conf"
+}
+
+emit_section "labunix/sanctum rebuild DB lint"
+say "db: ${DB_DIR}"
+say "public: ${PUBLIC_DIR}"
+say "secret: ${SECRET_DIR}"
+
+emit_section "Backup junk checks"
+check_backup_dirs
+
+emit_section "Nested duplicate root checks"
+check_nested_duplicate_roots
+
+emit_section "Overlapping capture-root checks"
+check_overlapping_i2pd_capture
+
+check_duplicate_canonical_files
+
+emit_section "Summary"
+if [[ ${ISSUES} -eq 0 ]]; then
+ okx "no DB shape issues detected"
+ exit 0
+else
+ warnx "DB shape issues detected"
+ exit 1
+fi