Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/backup-restore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ on:
- "lib/env.sh"
- "lib/system.sh"
- "tests/backup_restore_roundtrip.sh"
- "tests/unit_pasarguard.sh"
pull_request:
paths:
- ".github/workflows/backup-restore.yml"
Expand All @@ -24,6 +25,7 @@ on:
- "lib/env.sh"
- "lib/system.sh"
- "tests/backup_restore_roundtrip.sh"
- "tests/unit_pasarguard.sh"
workflow_dispatch:

jobs:
Expand All @@ -46,6 +48,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Install test dependencies
run: |
Expand All @@ -54,3 +58,25 @@ jobs:

- name: Run backup/restore round-trip
run: bash tests/backup_restore_roundtrip.sh "${{ matrix.database }}" "${{ matrix.archive_mode }}"

timescaledb-version-upgrade:
runs-on: ubuntu-latest
timeout-minutes: 45

steps:
- name: Checkout
uses: actions/checkout@v4
Comment thread
coderabbitai[bot] marked this conversation as resolved.
with:
persist-credentials: false

- name: Install test dependencies
run: |
sudo apt-get update
sudo apt-get install -y rsync zip unzip sqlite3

- name: Restore TimescaleDB 2.27 backup into 2.28 destination
env:
TIMESCALE_SOURCE_IMAGE: timescale/timescaledb:2.27.2-pg17
TIMESCALE_TARGET_IMAGE: timescale/timescaledb:2.28.3-pg17
TIMESCALEDB_COMPAT_IMAGE: timescale/timescaledb-ha:pg17-ts2.28-all
run: bash tests/backup_restore_roundtrip.sh timescaledb single
59 changes: 59 additions & 0 deletions lib/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,65 @@ die() {
exit 1
}

# Normalize redundant leading and trailing slashes without requiring the path
# to exist. This keeps legacy SQLite URLs containing five slashes compatible
# while producing the same path used by normal four-slash absolute URLs.
normalize_posix_path() {
local path="$1"

while [[ "$path" == *//* ]]; do
path="${path//\/\//\/}"
done
while [[ "$path" == //* ]]; do
path="${path#/}"
done
while [[ "$path" != "/" && "$path" == */ ]]; do
path="${path%/}"
done

printf '%s\n' "$path"
}

# Return the filesystem path represented by a SQLAlchemy SQLite URL.
# sqlite:///relative.db -> relative.db
# sqlite:////absolute/db -> /absolute/db
# sqlite://///absolute/db -> /absolute/db (legacy installer output)
sqlite_database_path_from_url() {
local url="$1"
local url_part=""
local path=""

[[ "$url" =~ ^sqlite[^:]*:// ]] || return 1

url_part="${url#*://}"
url_part="${url_part%%\?*}"
url_part="${url_part%%#*}"

if [[ "$url_part" == //* ]]; then
path="/${url_part#//}"
elif [[ "$url_part" == /* ]]; then
path="${url_part#/}"
else
path="$url_part"
fi

normalize_posix_path "$path"
}

# Build a SQLAlchemy URL for an absolute SQLite database path. Stripping the
# path's leading slash before adding the URL prefix guarantees exactly four
# slashes after the scheme separator.
sqlite_absolute_database_url() {
local driver="$1"
local path=""

path=$(normalize_posix_path "$2")
[[ "$driver" =~ ^sqlite([+][A-Za-z0-9_]+)?$ ]] || return 1
[[ "$path" == /* ]] || return 1

printf '%s:////%s\n' "$driver" "${path#/}"
}

# Ensure a secret-bearing file (e.g. .env, TLS private key) is only readable by
# its owner. Creates the file with 0600 if it is missing so callers can harden
# it *before* writing secrets; tightens it to 0600 if it already exists. A
Expand Down
Loading
Loading