|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# bpp-backup.sh — pobiera lokalnie kopię zapasową instancji BPP ze zdalnego hosta. |
| 4 | +# |
| 5 | +# Backup obejmuje: |
| 6 | +# - $HOME/bpp-deploy na zdalnym hoście |
| 7 | +# - katalog wskazany przez BPP_CONFIGS_DIR z $HOME/bpp-deploy/.env |
| 8 | +# |
| 9 | +# Wynik: ./backup-<host>-<compose_project>-<YYYYMMDD-HHMMSS>.tar.gz |
| 10 | +# |
| 11 | +# Użycie: ./bpp-backup.sh <host-ssh> |
| 12 | + |
| 13 | +set -euo pipefail |
| 14 | + |
| 15 | +if [ "$#" -lt 1 ] || [ -z "${1:-}" ]; then |
| 16 | + echo "Użycie: $0 <host-ssh>" >&2 |
| 17 | + echo "Przykład: $0 deploy@bpp.uczelnia.pl" >&2 |
| 18 | + exit 1 |
| 19 | +fi |
| 20 | + |
| 21 | +HOST="$1" |
| 22 | + |
| 23 | +echo "==> Odczytuję ~/bpp-deploy/.env z ${HOST}..." >&2 |
| 24 | + |
| 25 | +remote_env=$(ssh "$HOST" 'bash -s' <<'REMOTE' |
| 26 | +set -euo pipefail |
| 27 | +ENV_FILE="$HOME/bpp-deploy/.env" |
| 28 | +if [ ! -f "$ENV_FILE" ]; then |
| 29 | + echo "ERR: brak $ENV_FILE na zdalnym hoscie" >&2 |
| 30 | + exit 1 |
| 31 | +fi |
| 32 | +
|
| 33 | +get() { |
| 34 | + grep -E "^$1=" "$ENV_FILE" | tail -n1 | cut -d= -f2- \ |
| 35 | + | sed -e 's/^"\(.*\)"$/\1/' -e "s/^'\(.*\)'$/\1/" |
| 36 | +} |
| 37 | +
|
| 38 | +BPP_CONFIGS_DIR=$(get BPP_CONFIGS_DIR) |
| 39 | +COMPOSE_PROJECT_NAME=$(get COMPOSE_PROJECT_NAME) |
| 40 | +
|
| 41 | +if [ -z "$BPP_CONFIGS_DIR" ]; then |
| 42 | + echo "ERR: BPP_CONFIGS_DIR puste w $ENV_FILE" >&2 |
| 43 | + exit 1 |
| 44 | +fi |
| 45 | +if [ ! -d "$BPP_CONFIGS_DIR" ]; then |
| 46 | + echo "ERR: katalog $BPP_CONFIGS_DIR nie istnieje na zdalnym hoscie" >&2 |
| 47 | + exit 1 |
| 48 | +fi |
| 49 | +
|
| 50 | +if [ -z "$COMPOSE_PROJECT_NAME" ]; then |
| 51 | + COMPOSE_PROJECT_NAME=$(basename "$BPP_CONFIGS_DIR") |
| 52 | +fi |
| 53 | +
|
| 54 | +printf 'BPP_CONFIGS_DIR=%s\n' "$BPP_CONFIGS_DIR" |
| 55 | +printf 'COMPOSE_PROJECT_NAME=%s\n' "$COMPOSE_PROJECT_NAME" |
| 56 | +REMOTE |
| 57 | +) |
| 58 | + |
| 59 | +BPP_CONFIGS_DIR=$(printf '%s\n' "$remote_env" | sed -n 's/^BPP_CONFIGS_DIR=//p') |
| 60 | +COMPOSE_PROJECT_NAME=$(printf '%s\n' "$remote_env" | sed -n 's/^COMPOSE_PROJECT_NAME=//p') |
| 61 | + |
| 62 | +if [ -z "$BPP_CONFIGS_DIR" ] || [ -z "$COMPOSE_PROJECT_NAME" ]; then |
| 63 | + echo "ERR: nie udało się odczytać zmiennych ze zdalnego .env" >&2 |
| 64 | + exit 1 |
| 65 | +fi |
| 66 | + |
| 67 | +echo " BPP_CONFIGS_DIR=${BPP_CONFIGS_DIR}" >&2 |
| 68 | +echo " COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME}" >&2 |
| 69 | + |
| 70 | +TS=$(date +%Y%m%d-%H%M%S) |
| 71 | +HOST_TAG=$(printf '%s' "$HOST" | tr '@:/' '___') |
| 72 | +OUT="./backup-${HOST_TAG}-${COMPOSE_PROJECT_NAME}-${TS}.tar.gz" |
| 73 | +PARTIAL="${OUT}.partial" |
| 74 | + |
| 75 | +trap 'rm -f "$PARTIAL"' EXIT |
| 76 | + |
| 77 | +echo "==> Pakuję zdalnie i pobieram do ${OUT}..." >&2 |
| 78 | + |
| 79 | +# shellcheck disable=SC2087 # heredoc celowo niesquotowane: ${BPP_CONFIGS_DIR} |
| 80 | +# rozwija się lokalnie, a \$HOME / \$CONFIGS_DIR na zdalnym hoście. |
| 81 | +ssh "$HOST" 'bash -s' > "$PARTIAL" <<REMOTE_TAR |
| 82 | +set -euo pipefail |
| 83 | +CONFIGS_DIR="${BPP_CONFIGS_DIR}" |
| 84 | +CONFIGS_PARENT=\$(dirname "\$CONFIGS_DIR") |
| 85 | +CONFIGS_BASE=\$(basename "\$CONFIGS_DIR") |
| 86 | +# Każde -C zmienia katalog roboczy tar-a, więc w archiwum zapisujemy |
| 87 | +# wyłącznie nazwy bazowe (bpp-deploy/, <configs>/) bez prefiksu /home/... |
| 88 | +tar -czf - \\ |
| 89 | + -C "\$HOME" bpp-deploy \\ |
| 90 | + -C "\$CONFIGS_PARENT" "\$CONFIGS_BASE" |
| 91 | +REMOTE_TAR |
| 92 | + |
| 93 | +if [ ! -s "$PARTIAL" ]; then |
| 94 | + echo "ERR: pusty plik backupu — coś poszło nie tak po stronie SSH/tar" >&2 |
| 95 | + exit 1 |
| 96 | +fi |
| 97 | + |
| 98 | +mv "$PARTIAL" "$OUT" |
| 99 | +trap - EXIT |
| 100 | + |
| 101 | +echo "==> Gotowe: ${OUT}" >&2 |
| 102 | +du -h "$OUT" >&2 |
0 commit comments