audits: claper PG 16->17 bench + box proofs; calcom crash evidence
gates / gates (push) Successful in 25s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-28 10:55:25 +02:00
parent a8f790c0c6
commit 5340aec56b
25 changed files with 2215 additions and 0 deletions
@@ -0,0 +1,10 @@
## 2026-09-28T08:52:30Z bench destroy
hostname: upgrade-harness
purging CT 9401 from related configurations..
destroyed-9401
template-removed
VMID Status Lock Name
9201 running demo-hp
9202 running demo-hp-scratch
local-lvm lvmthin active 56487936 31401643 25086292 55.59%
nvme-scratch dir active 983379700 50610460 882742628 5.15%
@@ -0,0 +1,153 @@
[08:35:56] scratch drive folders cleared before FROM (R-656): none existed
[08:35:56] MV-claper: deploying claper at FROM {'claper': 'ghcr.io/claperco/claper:2.5', 'claper-postgres': 'postgres:16-alpine'}
[08:37:30] FROM settled=True in 31.0s :: {"claper": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "claper-postgres": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[08:37:30] fixture: the BOX walk's own (Claper), through upgrade_boxport
[08:37:31] claper: register_user :: DRILL_SEEDED=2
[08:37:32] claper: seeded user drill-dd9e4067@gate.invalid
[08:37:33] claper: readback — the seeded account authenticates=True
[08:37:33] C1 (seed reads back BEFORE): True
[08:37:33] MV-claper: PostgreSQL major move {'service': 'claper-postgres', 'engine': 'postgres', 'from': 16, 'to': 17} — converting on the bench before the swap
[08:38:04] CONVERTED claper-postgres PostgreSQL 16 -> 17 in 30.8s (dump 0.52s / 81588 B, load 1.15s, check equal over 32 tables)
[08:38:04] MV-claper: swapping to TO {'claper': 'ghcr.io/claperco/claper:2.5', 'claper-postgres': 'postgres:17-alpine'}
[08:38:11] TO up -d rc=0
[08:38:42] TO settled=True in 31.0s :: {"claper": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "claper-postgres": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[08:38:42] engine state claper-postgres: 17
[08:38:42] migration lines observed: 1
[08:38:43] claper: readback — the seeded account authenticates=True
[08:38:43] RESULT (seed reads back AFTER): True
[08:38:44] memory watch: 600s, 4 callers on 1 path(s) at 172.18.0.2:4000
[08:38:59] + 15s claper=232M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=300
[08:39:14] + 30s claper=232M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=596
[08:39:29] + 45s claper=233M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=896
[08:39:44] + 61s claper=233M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=1192
[08:39:59] + 76s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=1492
[08:40:15] + 91s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=1788
[08:40:30] + 106s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=2088
[08:40:45] + 121s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=2384
[08:41:00] + 136s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=2684
[08:41:15] + 151s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=158M kills=0 rs=0 reqs=2980
[08:41:30] + 167s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=158M kills=0 rs=0 reqs=3277
[08:41:45] + 182s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=159M kills=0 rs=0 reqs=3576
[08:42:01] + 197s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=155M/256M peak=159M kills=0 rs=0 reqs=3872
[08:42:16] + 212s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=159M kills=0 rs=0 reqs=4172
[08:42:31] + 227s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=159M kills=0 rs=0 reqs=4468
[08:42:46] + 242s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=159M kills=0 rs=0 reqs=4768
[08:43:01] + 257s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=155M/256M peak=159M kills=0 rs=0 reqs=5064
[08:43:16] + 273s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=155M/256M peak=159M kills=0 rs=0 reqs=5364
[08:43:31] + 288s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=157M/256M peak=159M kills=0 rs=0 reqs=5660
[08:43:47] + 303s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=158M/256M peak=161M kills=0 rs=0 reqs=5956
[08:44:02] + 318s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=159M/256M peak=162M kills=0 rs=0 reqs=6256
[08:44:17] + 333s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=161M/256M peak=164M kills=0 rs=0 reqs=6552
[08:44:32] + 348s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=162M/256M peak=164M kills=0 rs=0 reqs=6852
[08:44:47] + 363s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=164M/256M peak=166M kills=0 rs=0 reqs=7148
[08:45:02] + 378s claper=237M/384M peak=291M kills=0 rs=0 claper-postgres=196M/256M peak=199M kills=0 rs=0 reqs=7448
[08:45:17] + 394s claper=237M/384M peak=291M kills=0 rs=0 claper-postgres=196M/256M peak=199M kills=0 rs=0 reqs=7744
[08:45:33] + 409s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=8040
[08:45:48] + 424s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=8340
[08:46:03] + 439s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=8636
[08:46:18] + 454s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=8936
[08:46:33] + 469s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=9232
[08:46:48] + 484s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=9532
[08:47:03] + 500s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=9828
[08:47:19] + 515s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=10128
[08:47:34] + 530s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=10424
[08:47:49] + 545s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=10724
[08:48:04] + 560s claper=237M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=11020
[08:48:19] + 575s claper=237M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=11316
[08:48:34] + 590s claper=237M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=11616
[08:48:49] + 606s claper=237M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=11912
[08:48:50] memory watch: killed=False tight=[] requests=11912 codes={'200': 11912}
[08:48:50] MV-claper: ABORT — putting the FROM images back
[08:52:08] ABORT: the app did NOT come back (rc=1, 184.9s)
{
"harness_version": 4,
"edge": "MV-claper",
"app": "claper",
"note": "night 2026-09-23 within-a-major move: claper-postgres=postgres:17-alpine",
"from": {
"claper": "ghcr.io/claperco/claper:2.5",
"claper-postgres": "postgres:16-alpine"
},
"to": {
"claper": "ghcr.io/claperco/claper:2.5",
"claper-postgres": "postgres:17-alpine"
},
"verdict": "proven",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"migration_observed": "\u001b[2Kclaper | 08:38:11.995 [info] Migrations already up",
"abort": "refuses",
"abort_detail": "th this version 16.15.\n\u001b[2Kclaper-postgres | \n\u001b[2Kclaper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization\n\u001b[2Kclaper-postgres | \n\u001b[2Kclaper-postgres | 2026-09-28 10:50:47.008 CEST [1] FATAL: database files are incompatible with server\n\u001b[2Kclaper-postgres | 2026-09-28 10:50:47.008 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.\n\u001b[2Kclaper-postgres | \n\u001b[2Kclaper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization\n\u001b[2Kclaper-postgres | \n\u001b[2Kclaper-postgres | 2026-09-28 10:51:47.371 CEST [1] FATAL: database files are incompatible with server\n\u001b[2Kclaper-postgres | 2026-09-28 10:51:47.371 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.",
"engine_state_after": {
"claper-postgres": {
"image": "postgres:17-alpine",
"probe": "datadir major version",
"answer": "17",
"probe_rc": 0
}
},
"memory": {
"soak_s": 605.9,
"requested_s": 600,
"requests": 11912,
"codes": {
"200": 11912
},
"first_kill": null,
"containers": {
"claper": {
"limit": 402653184,
"peak": 305352704,
"peak_pct": 0.758,
"anon_peak_sampled": 193683456,
"anon_peak_pct": 0.481,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
},
"claper-postgres": {
"limit": 268435456,
"peak": 210284544,
"peak_pct": 0.783,
"anon_peak_sampled": 24072192,
"anon_peak_pct": 0.09,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
}
},
"unmeasured": [],
"load": "reached"
},
"marks": [],
"duration_s": 31.0,
"measured_at": "2026-09-28T08:52:08Z",
"evidence": "evidence/MV-claper",
"scratch_cleared": [],
"engine_conversion": {
"service": "claper-postgres",
"engine": "postgres",
"from": 16,
"to": 17,
"dump_s": 0.52,
"dump_bytes": 81588,
"new_engine_ready_s": 2.2,
"load_s": 1.15,
"dropped": [
"claper"
],
"skipped_create_role": [
"CREATE ROLE claper;"
],
"result": "converted",
"check_equal": true,
"pg_version": "17",
"tables": 32,
"convert_s": 30.8
},
"files_changed": [],
"total_s": 971.7
}
@@ -0,0 +1,40 @@
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:04.138 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:04.138 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:06.068 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:06.068 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:09.622 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:09.622 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:16.366 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:16.366 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:29.516 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:29.516 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:55.465 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:55.465 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:50:47.008 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:50:47.008 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:51:47.371 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:51:47.371 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
@@ -0,0 +1,14 @@
{
"claper": {
"status": "created",
"health": null,
"restarts": 0,
"exit": 0
},
"claper-postgres": {
"status": "restarting",
"health": "unhealthy",
"restarts": 0,
"exit": 1
}
}
@@ -0,0 +1,60 @@
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:01.258 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:01.258 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:01.719 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:01.719 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:02.264 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:02.264 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:03.000 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:03.000 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:04.138 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:04.138 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:06.068 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:06.068 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:09.622 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:09.622 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:16.366 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:16.366 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:29.516 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:29.516 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:49:55.465 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:49:55.465 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:50:47.008 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:50:47.008 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
claper-postgres |
claper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
claper-postgres |
claper-postgres | 2026-09-28 10:51:47.371 CEST [1] FATAL: database files are incompatible with server
claper-postgres | 2026-09-28 10:51:47.371 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.
@@ -0,0 +1,38 @@
db:claper owner=claper enc=UTF8 coll=en_US.utf8
db:postgres owner=claper enc=UTF8 coll=en_US.utf8
ext:claper:citext
ext:claper:pgcrypto
ext:claper:plpgsql
role:claper super=true login=true pw=true
rows:claper:public.activity_leaders=0
rows:claper:public.audit_logs=0
rows:claper:public.embeds=0
rows:claper:public.events=0
rows:claper:public.form_submits=0
rows:claper:public.forms=0
rows:claper:public.lti_13_deployments=0
rows:claper:public.lti_13_jwks=1
rows:claper:public.lti_13_nonces=0
rows:claper:public.lti_13_registrations=0
rows:claper:public.lti_13_resources=0
rows:claper:public.lti_13_users=0
rows:claper:public.oban_jobs=0
rows:claper:public.oban_peers=1
rows:claper:public.oidc_providers=0
rows:claper:public.oidc_users=0
rows:claper:public.poll_opts=0
rows:claper:public.poll_votes=0
rows:claper:public.polls=0
rows:claper:public.posts=0
rows:claper:public.presentation_files=0
rows:claper:public.presentation_states=0
rows:claper:public.quiz_question_opts=0
rows:claper:public.quiz_questions=0
rows:claper:public.quiz_responses=0
rows:claper:public.quizzes=0
rows:claper:public.reactions=0
rows:claper:public.roles=2
rows:claper:public.schema_migrations=44
rows:claper:public.stats=0
rows:claper:public.users=2
rows:claper:public.users_tokens=0
@@ -0,0 +1,38 @@
db:claper owner=claper enc=UTF8 coll=en_US.utf8
db:postgres owner=claper enc=UTF8 coll=en_US.utf8
ext:claper:citext
ext:claper:pgcrypto
ext:claper:plpgsql
role:claper super=true login=true pw=true
rows:claper:public.activity_leaders=0
rows:claper:public.audit_logs=0
rows:claper:public.embeds=0
rows:claper:public.events=0
rows:claper:public.form_submits=0
rows:claper:public.forms=0
rows:claper:public.lti_13_deployments=0
rows:claper:public.lti_13_jwks=1
rows:claper:public.lti_13_nonces=0
rows:claper:public.lti_13_registrations=0
rows:claper:public.lti_13_resources=0
rows:claper:public.lti_13_users=0
rows:claper:public.oban_jobs=0
rows:claper:public.oban_peers=1
rows:claper:public.oidc_providers=0
rows:claper:public.oidc_users=0
rows:claper:public.poll_opts=0
rows:claper:public.poll_votes=0
rows:claper:public.polls=0
rows:claper:public.posts=0
rows:claper:public.presentation_files=0
rows:claper:public.presentation_states=0
rows:claper:public.quiz_question_opts=0
rows:claper:public.quiz_questions=0
rows:claper:public.quiz_responses=0
rows:claper:public.quizzes=0
rows:claper:public.reactions=0
rows:claper:public.roles=2
rows:claper:public.schema_migrations=44
rows:claper:public.stats=0
rows:claper:public.users=2
rows:claper:public.users_tokens=0
@@ -0,0 +1,8 @@
{
"claper-postgres": {
"image": "postgres:17-alpine",
"probe": "datadir major version",
"answer": "17",
"probe_rc": 0
}
}
@@ -0,0 +1 @@
claper | 08:38:11.995 [info] Migrations already up
@@ -0,0 +1,61 @@
[08:35:56] scratch drive folders cleared before FROM (R-656): none existed
[08:35:56] MV-claper: deploying claper at FROM {'claper': 'ghcr.io/claperco/claper:2.5', 'claper-postgres': 'postgres:16-alpine'}
[08:37:30] FROM settled=True in 31.0s :: {"claper": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "claper-postgres": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[08:37:30] fixture: the BOX walk's own (Claper), through upgrade_boxport
[08:37:31] claper: register_user :: DRILL_SEEDED=2
[08:37:32] claper: seeded user drill-dd9e4067@gate.invalid
[08:37:33] claper: readback — the seeded account authenticates=True
[08:37:33] C1 (seed reads back BEFORE): True
[08:37:33] MV-claper: PostgreSQL major move {'service': 'claper-postgres', 'engine': 'postgres', 'from': 16, 'to': 17} — converting on the bench before the swap
[08:38:04] CONVERTED claper-postgres PostgreSQL 16 -> 17 in 30.8s (dump 0.52s / 81588 B, load 1.15s, check equal over 32 tables)
[08:38:04] MV-claper: swapping to TO {'claper': 'ghcr.io/claperco/claper:2.5', 'claper-postgres': 'postgres:17-alpine'}
[08:38:11] TO up -d rc=0
[08:38:42] TO settled=True in 31.0s :: {"claper": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "claper-postgres": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[08:38:42] engine state claper-postgres: 17
[08:38:42] migration lines observed: 1
[08:38:43] claper: readback — the seeded account authenticates=True
[08:38:43] RESULT (seed reads back AFTER): True
[08:38:44] memory watch: 600s, 4 callers on 1 path(s) at 172.18.0.2:4000
[08:38:59] + 15s claper=232M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=300
[08:39:14] + 30s claper=232M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=596
[08:39:29] + 45s claper=233M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=896
[08:39:44] + 61s claper=233M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=1192
[08:39:59] + 76s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=1492
[08:40:15] + 91s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=1788
[08:40:30] + 106s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=2088
[08:40:45] + 121s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=2384
[08:41:00] + 136s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=157M kills=0 rs=0 reqs=2684
[08:41:15] + 151s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=158M kills=0 rs=0 reqs=2980
[08:41:30] + 167s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=158M kills=0 rs=0 reqs=3277
[08:41:45] + 182s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=159M kills=0 rs=0 reqs=3576
[08:42:01] + 197s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=155M/256M peak=159M kills=0 rs=0 reqs=3872
[08:42:16] + 212s claper=234M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=159M kills=0 rs=0 reqs=4172
[08:42:31] + 227s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=159M kills=0 rs=0 reqs=4468
[08:42:46] + 242s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=154M/256M peak=159M kills=0 rs=0 reqs=4768
[08:43:01] + 257s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=155M/256M peak=159M kills=0 rs=0 reqs=5064
[08:43:16] + 273s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=155M/256M peak=159M kills=0 rs=0 reqs=5364
[08:43:31] + 288s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=157M/256M peak=159M kills=0 rs=0 reqs=5660
[08:43:47] + 303s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=158M/256M peak=161M kills=0 rs=0 reqs=5956
[08:44:02] + 318s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=159M/256M peak=162M kills=0 rs=0 reqs=6256
[08:44:17] + 333s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=161M/256M peak=164M kills=0 rs=0 reqs=6552
[08:44:32] + 348s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=162M/256M peak=164M kills=0 rs=0 reqs=6852
[08:44:47] + 363s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=164M/256M peak=166M kills=0 rs=0 reqs=7148
[08:45:02] + 378s claper=237M/384M peak=291M kills=0 rs=0 claper-postgres=196M/256M peak=199M kills=0 rs=0 reqs=7448
[08:45:17] + 394s claper=237M/384M peak=291M kills=0 rs=0 claper-postgres=196M/256M peak=199M kills=0 rs=0 reqs=7744
[08:45:33] + 409s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=8040
[08:45:48] + 424s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=8340
[08:46:03] + 439s claper=235M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=8636
[08:46:18] + 454s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=8936
[08:46:33] + 469s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=9232
[08:46:48] + 484s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=9532
[08:47:03] + 500s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=9828
[08:47:19] + 515s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=10128
[08:47:34] + 530s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=10424
[08:47:49] + 545s claper=236M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=10724
[08:48:04] + 560s claper=237M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=11020
[08:48:19] + 575s claper=237M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=11316
[08:48:34] + 590s claper=237M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=11616
[08:48:49] + 606s claper=237M/384M peak=291M kills=0 rs=0 claper-postgres=195M/256M peak=200M kills=0 rs=0 reqs=11912
[08:48:50] memory watch: killed=False tight=[] requests=11912 codes={'200': 11912}
[08:48:50] MV-claper: ABORT — putting the FROM images back
[08:52:08] ABORT: the app did NOT come back (rc=1, 184.9s)
@@ -0,0 +1,328 @@
claper-postgres | The files belonging to this database system will be owned by user "postgres".
claper-postgres | This user must also own the server process.
claper-postgres |
claper-postgres | The database cluster will be initialized with locale "en_US.utf8".
claper-postgres | The default database encoding has accordingly been set to "UTF8".
claper-postgres | The default text search configuration will be set to "english".
claper-postgres |
claper-postgres | Data page checksums are disabled.
claper-postgres |
claper-postgres | fixing permissions on existing directory /var/lib/postgresql/data ... ok
claper-postgres | creating subdirectories ... ok
claper-postgres | selecting dynamic shared memory implementation ... posix
claper-postgres | selecting default "max_connections" ... 100
claper-postgres | selecting default "shared_buffers" ... 128MB
claper-postgres | selecting default time zone ... Europe/Budapest
claper-postgres | creating configuration files ... ok
claper-postgres | running bootstrap script ... ok
claper-postgres | sh: locale: not found
claper-postgres | 2026-09-28 10:38:00.936 CEST [41] WARNING: no usable system locales were found
claper-postgres | performing post-bootstrap initialization ... ok
claper-postgres | syncing data to disk ... ok
claper-postgres |
claper-postgres |
claper-postgres | Success. You can now start the database server using:
claper-postgres | initdb: warning: enabling "trust" authentication for local connections
claper-postgres | initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.
claper-postgres |
claper-postgres | pg_ctl -D /var/lib/postgresql/data -l logfile start
claper-postgres |
claper-postgres | waiting for server to start....2026-09-28 10:38:01.684 CEST [47] LOG: starting PostgreSQL 17.11 on x86_64-pc-linux-musl, compiled by gcc (Alpine 15.2.0) 15.2.0, 64-bit
claper-postgres | 2026-09-28 10:38:01.687 CEST [47] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
claper-postgres | 2026-09-28 10:38:01.698 CEST [50] LOG: database system was shut down at 2026-09-28 10:38:01 CEST
claper-postgres | 2026-09-28 10:38:01.707 CEST [47] LOG: database system is ready to accept connections
claper-postgres | done
claper-postgres | server started
claper-postgres | CREATE DATABASE
claper-postgres |
claper-postgres |
claper-postgres | /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
claper-postgres |
claper-postgres | waiting for server to shut down...2026-09-28 10:38:01.867 CEST [47] LOG: received fast shutdown request
claper-postgres | .2026-09-28 10:38:01.871 CEST [47] LOG: aborting any active transactions
claper-postgres | 2026-09-28 10:38:01.875 CEST [47] LOG: background worker "logical replication launcher" (PID 53) exited with exit code 1
claper-postgres | 2026-09-28 10:38:01.875 CEST [48] LOG: shutting down
claper-postgres | 2026-09-28 10:38:01.878 CEST [48] LOG: checkpoint starting: shutdown immediate
claper-postgres | 2026-09-28 10:38:01.954 CEST [48] LOG: checkpoint complete: wrote 926 buffers (5.7%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.025 s, sync=0.040 s, total=0.080 s; sync files=301, longest=0.010 s, average=0.001 s; distance=4266 kB, estimate=4266 kB; lsn=0/191E810, redo lsn=0/191E810
claper-postgres | 2026-09-28 10:38:01.968 CEST [47] LOG: database system is shut down
claper-postgres | done
claper-postgres | server stopped
claper-postgres |
claper-postgres | PostgreSQL init process complete; ready for start up.
claper-postgres |
claper-postgres | 2026-09-28 10:38:02.103 CEST [1] LOG: starting PostgreSQL 17.11 on x86_64-pc-linux-musl, compiled by gcc (Alpine 15.2.0) 15.2.0, 64-bit
claper-postgres | 2026-09-28 10:38:02.103 CEST [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
claper-postgres | 2026-09-28 10:38:02.103 CEST [1] LOG: listening on IPv6 address "::", port 5432
claper-postgres | 2026-09-28 10:38:02.109 CEST [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
claper-postgres | 2026-09-28 10:38:02.118 CEST [63] LOG: database system was shut down at 2026-09-28 10:38:01 CEST
claper-postgres | 2026-09-28 10:38:02.128 CEST [1] LOG: database system is ready to accept connections
claper-postgres | 2026-09-28 10:38:02.980 CEST [61] LOG: checkpoint starting: immediate force wait
claper-postgres | 2026-09-28 10:38:03.008 CEST [61] LOG: checkpoint complete: wrote 4 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.009 s, sync=0.005 s, total=0.028 s; sync files=3, longest=0.003 s, average=0.002 s; distance=0 kB, estimate=0 kB; lsn=0/191EC50, redo lsn=0/191EBF8
claper | warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) or set the ELIXIR_ERL_OPTIONS="+fnu" environment variable
claper | 08:37:01.436 [info] == Running 20211007130631 Claper.Repo.Migrations.CreateUsersAuthTables.change/0 forward
claper | 08:37:01.441 [info] execute "CREATE EXTENSION IF NOT EXISTS citext"
claper | 08:37:01.466 [info] execute "CREATE EXTENSION IF NOT EXISTS pgcrypto"
claper | 08:37:01.472 [info] create table users
claper | 08:37:01.486 [info] create index users_email_index
claper | 08:37:01.491 [info] create index users_uuid_index
claper | 08:37:01.497 [info] create table users_tokens
claper | 08:37:01.508 [info] create index users_tokens_user_id_index
claper | 08:37:01.513 [info] create index users_tokens_uuid_index
claper | 08:37:01.518 [info] create index users_tokens_context_token_index
claper | 08:37:01.524 [info] == Migrated 20211007130631 in 0.0s
claper | 08:37:01.570 [info] == Running 20211007145520 Claper.Repo.Migrations.CreateEvents.change/0 forward
claper | 08:37:01.570 [info] create table events
claper | 08:37:01.585 [info] create index events_id_index
claper | 08:37:01.591 [info] create index events_uuid_index
claper | 08:37:01.596 [info] create index events_user_id_index
claper | 08:37:01.602 [info] == Migrated 20211007145520 in 0.0s
claper | 08:37:01.606 [info] == Running 20211007152922 Claper.Repo.Migrations.CreatePosts.change/0 forward
claper | 08:37:01.607 [info] create table posts
claper | 08:37:01.622 [info] create index posts_uuid_index
claper | 08:37:01.627 [info] create index posts_id_index
claper | 08:37:01.631 [info] create index posts_attendee_identifier_index
claper | 08:37:01.637 [info] create index posts_user_id_index
claper | 08:37:01.641 [info] == Migrated 20211007152922 in 0.0s
claper | 08:37:01.645 [info] == Running 20220111171051 Claper.Repo.Migrations.CreateReactions.change/0 forward
claper | 08:37:01.646 [info] create table reactions
claper | 08:37:01.661 [info] create index reactions_icon_post_id_user_id_index
claper | 08:37:01.667 [info] create index reactions_icon_post_id_attendee_identifier_index
claper | 08:37:01.673 [info] == Migrated 20220111171051 in 0.0s
claper | 08:37:01.677 [info] == Running 20220226210445 Claper.Repo.Migrations.CreatePresentationFiles.change/0 forward
claper | 08:37:01.677 [info] create table presentation_files
claper | 08:37:01.691 [info] create index presentation_files_hash_index
claper | 08:37:01.695 [info] == Migrated 20220226210445 in 0.0s
claper | 08:37:01.699 [info] == Running 20220305222231 Claper.Repo.Migrations.CreatePolls.change/0 forward
claper | 08:37:01.699 [info] create table polls
claper | 08:37:01.708 [info] == Migrated 20220305222231 in 0.0s
claper | 08:37:01.712 [info] == Running 20220305223506 Claper.Repo.Migrations.CreatePollOpts.change/0 forward
claper | 08:37:01.713 [info] create table poll_opts
claper | 08:37:01.720 [info] == Migrated 20220305223506 in 0.0s
claper | 08:37:01.724 [info] == Running 20220314171347 Claper.Repo.Migrations.CreateActivityLeaders.change/0 forward
claper | 08:37:01.725 [info] create table activity_leaders
claper | 08:37:01.734 [info] create index activity_leaders_event_id_email_index
claper | 08:37:01.738 [info] == Migrated 20220314171347 in 0.0s
claper | 08:37:01.742 [info] == Running 20220409094249 Claper.Repo.Migrations.CreatePresentationStates.change/0 forward
claper | 08:37:01.743 [info] create table presentation_states
claper | 08:37:01.758 [info] == Migrated 20220409094249 in 0.0s
claper | 08:37:01.762 [info] == Running 20220418194055 Claper.Repo.Migrations.CreatePollVotes.change/0 forward
claper | 08:37:01.763 [info] create table poll_votes
claper | 08:37:01.775 [info] create index poll_votes_poll_id_user_id_index
claper | 08:37:01.780 [info] create index poll_votes_poll_id_attendee_identifier_index
claper | 08:37:01.785 [info] == Migrated 20220418194055 in 0.0s
claper | 08:37:01.790 [info] == Running 20220419141142 Claper.Repo.Migrations.CreateStats.change/0 forward
claper | 08:37:01.791 [info] create table stats
claper | 08:37:01.799 [info] == Migrated 20220419141142 in 0.0s
claper | 08:37:01.803 [info] == Running 20220420124141 Claper.Repo.Migrations.PresentationFilesAddAudiencePeakColumn.change/0 forward
claper | 08:37:01.803 [info] alter table events
claper | 08:37:01.805 [info] == Migrated 20220420124141 in 0.0s
claper | 08:37:01.808 [info] == Running 20220822205711 Claper.Repo.Migrations.AddHashedPasswordToUsers.change/0 forward
claper | 08:37:01.808 [info] alter table users
claper | 08:37:01.809 [info] == Migrated 20220822205711 in 0.0s
claper | 08:37:01.813 [info] == Running 20230218180723 Claper.Repo.Migrations.CreateForms.change/0 forward
claper | 08:37:01.813 [info] create table forms
claper | 08:37:01.826 [info] == Migrated 20230218180723 in 0.0s
claper | 08:37:01.830 [info] == Running 20230218181013 Claper.Repo.Migrations.CreateFormSubmits.change/0 forward
claper | 08:37:01.831 [info] create table form_submits
claper | 08:37:01.845 [info] create index form_submits_form_id_user_id_index
claper | 08:37:01.850 [info] create index form_submits_form_id_attendee_identifier_index
claper | 08:37:01.856 [info] == Migrated 20230218181013 in 0.0s
claper | 08:37:01.861 [info] == Running 20230419205637 Claper.Repo.Migrations.AddMultipleFromPolls.change/0 forward
claper | 08:37:01.861 [info] alter table polls
claper | 08:37:01.862 [info] drop index poll_votes_poll_id_user_id_index cascade
claper | 08:37:01.864 [info] drop index poll_votes_poll_id_attendee_identifier_index cascade
claper | 08:37:01.866 [info] == Migrated 20230419205637 in 0.0s
claper | 08:37:01.870 [info] == Running 20230421093834 Claper.Repo.Migrations.AddChatEnabledToPresentationStates.change/0 forward
claper | 08:37:01.870 [info] alter table presentation_states
claper | 08:37:01.872 [info] == Migrated 20230421093834 in 0.0s
claper | 08:37:01.875 [info] == Running 20230809172244 Claper.Repo.Migrations.AddAnonymousChatEnabledToPresentationStates.change/0 forward
claper | 08:37:01.875 [info] alter table presentation_states
claper | 08:37:01.877 [info] == Migrated 20230809172244 in 0.0s
claper | 08:37:01.880 [info] == Running 20231020175202 Claper.Repo.Migrations.AddPinnedToPostsAndPresentationStates.change/0 forward
claper | 08:37:01.881 [info] alter table presentation_states
claper | 08:37:01.882 [info] alter table posts
claper | 08:37:01.884 [info] == Migrated 20231020175202 in 0.0s
claper | 08:37:01.887 [info] == Running 20231028144823 Claper.Repo.Migrations.CreateEmbeds.change/0 forward
claper | 08:37:01.887 [info] create table embeds
claper | 08:37:01.902 [info] == Migrated 20231028144823 in 0.0s
claper | 08:37:01.906 [info] == Running 20240323140827 Claper.Repo.Migrations.AddMessageReactionEnabledToPresentationStates.change/0 forward
claper | 08:37:01.906 [info] alter table presentation_states
claper | 08:37:01.907 [info] == Migrated 20240323140827 in 0.0s
claper | 08:37:01.911 [info] == Running 20240405111550 Claper.Repo.Migrations.AddShowPollResultsEnabledToPresentationStates.change/0 forward
claper | 08:37:01.911 [info] alter table presentation_states
claper | 08:37:01.912 [info] == Migrated 20240405111550 in 0.0s
claper | 08:37:01.916 [info] == Running 20240407090614 Claper.Repo.Migrations.AddTimezoneAndLocaleToUsers.change/0 forward
claper | 08:37:01.916 [info] alter table users
claper | 08:37:01.917 [info] == Migrated 20240407090614 in 0.0s
claper | 08:37:01.921 [info] == Running 20240609150059 Claper.Repo.Migrations.AddLtiTables.change/0 forward
claper | 08:37:01.922 [info] create table lti_13_jwks
claper | 08:37:01.934 [info] create table lti_13_registrations
claper | 08:37:01.947 [info] create index lti_13_registrations_client_id_index
claper | 08:37:01.952 [info] create table lti_13_users
claper | 08:37:01.966 [info] create index lti_13_users_sub_registration_id_index
claper | 08:37:01.971 [info] create table lti_13_nonces
claper | 08:37:01.984 [info] create index value_domain_index
claper | 08:37:01.988 [info] create table lti_13_deployments
claper | 08:37:01.997 [info] create table lti_13_resources
claper | 08:37:02.007 [info] create index lti_13_resources_resource_id_registration_id_index
claper | 08:37:02.013 [info] == Migrated 20240609150059 in 0.0s
claper | 08:37:02.018 [info] == Running 20240729152555 Claper.Repo.Migrations.AddOidcUsers.change/0 forward
claper | 08:37:02.018 [info] create table oidc_users
claper | 08:37:02.032 [info] == Migrated 20240729152555 in 0.0s
claper | 08:37:02.036 [info] == Running 20240730123205 Claper.Repo.Migrations.RemoveIsAdminFromUsers.change/0 forward
claper | 08:37:02.036 [info] alter table users
claper | 08:37:02.038 [info] == Migrated 20240730123205 in 0.0s
claper | 08:37:02.042 [info] == Running 20240730123331 Claper.Repo.Migrations.AddIsRandomizedPasswordToUsers.change/0 forward
claper | 08:37:02.042 [info] alter table users
claper | 08:37:02.044 [info] == Migrated 20240730123331 in 0.0s
claper | 08:37:02.047 [info] == Running 20240731132357 Claper.Repo.Migrations.AddProviderToEmbeds.change/0 forward
claper | 08:37:02.047 [info] alter table embeds
claper | 08:37:02.049 [info] == Migrated 20240731132357 in 0.0s
claper | 08:37:02.053 [info] == Running 20240801084601 Claper.Repo.Migrations.AddShowResultsToPolls.change/0 forward
claper | 08:37:02.053 [info] alter table polls
claper | 08:37:02.055 [info] == Migrated 20240801084601 in 0.0s
claper | 08:37:02.060 [info] == Running 20240801084731 Claper.Repo.Migrations.RemoveShowPollResultsEnabledFromPresentationStates.change/0 forward
claper | 08:37:02.060 [info] alter table presentation_states
claper | 08:37:02.061 [info] == Migrated 20240801084731 in 0.0s
claper | 08:37:02.065 [info] == Running 20240801130739 Claper.Repo.Migrations.RemoveUniquenessOfHashFromPresentationFiles.up/0 forward
claper | 08:37:02.066 [info] drop index if exists presentation_files_hash_index
claper | 08:37:02.067 [info] create index presentation_files_hash_event_id_index
claper | 08:37:02.072 [info] == Migrated 20240801130739 in 0.0s
claper | 08:37:02.076 [info] == Running 20240928085505 Claper.Repo.Migrations.CreateQuizzes.change/0 forward
claper | 08:37:02.077 [info] create table quizzes
claper | 08:37:02.086 [info] create table quiz_questions
claper | 08:37:02.098 [info] create table quiz_question_opts
claper | 08:37:02.108 [info] create table quiz_responses
claper | 08:37:02.119 [info] create index quizzes_presentation_file_id_index
claper | 08:37:02.124 [info] create index quiz_questions_quiz_id_index
claper | 08:37:02.128 [info] create index quiz_question_opts_quiz_question_id_index
claper | 08:37:02.133 [info] create index quiz_responses_quiz_id_index
claper | 08:37:02.138 [info] create index quiz_responses_quiz_question_id_index
claper | 08:37:02.143 [info] create index quiz_responses_quiz_question_opt_id_index
claper | 08:37:02.147 [info] create index quiz_responses_user_id_index
claper | 08:37:02.154 [info] == Migrated 20240928085505 in 0.0s
claper | 08:37:02.158 [info] == Running 20241128102850 Claper.Repo.Migrations.AddAttendeesColumnsToStats.up/0 forward
claper | 08:37:02.158 [info] alter table stats
claper | 08:37:02.163 [info] create index stats_event_id_user_id_index
claper | 08:37:02.168 [info] create index stats_event_id_attendee_identifier_index
claper | 08:37:02.174 [info] == Migrated 20241128102850 in 0.0s
claper | 08:37:02.178 [info] == Running 20241207115352 Claper.Repo.Migrations.AddLtiLineItemColumnsToQuizzesAndEvents.change/0 forward
claper | 08:37:02.178 [info] alter table quizzes
claper | 08:37:02.183 [info] alter table lti_13_resources
claper | 08:37:02.190 [info] == Migrated 20241207115352 in 0.0s
claper | 08:37:02.194 [info] == Running 20241207162344 Claper.Repo.Migrations.AddUserIdToLtiRegistrations.change/0 forward
claper | 08:37:02.194 [info] alter table lti_13_registrations
claper | 08:37:02.198 [info] == Migrated 20241207162344 in 0.0s
claper | 08:37:02.202 [info] == Running 20241207195849 Claper.Repo.Migrations.AddObanJobsTable.up/0 forward
claper | 08:37:02.234 [info] execute "DO $$\nBEGIN\nIF NOT EXISTS (SELECT 1 FROM pg_type\n WHERE typname = 'oban_job_state'\n AND typnamespace = 'public'::regnamespace::oid) THEN\n CREATE TYPE \"public\".oban_job_state AS ENUM (\n 'available',\n 'scheduled',\n 'executing',\n 'retryable',\n 'completed',\n 'discarded'\n );\n END IF;\nEND$$;\n"
claper | 08:37:02.237 [info] create table if not exists public.oban_jobs
claper | 08:37:02.251 [info] create index if not exists public.oban_jobs_queue_index
claper | 08:37:02.256 [info] create index if not exists public.oban_jobs_state_index
claper | 08:37:02.262 [info] create index if not exists public.oban_jobs_scheduled_at_index
claper | 08:37:02.269 [info] execute "CREATE OR REPLACE FUNCTION \"public\".oban_jobs_notify() RETURNS trigger AS $$\nDECLARE\n channel text;\n notice json;\nBEGIN\n IF (TG_OP = 'INSERT') THEN\n channel = 'public.oban_insert';\n notice = json_build_object('queue', NEW.queue, 'state', NEW.state);\n\n -- No point triggering for a job that isn't scheduled to run now\n IF NEW.scheduled_at IS NOT NULL AND NEW.scheduled_at > now() AT TIME ZONE 'utc' THEN\n RETURN null;\n END IF;\n ELSE\n channel = 'public.oban_update';\n notice = json_build_object('queue', NEW.queue, 'new_state', NEW.state, 'old_state', OLD.state);\n END IF;\n\n PERFORM pg_notify(channel, notice::text);\n\n RETURN NULL;\nEND;\n$$ LANGUAGE plpgsql;\n"
claper | 08:37:02.270 [info] execute "DROP TRIGGER IF EXISTS oban_notify ON \"public\".oban_jobs"
claper | 08:37:02.271 [info] trigger "oban_notify" for relation "public.oban_jobs" does not exist, skipping
claper | 08:37:02.271 [info] execute "CREATE TRIGGER oban_notify\nAFTER INSERT OR UPDATE OF state ON \"public\".oban_jobs\nFOR EACH ROW EXECUTE PROCEDURE \"public\".oban_jobs_notify();\n"
claper | 08:37:02.272 [info] drop index if exists public.oban_jobs_scheduled_at_index
claper | 08:37:02.273 [info] create index public.oban_jobs_scheduled_at_index
claper | 08:37:02.279 [info] create check constraint worker_length on table public.oban_jobs
claper | 08:37:02.280 [info] create check constraint queue_length on table public.oban_jobs
claper | 08:37:02.281 [info] execute "CREATE OR REPLACE FUNCTION \"public\".oban_wrap_id(value bigint) RETURNS int AS $$\nBEGIN\n RETURN (CASE WHEN value > 2147483647 THEN mod(value, 2147483647) ELSE value END)::int;\nEND;\n$$ LANGUAGE plpgsql IMMUTABLE;\n"
claper | 08:37:02.282 [info] alter table public.oban_jobs
claper | 08:37:02.283 [info] execute "DROP FUNCTION IF EXISTS \"public\".oban_wrap_id(value bigint)"
claper | 08:37:02.284 [info] drop index if exists public.oban_jobs_scheduled_at_index
claper | 08:37:02.285 [info] drop index if exists public.oban_jobs_queue_index
claper | 08:37:02.286 [info] drop index if exists public.oban_jobs_state_index
claper | 08:37:02.286 [info] create index if not exists public.oban_jobs_queue_state_scheduled_at_id_index
claper | 08:37:02.293 [info] create index if not exists public.oban_jobs_attempted_at_id_index
claper | 08:37:02.298 [info] alter table public.oban_jobs
claper | 08:37:02.300 [info] alter table public.oban_jobs
claper | 08:37:02.301 [info] drop index if exists public.oban_jobs_queue_state_scheduled_at_id_index
claper | 08:37:02.302 [info] create index if not exists public.oban_jobs_state_queue_priority_scheduled_at_id_index
claper | 08:37:02.308 [info] execute "CREATE OR REPLACE FUNCTION \"public\".oban_jobs_notify() RETURNS trigger AS $$\nDECLARE\n channel text;\n notice json;\nBEGIN\n IF NEW.state = 'available' THEN\n channel = 'public.oban_insert';\n notice = json_build_object('queue', NEW.queue);\n\n PERFORM pg_notify(channel, notice::text);\n END IF;\n\n RETURN NULL;\nEND;\n$$ LANGUAGE plpgsql;\n"
claper | 08:37:02.309 [info] execute "DROP TRIGGER IF EXISTS oban_notify ON \"public\".oban_jobs"
claper | 08:37:02.310 [info] execute "CREATE TRIGGER oban_notify\nAFTER INSERT ON \"public\".oban_jobs\nFOR EACH ROW EXECUTE PROCEDURE \"public\".oban_jobs_notify();\n"
claper | 08:37:02.310 [info] alter table public.oban_jobs
claper | 08:37:02.319 [info] execute "DO $$\nDECLARE\n version int;\n already bool;\nBEGIN\n SELECT current_setting('server_version_num')::int INTO version;\n SELECT '{cancelled}' <@ enum_range(NULL::\"public\".oban_job_state)::text[] INTO already;\n\n IF already THEN\n RETURN;\n ELSIF version >= 120000 THEN\n ALTER TYPE \"public\".oban_job_state ADD VALUE IF NOT EXISTS 'cancelled';\n ELSE\n ALTER TYPE \"public\".oban_job_state RENAME TO old_oban_job_state;\n\n CREATE TYPE \"public\".oban_job_state AS ENUM (\n 'available',\n 'scheduled',\n 'executing',\n 'retryable',\n 'completed',\n 'discarded',\n 'cancelled'\n );\n\n ALTER TABLE \"public\".oban_jobs RENAME column state TO _state;\n ALTER TABLE \"public\".oban_jobs ADD state \"public\".oban_job_state NOT NULL default 'available';\n\n UPDATE \"public\".oban_jobs SET state = _state::text::\"public\".oban_job_state;\n\n ALTER TABLE \"public\".oban_jobs DROP column _state;\n DROP TYPE \"public\".old_oban_job_state;\n END IF;\nEND$$;\n"
claper | 08:37:02.321 [info] create index if not exists public.oban_jobs_state_queue_priority_scheduled_at_id_index
claper | 08:37:02.322 [info] relation "oban_jobs_state_queue_priority_scheduled_at_id_index" already exists, skipping
claper | 08:37:02.322 [info] alter table public.oban_jobs
claper | 08:37:02.327 [info] create check constraint priority_range on table public.oban_jobs
claper | 08:37:02.329 [info] create check constraint positive_max_attempts on table public.oban_jobs
claper | 08:37:02.330 [info] create check constraint attempt_range on table public.oban_jobs
claper | 08:37:02.331 [info] drop index if exists public.oban_jobs_args_vector
claper | 08:37:02.332 [info] index "oban_jobs_args_vector" does not exist, skipping
claper | 08:37:02.332 [info] drop index if exists public.oban_jobs_worker_gist
claper | 08:37:02.332 [info] index "oban_jobs_worker_gist" does not exist, skipping
claper | 08:37:02.332 [info] drop index if exists public.oban_jobs_attempted_at_id_index
claper | 08:37:02.333 [info] create index if not exists public.oban_jobs_args_index
claper | 08:37:02.335 [info] create index if not exists public.oban_jobs_meta_index
claper | 08:37:02.337 [info] create table if not exists public.oban_peers
claper | 08:37:02.347 [info] execute "ALTER TABLE \"public\".oban_peers SET UNLOGGED"
claper | 08:37:02.359 [info] drop constraint priority_range from table public.oban_jobs
claper | 08:37:02.360 [info] create check constraint non_negative_priority on table public.oban_jobs
claper | 08:37:02.361 [info] execute "DROP TRIGGER IF EXISTS oban_notify ON \"public\".oban_jobs"
claper | 08:37:02.362 [info] execute "DROP FUNCTION IF EXISTS \"public\".oban_jobs_notify()"
claper | 08:37:02.362 [info] execute "COMMENT ON TABLE \"public\".oban_jobs IS '12'"
claper | 08:37:02.363 [info] == Migrated 20241207195849 in 0.1s
claper | 08:37:02.369 [info] == Running 20241223150438 Claper.Repo.Migrations.AddLtiResourceIdToQuizzes.change/0 forward
claper | 08:37:02.369 [info] alter table quizzes
claper | 08:37:02.373 [info] == Migrated 20241223150438 in 0.0s
claper | 08:37:02.377 [info] == Running 20241228162732 Claper.Repo.Migrations.AddDeletedAtToUsers.change/0 forward
claper | 08:37:02.377 [info] alter table users
claper | 08:37:02.378 [info] create index users_deleted_at_index
claper | 08:37:02.384 [info] == Migrated 20241228162732 in 0.0s
claper | 08:37:02.388 [info] == Running 20250102174720 Claper.Repo.Migrations.AddAllowAnonymousToQuizzes.change/0 forward
claper | 08:37:02.388 [info] alter table quizzes
claper | 08:37:02.390 [info] == Migrated 20250102174720 in 0.0s
claper | 08:37:02.393 [info] == Running 20250711135508 Claper.Repo.Migrations.CreateRoles.change/0 forward
claper | 08:37:02.394 [info] create table roles
claper | 08:37:02.406 [info] create index roles_name_index
claper | 08:37:02.410 [info] == Migrated 20250711135508 in 0.0s
claper | 08:37:02.414 [info] == Running 20250711135909 Claper.Repo.Migrations.AddRoleIdToUsers.change/0 forward
claper | 08:37:02.414 [info] alter table users
claper | 08:37:02.418 [info] create index users_role_id_index
claper | 08:37:02.424 [info] == Migrated 20250711135909 in 0.0s
claper | 08:37:02.428 [info] == Running 20250711164053 Claper.Repo.Migrations.CreateOidcProviders.change/0 forward
claper | 08:37:02.428 [info] create table oidc_providers
claper | 08:37:02.439 [info] create index oidc_providers_name_index
claper | 08:37:02.446 [info] create index oidc_providers_issuer_index
claper | 08:37:02.451 [info] == Migrated 20250711164053 in 0.0s
claper | 08:37:02.454 [info] == Running 20251020162958 Claper.Repo.Migrations.AddShowAttendeeCountPresentationState.change/0 forward
claper | 08:37:02.455 [info] alter table presentation_states
claper | 08:37:02.456 [info] == Migrated 20251020162958 in 0.0s
claper | 08:37:02.460 [info] == Running 20260129165937 Claper.Repo.Migrations.CreateAuditLogs.change/0 forward
claper | 08:37:02.460 [info] create table audit_logs
claper | 08:37:02.474 [info] create index audit_logs_inserted_at_index
claper | 08:37:02.480 [info] create index audit_logs_action_inserted_at_index
claper | 08:37:02.485 [info] create index audit_logs_user_id_inserted_at_index
claper | 08:37:02.489 [info] == Migrated 20260129165937 in 0.0s
claper | warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) or set the ELIXIR_ERL_OPTIONS="+fnu" environment variable
claper | Created admin role
claper | Created user role
claper | Created default admin user:
claper | Email: admin@claper.co
claper | Password: claper
claper | IMPORTANT: Please change this password after first login!
claper | warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) or set the ELIXIR_ERL_OPTIONS="+fnu" environment variable
claper | 08:37:06.732 [info] Running ClaperWeb.Endpoint with cowboy 2.13.0 at 0.0.0.0:4000 (http)
claper | 08:37:06.741 [info] Access ClaperWeb.Endpoint at https://present.gate.invalid
claper | 08:37:06.803 [info] {"message":"notifier only receiving messages from its own node, functionality may be degraded","source":"oban","event":"notifier:switch","connectivity_status":"solitary"}
claper | 08:37:06.806 [info] {"message":"peer became leader","node":"claper@245187f8464f","source":"oban","event":"peer:election","leader":true,"was_leader":false}
claper | 08:37:30.034 request_id=GNlvQJWJbXVeLukAAAAh [info] HEAD /
claper | 08:37:30.036 request_id=GNlvQJWJbXVeLukAAAAh [info] Sent 200 in 2ms
claper | 08:37:30.968 request_id=GNlvQM1Cuhs5yVEAAABj [info] GET /
claper | 08:37:30.969 request_id=GNlvQM1Cuhs5yVEAAABj [info] Sent 200 in 884�s
claper | 08:37:32.412 request_id=GNlvQSNQg0Yc2yQAAADD [info] GET /
claper | 08:37:32.413 request_id=GNlvQSNQg0Yc2yQAAADD [info] Sent 200 in 854�s
claper | 08:37:36.747 [info] {"source":"oban","duration":3489,"event":"plugin:stop","plugin":"Oban.Plugins.Pruner","pruned_count":0}
claper | warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) or set the ELIXIR_ERL_OPTIONS="+fnu" environment variable
claper | 08:38:11.995 [info] Migrations already up
claper | warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) or set the ELIXIR_ERL_OPTIONS="+fnu" environment variable
claper | warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) or set the ELIXIR_ERL_OPTIONS="+fnu" environment variable
claper | 08:38:14.979 [info] Running ClaperWeb.Endpoint with cowboy 2.13.0 at 0.0.0.0:4000 (http)
claper | 08:38:14.986 [info] Access ClaperWeb.Endpoint at https://present.gate.invalid
claper | 08:38:15.046 [info] {"message":"notifier only receiving messages from its own node, functionality may be degraded","source":"oban","event":"notifier:switch","connectivity_status":"solitary"}
claper | 08:38:15.047 [info] {"message":"peer became leader","node":"claper@245187f8464f","source":"oban","event":"peer:election","leader":true,"was_leader":false}
claper | 08:38:41.286 request_id=GNlvUSyKFV1eLukAAADh [info] HEAD /
claper | 08:38:41.289 request_id=GNlvUSyKFV1eLukAAADh [info] Sent 200 in 3ms
@@ -0,0 +1,14 @@
{
"claper": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
},
"claper-postgres": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
}
}
@@ -0,0 +1,92 @@
{
"harness_version": 4,
"edge": "MV-claper",
"app": "claper",
"note": "night 2026-09-23 within-a-major move: claper-postgres=postgres:17-alpine",
"from": {
"claper": "ghcr.io/claperco/claper:2.5",
"claper-postgres": "postgres:16-alpine"
},
"to": {
"claper": "ghcr.io/claperco/claper:2.5",
"claper-postgres": "postgres:17-alpine"
},
"verdict": "proven",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"migration_observed": "\u001b[2Kclaper | 08:38:11.995 [info] Migrations already up",
"abort": "refuses",
"abort_detail": "th this version 16.15.\n\u001b[2Kclaper-postgres | \n\u001b[2Kclaper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization\n\u001b[2Kclaper-postgres | \n\u001b[2Kclaper-postgres | 2026-09-28 10:50:47.008 CEST [1] FATAL: database files are incompatible with server\n\u001b[2Kclaper-postgres | 2026-09-28 10:50:47.008 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.\n\u001b[2Kclaper-postgres | \n\u001b[2Kclaper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization\n\u001b[2Kclaper-postgres | \n\u001b[2Kclaper-postgres | 2026-09-28 10:51:47.371 CEST [1] FATAL: database files are incompatible with server\n\u001b[2Kclaper-postgres | 2026-09-28 10:51:47.371 CEST [1] DETAIL: The data directory was initialized by PostgreSQL version 17, which is not compatible with this version 16.15.",
"engine_state_after": {
"claper-postgres": {
"image": "postgres:17-alpine",
"probe": "datadir major version",
"answer": "17",
"probe_rc": 0
}
},
"memory": {
"soak_s": 605.9,
"requested_s": 600,
"requests": 11912,
"codes": {
"200": 11912
},
"first_kill": null,
"containers": {
"claper": {
"limit": 402653184,
"peak": 305352704,
"peak_pct": 0.758,
"anon_peak_sampled": 193683456,
"anon_peak_pct": 0.481,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
},
"claper-postgres": {
"limit": 268435456,
"peak": 210284544,
"peak_pct": 0.783,
"anon_peak_sampled": 24072192,
"anon_peak_pct": 0.09,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
}
},
"unmeasured": [],
"load": "reached"
},
"marks": [],
"duration_s": 31.0,
"measured_at": "2026-09-28T08:52:08Z",
"evidence": "evidence/MV-claper",
"scratch_cleared": [],
"engine_conversion": {
"service": "claper-postgres",
"engine": "postgres",
"from": 16,
"to": 17,
"dump_s": 0.52,
"dump_bytes": 81588,
"new_engine_ready_s": 2.2,
"load_s": 1.15,
"dropped": [
"claper"
],
"skipped_create_role": [
"CREATE ROLE claper;"
],
"result": "converted",
"check_equal": true,
"pg_version": "17",
"tables": 32,
"convert_s": 30.8
},
"files_changed": [],
"total_s": 971.7
}
@@ -1 +1,3 @@
10:35:51 START claper ['claper-postgres=postgres:17-alpine']
10:52:12 DONE claper rc=0 verdict=proven read_before=True read_after=True abort=refuses marks=[] peaks={'claper': 0.758, 'claper-postgres': 0.783} detail='th this version 16.15.\n\x1b[2Kclaper-postgres | \n\x1b[2Kclaper-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization\n\x1b[2Kc' (981s)
10:52:12 QUEUE q2 FINISHED
@@ -0,0 +1,10 @@
git:
branch: main
repo_url: https://gitea.dooplex.hu/admin/app-catalog-drill.git
sync_interval: 15m
token: <redacted>
username: "admin"
hub:
update:
health_timeout: 90s
@@ -0,0 +1,27 @@
{
"app": "claper",
"venue": "box 9202 (drill catalog, controller 0.277.0), the product's guarded Update",
"from": {
"claper": "ghcr.io/claperco/claper:2.5",
"claper-postgres": "postgres:16-alpine"
},
"to": {
"claper": "ghcr.io/claperco/claper:2.5",
"claper-postgres": "postgres:17-alpine"
},
"verdict": "proven",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"engine_conversion": {
"service": "claper-postgres",
"engine": "postgres",
"from": 16,
"to": 17,
"result": "converted",
"controller_line": "update claper: CONVERTED 16 \u2192 17 in 7.244s \u2014 the check is equal (2 database(s), 32 table(s), 52 row(s)), PG_VERSION 17"
},
"duration_s": 47.2,
"measured_at": "2026-09-28T08:53:41Z",
"evidence": "felhom.eu/documentation/audits/pg-calcom-claper-2026-09-28/box/claper/move.txt"
}
@@ -0,0 +1,44 @@
before: pinned={'claper': 'ghcr.io/claperco/claper:2.5', 'claper-postgres': 'postgres:16-alpine'} PG_VERSION=16
drill: d14296c DRILL claper: claper-postgres postgres:16-alpine -> postgres:17-alpine with the engine_conversion mark (box proof)
phase +0.0s backing-up | err=None
phase +19.5s safety-dump | err=None
phase +20.5s pulling | err=None
phase +22.6s copying | err=None
phase +33.8s converting | err=None
phase +41.0s starting | err=None
phase +42.0s verifying | err=None
phase +47.2s done | err=None
claper: readback — the seeded account authenticates=True
2026/09/28 08:53:43 update.go:536: [INFO] [stacks] update claper: accepted — guarded update started
2026/09/28 08:53:43 update.go:1365: [INFO] [stacks] update claper: phase checking
2026/09/28 08:53:43 update.go:786: [INFO] [stacks] update claper: ladder — the last step (1 of 1) — the catalog's current definition
2026/09/28 08:53:43 update.go:800: [INFO] [stacks] update claper: this step CONVERTS claper-postgres PostgreSQL 16 → 17 (the ladder entry's mark); database volume claper_claper_postgres_data
2026/09/28 08:53:43 update.go:816: [INFO] [stacks] update claper: no usable copy on any tier — younger than 24h0m0s and not older than this install's deploy (2026-09-28T08:15:41Z) (found: none) — backing up first
2026/09/28 08:53:43 update.go:1365: [INFO] [stacks] update claper: phase backing-up
2026/09/28 08:54:01 update.go:831: [INFO] [stacks] update claper: precondition met after the backup — Tier 2 (second drive) copy from 2026-09-28T08:53:43Z
2026/09/28 08:54:01 update.go:1365: [INFO] [stacks] update claper: phase safety-dump
2026/09/28 08:54:02 update.go:846: [INFO] [stacks] update claper: safety dump done (1 file(s)) [/mnt/sys_drive/felhom-data/backups/primary/claper/db-dumps/pre-restore-20260928T085401Z-claper-postgres.sql]
2026/09/28 08:54:03 undo.go:287: [INFO] [stacks] update claper: the undo copy will hold 2 named volume(s), 47.8 MiB
2026/09/28 08:54:03 pgconvert.go:340: [INFO] [stacks] update claper: conversion space — database volume claper_claper_postgres_data is 48 MB; the dump needs up to 60 MB + the 2 GB floor; 27.7 GB free beside the stack dir
2026/09/28 08:54:03 update.go:1365: [INFO] [stacks] update claper: phase pinning
2026/09/28 08:54:03 pin.go:373: [INFO] [stacks] update claper: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/claper/docker-compose.yml (claper=ghcr.io/claperco/claper:2.5, claper-postgres=postgres:17-alpine)
2026/09/28 08:54:03 update.go:1365: [INFO] [stacks] update claper: phase pulling
2026/09/28 08:54:04 update.go:1365: [INFO] [stacks] update claper: phase copying
2026/09/28 08:54:15 update.go:1365: [INFO] [stacks] update claper: phase copying
2026/09/28 08:54:15 undo.go:437: [INFO] [stacks] update claper: copied claper_claper_postgres_data → claper_claper_postgres_data.pre-update-20260928T085415Z in 625ms
2026/09/28 08:54:15 update.go:1365: [INFO] [stacks] update claper: phase copying
2026/09/28 08:54:16 undo.go:437: [INFO] [stacks] update claper: copied claper_claper_uploads → claper_claper_uploads.pre-update-20260928T085415Z in 412ms
2026/09/28 08:54:16 update.go:1365: [INFO] [stacks] update claper: phase converting
2026/09/28 08:54:16 pgconvert.go:423: [INFO] [stacks] update claper: CONVERTING claper-postgres PostgreSQL 16 → 17 (volume claper_claper_postgres_data, kept copy claper_claper_postgres_data.pre-update-20260928T085415Z)
2026/09/28 08:54:17 pgconvert.go:468: [INFO] [stacks] update claper: pg_dumpall from 16 done in 544ms — 80 kB, completion line present; before: 2 database(s), 32 table(s), 52 row(s)
2026/09/28 08:54:18 update.go:1365: [INFO] [stacks] update claper: phase converting
2026/09/28 08:54:18 pgconvert.go:484: [INFO] [stacks] update claper: database volume claper_claper_postgres_data emptied (its copy claper_claper_postgres_data.pre-update-20260928T085415Z holds the old datadir, marker checked twice)
2026/09/28 08:54:23 pgconvert.go:513: [INFO] [stacks] update claper: loaded into 17 in 1.125s (dropped the entrypoint's empty database(s) [claper]; skipped CREATE ROLE for [claper])
2026/09/28 08:54:23 pgconvert.go:529: [INFO] [stacks] update claper: CONVERTED 16 → 17 in 7.244s — the check is equal (2 database(s), 32 table(s), 52 row(s)), PG_VERSION 17
2026/09/28 08:54:23 update.go:1365: [INFO] [stacks] update claper: phase starting
2026/09/28 08:54:24 update.go:1365: [INFO] [stacks] update claper: phase verifying
2026/09/28 08:54:30 update.go:997: [INFO] [stacks] update claper: healthy after 5s (the app's health check passed)
2026/09/28 08:54:30 update.go:1015: [INFO] [stacks] update claper: KEEPING the pre-conversion datadir copy claper_claper_postgres_data.pre-update-20260928T085415Z (PostgreSQL 16) until a backup of the converted app is proven
2026/09/28 08:54:30 update.go:1033: [INFO] [stacks] update claper: DONE in 47s
RESULT final_phase=done PG_VERSION=17 seed_after=True verdict=proven
@@ -0,0 +1,5 @@
deploy/reuse claper: True
claper: register_user :: DRILL_SEEDED=4
claper: seeded user drill-d9219d77@gate.invalid
claper: readback — the seeded account authenticates=True
C1 seed reads back BEFORE: True
@@ -0,0 +1,47 @@
"""boxmove.py <phase> <app> <sub> [<svc> <from> <to> <fmj> <tmj>] — Part B's BOX venue on 9202 (drill catalog):
prep: deploy (reuse if installed), seed through the app's own route, read it back (C1)
move: drill commit with the mark → sync → the guarded Update → engine state + seed read back → box verdict JSON
Evidence: B/apps/<app>/box/."""
import json, os, sys, time, subprocess
import walk as w, fixtures
phase, app, sub = sys.argv[1:4]
EVD = f"{w.EV}/box/{app}"; os.makedirs(EVD, exist_ok=True)
TOK = w.SC + "/seed-tokens-box.json"
log = open(f"{EVD}/{phase}.txt", "a", buffering=1)
def say(*a):
w.say(*a); log.write(" ".join(map(str, a)) + "\n")
w.login()
toks = json.load(open(TOK)) if os.path.exists(TOK) else {}
if phase == "prep":
say(f"deploy/reuse {app}: {w.deploy(app, sub)}")
toks[app] = fixtures.FIXTURES[app].seed(w, sub, say)
json.dump(toks, open(TOK, "w"), default=str); os.chmod(TOK, 0o600)
say(f"C1 seed reads back BEFORE: {fixtures.FIXTURES[app].verify(w, sub, toks[app], say)}")
else:
svc, frm, to, fmj, tmj = sys.argv[4:9]
st = w.stack(app); before = (st.get("app_config") or {}).get("pinned_images")
pg = lambda: w.guest(f"docker exec {svc} sh -c 'cat $PGDATA/PG_VERSION' 2>&1").strip()
say(f"before: pinned={before} PG_VERSION={pg()}")
r = subprocess.run([sys.executable, os.path.join(os.path.dirname(__file__), "drillmove.py"), app, svc, frm, to, fmj, tmj], capture_output=True, text=True)
say("drill:", r.stdout.strip().splitlines()[0] if r.stdout else r.stderr[-300:])
w.sync_rescan(app, to)
since = w.guest("date -u +%Y-%m-%dT%H:%M:%SZ").strip()
res = w.press_update(app, poll=1, cap_s=1800)
for p in res.get("phases", []):
log.write(f" phase +{p['t']}s {p['phase']} | err={p['error']}\n")
time.sleep(10)
after_pg = pg(); read = fixtures.FIXTURES[app].verify(w, sub, toks[app], say)
conv = w.guest(f"docker logs --since {since} felhom-controller 2>&1 | grep -E 'update {app}|CONVERT' | grep -v DEBUG | cut -c1-400")
log.write(conv + "\n")
line = next((l for l in conv.splitlines() if "CONVERTED" in l), "")
st = w.stack(app)
verdict = {"app": app, "venue": "box 9202 (drill catalog, controller 0.277.0), the product's guarded Update",
"from": before, "to": (st.get("app_config") or {}).get("pinned_images"),
"verdict": "proven" if (res.get("final_phase") == "done" and read and after_pg == str(tmj)) else "failed",
"seed_read_before": True, "seed_read_after": read, "healthy_after": st.get("state") == "running",
"engine_conversion": {"service": svc, "engine": "postgres", "from": int(fmj), "to": int(tmj),
"result": "converted" if line else "not-seen", "controller_line": line.split("] ", 2)[-1] if line else ""},
"duration_s": res.get("duration_s"), "measured_at": since,
"evidence": f"felhom.eu/documentation/audits/pg-calcom-claper-2026-09-28/box/{app}/move.txt"}
json.dump(verdict, open(f"{EVD}/box-verdict-{app}.json", "w"), indent=2)
say(f"RESULT final_phase={res.get('final_phase')} PG_VERSION={after_pg} seed_after={read} verdict={verdict['verdict']}")
@@ -0,0 +1,39 @@
"""drillmove.py <app> <svc> <from-ref> <to-ref> <from-major> <to-major>
DRILL-ONLY commit: move one PostgreSQL service in the drill catalog and add the ladder entry that carries the
engine_conversion mark, so the box (9202) can prove the conversion through its own guarded Update. The live
catalog's entry is written later ONLY by `upgrade-test.py --write-ladder` from both verdicts."""
import json, re, subprocess, sys
D = "/mnt/5_hdd/felhom.eu/drill/app-catalog-drill"
app, svc, frm, to, fmj, tmj = sys.argv[1:7]
subprocess.run(["git", "-C", D, "pull", "-q", "--rebase", "origin", "main"], check=True)
comp = f"{D}/templates/{app}/docker-compose.yml"
fy = f"{D}/templates/{app}/.felhom.yml"
s = open(comp).read()
assert f"image: {frm}" in s, "from ref not in compose"
pins = {}
cur = None
for line in s.splitlines():
m = re.match(r"^ ([a-z0-9-]+):\s*$", line)
if m: cur = m.group(1)
m = re.match(r"^\s+image:\s*(\S+)", line)
if m and cur: pins[cur] = m.group(1)
s = s.replace(f"image: {frm}", f"image: {to}")
if int(tmj) >= 18: # 18+ wants the volume at /var/lib/postgresql (09 decision 37)
s = re.sub(r"(-\s+[A-Za-z0-9_.-]*postgres[A-Za-z0-9_.-]*:)/var/lib/postgresql/data(\s*)$", r"\1/var/lib/postgresql\2", s, flags=re.M)
open(comp, "w").write(s)
top = dict(pins); top[svc] = to
entry = {"from": pins, "to": top, "verdict": "proven", "tested_at": "DRILL", "harness_version": 4,
"evidence": "DRILL (box proof in progress)", "marks": {"files_may_change": False, "needs_person": None, "memory_tight": False},
"engine_conversion": {"service": svc, "engine": "postgres", "from": int(fmj), "to": int(tmj)}}
f = open(fy).read()
line = " - " + json.dumps(entry) + "\n"
if "update_ladder:" in f:
f = f.replace("update_ladder:\n", "update_ladder:\n", 1)
f = f.rstrip("\n") + "\n" + line if f.rstrip("\n").endswith("}") else f + line
else:
f = f.rstrip("\n") + "\nupdate_ladder:\n" + line
open(fy, "w").write(f)
subprocess.run(["git", "-C", D, "commit", "-q", "-am", f"DRILL {app}: {svc} {frm} -> {to} with the engine_conversion mark (box proof)"], check=True)
subprocess.run(["git", "-C", D, "push", "-q", "origin", "main"], check=True, capture_output=True)
print(subprocess.run(["git", "-C", D, "log", "--oneline", "-1"], capture_output=True, text=True).stdout.strip())
print(subprocess.run(["git", "-C", D, "show", "--stat", "HEAD"], capture_output=True, text=True).stdout[-300:])
@@ -0,0 +1,60 @@
#!/usr/bin/env python3
"""Point guest 9202 at the drill catalog (and a 90 s health timeout), or restore the saved config.
`09` §6.5: `git.repo_url` alone is INERT (R-615) — the cache dir must go too. The saved copy is
`controller.yaml.pre-pg0928` (NOT the older `.pre-28`, which a restore must never pick up).
"""
import re, sys, io
sys.path.insert(0, '.')
import walk as w
VOL = "/var/lib/docker/volumes/felhom-controller-data/_data"
DRILL_REPO = "https://gitea.dooplex.hu/admin/app-catalog-drill.git"
def creds():
for l in io.open("/home/kisfenyo/.git-credentials").read().strip().split("\n"):
m = re.match(r'https://(admin):([^@]+)@gitea\.dooplex\.hu', l)
if m:
return m.group(1), m.group(2)
raise SystemExit("no admin credential")
def to_drill():
u, t = creds()
print(w.guest(f"""
set -e
test -f {VOL}/controller.yaml.pre-pg0928 || cp -p {VOL}/controller.yaml {VOL}/controller.yaml.pre-pg0928
python3 - <<'PY'
import re
p = "{VOL}/controller.yaml"
s = open(p).read()
s = re.sub(r'(^\\s+repo_url: ).*$', r'\\g<1>{DRILL_REPO}', s, count=1, flags=re.M)
s = re.sub(r'(^git:(?:\\n\\s+.*)*?\\n\\s+token: ).*$', r'\\g<1>"{t}"', s, count=1, flags=re.M)
s = re.sub(r'(^git:(?:\\n\\s+.*)*?\\n\\s+username: ).*$', r'\\g<1>"{u}"', s, count=1, flags=re.M)
if not re.search(r'^update:', s, re.M):
s += "update:\\n health_timeout: 90s\\n"
open(p, "w").write(s)
PY
rm -rf {VOL}/catalog-cache {VOL}/data/catalog-cache
docker restart felhom-controller >/dev/null
sleep 15
grep -A6 '^git:' {VOL}/controller.yaml | sed 's/token:.*/token: <redacted>/'
grep -A2 '^update:' {VOL}/controller.yaml
"""))
def restore():
print(w.guest(f"""
set -e
cp -p {VOL}/controller.yaml.pre-pg0928 {VOL}/controller.yaml
rm -rf {VOL}/catalog-cache {VOL}/data/catalog-cache
docker restart felhom-controller >/dev/null
sleep 15
grep -A6 '^git:' {VOL}/controller.yaml | sed 's/token:.*/token: <redacted>/'
grep -c '^update:' {VOL}/controller.yaml || true
"""))
if __name__ == "__main__":
to_drill() if sys.argv[1] == "drill" else restore()