File size: 2,708 Bytes
cd8bd0a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# bin/_ops-common.sh — shared helpers for the OmniRoute ops runbook scripts.
#
# Sourced (not executed) by rollback.sh / snapshot-data.sh / restore-data.sh /
# restore-policies.sh / cold-start-bench.sh. The runbook context lives in
# docs/INCIDENT_RESPONSE.md and docs/PERF_BUDGETS.md.
#
# Path resolution mirrors the app (src/lib/db/core.ts): the SQLite store is
# $DATA_DIR/storage.sqlite and managed backups go to $DATA_DIR/db_backups
# (overridable via DB_BACKUPS_DIR), so snapshots created here are interchangeable
# with the ones the server writes on migrations.

# Recompute the data-dir-derived paths. Called once on source, and again by
# scripts that accept a --data-dir override.
ops_set_data_dir() {
  OMNIROUTE_DATA_DIR="$1"
  OMNIROUTE_SQLITE="${OMNIROUTE_DATA_DIR}/storage.sqlite"
  OMNIROUTE_BACKUPS_DIR="${DB_BACKUPS_DIR:-${OMNIROUTE_DATA_DIR}/db_backups}"
}
ops_set_data_dir "${DATA_DIR:-$HOME/.omniroute}"

ops_log() { printf '[%s] %s\n' "${SCRIPT_NAME:-ops}" "$*" >&2; }
ops_die() {
  printf '[%s] ERROR: %s\n' "${SCRIPT_NAME:-ops}" "$*" >&2
  exit 1
}

ops_require_cmd() {
  command -v "$1" >/dev/null 2>&1 || ops_die "required command not found: $1"
}

# ops_confirm "<prompt>" — return 0 to proceed. Honors ASSUME_YES=1 (set by the
# --yes flag) and REFUSES a destructive action on a non-interactive stdin unless
# ASSUME_YES is set, so an unattended/CI invocation can never silently destroy data.
ops_confirm() {
  local prompt="$1" reply
  if [ "${ASSUME_YES:-0}" = "1" ]; then return 0; fi
  if [ ! -t 0 ]; then
    ops_die "refusing a destructive action without a TTY; pass --yes to proceed non-interactively"
  fi
  read -r -p "$prompt [y/N] " reply
  case "$reply" in
    [yY] | [yY][eE][sS]) return 0 ;;
    *) return 1 ;;
  esac
}

# ops_find_snapshot <id> — resolve a snapshot identifier (a snapshot dir name,
# a bare timestamp/sha, or an explicit path) to a directory containing
# storage.sqlite. Echoes the resolved dir or dies.
ops_find_snapshot() {
  local id="$1" cand
  [ -n "$id" ] || ops_die "snapshot id required (a timestamp/sha, dir name, or path)"
  for cand in \
    "$id" \
    "$id/" \
    "$OMNIROUTE_BACKUPS_DIR/$id" \
    "$OMNIROUTE_BACKUPS_DIR/snapshot_$id"; do
    if [ -f "${cand%/}/storage.sqlite" ]; then
      printf '%s\n' "${cand%/}"
      return 0
    fi
  done
  # Fall back to a prefix match against snapshot_* dirs (e.g. a short sha/date).
  if [ -d "$OMNIROUTE_BACKUPS_DIR" ]; then
    for cand in "$OMNIROUTE_BACKUPS_DIR"/snapshot_*"$id"*; do
      [ -f "$cand/storage.sqlite" ] && { printf '%s\n' "$cand"; return 0; }
    done
  fi
  ops_die "no snapshot matching '$id' under $OMNIROUTE_BACKUPS_DIR (run bin/snapshot-data.sh first)"
}