From 9fb31dfa9e4d36276400b81187e63d985217acc0 Mon Sep 17 00:00:00 2001 From: Ramon Date: Mon, 3 Aug 2026 22:36:26 +0200 Subject: [PATCH] v0.8.06-beta - de backuptest in de CI struikelde over postgres Vier runs op rij faalden op "psql: connection to server on socket ... No such file or directory". Het officiele postgres-image start bij een eerste run eerst een tijdelijke server om de init-scripts te draaien, stopt die, en start dan pas de echte. pg_isready meldt tijdens die tijdelijke server al "klaar", dus kwam de volgende opdracht net in het gat daarna, dan was de socket weg. - de wachtlus voert nu echte query's uit en gaat pas door na twee geslaagde achter elkaar; bij een time-out staat de laatste fout erbij - een achtergebleven testcontainer wordt voor de start opgeruimd, want een geannuleerde run draait zijn opruimblok niet De deploy zelf werkte al die tijd; deze stap draait erna. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy --- CHANGELOG.md | 27 +++++++++++++++++++++++ VERSION | 2 +- tools/backup_rondgang.py | 47 +++++++++++++++++++++++++++++++--------- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bed7f3..e8891d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,30 @@ +# v0.8.06-beta — De backuptest in de CI struikelde over postgres + +Vier CI-runs op rij faalden, en niet op iets in Server Up: de backup-rondgang +die sinds v0.7.96 in de CI draait, viel om op + +``` +psql: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed +``` + +Het officiële postgres-image start bij een eerste run **twee** servers: eerst +een tijdelijke op de socket om de init-scripts te draaien, die daarna stopt, en +pas dan de echte. `pg_isready` meldt tijdens die tijdelijke server al "klaar". +Kwam de volgende opdracht net in het gat daartussen, dan was de socket weg. Een +race, dus soms goed en soms niet. + +De wachtlus kijkt nu niet meer naar `pg_isready` maar voert echte query's uit, +en gaat pas door na twee geslaagde achter elkaar — één toevallige treffer op de +tijdelijke server overleeft dat niet. Bij een time-out staat de laatste fout +erbij in plaats van alleen "kwam niet op". + +Verder wordt een achtergebleven testcontainer nu vóór de start opgeruimd. Een +geannuleerde run draait zijn opruimblok niet, en een half geïnitialiseerde +datamap levert daarna raadselachtige fouten op. + +De deploy zelf werkte al die tijd gewoon; deze stap draait er ná en liet alleen +de job rood kleuren. + # v0.8.05-beta — Een onbereikbaar pad liet zich gewoon opslaan Dit is de oorzaak van de lege appslijst waar de vorige vier uitgaven omheen diff --git a/VERSION b/VERSION index 9344553..fec0c18 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.8.05-beta +0.8.06-beta diff --git a/tools/backup_rondgang.py b/tools/backup_rondgang.py index 470c544..7075ce2 100644 --- a/tools/backup_rondgang.py +++ b/tools/backup_rondgang.py @@ -55,26 +55,47 @@ def mislukt(tekst: str) -> None: raise SystemExit(1) -def psql(sql: str, verwacht_fout: bool = False) -> str: - """Voer SQL uit in de draaiende container.""" - r = subprocess.run( +def _psql(sql: str): + return subprocess.run( ["docker", "exec", "-e", f"PGPASSWORD={WACHTWOORD}", f"{STACK}-db", "psql", "-U", STACK, "-d", STACK, "-tAc", sql], capture_output=True, text=True, timeout=120) - if r.returncode != 0 and not verwacht_fout: + + +def psql(sql: str) -> str: + """Voer SQL uit in de draaiende container.""" + r = _psql(sql) + if r.returncode != 0: mislukt(f"psql mislukte: {(r.stderr or r.stdout).strip()[:300]}") return (r.stdout or "").strip() def wacht_op_postgres(pogingen: int = 60) -> None: + """Wacht tot psql het écht doet — niet tot pg_isready dat zegt. + + Het officiële postgres-image start bij een eerste run eerst een tijdelijke + server op de socket om de init-scripts te draaien, stopt die daarna, en + start pas dan de echte. `pg_isready` zegt tijdens die tijdelijke server al + "ok". Kwam de volgende opdracht net in het gat daarna, dan was er geen + socket meer: "connection to server on socket ... No such file or + directory". Een race, dus soms goed en soms niet. + + Twee keer achter elkaar een geslaagde query is het antwoord: één toevallige + treffer op de tijdelijke server overleeft dat niet. + """ + goed_achtereen = 0 + laatste = "" for _ in range(pogingen): - r = subprocess.run(["docker", "exec", f"{STACK}-db", - "pg_isready", "-U", STACK], - capture_output=True, text=True) + r = _psql("SELECT 1") if r.returncode == 0: - return + goed_achtereen += 1 + if goed_achtereen >= 2: + return + else: + goed_achtereen = 0 + laatste = (r.stderr or r.stdout or "").strip().splitlines()[:1] time.sleep(2) - mislukt("postgres kwam niet op") + mislukt(f"postgres kwam niet op: {laatste}") def main() -> None: @@ -110,7 +131,13 @@ def main() -> None: try: kop("1. Stack starten en vullen") - if docker.compose_up(stackmap, name=STACK) != 0: + # Een afgebroken of geannuleerde vorige run draait zijn opruimblok niet. + # Een achtergebleven container met een half geïnitialiseerde datamap + # levert daarna raadselachtige fouten op. + subprocess.run(["docker", "rm", "-f", f"{STACK}-db"], + capture_output=True, timeout=120) + if docker.compose_up(stackmap, log_fn=lambda m: print(f" · {m}"), + name=STACK) != 0: mislukt("de stack startte niet") wacht_op_postgres() psql("CREATE TABLE proef (id int, tekst text);")