test(postgres): run the backup round-trip e2e in CI under TIA

Ungate postgres-2-backup-roundtrip: instead of an opt-in env flag it now
runs whenever TIA selects the postgres suite (postgres changes, and every
release cut), like the other chainsaw tests. The blocker was network
placement, not capability: the S3 client is the barman-cloud sidecar
inside the Postgres Pod, and the isolated e2e tenant's Cilium egress
allowlist blocks it from tenant-root's seaweedfs — so the Test runs in
tenant-root (same-tenant egress) against the in-cluster S3 endpoint,
trusting its self-signed cert via the copied seaweedfs-system-ca-cert.
This is exactly the recipe validated end to end on a real cluster.

Also map examples/backups/<app>/ edits to that app's suite in
hack/select-e2e.sh (the round-trip executes those scripts as its
harness; previously such edits were silently ignored), with bats
coverage for both the mapped and the no-suite case.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Andrey Kolkov <androndo@gmail.com>
This commit is contained in:
Andrey KolkovandClaude Fable 5 committed 2026-07-16 21:44:41 +04:00
1 parent 04d74bbfad
commit 50fb3c87c2
7 files changed
+58 -34

No files matched your search

@@ -6,8 +6,8 @@
#
# This manifest is the reference for the same-namespace to-copy happy path:
# deploy it alongside pg-src and the restore leaves the source running. The
# gated postgres backup e2e (hack/e2e-chainsaw/postgres, opt in with
# POSTGRES_E2E_S3_ROUNDTRIP=1) drives exactly this flow via run-all.sh. The
# postgres backup e2e (hack/e2e-chainsaw/postgres, postgres-2-backup-roundtrip)
# drives exactly this flow via run-all.sh in CI. The
# cross-tenant variant (target in tenant-test, source's seaweedfs in
# tenant-root) is blocked by the per-tenant Cilium egress policy.
---
@@ -4,8 +4,8 @@
# untouched.
#
# The reference for the same-namespace happy path, and the final step the
# gated postgres backup e2e (hack/e2e-chainsaw/postgres, opt in with
# POSTGRES_E2E_S3_ROUNDTRIP=1) asserts via run-all.sh. The cross-tenant variant
# postgres backup e2e (hack/e2e-chainsaw/postgres, postgres-2-backup-roundtrip)
# asserts via run-all.sh in CI. The cross-tenant variant
# stays manual; see 30-postgres-target.yaml for the network-policy reason.
---
apiVersion: backups.cozystack.io/v1alpha1
+1 -1
View File
@@ -34,4 +34,4 @@ NAMESPACE=tenant-root examples/backups/postgres/cleanup.sh
## Automated e2e
The Chainsaw suite at `hack/e2e-chainsaw/postgres/` drives this same `run-all.sh` as a second, opt-in test (`postgres-2-backup-roundtrip`). It is gated out of CI because kind has no reachable, CA-trusted S3 endpoint; run it on a real cluster with `POSTGRES_E2E_S3_ROUNDTRIP=1`.
The Chainsaw suite at `hack/e2e-chainsaw/postgres/` drives this same `run-all.sh` as a second test (`postgres-2-backup-roundtrip`), selected by CI whenever the postgres app (or these scripts) change and on every release cut. It runs in `tenant-root` against the in-cluster seaweedfs endpoint — the isolated e2e tenant cannot reach it across the Cilium egress policy, and the external ingress endpoint is an unroutable placeholder in the sandbox.
+1 -1
View File
@@ -13,7 +13,7 @@
# through S3 into the restored copy.
#
# Override NAMESPACE / endpoint / CA via the environment; see 00-helpers.sh.
# hack/e2e-chainsaw/postgres/ drives this file behind POSTGRES_E2E_S3_ROUNDTRIP.
# hack/e2e-chainsaw/postgres/ drives this file as postgres-2-backup-roundtrip.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+22 -28
View File
@@ -136,28 +136,22 @@ spec:
# restored copy — the in-cluster witness that a barman-cloud plugin backup is
# both taken and restorable end to end.
#
# GATED OUT OF CI (opt in with POSTGRES_E2E_S3_ROUNDTRIP=1). The backup path
# cannot succeed in the kind e2e environment:
# - the barman-cloud sidecar backs up to the bucket's EXTERNAL ingress
# endpoint (from the BucketInfo Secret); in CI that is the s3.example.org
# placeholder, which the source Postgres Pod can neither route to nor
# TLS-validate;
# - the in-cluster seaweedfs-s3.tenant-root:8333 endpoint serves HTTPS with a
# self-signed cert — the ObjectStore CAN trust it (run-all.sh copies
# seaweedfs-system-ca-cert into <app>-cnpg-backup-ca and wires endpointCA),
# but the e2e tenant is created with isolated: true
# (hack/e2e-install-cozystack.bats), so the Cilium tenant policy blocks the
# source Pod from reaching tenant-root's seaweedfs.
# The round-trip therefore only works against a reachable, CA-trusted S3
# endpoint (a real cluster). Chainsaw v0.2.15 has no conditional Test-level
# skip, so the gate is a plain in-script conditional that exits 0 in CI with the
# skip reason in the log — the same file runs un-gated on a real cluster with
# just the env var set.
# Runs in tenant-root, not the default tenant-test: the S3 client here is the
# barman-cloud sidecar INSIDE the Postgres Pod, and the e2e tenant is created
# isolated (hack/e2e-install-cozystack.bats) — its Cilium egress allowlist
# blocks a tenant-test Pod from reaching tenant-root's seaweedfs, while a
# tenant-root Pod reaches it over same-tenant egress. The harness targets the
# in-cluster endpoint (S3_ENDPOINT below) instead of the BucketInfo external
# ingress URL, which in CI is an unroutable placeholder, and trusts its
# self-signed cert by copying seaweedfs-system-ca-cert into the per-app
# endpointCA Secret. (The bucket suite's mc checks lean on the same
# tenant-root seaweedfs, just from the test runner via port-forward.)
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
name: postgres-2-backup-roundtrip
spec:
namespace: tenant-root
skipDelete: true
catch:
- events: {}
@@ -186,26 +180,26 @@ spec:
steps:
- name: run
try:
# The 25m budget is the whole documented flow: bucket provisioning, a
# 2-replica source Postgres, the plugin base backup to S3, an empty target
# app, and the purge + re-bootstrap restore (convention 6: justified
# in-line). run-all.sh fails fast on terminal BackupJob/RestoreJob phases
# and stalled HelmReleases rather than polling out the budget.
- script:
timeout: 25m
content: |
set -eu
if [ "${POSTGRES_E2E_S3_ROUNDTRIP:-0}" != "1" ]; then
echo "# S3 backup/restore round-trip gated out of CI: no reachable,"
echo "# CA-trusted S3 endpoint in kind (see comment in this file). Set"
echo "# POSTGRES_E2E_S3_ROUNDTRIP=1 on a real cluster to run it."
exit 0
fi
cd ../../..
[ -x examples/backups/postgres/run-all.sh ] || { echo "postgres backup example scripts not found at examples/backups/postgres" >&2; exit 1; }
NAMESPACE="$NAMESPACE" examples/backups/postgres/run-all.sh
NAMESPACE="$NAMESPACE" S3_ENDPOINT="https://seaweedfs-s3.tenant-root:8333" \
examples/backups/postgres/run-all.sh
check:
($error == null): true
finally:
# Idempotent — a no-op when the round-trip was gated out. Resumes the
# driver-suspended HelmReleases before deleting the RestoreJob so the apps
# are not stranded, then removes every resource the harness created
# (chainsaw did not apply them, so they are not part of automatic cleanup).
# Resumes the driver-suspended HelmReleases before deleting the RestoreJob
# so the apps are not stranded, then removes every resource the harness
# created (chainsaw did not apply them, so they are not part of automatic
# cleanup).
- description: backup-flow cleanup
script:
timeout: 8m
+12
View File
@@ -91,6 +91,18 @@ while IFS= read -r file; do
selected_apps="$selected_apps $app"
trigger_any=1
continue ;;
examples/backups/*/*)
# The etcd and postgres backup round-trip tests execute the example
# scripts under examples/backups/<app>/ as their harness, so an edit
# there must run that app's suite. A dir with no matching suite is a
# docs-only demo and stays ignored (adding it to selected_apps would
# empty the final intersection and trip the full-suite safety net).
app=$(echo "$file" | sed -nE 's,^examples/backups/([^/]+)/.*,\1,p')
if echo "$all_apps" | grep -Fxq "$app"; then
selected_apps="$selected_apps $app"
trigger_any=1
fi
continue ;;
esac
# 3. Full-suite trigger
+18
View File
@@ -152,3 +152,21 @@
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
[ "$(echo "$output" | wc -w)" -gt 5 ]
}
@test "backup example harness edit selects its app suite" {
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
cp -r packages/core/platform/sources "$tmp/sources"
echo "examples/backups/postgres/run-all.sh" > "$tmp/diff"
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
[ "$output" = "postgres" ]
}
@test "backup example without a matching suite selects nothing" {
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
cp -r packages/core/platform/sources "$tmp/sources"
echo "examples/backups/no-such-app/run.sh" > "$tmp/diff"
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources") || true
[ -z "$output" ]
}