fix provision: pass PGPASSWORD to psql, fix .env.bak path, accept 403 from rustfs
Some checks are pending
ci/woodpecker/push/deploy Pipeline is running
ci/woodpecker/push/infra-ci Pipeline was successful
coverage 99% coverage
ci/woodpecker/push/ci Pipeline was successful

- provision_postgres: pass PGPASSWORD via docker exec -e so psql
  can authenticate as superuser (was failing with exit 2)
- bootstrap_postgres: same PGPASSWORD fix for all docker exec calls
- deploy.py: fix .env.bak path (was .env.env.bak due to with_suffix)
- verify_rustfs: accept 403 as healthy (RustFS requires auth on health)
- Updated tests for new docker exec -e flag
This commit is contained in:
kert
2026-03-23 10:08:41 -04:00
parent b8a98d6271
commit d0c33848ac
3 changed files with 16 additions and 5 deletions

View File

@@ -94,11 +94,11 @@ def verify_gitea(
def verify_rustfs(*, endpoint: str = "http://rustfs:9000") -> list[str]:
"""Verify RustFS is healthy."""
"""Verify RustFS is reachable (returns 403 = alive, needs auth)."""
errors = []
try:
resp = httpx.get(f"{endpoint}/minio/health/live", timeout=10)
if resp.status_code != 200:
if resp.status_code not in (200, 403):
errors.append(f"rustfs: HTTP {resp.status_code}")
except Exception as e:
errors.append(f"rustfs: {e}")
@@ -167,7 +167,7 @@ def deploy(
# ── Phase 2: Write .env + restart services ────────────────
# Back up current .env
env_bak = env_path.with_suffix(".env.bak")
env_bak = env_path.parent / (env_path.name + ".bak")
if env_path.exists():
shutil.copy2(env_path, env_bak)

View File

@@ -109,13 +109,17 @@ def provision_postgres(values: dict[str, str], *, container: str = "postgres") -
"""Rotate passwords for all managed PostgreSQL roles.
Uses psql -v variable binding so passwords never appear in SQL text.
Authenticates as superuser using POSTGRES_PASSWORD from the values dict.
"""
superuser_pw = values.get("POSTGRES_PASSWORD", "")
for role, env_var in POSTGRES_ROLES.items():
pw = values[env_var]
subprocess.run(
[
"docker",
"exec",
"-e",
f"PGPASSWORD={superuser_pw}",
container,
"psql",
"-U",
@@ -133,10 +137,12 @@ def provision_postgres(values: dict[str, str], *, container: str = "postgres") -
def bootstrap_postgres(values: dict[str, str], *, container: str = "postgres") -> None:
"""Idempotent first-time setup: create roles and databases."""
superuser_pw = values["POSTGRES_PASSWORD"]
pgenv = ["-e", f"PGPASSWORD={superuser_pw}"]
subprocess.run(
[
"docker",
"exec",
*pgenv,
container,
"psql",
"-U",
@@ -158,7 +164,7 @@ def bootstrap_postgres(values: dict[str, str], *, container: str = "postgres") -
f"THEN CREATE ROLE {role} LOGIN; END IF; END $$;"
)
subprocess.run(
["docker", "exec", container, "psql", "-U", "postgres", "-c", sql],
["docker", "exec", *pgenv, container, "psql", "-U", "postgres", "-c", sql],
check=True,
capture_output=True,
)
@@ -166,6 +172,7 @@ def bootstrap_postgres(values: dict[str, str], *, container: str = "postgres") -
[
"docker",
"exec",
*pgenv,
container,
"psql",
"-U",
@@ -182,6 +189,7 @@ def bootstrap_postgres(values: dict[str, str], *, container: str = "postgres") -
[
"docker",
"exec",
*pgenv,
container,
"psql",
"-U",

View File

@@ -167,8 +167,11 @@ class TestProvisionPostgres:
assert mock_run.call_count == len(POSTGRES_ROLES)
for c in mock_run.call_args_list:
cmd = c[0][0]
assert cmd[:3] == ["docker", "exec", "test-pg"]
assert cmd[0] == "docker"
assert cmd[1] == "exec"
assert "test-pg" in cmd
assert "-v" in cmd
assert "-e" in cmd
assert ":'pw'" in cmd[-1]
def test_no_password_in_sql(self):