From 1af6d828f5dcced5af4b279ba11f9f0236f56811 Mon Sep 17 00:00:00 2001 From: tegwick Date: Wed, 21 Oct 2026 08:38:12 +0200 Subject: [PATCH] RAPPS-WP-0014-T04: record isolated target-hardware Vergabe replay Throwaway namespace on railiance01 ran the deployed digest (3 workers, 60m/1000m CPU, 256Mi/1Gi) against fresh PostgreSQL 16 with the phased synthetic profile: ordinary p95 0.192s, transfer p95 0.076s, zero errors. Raw cgroup/node/Prometheus samples, manifests, driver and a bounded recommendation retained; namespace torn down; T03 unchanged. Co-Authored-By: Claude Opus 5.5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 8340@bnt-lap001 Assistant-Session: 2e192b3d-b3e8-4403-94d4-d55a2c8b476c --- WORK-RECORDS.md | 2 +- .../README.md | 155 +++ .../analysis.json | 923 ++++++++++++++ .../harness/analyze.py | 73 ++ .../harness/bench.yaml | 125 ++ .../harness/driver-config.json | 53 + .../harness/driver.yaml | 29 + .../harness/executed-synthetic_pilot.py | 1091 +++++++++++++++++ .../harness/orchestrate.sh | 15 + .../harness/prom.py | 25 + .../harness/sampler.sh | 16 + .../harness/synthetic_settings.py | 12 + .../harness/top.sh | 3 + .../raw/app-cgroup.txt.gz | Bin 0 -> 30529 bytes .../raw/db-cgroup.txt.gz | Bin 0 -> 29035 bytes .../raw/driver-cgroup.txt.gz | Bin 0 -> 28201 bytes .../raw/driver-stdout.txt | 1 + .../raw/kubectl-top.txt.gz | Bin 0 -> 8104 bytes .../raw/namespace-events.txt | 36 + .../raw/pod-provenance.txt | 4 + .../raw/prometheus-baseline.json.gz | Bin 0 -> 7943 bytes .../raw/prometheus-workload.json.gz | Bin 0 -> 10883 bytes .../raw/result.json.gz | Bin 0 -> 58759 bytes .../raw/teardown.txt | 7 + .../raw/windows.txt | 4 + .../RAPPS-WP-0014-vergabe-invited-pilot.md | 19 +- 26 files changed, 2590 insertions(+), 3 deletions(-) create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/README.md create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/analysis.json create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/harness/analyze.py create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/harness/bench.yaml create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/harness/driver-config.json create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/harness/driver.yaml create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/harness/executed-synthetic_pilot.py create mode 100755 docs/evidence/2026-10-21-vergabe-target-replay/harness/orchestrate.sh create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/harness/prom.py create mode 100755 docs/evidence/2026-10-21-vergabe-target-replay/harness/sampler.sh create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/harness/synthetic_settings.py create mode 100755 docs/evidence/2026-10-21-vergabe-target-replay/harness/top.sh create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/raw/app-cgroup.txt.gz create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/raw/db-cgroup.txt.gz create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/raw/driver-cgroup.txt.gz create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/raw/driver-stdout.txt create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/raw/kubectl-top.txt.gz create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/raw/namespace-events.txt create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/raw/pod-provenance.txt create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/raw/prometheus-baseline.json.gz create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/raw/prometheus-workload.json.gz create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/raw/result.json.gz create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/raw/teardown.txt create mode 100644 docs/evidence/2026-10-21-vergabe-target-replay/raw/windows.txt diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index 94d107d..f7c5fa8 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -34,7 +34,7 @@ | task | RAPPS-WP-0014-T01 | done | — | workplans/RAPPS-WP-0014-vergabe-invited-pilot.md | | task | RAPPS-WP-0014-T02 | done | — | workplans/RAPPS-WP-0014-vergabe-invited-pilot.md | | task | RAPPS-WP-0014-T03 | wait | — | workplans/RAPPS-WP-0014-vergabe-invited-pilot.md | -| task | RAPPS-WP-0014-T04 | todo | — | workplans/RAPPS-WP-0014-vergabe-invited-pilot.md | +| task | RAPPS-WP-0014-T04 | done | — | workplans/RAPPS-WP-0014-vergabe-invited-pilot.md | | task | RAPPS-WP-0015-T01 | done | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md | | task | RAPPS-WP-0015-T02 | done | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md | | task | RAPPS-WP-0015-T03 | done | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md | diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/README.md b/docs/evidence/2026-10-21-vergabe-target-replay/README.md new file mode 100644 index 0000000..ef9c237 --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/README.md @@ -0,0 +1,155 @@ +# Vergabe target-hardware synthetic replay — 2026-10-21 + +Task: `RAPPS-WP-0014-T04` (feeds `CUST-WP-0071-T02`, `RESOURCE-WP-0008-T02`). +Authority: founder decision of 2026-10-21 +(`the-custodian/docs/decisions/2026-10-21-cust-wp-0071-delivery-interview.md`): +isolated replay in a throwaway namespace on railiance01, reads elsewhere only. +No customer data was read or written; the live `vergabe-demo-company` deployment, +its database (`apps-pg`), quotas, policies and nodes were not modified (live +Deployment generation 4, same digest, Ready 1/1 before and after). No Secret was +read. This is synthetic sizing evidence, not human/recovery acceptance (T03). + +## Deployed release (read-only capture, 2026-10-21) + +| Item | Value | +| --- | --- | +| Cluster / node | context `default` → 92.205.62.239, single k3s v1.35.1 control-plane node | +| Node CPU / memory | 4 vCPU `AMD EPYC Processor (with IBPB)`, 16 GiB; requests 3605m (90%) / limits 37500m; reservation residual 395m | +| Image | `forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91` (source `c067993`, per `docs/vergabe-demo-company-binding.md`) | +| Chart / rollout | `vergabe-teilnahme-0.2.1`, one replica, Recreate, init `migrate`; Deployment revision 4 (rollout restart 2026-09-25). Helm release revision not re-read (release storage is a Secret) | +| Gunicorn | no command override → image CMD `--workers 3` (sync), default 30s timeout | +| Resources (app and migrate) | requests 60m CPU / 256Mi, limits 1000m CPU / 1Gi | +| Settings | `vergabe_teilnahme.settings.prod`, SSO via NetKingdom, `envFrom` Secret reference `vergabe-demo-env` (not read) | +| Database binding | namespace label `railiance.io/postgres-client=apps-pg`: shared CNPG `databases/apps-pg`, PostgreSQL 16, 100m/256Mi request, 1000m/1Gi limit, WAL archiving + `wal_level=logical` | +| Storage | media 5Gi and app-state 1Gi PVCs, `local-path` | + +Drift vs. the 2026-10-19 local test image (`vergabe-synthetic:local-11f7c8a`, +`sha256:57da46…`): source `11f7c8a` is 16 commits ahead of deployed `c067993`; +9 application files differ (+181/−10: ausschreibungen forms/views/templates, +core views, search partial); Dockerfile, `uv.lock`, `pyproject.toml` identical. +The local runs used 2 workers; the deployed image runs 3. This replay used the +deployed digest itself, so the drift does not affect these results. + +## Replay configuration (pinned) + +Namespace `vergabe-sizing-20261021` (manifests in `harness/bench.yaml`, +`harness/driver.yaml`), all pods on the same node: + +- **app**: deployed digest, image CMD (3 workers), init `migrate`, 60m/256Mi request, + 1000m/1Gi limit, live securityContext/probes, Recreate; media on a fresh + `local-path` PVC, issue state emptyDir. Settings = harness synthetic settings + (`harness/synthetic_settings.py`: base settings, SSO off, password login). +- **db**: fresh `docker.io/library/postgres@sha256:4b7183ac…` (PostgreSQL 16), + emptyDir, 100m/256Mi request, 1000m/1Gi limit (matching apps-pg resources). +- **driver**: deployed digest running `vergabe-teilnahme/scripts/synthetic_pilot.py` + `runtime: remote` (commit `dca6683`; executed copy and config retained, digests + `c8da867f…` / `9045f2c7…` match `raw/result.json.gz`), 100m request/1000m limit. + In-cluster HTTP via ClusterIP Service — chosen over port-forward so latency + excludes the WSL/SSH tunnel. Restart deletes the app pod through a namespaced + Role (pods get/list/delete) and waits for a different ready pod. +- NetworkPolicy: ingress/egress within the namespace, DNS, API server only; + preflight confirmed the live Service was unreachable. +- Profile `config/synthetic-pilot-phases.json` unchanged except runtime fields + (`synthetic-pilot-target-remote.json`): 2 users, 100 seed tenders, 1 MiB + documents, 30s idle, 90s ordinary (0.2s think), 30s burst (0 think), restart, + 60s recovery; 11 named operations including edits. +- Sampling: 1s cgroup v2 `cpu.stat`/`memory.current`/`cpu.pressure` inside app, + db and driver containers plus node-wide `/proc/stat` (`harness/sampler.sh`); + `kubectl top` every 15s; Prometheus (cadvisor) per-namespace CPU/throttling. + The sampler shell itself costs ~11–12m per container and is included. + +Timeline (UTC): namespace created 06:26; pre-run idle baseline 06:27:14–06:29:26; +harness idle 06:29:31–06:30:01; ordinary 06:30:01–06:31:32; burst –06:32:03; +restart –06:32:22 (18.98s to ready incl. migrate); recovery –06:33:23; post +idle –06:34:28; namespace deletion requested 06:35:25, completed 06:36:18; namespace and its PV verified absent (`raw/teardown.txt`). + +## Results + +Driver: complete, `provisional_pass: true`, `measurement_complete: true`, no gaps. + +| Phase | Ordinary req / err / p95 | Transfer req / err / p95 | +| --- | --- | --- | +| ordinary | 1903 / 0 / 0.142s | 422 / 0 / 0.085s | +| burst | 697 / 0 / 0.192s | 154 / 0 / 0.069s | +| recovery | 1075 / 0 / 0.214s | 238 / 0 / 0.073s | +| **all** | **3675 / 0 / 0.192s** | **814 / 0 / 0.076s** | + +Per operation p95 (all phases): list 0.262s, search 0.255s, detail 0.146s, +creates/edits 0.059–0.066s, upload 0.088s, download 0.050s; login 1.27s and +login form 0.62s (n=6, first requests after idle). ~24.7 requests/s closed loop — +far above two human users' pace. + +| Window | App CPU mean / p95 / peak | Throttled periods | App memory peak | DB CPU mean / p95 | Node busy mean (free mean / free p5) | +| --- | --- | --- | --- | --- | --- | +| pre-run baseline | 12m / 15m / 16m | 0% | 166 MiB | 22m / 66m | 1348m (2652m / 1499m) | +| ordinary | 711m / 845m / 1003m | 20.4% | 403 MiB | 388m / 501m | 2979m (1021m / 78m) | +| burst | 953m / 1004m / 1011m | 65.8% | 482 MiB | 430m / 539m | 2806m (1194m / 278m) | +| recovery | 861m / 957m / 982m | 41.5% | 322 MiB | 335m / 399m | 2624m (1376m / 392m) | +| all load phases | 775m / 998m / 1020m | 35.7% (22.8s throttled) | 483 MiB | 341m / 500m | 2790m (1210m / 147m) | +| post | 12m | 0% | 323 MiB | 22m | 1413m (2587m) | + +App memory is cgroup `memory.current` (includes page cache); no OOM, no restarts. +CPU pressure (PSI some) on the app was 15–21% of wall time under load. +Incremental PostgreSQL CPU ≈ 320m mean / ~480m p95 over its idle baseline, on +the isolated DB only (live `apps-pg` stayed at ~8m during the window). Driver +added ~84m mean. + +Competing workloads (Prometheus, workload window): all containers 1622m mean, of +which the replay namespace 915m; others led by databases 121m, state-hub 120m, +telemetry 102m, forgejo 78m (max 385m), activity-core 59m, core-hub 43m; live +vergabe ~0m. Node-wide busy includes ~0.7 core of k3s/system outside containers. +Pre-run competing load left ~2.65 cores free on average; during the replay the +node reached near-saturation at peaks (free p5 ~150m) largely through the replay +itself (app + db + driver ≈ 1.2 cores). Requests during the run were 3865m of +4000m (replay 260m of the 395m residual, released at teardown). + +## Coverage and gaps + +- Representative: exact deployed image/digest, worker count, CPU/memory + requests and limits (CFS quota 100000/100000 verified), Recreate + init migrate + restart path, target hardware and real shared node contention. +- Not representative: synthetic settings instead of prod (no SSO/OIDC, insecure + cookies, no whitenoise manifest storage); no Traefik ingress/TLS/browser; DB is a + standalone PostgreSQL 16 pod, not shared CNPG `apps-pg` (WAL archiving, logical + WAL, other tenants) — the ~320m incremental DB demand would land on apps-pg's + 1000m limit/100m request in production and is not proven there. +- Load is a synthetic closed loop (~25 req/s), not observed human demand; one run + with ~3.5 min of load (pinned profile), ~9 min namespace lifetime. +- Node contention was partly self-induced; contention from other tenants was + light at this hour. A busier moment (forgejo CI, backups) is not covered. +- The 60m request is a scheduling weight/reservation, not a quota; the 1000m + limit is the quota that throttled. Sampler exec overhead is in the app cgroup. + +## Bounded recommendation (for RESOURCE-WP-0008-T02 / CUST-WP-0071-T02) + +- **CPU limit 1000m: keep.** Under an aggressive synthetic mix it throttles + (36% of periods, 66% in burst) yet ordinary p95 stays ≤0.22s per phase — ~9× + margin to the 2s target, zero failed operations, including restart recovery. +- **CPU request 60m: keep for the two-user invited pilot**, provisionally. Even + with the node near saturation and only a 60m weight, latency stayed far inside + target; two humans generate a small fraction of this load. Raising it (e.g. + 250m) is not required by these results and would consume most of the 395m + residual — an allocation-owner decision, not made here. +- **Memory limit 1Gi: keep** (peak 483 MiB incl. page cache, ~2× margin). + **Memory request 256Mi: keep, consider 512Mi** at the next allocation review, + since loaded working set (320–480 MiB) exceeds the request; node memory requests + are 61%, so this is low-risk but not urgent. +- **Database**: budget ~0.3–0.5 core incremental on apps-pg at this synthetic + rate; acceptable against its 1000m limit for a two-user pilot, unverified on the + shared cluster. +- **Revisit when**: user count/companies or corpus grow, image or worker count + changes, live p95 >1s or any 5xx, node requests >95% or sustained node free CPU + <500m outside benchmarks, apps-pg CPU >600m sustained, or the pilot moves to + railiance02/other hardware. + +## Files + +- `analysis.json` — per-window cgroup statistics, per-operation p95, phase results + (`harness/analyze.py raw/ analysis.json` after gunzip) +- `raw/result.json.gz` — driver output (all operations, phase UTC windows, host facts) +- `raw/{app,db,driver}-cgroup.txt.gz` — 1s cgroup/node samples (`POD` lines mark + the restart re-attach; the `exit code 137` exec termination is that restart) +- `raw/kubectl-top.txt.gz`, `raw/prometheus-{baseline,workload}.json.gz` +- `raw/windows.txt`, `raw/pod-provenance.txt`, `raw/namespace-events.txt`, + `raw/teardown.txt`, `raw/driver-stdout.txt` +- `harness/` — manifests, settings, samplers, orchestrator, executed driver/config diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/analysis.json b/docs/evidence/2026-10-21-vergabe-target-replay/analysis.json new file mode 100644 index 0000000..06ef31f --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/analysis.json @@ -0,0 +1,923 @@ +{ + "windows_utc": { + "baseline_pre": [ + "2026-10-21T06:27:14.447540Z", + "2026-10-21T06:29:26.175778Z" + ], + "harness_idle": [ + "2026-10-21T06:29:31.522662Z", + "2026-10-21T06:30:01.522800Z" + ], + "ordinary": [ + "2026-10-21T06:30:01.523056Z", + "2026-10-21T06:31:32.589152Z" + ], + "burst": [ + "2026-10-21T06:31:32.589194Z", + "2026-10-21T06:32:03.275085Z" + ], + "restart": [ + "2026-10-21T06:32:03.275117Z", + "2026-10-21T06:32:22.256585Z" + ], + "recovery": [ + "2026-10-21T06:32:22.256609Z", + "2026-10-21T06:33:23.057045Z" + ], + "workload_all_load_phases": [ + "2026-10-21T06:30:01.523056Z", + "2026-10-21T06:33:23.057045Z" + ], + "post": [ + "2026-10-21T06:33:22.885983Z", + "2026-10-21T06:34:28.753426Z" + ] + }, + "cgroup": { + "app": { + "pods": [ + "vergabe-app-579448bf49-2fsn2", + "vergabe-app-579448bf49-plp4j" + ], + "baseline_pre": { + "samples": 126, + "seconds": 128.0, + "cpu_mean_m": 12.2, + "cpu_p95_m": 14.7, + "cpu_peak_m": 16.2, + "cfs_periods": 317, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.002, + "mem_peak_mib": 165.6, + "mem_mean_mib": 165.2, + "node_busy_mean_m": 1348, + "node_busy_p95_m": 2501, + "node_free_mean_m": 2652, + "node_free_p5_m": 1499, + "load1_max": 4.91 + }, + "harness_idle": { + "samples": 28, + "seconds": 28.4, + "cpu_mean_m": 11.5, + "cpu_p95_m": 13.4, + "cpu_peak_m": 13.6, + "cfs_periods": 76, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.002, + "mem_peak_mib": 165.3, + "mem_mean_mib": 165.1, + "node_busy_mean_m": 1538, + "node_busy_p95_m": 2800, + "node_free_mean_m": 2462, + "node_free_p5_m": 1200, + "load1_max": 2.91 + }, + "ordinary": { + "samples": 88, + "seconds": 90.2, + "cpu_mean_m": 711.4, + "cpu_p95_m": 845.4, + "cpu_peak_m": 1003.2, + "cfs_periods": 902, + "cfs_throttled_periods": 184, + "throttle_ratio": 0.204, + "throttled_seconds": 4.85, + "psi_cpu_some_share": 0.15, + "mem_peak_mib": 402.5, + "mem_mean_mib": 295.2, + "node_busy_mean_m": 2979, + "node_busy_p95_m": 3922, + "node_free_mean_m": 1021, + "node_free_p5_m": 78, + "load1_max": 7.83 + }, + "burst": { + "samples": 29, + "seconds": 29.9, + "cpu_mean_m": 952.9, + "cpu_p95_m": 1003.7, + "cpu_peak_m": 1011.1, + "cfs_periods": 298, + "cfs_throttled_periods": 196, + "throttle_ratio": 0.658, + "throttled_seconds": 8.94, + "psi_cpu_some_share": 0.211, + "mem_peak_mib": 481.8, + "mem_mean_mib": 443.4, + "node_busy_mean_m": 2806, + "node_busy_p95_m": 3722, + "node_free_mean_m": 1194, + "node_free_p5_m": 278, + "load1_max": 8.19 + }, + "restart": { + "samples": 10, + "seconds": 10.3, + "cpu_mean_m": 403.3, + "cpu_p95_m": 1019.7, + "cpu_peak_m": 1019.7, + "cfs_periods": 54, + "cfs_throttled_periods": 39, + "throttle_ratio": 0.722, + "throttled_seconds": 2.37, + "psi_cpu_some_share": 0.235, + "mem_peak_mib": 483.3, + "mem_mean_mib": 154.0, + "node_busy_mean_m": 1908, + "node_busy_p95_m": 3359, + "node_free_mean_m": 2092, + "node_free_p5_m": 641, + "load1_max": 7.84 + }, + "recovery": { + "samples": 59, + "seconds": 60.6, + "cpu_mean_m": 860.6, + "cpu_p95_m": 956.8, + "cpu_peak_m": 982.3, + "cfs_periods": 605, + "cfs_throttled_periods": 251, + "throttle_ratio": 0.415, + "throttled_seconds": 6.17, + "psi_cpu_some_share": 0.152, + "mem_peak_mib": 322.2, + "mem_mean_mib": 251.0, + "node_busy_mean_m": 2624, + "node_busy_p95_m": 3608, + "node_free_mean_m": 1376, + "node_free_p5_m": 392, + "load1_max": 6.66 + }, + "workload_all_load_phases": { + "samples": 189, + "seconds": 194.0, + "cpu_mean_m": 775.3, + "cpu_p95_m": 998.3, + "cpu_peak_m": 1019.7, + "cfs_periods": 1889, + "cfs_throttled_periods": 675, + "throttle_ratio": 0.357, + "throttled_seconds": 22.77, + "psi_cpu_some_share": 0.166, + "mem_peak_mib": 483.3, + "mem_mean_mib": 295.7, + "node_busy_mean_m": 2790, + "node_busy_p95_m": 3853, + "node_free_mean_m": 1210, + "node_free_p5_m": 147, + "load1_max": 8.19 + }, + "post": { + "samples": 63, + "seconds": 63.9, + "cpu_mean_m": 12.3, + "cpu_p95_m": 14.3, + "cpu_peak_m": 15.1, + "cfs_periods": 161, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.001, + "mem_peak_mib": 322.5, + "mem_mean_mib": 322.2, + "node_busy_mean_m": 1413, + "node_busy_p95_m": 2414, + "node_free_mean_m": 2587, + "node_free_p5_m": 1586, + "load1_max": 5.75 + } + }, + "db": { + "pods": [ + "vergabe-db-7c4bffdd48-w4jz4" + ], + "baseline_pre": { + "samples": 127, + "seconds": 128.5, + "cpu_mean_m": 21.5, + "cpu_p95_m": 65.7, + "cpu_peak_m": 71.7, + "cfs_periods": 333, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.002, + "mem_peak_mib": 91.3, + "mem_mean_mib": 90.4, + "node_busy_mean_m": 1346, + "node_busy_p95_m": 2448, + "node_free_mean_m": 2654, + "node_free_p5_m": 1552, + "load1_max": 4.91 + }, + "harness_idle": { + "samples": 29, + "seconds": 29.3, + "cpu_mean_m": 20.9, + "cpu_p95_m": 64.5, + "cpu_peak_m": 64.9, + "cfs_periods": 75, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.003, + "mem_peak_mib": 93.0, + "mem_mean_mib": 92.7, + "node_busy_mean_m": 1522, + "node_busy_p95_m": 2680, + "node_free_mean_m": 2478, + "node_free_p5_m": 1320, + "load1_max": 3.15 + }, + "ordinary": { + "samples": 88, + "seconds": 89.9, + "cpu_mean_m": 387.8, + "cpu_p95_m": 501.1, + "cpu_peak_m": 532.2, + "cfs_periods": 892, + "cfs_throttled_periods": 2, + "throttle_ratio": 0.002, + "throttled_seconds": 0.02, + "psi_cpu_some_share": 0.067, + "mem_peak_mib": 101.4, + "mem_mean_mib": 95.7, + "node_busy_mean_m": 2974, + "node_busy_p95_m": 3895, + "node_free_mean_m": 1026, + "node_free_p5_m": 105, + "load1_max": 8.19 + }, + "burst": { + "samples": 29, + "seconds": 29.6, + "cpu_mean_m": 430.1, + "cpu_p95_m": 539.1, + "cpu_peak_m": 544.4, + "cfs_periods": 293, + "cfs_throttled_periods": 2, + "throttle_ratio": 0.007, + "throttled_seconds": 0.06, + "psi_cpu_some_share": 0.062, + "mem_peak_mib": 113.1, + "mem_mean_mib": 97.1, + "node_busy_mean_m": 2798, + "node_busy_p95_m": 3664, + "node_free_mean_m": 1202, + "node_free_p5_m": 336, + "load1_max": 8.19 + }, + "restart": { + "samples": 18, + "seconds": 18.3, + "cpu_mean_m": 24.3, + "cpu_p95_m": 67.7, + "cpu_peak_m": 67.7, + "cfs_periods": 55, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.009, + "mem_peak_mib": 103.3, + "mem_mean_mib": 101.4, + "node_busy_mean_m": 2650, + "node_busy_p95_m": 3961, + "node_free_mean_m": 1350, + "node_free_p5_m": 39, + "load1_max": 7.84 + }, + "recovery": { + "samples": 58, + "seconds": 58.9, + "cpu_mean_m": 335.0, + "cpu_p95_m": 398.7, + "cpu_peak_m": 408.1, + "cfs_periods": 581, + "cfs_throttled_periods": 1, + "throttle_ratio": 0.002, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.041, + "mem_peak_mib": 111.3, + "mem_mean_mib": 106.9, + "node_busy_mean_m": 2621, + "node_busy_p95_m": 3524, + "node_free_mean_m": 1379, + "node_free_p5_m": 476, + "load1_max": 6.66 + }, + "workload_all_load_phases": { + "samples": 196, + "seconds": 199.8, + "cpu_mean_m": 340.8, + "cpu_p95_m": 500.0, + "cpu_peak_m": 544.4, + "cfs_periods": 1837, + "cfs_throttled_periods": 5, + "throttle_ratio": 0.003, + "throttled_seconds": 0.08, + "psi_cpu_some_share": 0.052, + "mem_peak_mib": 113.1, + "mem_mean_mib": 99.8, + "node_busy_mean_m": 2813, + "node_busy_p95_m": 3894, + "node_free_mean_m": 1187, + "node_free_p5_m": 106, + "load1_max": 8.19 + }, + "post": { + "samples": 64, + "seconds": 64.8, + "cpu_mean_m": 21.7, + "cpu_p95_m": 65.1, + "cpu_peak_m": 79.6, + "cfs_periods": 161, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.002, + "mem_peak_mib": 101.3, + "mem_mean_mib": 98.1, + "node_busy_mean_m": 1420, + "node_busy_p95_m": 2509, + "node_free_mean_m": 2580, + "node_free_p5_m": 1491, + "load1_max": 5.75 + } + }, + "driver": { + "pods": [ + "synthetic-driver" + ], + "baseline_pre": { + "samples": 126, + "seconds": 127.9, + "cpu_mean_m": 11.6, + "cpu_p95_m": 13.2, + "cpu_peak_m": 13.7, + "cfs_periods": 267, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.002, + "mem_peak_mib": 6.6, + "mem_mean_mib": 6.3, + "node_busy_mean_m": 1348, + "node_busy_p95_m": 2510, + "node_free_mean_m": 2652, + "node_free_p5_m": 1490, + "load1_max": 4.91 + }, + "harness_idle": { + "samples": 28, + "seconds": 28.4, + "cpu_mean_m": 11.6, + "cpu_p95_m": 13.1, + "cpu_peak_m": 13.1, + "cfs_periods": 59, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.002, + "mem_peak_mib": 63.3, + "mem_mean_mib": 63.0, + "node_busy_mean_m": 1537, + "node_busy_p95_m": 2829, + "node_free_mean_m": 2463, + "node_free_p5_m": 1171, + "load1_max": 2.91 + }, + "ordinary": { + "samples": 88, + "seconds": 90.0, + "cpu_mean_m": 91.7, + "cpu_p95_m": 117.2, + "cpu_peak_m": 124.8, + "cfs_periods": 891, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.029, + "mem_peak_mib": 75.9, + "mem_mean_mib": 72.4, + "node_busy_mean_m": 2977, + "node_busy_p95_m": 3912, + "node_free_mean_m": 1023, + "node_free_p5_m": 88, + "load1_max": 7.83 + }, + "burst": { + "samples": 29, + "seconds": 29.6, + "cpu_mean_m": 98.5, + "cpu_p95_m": 124.8, + "cpu_peak_m": 129.3, + "cfs_periods": 289, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.026, + "mem_peak_mib": 78.4, + "mem_mean_mib": 76.4, + "node_busy_mean_m": 2790, + "node_busy_p95_m": 3387, + "node_free_mean_m": 1210, + "node_free_p5_m": 613, + "load1_max": 8.19 + }, + "restart": { + "samples": 18, + "seconds": 18.3, + "cpu_mean_m": 22.4, + "cpu_p95_m": 25.5, + "cpu_peak_m": 25.5, + "cfs_periods": 112, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.009, + "mem_peak_mib": 73.7, + "mem_mean_mib": 71.3, + "node_busy_mean_m": 2650, + "node_busy_p95_m": 3990, + "node_free_mean_m": 1350, + "node_free_p5_m": 10, + "load1_max": 7.84 + }, + "recovery": { + "samples": 59, + "seconds": 60.1, + "cpu_mean_m": 82.2, + "cpu_p95_m": 95.4, + "cpu_peak_m": 139.7, + "cfs_periods": 594, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.02, + "mem_peak_mib": 80.9, + "mem_mean_mib": 77.2, + "node_busy_mean_m": 2635, + "node_busy_p95_m": 3540, + "node_free_mean_m": 1365, + "node_free_p5_m": 460, + "load1_max": 6.66 + }, + "workload_all_load_phases": { + "samples": 197, + "seconds": 201.1, + "cpu_mean_m": 84.4, + "cpu_p95_m": 117.7, + "cpu_peak_m": 200.8, + "cfs_periods": 1911, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.024, + "mem_peak_mib": 80.9, + "mem_mean_mib": 74.4, + "node_busy_mean_m": 2820, + "node_busy_p95_m": 3912, + "node_free_mean_m": 1180, + "node_free_p5_m": 88, + "load1_max": 8.19 + }, + "post": { + "samples": 64, + "seconds": 64.9, + "cpu_mean_m": 16.3, + "cpu_p95_m": 13.2, + "cpu_peak_m": 317.3, + "cfs_periods": 137, + "cfs_throttled_periods": 0, + "throttle_ratio": 0.0, + "throttled_seconds": 0.0, + "psi_cpu_some_share": 0.002, + "mem_peak_mib": 79.1, + "mem_mean_mib": 19.2, + "node_busy_mean_m": 1423, + "node_busy_p95_m": 2535, + "node_free_mean_m": 2577, + "node_free_p5_m": 1465, + "load1_max": 5.75 + } + } + }, + "per_operation": { + "burst/detail": { + "n": 77, + "errors": 0, + "p95_s": 0.1132, + "max_s": 0.1706 + }, + "burst/document-download": { + "n": 77, + "errors": 0, + "p95_s": 0.0447, + "max_s": 0.0592 + }, + "burst/document-upload": { + "n": 77, + "errors": 0, + "p95_s": 0.075, + "max_s": 0.1055 + }, + "burst/list": { + "n": 77, + "errors": 0, + "p95_s": 0.2974, + "max_s": 0.3233 + }, + "burst/login": { + "n": 2, + "errors": 0, + "p95_s": 1.1775, + "max_s": 1.1775 + }, + "burst/login-form": { + "n": 2, + "errors": 0, + "p95_s": 0.0281, + "max_s": 0.0281 + }, + "burst/lot-create": { + "n": 77, + "errors": 0, + "p95_s": 0.0581, + "max_s": 0.0971 + }, + "burst/lot-edit": { + "n": 77, + "errors": 0, + "p95_s": 0.0536, + "max_s": 0.0743 + }, + "burst/search": { + "n": 77, + "errors": 0, + "p95_s": 0.2652, + "max_s": 0.3359 + }, + "burst/task-create": { + "n": 77, + "errors": 0, + "p95_s": 0.0599, + "max_s": 0.1778 + }, + "burst/task-edit": { + "n": 77, + "errors": 0, + "p95_s": 0.0597, + "max_s": 0.0759 + }, + "burst/tender-create": { + "n": 77, + "errors": 0, + "p95_s": 0.0772, + "max_s": 0.0845 + }, + "burst/tender-edit": { + "n": 77, + "errors": 0, + "p95_s": 0.0623, + "max_s": 0.0732 + }, + "ordinary/detail": { + "n": 211, + "errors": 0, + "p95_s": 0.1758, + "max_s": 0.3877 + }, + "ordinary/document-download": { + "n": 211, + "errors": 0, + "p95_s": 0.0537, + "max_s": 0.11 + }, + "ordinary/document-upload": { + "n": 211, + "errors": 0, + "p95_s": 0.1051, + "max_s": 0.4418 + }, + "ordinary/list": { + "n": 211, + "errors": 0, + "p95_s": 0.194, + "max_s": 0.3779 + }, + "ordinary/login": { + "n": 2, + "errors": 0, + "p95_s": 1.2574, + "max_s": 1.2574 + }, + "ordinary/login-form": { + "n": 2, + "errors": 0, + "p95_s": 0.3288, + "max_s": 0.3288 + }, + "ordinary/lot-create": { + "n": 211, + "errors": 0, + "p95_s": 0.0696, + "max_s": 0.1603 + }, + "ordinary/lot-edit": { + "n": 211, + "errors": 0, + "p95_s": 0.0763, + "max_s": 0.1017 + }, + "ordinary/search": { + "n": 211, + "errors": 0, + "p95_s": 0.2294, + "max_s": 0.6217 + }, + "ordinary/task-create": { + "n": 211, + "errors": 0, + "p95_s": 0.0697, + "max_s": 0.1338 + }, + "ordinary/task-edit": { + "n": 211, + "errors": 0, + "p95_s": 0.0686, + "max_s": 0.1146 + }, + "ordinary/tender-create": { + "n": 211, + "errors": 0, + "p95_s": 0.0626, + "max_s": 0.1187 + }, + "ordinary/tender-edit": { + "n": 211, + "errors": 0, + "p95_s": 0.0633, + "max_s": 0.1171 + }, + "recovery/detail": { + "n": 119, + "errors": 0, + "p95_s": 0.131, + "max_s": 0.1379 + }, + "recovery/document-download": { + "n": 119, + "errors": 0, + "p95_s": 0.0475, + "max_s": 0.0818 + }, + "recovery/document-upload": { + "n": 119, + "errors": 0, + "p95_s": 0.08, + "max_s": 0.1587 + }, + "recovery/list": { + "n": 119, + "errors": 0, + "p95_s": 0.3302, + "max_s": 0.3757 + }, + "recovery/login": { + "n": 2, + "errors": 0, + "p95_s": 1.2653, + "max_s": 1.2653 + }, + "recovery/login-form": { + "n": 2, + "errors": 0, + "p95_s": 0.6157, + "max_s": 0.6157 + }, + "recovery/lot-create": { + "n": 119, + "errors": 0, + "p95_s": 0.0526, + "max_s": 0.0945 + }, + "recovery/lot-edit": { + "n": 119, + "errors": 0, + "p95_s": 0.0602, + "max_s": 0.1186 + }, + "recovery/search": { + "n": 119, + "errors": 0, + "p95_s": 0.3193, + "max_s": 0.4237 + }, + "recovery/task-create": { + "n": 119, + "errors": 0, + "p95_s": 0.0558, + "max_s": 0.0888 + }, + "recovery/task-edit": { + "n": 119, + "errors": 0, + "p95_s": 0.0577, + "max_s": 0.0959 + }, + "recovery/tender-create": { + "n": 119, + "errors": 0, + "p95_s": 0.0489, + "max_s": 0.0661 + }, + "recovery/tender-edit": { + "n": 119, + "errors": 0, + "p95_s": 0.0556, + "max_s": 0.0753 + } + }, + "per_operation_all_phases": { + "detail": { + "n": 407, + "errors": 0, + "p95_s": 0.1463 + }, + "document-download": { + "n": 407, + "errors": 0, + "p95_s": 0.0498 + }, + "document-upload": { + "n": 407, + "errors": 0, + "p95_s": 0.0878 + }, + "list": { + "n": 407, + "errors": 0, + "p95_s": 0.2624 + }, + "login": { + "n": 6, + "errors": 0, + "p95_s": 1.2653 + }, + "login-form": { + "n": 6, + "errors": 0, + "p95_s": 0.6157 + }, + "lot-create": { + "n": 407, + "errors": 0, + "p95_s": 0.0613 + }, + "lot-edit": { + "n": 407, + "errors": 0, + "p95_s": 0.0621 + }, + "search": { + "n": 407, + "errors": 0, + "p95_s": 0.2553 + }, + "task-create": { + "n": 407, + "errors": 0, + "p95_s": 0.0621 + }, + "task-edit": { + "n": 407, + "errors": 0, + "p95_s": 0.0657 + }, + "tender-create": { + "n": 407, + "errors": 0, + "p95_s": 0.0661 + }, + "tender-edit": { + "n": 407, + "errors": 0, + "p95_s": 0.0587 + } + }, + "summary": { + "ordinary": { + "requests": 3675, + "errors": 0, + "p95_seconds": 0.19182809395715594 + }, + "document_transfer": { + "requests": 814, + "errors": 0, + "p95_seconds": 0.07621732295956463 + }, + "complete": true, + "provisional_pass": true, + "measurement_complete": true, + "measurement_gaps": [], + "startup_seconds": 0.04661138809751719, + "duration_seconds": 201.53947580303065, + "completed_iterations": { + "ordinary": [ + 106, + 105 + ], + "burst": [ + 39, + 38 + ], + "recovery": [ + 59, + 60 + ] + }, + "host": { + "logical_cpus": 4, + "affinity_cpus": 4, + "cpu_model": "AMD EPYC Processor (with IBPB)", + "memory_total": "MemTotal: 16377032 kB", + "cgroup_cpu_max": "100000 100000", + "app_cpu_quota": 1.0 + } + }, + "phase_results": [ + { + "name": "ordinary", + "kind": "load", + "seconds": 91.06608834001236, + "started_at": "2026-10-21T06:30:01.523056+00:00", + "finished_at": "2026-10-21T06:31:32.589152+00:00", + "expected_requests": 2325, + "actual_requests": 2325, + "complete": true, + "ordinary": { + "requests": 1903, + "errors": 0, + "p95_seconds": 0.14162223995663226 + }, + "document_transfer": { + "requests": 422, + "errors": 0, + "p95_seconds": 0.08520571992266923 + } + }, + { + "name": "burst", + "kind": "load", + "seconds": 30.685886312043294, + "started_at": "2026-10-21T06:31:32.589194+00:00", + "finished_at": "2026-10-21T06:32:03.275085+00:00", + "expected_requests": 851, + "actual_requests": 851, + "complete": true, + "ordinary": { + "requests": 697, + "errors": 0, + "p95_seconds": 0.19206618797034025 + }, + "document_transfer": { + "requests": 154, + "errors": 0, + "p95_seconds": 0.06853019201662391 + } + }, + { + "name": "restart", + "kind": "restart", + "seconds": 18.981462653027847, + "started_at": "2026-10-21T06:32:03.275117+00:00", + "finished_at": "2026-10-21T06:32:22.256585+00:00", + "ready": true + }, + { + "name": "recovery", + "kind": "load", + "seconds": 60.80042844603304, + "started_at": "2026-10-21T06:32:22.256609+00:00", + "finished_at": "2026-10-21T06:33:23.057045+00:00", + "expected_requests": 1313, + "actual_requests": 1313, + "complete": true, + "ordinary": { + "requests": 1075, + "errors": 0, + "p95_seconds": 0.21410848898813128 + }, + "document_transfer": { + "requests": 238, + "errors": 0, + "p95_seconds": 0.07255190098658204 + } + } + ] +} \ No newline at end of file diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/harness/analyze.py b/docs/evidence/2026-10-21-vergabe-target-replay/harness/analyze.py new file mode 100644 index 0000000..32435ba --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/harness/analyze.py @@ -0,0 +1,73 @@ +import json, math, sys, gzip, collections +from datetime import datetime +R = sys.argv[1] +def ts(x): return datetime.fromisoformat(x.replace("Z", "+00:00").replace(".", ".", 1)[:26] + ("+00:00" if "+" not in x[19:] and not x.endswith("Z") else "")).timestamp() if False else _ts(x) +def _ts(x): + x = x.rstrip("Z") + if "+" in x[19:]: x = x[:x.index("+", 19)] + if "." in x: a, b = x.split("."); x = a + "." + b[:6] + return datetime.fromisoformat(x + "+00:00").timestamp() +def p95(v): + v = sorted(v); return v[max(0, math.ceil(0.95 * len(v)) - 1)] if v else None +def parse(path): + segs, cur, s = [], None, None + for line in open(path): + line = line.rstrip("\n") + if line.startswith("POD "): cur = {"pod": line.split()[1], "samples": []}; segs.append(cur) + elif line.startswith("S "): + s = {"t": float(line[2:])}; cur["samples"].append(s) + elif s is None: continue + elif line.startswith("M "): s["mem"] = int(line[2:]) + elif line.startswith("P "): s["psi_some_total"] = int(line.split("total=")[1]) + elif line.startswith("N "): + f = [int(x) for x in line.split()[2:]]; s["node_total"] = sum(f[:8]); s["node_idle"] = f[3] + f[4] + elif line.startswith("L "): s["load1"] = float(line.split()[1]) + elif line.split() and line.split()[0] in ("usage_usec","nr_periods","nr_throttled","throttled_usec"): + k, v = line.split(); s[k] = int(v) + for seg in segs: seg["samples"] = [x for x in seg["samples"] if "mem" in x and "node_total" in x and "usage_usec" in x] + return segs +def window(segs, a, b, cores=4): + rates, mems, thr_p, per_p, thr_us, nodebusy, psi, load = [], [], 0, 0, 0, [], 0, [] + span = 0; used = 0 + for seg in segs: + xs = [x for x in seg["samples"] if a <= x["t"] <= b] + for x in xs: mems.append(x["mem"]); load.append(x["load1"]) + for p, q in zip(xs, xs[1:]): + dt = q["t"] - p["t"] + if dt <= 0 or dt > 5: continue + du = q["usage_usec"] - p["usage_usec"]; used += du; span += dt + rates.append(du / 1e3 / dt) + per_p += q.get("nr_periods",0) - p.get("nr_periods",0); thr_p += q.get("nr_throttled",0) - p.get("nr_throttled",0) + thr_us += q.get("throttled_usec",0) - p.get("throttled_usec",0) + psi += q["psi_some_total"] - p["psi_some_total"] + tot = q["node_total"] - p["node_total"]; idle = q["node_idle"] - p["node_idle"] + if tot > 0: nodebusy.append(cores * (tot - idle) / tot * 1000) + if not rates: return None + return {"samples": len(rates), "seconds": round(span,1), "cpu_mean_m": round(used/1e3/span,1), "cpu_p95_m": round(p95(rates),1), "cpu_peak_m": round(max(rates),1), + "cfs_periods": per_p, "cfs_throttled_periods": thr_p, "throttle_ratio": round(thr_p/per_p,3) if per_p else None, "throttled_seconds": round(thr_us/1e6,2), + "psi_cpu_some_share": round(psi/1e6/span,3), "mem_peak_mib": round(max(mems)/2**20,1), "mem_mean_mib": round(sum(mems)/len(mems)/2**20,1), + "node_busy_mean_m": round(sum(nodebusy)/len(nodebusy)), "node_busy_p95_m": round(p95(nodebusy)), "node_free_mean_m": round(cores*1000-sum(nodebusy)/len(nodebusy)), + "node_free_p5_m": round(cores*1000-p95(nodebusy)), "load1_max": max(load)} +win = {} +for line in open(f"{R}/windows.txt"): + k, *v = line.split(); win[k] = v +res = json.load(open(f"{R}/result.json")) +W = {"baseline_pre": (_ts(win["baseline_start"][0]), _ts(win["driver_start"][0])), + "harness_idle": (_ts(res["idle_window"]["started_at"]), _ts(res["idle_window"]["finished_at"]))} +for p in res["phase_results"]: W[p["name"]] = (_ts(p["started_at"]), _ts(p["finished_at"])) +loads = [p for p in res["phase_results"] if p["kind"] == "load"] +W["workload_all_load_phases"] = (_ts(loads[0]["started_at"]), _ts(loads[-1]["finished_at"])) +W["post"] = (_ts(win["driver_exit"][1]), _ts(win["post_end"][0])) +out = {"windows_utc": {k: [datetime.utcfromtimestamp(a).isoformat()+"Z", datetime.utcfromtimestamp(b).isoformat()+"Z"] for k,(a,b) in W.items()}, "cgroup": {}} +for name in ("app", "db", "driver"): + segs = parse(f"{R}/{name}-cgroup.txt") + out["cgroup"][name] = {"pods": [s["pod"] for s in segs], **{k: window(segs, a, b) for k, (a, b) in W.items() if k != "workload_all_load_phases" or True}} +ops = collections.defaultdict(list) +for r in res["operations"]: ops[(r["phase"], r["operation"])].append(r) +out["per_operation"] = {f"{ph}/{op}": {"n": len(v), "errors": sum(not x["ok"] for x in v), "p95_s": round(p95([x["seconds"] for x in v]),4), "max_s": round(max(x["seconds"] for x in v),4)} for (ph, op), v in sorted(ops.items())} +allops = collections.defaultdict(list) +for r in res["operations"]: allops[r["operation"]].append(r) +out["per_operation_all_phases"] = {op: {"n": len(v), "errors": sum(not x["ok"] for x in v), "p95_s": round(p95([x["seconds"] for x in v]),4)} for op, v in sorted(allops.items())} +out["summary"] = {k: res[k] for k in ("ordinary","document_transfer","complete","provisional_pass","measurement_complete","measurement_gaps","startup_seconds","duration_seconds","completed_iterations","host")} +out["phase_results"] = [{k: v for k, v in p.items() if k != "operations"} for p in res["phase_results"]] +json.dump(out, open(sys.argv[2], "w"), indent=1) diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/harness/bench.yaml b/docs/evidence/2026-10-21-vergabe-target-replay/harness/bench.yaml new file mode 100644 index 0000000..573740b --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/harness/bench.yaml @@ -0,0 +1,125 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: vergabe-sizing-20261021 + labels: + railiance.io/purpose: synthetic-sizing + railiance.io/task: rapps-wp-0014-t04 + railiance.io/ephemeral: "true" +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: {name: bench-media, namespace: vergabe-sizing-20261021} +spec: + accessModes: [ReadWriteOnce] + storageClassName: local-path + resources: {requests: {storage: 5Gi}} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: {name: vergabe-db, namespace: vergabe-sizing-20261021} +spec: + replicas: 1 + strategy: {type: Recreate} + selector: {matchLabels: {app: vergabe-sizing-db}} + template: + metadata: {labels: {app: vergabe-sizing-db}} + spec: + automountServiceAccountToken: false + containers: + - name: postgres + image: docker.io/library/postgres@sha256:4b7183ac05f8ef417db21fd72d71047a4238340c261d3cc3ddb6d579ab5071ae + imagePullPolicy: IfNotPresent + env: + - {name: POSTGRES_DB, value: synthetic} + - {name: POSTGRES_USER, value: synthetic} + - {name: POSTGRES_PASSWORD, value: synthetic-local-only} + - {name: PGDATA, value: /var/lib/postgresql/data/pgdata} + ports: [{containerPort: 5432}] + readinessProbe: {exec: {command: [pg_isready, -U, synthetic]}, periodSeconds: 5} + resources: {requests: {cpu: 100m, memory: 256Mi}, limits: {cpu: "1", memory: 1Gi}} + volumeMounts: [{name: data, mountPath: /var/lib/postgresql/data}] + volumes: [{name: data, emptyDir: {}}] +--- +apiVersion: v1 +kind: Service +metadata: {name: vergabe-db, namespace: vergabe-sizing-20261021} +spec: {selector: {app: vergabe-sizing-db}, ports: [{port: 5432, targetPort: 5432}]} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: {name: vergabe-app, namespace: vergabe-sizing-20261021} +spec: + replicas: 1 + strategy: {type: Recreate} + selector: {matchLabels: {app: vergabe-sizing-app}} + template: + metadata: {labels: {app: vergabe-sizing-app}} + spec: + automountServiceAccountToken: false + securityContext: {fsGroup: 999, runAsGroup: 999, runAsNonRoot: true, runAsUser: 999} + initContainers: + - name: migrate + image: forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91 + imagePullPolicy: IfNotPresent + command: [python, manage.py, migrate, --noinput] + env: &env + - {name: DJANGO_SETTINGS_MODULE, value: synthetic_settings} + - {name: PYTHONPATH, value: /synthetic} + - {name: SECRET_KEY, value: synthetic-disposable-not-a-deployment-key} + - {name: DATABASE_URL, value: "postgres://synthetic:synthetic-local-only@vergabe-db:5432/synthetic"} + resources: &res {requests: {cpu: 60m, memory: 256Mi}, limits: {cpu: "1", memory: 1Gi}} + securityContext: &sc {allowPrivilegeEscalation: false, capabilities: {drop: [ALL]}, readOnlyRootFilesystem: false} + volumeMounts: [{name: settings, mountPath: /synthetic}] + containers: + - name: app + image: forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91 + imagePullPolicy: IfNotPresent + env: *env + ports: [{containerPort: 8000, name: http}] + readinessProbe: {httpGet: {path: /health/, port: 8000, httpHeaders: [{name: Host, value: vergabe-app}]}, initialDelaySeconds: 5, periodSeconds: 10, timeoutSeconds: 5, failureThreshold: 3} + livenessProbe: {httpGet: {path: /health/, port: 8000, httpHeaders: [{name: Host, value: vergabe-app}]}, initialDelaySeconds: 30, periodSeconds: 30, timeoutSeconds: 5, failureThreshold: 3} + resources: *res + securityContext: *sc + volumeMounts: + - {name: settings, mountPath: /synthetic} + - {name: media, mountPath: /app/media} + - {name: app-state, mountPath: /app/.issue-facade} + volumes: + - {name: settings, configMap: {name: synthetic-settings}} + - {name: media, persistentVolumeClaim: {claimName: bench-media}} + - {name: app-state, emptyDir: {}} +--- +apiVersion: v1 +kind: Service +metadata: {name: vergabe-app, namespace: vergabe-sizing-20261021} +spec: {selector: {app: vergabe-sizing-app}, ports: [{port: 80, targetPort: 8000}]} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: {name: synthetic-driver, namespace: vergabe-sizing-20261021} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: {name: synthetic-driver-restart, namespace: vergabe-sizing-20261021} +rules: [{apiGroups: [""], resources: [pods], verbs: [get, list, delete]}] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: {name: synthetic-driver-restart, namespace: vergabe-sizing-20261021} +roleRef: {apiGroup: rbac.authorization.k8s.io, kind: Role, name: synthetic-driver-restart} +subjects: [{kind: ServiceAccount, name: synthetic-driver, namespace: vergabe-sizing-20261021}] +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: {name: synthetic-isolation, namespace: vergabe-sizing-20261021} +spec: + podSelector: {} + policyTypes: [Ingress, Egress] + ingress: [{from: [{podSelector: {}}]}] + egress: + - to: [{podSelector: {}}] + - to: [{namespaceSelector: {matchLabels: {kubernetes.io/metadata.name: kube-system}}, podSelector: {matchLabels: {k8s-app: kube-dns}}}] + ports: [{port: 53, protocol: UDP}, {port: 53, protocol: TCP}] + - to: [{ipBlock: {cidr: 92.205.62.239/32}}, {ipBlock: {cidr: 10.43.0.1/32}}] + ports: [{port: 6443, protocol: TCP}, {port: 443, protocol: TCP}] diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/harness/driver-config.json b/docs/evidence/2026-10-21-vergabe-target-replay/harness/driver-config.json new file mode 100644 index 0000000..25241c5 --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/harness/driver-config.json @@ -0,0 +1,53 @@ +{ + "users": 2, + "workers": 3, + "iterations": 100000, + "tenders": 100, + "document_bytes": 1048576, + "think_seconds": 0.2, + "timeout_seconds": 30, + "ordinary_p95_seconds": 2.0, + "duration_seconds": 180, + "idle_seconds": 30, + "runtime": "remote", + "app_image": "forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91", + "app_cpu_limit": 1.0, + "app_memory_limit": "1Gi", + "operations": [ + "list", + "search", + "tender-create", + "detail", + "tender-edit", + "lot-create", + "lot-edit", + "task-create", + "task-edit", + "document-upload", + "document-download" + ], + "phases": [ + { + "name": "ordinary", + "kind": "load", + "duration_seconds": 90, + "think_seconds": 0.2 + }, + { + "name": "burst", + "kind": "load", + "duration_seconds": 30, + "think_seconds": 0 + }, + { + "name": "restart", + "kind": "restart" + }, + { + "name": "recovery", + "kind": "load", + "duration_seconds": 60, + "think_seconds": 0.2 + } + ] +} diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/harness/driver.yaml b/docs/evidence/2026-10-21-vergabe-target-replay/harness/driver.yaml new file mode 100644 index 0000000..db2991a --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/harness/driver.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Pod +metadata: {name: synthetic-driver, namespace: vergabe-sizing-20261021, labels: {app: vergabe-sizing-driver}} +spec: + serviceAccountName: synthetic-driver + restartPolicy: Never + securityContext: {runAsGroup: 999, runAsNonRoot: true, runAsUser: 999} + containers: + - name: driver + image: forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91 + imagePullPolicy: IfNotPresent + workingDir: /app + command: [sleep, "7200"] + env: + - {name: PYTHONPATH, value: /app} + - {name: SYNTHETIC_BASE_URL, value: "http://vergabe-app"} + - {name: SYNTHETIC_DATABASE_URL, value: "postgres://synthetic:synthetic-local-only@vergabe-db:5432/synthetic"} + - {name: SYNTHETIC_RESTART_SELECTOR, value: "app=vergabe-sizing-app"} + - {name: SYNTHETIC_SOURCE_REVISION, value: "deployed image c067993037f1cdeeb7b22d5600b51c649bc239db; driver from vergabe-teilnahme working tree"} + - {name: SYNTHETIC_DATABASE_DESCRIPTION, value: "fresh PostgreSQL 16 pod in throwaway namespace (docker.io/library/postgres:16 pinned digest)"} + - {name: SYNTHETIC_TRANSPORT_DESCRIPTION, value: "in-cluster HTTP via ClusterIP Service to Gunicorn (image CMD, 3 workers)"} + resources: {requests: {cpu: 100m, memory: 256Mi}, limits: {cpu: "1", memory: 1Gi}} + securityContext: {allowPrivilegeEscalation: false, capabilities: {drop: [ALL]}} + volumeMounts: + - {name: driver, mountPath: /driver} + - {name: out, mountPath: /out} + volumes: + - {name: driver, configMap: {name: synthetic-driver}} + - {name: out, emptyDir: {}} diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/harness/executed-synthetic_pilot.py b/docs/evidence/2026-10-21-vergabe-target-replay/harness/executed-synthetic_pilot.py new file mode 100644 index 0000000..0ef5b91 --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/harness/executed-synthetic_pilot.py @@ -0,0 +1,1091 @@ +#!/usr/bin/env python3 +"""Provisional HTTP workload against Gunicorn and a disposable PostgreSQL. + +Runtimes: ``host`` and ``container`` start everything locally. ``remote`` drives +an already running isolated synthetic deployment (for example a throwaway +Kubernetes namespace): the base URL, database URL and optional restart pod +selector come from ``SYNTHETIC_BASE_URL``, ``SYNTHETIC_DATABASE_URL`` and +``SYNTHETIC_RESTART_SELECTOR``. Remote resource sampling is external; phase UTC +windows are retained so samples can be aligned afterwards. +""" + +import argparse +import concurrent.futures +import hashlib +import http.cookiejar +import json +import math +import os +import platform +import signal +import socket +import subprocess +import sys +import tempfile +import threading +import time +import urllib.error +import urllib.parse +import urllib.request +import uuid +from datetime import UTC, datetime +from pathlib import Path + + +def summarize(rows): + durations = sorted(row["seconds"] for row in rows) + return { + "requests": len(rows), + "errors": sum(not r["ok"] for r in rows), + "p95_seconds": durations[math.ceil(len(durations) * 0.95) - 1] if durations else None, + } + + +LEGACY_OPERATIONS = [ + "list", + "search", + "tender-create", + "detail", + "lot-create", + "task-create", + "document-upload", + "document-download", +] +DEPENDENCIES = { + "list": None, + "search": None, + "tender-create": None, + "detail": "tender-create", + "tender-edit": "tender-create", + "lot-create": "tender-create", + "lot-edit": "lot-create", + "task-create": "tender-create", + "task-edit": "task-create", + "document-upload": "tender-create", + "document-download": "document-upload", +} + + +def operation_plan(operations): + if not isinstance(operations, list) or not operations: + raise ValueError("operations must be a nonempty ordered list") + seen = set() + for operation in operations: + if operation not in DEPENDENCIES: + raise ValueError(f"unknown operation: {operation}") + dependency = DEPENDENCIES[operation] + if dependency and dependency not in seen: + raise ValueError(f"{operation} requires earlier {dependency}") + if operation in seen and (operation.endswith("-create") or operation == "document-upload"): + raise ValueError(f"only one {operation} per cycle; repeat reads/edits to tune mix") + seen.add(operation) + return list(operations) + + +def phase_plan(config): + phases = config.get( + "phases", + [ + { + "name": "ordinary", + "kind": "load", + "duration_seconds": config["duration_seconds"], + "think_seconds": config["think_seconds"], + } + ], + ) + if not isinstance(phases, list) or not phases: + raise ValueError("phases must be a nonempty list") + names = set() + result = [] + for item in phases: + item = dict(item) + name = item.get("name") + if not isinstance(name, str) or not name or name in names or name in ("idle", "startup"): + raise ValueError("phase names must be unique and not idle/startup") + names.add(name) + if item.get("kind") == "restart": + if config.get("runtime") not in ("container", "remote"): + raise ValueError("restart phase requires container or remote runtime") + elif item.get("kind") == "load": + for key in ("duration_seconds", "think_seconds"): + value = item.get(key) + if type(value) not in (int, float) or not math.isfinite(value) or value < 0: + raise ValueError(f"invalid phase {key}") + if not item["duration_seconds"]: + raise ValueError("load duration must be positive") + item["operations"] = operation_plan( + item.get("operations", config.get("operations", LEGACY_OPERATIONS)) + ) + else: + raise ValueError("phase kind must be load or restart") + result.append(item) + if not any(p["kind"] == "load" for p in result): + raise ValueError("at least one load phase required") + return result + + +def expected_requests(completed, operations, users): + return sum(completed) * len(operations) + users * 2 + + +def wait_ready(base_url, timeout=30): + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + try: + with urllib.request.urlopen(base_url + "/health/", timeout=1) as response: + if response.status == 200: + return + except OSError: + pass + time.sleep(0.1) + raise RuntimeError("application readiness timeout") + + +def container_url(name): + binding = subprocess.check_output( + ["docker", "port", name, "8000/tcp"], text=True, timeout=10 + ).strip() + host, port = binding.rsplit(":", 1) + if host != "127.0.0.1" or not port.isdigit(): + raise ValueError("synthetic runtime must have one loopback HTTP binding") + return f"http://127.0.0.1:{port}" + + +KUBE_SA = Path("/var/run/secrets/kubernetes.io/serviceaccount") + + +def kube_request(method, path, sa_dir=KUBE_SA): + """Minimal in-cluster API call using the pod's own namespaced ServiceAccount.""" + host = os.environ["KUBERNETES_SERVICE_HOST"] + port = os.environ.get("KUBERNETES_SERVICE_PORT", "443") + import ssl + + context = ssl.create_default_context(cafile=str(sa_dir / "ca.crt")) + req = urllib.request.Request( + f"https://{host}:{port}{path}", + method=method, + headers={"Authorization": "Bearer " + (sa_dir / "token").read_text().strip()}, + ) + with urllib.request.urlopen(req, timeout=10, context=context) as response: + return json.loads(response.read()) + + +def ready_pods(listing): + return [ + item["metadata"]["name"] + for item in listing.get("items", []) + if not item["metadata"].get("deletionTimestamp") + and any( + c["type"] == "Ready" and c["status"] == "True" + for c in item.get("status", {}).get("conditions", []) + ) + ] + + +def restart_kubernetes_pod(base_url, selector, timeout=180, sa_dir=KUBE_SA, request=None): + """Delete the single selected pod in this namespace and wait for a new ready one.""" + request = request or (lambda method, path: kube_request(method, path, sa_dir)) + namespace = (sa_dir / "namespace").read_text().strip() + query = urllib.parse.urlencode({"labelSelector": selector}) + pods = f"/api/v1/namespaces/{namespace}/pods" + before = ready_pods(request("GET", f"{pods}?{query}")) + if len(before) != 1: + raise RuntimeError("restart requires exactly one ready selected pod") + request("DELETE", f"{pods}/{before[0]}") + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + listing = request("GET", f"{pods}?{query}") + names = [i["metadata"]["name"] for i in listing.get("items", [])] + if before[0] not in names and ready_pods(listing): + wait_ready(base_url, timeout=max(1, deadline - time.monotonic())) + return base_url + time.sleep(0.5) + raise RuntimeError("replacement pod readiness timeout") + + +def settings_text(media, issue_db, allowed_hosts=("127.0.0.1",)): + return ( + "from vergabe_teilnahme.settings.base import *\n" + f"DEBUG = False\nALLOWED_HOSTS = {list(allowed_hosts)!r}\nNETKINGDOM_ENABLED = False\n" + f"MEDIA_ROOT = {media!r}\n" + f"ISSUE_FACADE_LOCAL_DB = {issue_db!r}\n" + 'ISSUE_FACADE_GITEA = None\nFORCE_SCRIPT_NAME = None\nMEDIA_URL = "/media/"\n' + 'EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"\n' + "SESSION_COOKIE_SECURE = False\nCSRF_COOKIE_SECURE = False\n" + ) + + +def restart_container(name): + subprocess.run( + ["docker", "restart", "--time", "5", name], + check=True, + timeout=20, + stdout=subprocess.DEVNULL, + ) + # Docker can allocate a different random published port after restart. + endpoint = container_url(name) + wait_ready(endpoint) + return endpoint + + +def validate(config): + for key in ( + "users", + "iterations", + "tenders", + "document_bytes", + "workers", + "timeout_seconds", + ): + if type(config[key]) is not int or config[key] < 1: + raise ValueError(f"{key} must be a positive integer") + for key in ( + "think_seconds", + "ordinary_p95_seconds", + "duration_seconds", + "idle_seconds", + ): + if not isinstance(config[key], (int, float)) or not math.isfinite(config[key]): + raise ValueError(f"{key} must be finite") + if config["think_seconds"] < 0 or config["ordinary_p95_seconds"] <= 0: + raise ValueError("invalid timing parameter") + if config["duration_seconds"] <= 0 or config["idle_seconds"] < 0: + raise ValueError("duration must be positive and idle nonnegative") + if config["document_bytes"] < 8: + raise ValueError("document_bytes must be at least 8") + if config.get("runtime", "host") not in ("host", "container", "remote"): + raise ValueError("unsupported runtime") + if config.get("runtime") == "container": + if ( + not isinstance(config["app_cpu_limit"], (int, float)) + or not 0 < config["app_cpu_limit"] <= 8 + ): + raise ValueError("app_cpu_limit must be positive and at most 8") + if not config.get("app_image") or not config.get("app_memory_limit"): + raise ValueError("container image and memory limit required") + phase_plan(config) + return config + + +def stop_process(server): + """Bounded teardown of a process group, including Gunicorn workers.""" + if server is None: + return + try: + os.killpg(server.pid, signal.SIGTERM) + except ProcessLookupError: + pass + try: + server.wait(timeout=5) + except subprocess.TimeoutExpired: + try: + os.killpg(server.pid, signal.SIGKILL) + except ProcessLookupError: + pass + server.wait(timeout=5) + + +def guarded_sampler(function, errors): + try: + function() + except Exception as exc: + errors.append({"sampler": function.__name__, "error_type": type(exc).__name__}) + + +def sampling_gaps(samples, db_samples, errors, remote=False): + gaps = list(errors) + if remote: + return gaps + if any(s.get("sample_error") for s in samples): + gaps.append({"sampler": "application", "reason": "sample failed"}) + good = [s for s in samples if "monotonic_seconds" in s] + if len(good) < 2 or not db_samples: + gaps.append({"sampler": "coverage", "reason": "insufficient samples"}) + if any( + b["monotonic_seconds"] - a["monotonic_seconds"] > 3 + for a, b in zip(good, good[1:]) + if a.get("phase") == b.get("phase") + ): + gaps.append({"sampler": "application", "reason": "sampling interval exceeds 3 seconds"}) + return gaps + + +def run(config, root, failure_output=None): + # Never consume a deployment database, media tree, session or credential. + os.environ["DATABASE_URL"] = os.environ["SYNTHETIC_DATABASE_URL"] + os.environ["SECRET_KEY"] = "synthetic-disposable-not-a-deployment-key" + os.environ["DJANGO_SETTINGS_MODULE"] = "synthetic_settings" + container_mode = config.get("runtime", "host") == "container" + remote_mode = config.get("runtime") == "remote" + media = "/tmp/synthetic-media" if container_mode else str(root / "media") + issue_db = "/tmp/synthetic-issues.db" if container_mode else str(root / "issues.db") + (root / "synthetic_settings.py").write_text(settings_text(media, issue_db)) + sys.path.insert(0, str(root)) + import django + + django.setup() + from django.core.management import call_command + from django.db import connections + + from vergabe_teilnahme.apps.accounts.models import Mitarbeiter + from vergabe_teilnahme.apps.aufgaben.models import Aufgabe + from vergabe_teilnahme.apps.ausschreibungen.models import Ausschreibung + from vergabe_teilnahme.apps.dokumente.models import Dokument + from vergabe_teilnahme.apps.lose.models import Los + + call_command("migrate", verbosity=0) + for i in range(config["tenders"]): + Ausschreibung.objects.create(titel=f"Synthetic tender {i}", ausschreiber="Synthetic") + users = [] + password = uuid.uuid4().hex + for i in range(config["users"]): + user = Mitarbeiter.objects.create_user(username=f"synthetic-{i}", password=password) + users.append(user.username) + with socket.socket() as sock: + sock.bind(("127.0.0.1", 0)) + port = sock.getsockname()[1] + base_url = f"http://127.0.0.1:{port}" + env = dict(os.environ, PYTHONPATH=str(root) + os.pathsep + str(Path.cwd())) + server_log = (root / "server.log").open("w") + server = None + app_container = None + sampling_done = threading.Event() + sampler_threads = [] + sampler_errors = [] + sampling_lock = threading.Lock() + try: + startup_started = time.monotonic() + if remote_mode: + base_url = os.environ["SYNTHETIC_BASE_URL"].rstrip("/") + elif container_mode: + app_container = os.environ["SYNTHETIC_CONTAINER"] + "-app" + root.chmod(0o755) + subprocess.run( + [ + "docker", + "run", + "--detach", + "--pull=never", + "--name", + app_container, + "--network", + os.environ["SYNTHETIC_NETWORK"], + "--publish", + "127.0.0.1::8000", + "--cpus", + str(config["app_cpu_limit"]), + "--memory", + config["app_memory_limit"], + "--pids-limit", + "256", + "--mount", + ( + f"type=bind,src={root / 'synthetic_settings.py'}," + "dst=/synthetic_settings.py,readonly" + ), + "--env", + "PYTHONPATH=/", + "--env", + "DJANGO_SETTINGS_MODULE=synthetic_settings", + "--env", + "SECRET_KEY=synthetic-disposable-not-a-deployment-key", + "--env", + "DATABASE_URL=postgres://synthetic:synthetic-local-only@db:5432/synthetic", + config["app_image"], + "gunicorn", + "vergabe_teilnahme.wsgi:application", + "--bind", + "0.0.0.0:8000", + "--workers", + str(config["workers"]), + "--timeout", + "30", + ], + check=True, + timeout=30, + stdout=subprocess.DEVNULL, + ) + base_url = container_url(app_container) + else: + server = subprocess.Popen( + [ + sys.executable, + "-m", + "gunicorn", + "vergabe_teilnahme.wsgi:application", + "--bind", + f"127.0.0.1:{port}", + "--workers", + str(config["workers"]), + "--timeout", + "30", + ], + start_new_session=True, + env=env, + stdout=server_log, + stderr=server_log, + ) + samples = [] + db_samples = [] + phase = {"name": "startup", "kind": "startup"} + + def sample(): + ticks_per_second = os.sysconf("SC_CLK_TCK") + while not sampling_done.is_set(): + if phase.get("kind") == "restart": + samples.append( + { + "at": datetime.now(UTC).isoformat(), + "phase": phase["name"], + "expected_unavailable": True, + "reason": "planned restart", + } + ) + sampling_done.wait(0.5) + continue + if container_mode: + with sampling_lock: + value = subprocess.check_output( + [ + "docker", + "exec", + app_container, + "sh", + "-c", + ( + "cat /sys/fs/cgroup/cpu.stat; echo MEMORY; " + "cat /sys/fs/cgroup/memory.current" + ), + ], + text=True, + timeout=5, + ) + cpu_text, memory_text = value.split("MEMORY\n") + counters = { + k: int(v) for k, v in (line.split() for line in cpu_text.splitlines()) + } + samples.append( + { + "at": datetime.now(UTC).isoformat(), + "monotonic_seconds": time.monotonic(), + "phase": phase["name"], + "cpu_seconds": counters["usage_usec"] / 1e6, + "rss_bytes": int(memory_text.strip()), + "memory_kind": "cgroup-memory-current", + "cpu_stat": counters, + "pids": [app_container], + } + ) + sampling_done.wait(0.5) + continue + pids = [server.pid] + try: + pids += [ + int(x) + for x in Path(f"/proc/{server.pid}/task/{server.pid}/children") + .read_text() + .split() + ] + cpu, rss = 0, 0 + for pid in pids: + fields = Path(f"/proc/{pid}/stat").read_text().split(") ", 1)[1].split() + cpu += (int(fields[11]) + int(fields[12])) / ticks_per_second + rss += int(fields[21]) * os.sysconf("SC_PAGE_SIZE") + samples.append( + { + "at": datetime.now(UTC).isoformat(), + "monotonic_seconds": time.monotonic(), + "phase": phase["name"], + "cpu_seconds": cpu, + "rss_bytes": rss, + "pids": pids, + } + ) + except (OSError, ValueError): + samples.append({"at": datetime.now(UTC).isoformat(), "sample_error": True}) + sampling_done.wait(0.5) + + def sample_db(): + while not sampling_done.is_set(): + value = subprocess.check_output( + [ + "docker", + "stats", + "--no-stream", + "--format", + "{{json .}}", + os.environ["SYNTHETIC_CONTAINER"], + ], + text=True, + timeout=5, + ) + db_samples.append( + { + "at": datetime.now(UTC).isoformat(), + "phase": phase["name"], + "docker_stats": json.loads(value), + } + ) + sampling_done.wait(1) + + sampler = threading.Thread( + target=guarded_sampler, args=(sample, sampler_errors), daemon=True + ) + db_sampler = threading.Thread( + target=guarded_sampler, args=(sample_db, sampler_errors), daemon=True + ) + if not remote_mode: + sampler_threads.extend([sampler, db_sampler]) + sampler.start() + db_sampler.start() + wait_ready(base_url) + startup_seconds = time.monotonic() - startup_started + phase.update(name="idle", kind="idle") + idle_window = {"name": "idle", "kind": "idle", "started_at": datetime.now(UTC).isoformat()} + time.sleep(config["idle_seconds"]) + idle_window["finished_at"] = datetime.now(UTC).isoformat() + plan = phase_plan(config) + active_plan = [] + phase_results = [] + transport_rebinds = [] + phase_completed = {} + + def worker(i): + jar = http.cookiejar.CookieJar() + + class NoRedirect(urllib.request.HTTPRedirectHandler): + def redirect_request(self, *args, **kwargs): + return None + + opener = urllib.request.build_opener( + urllib.request.HTTPCookieProcessor(jar), NoRedirect() + ) + rows = [] + + def request(operation, method, path, data=None, expected=200, transfer=False): + started = time.perf_counter() + try: + headers = {} + body = None + if method == "post": + token = next((c.value for c in jar if c.name == "csrftoken"), "") + fields = dict(data or {}, csrfmiddlewaretoken=token) + if transfer: + boundary = "synthetic-" + uuid.uuid4().hex + body = b"" + for name, value in fields.items(): + body += ( + f"--{boundary}\r\nContent-Disposition: form-data; " + f'name="{name}"\r\n\r\n{value}\r\n' + ).encode() + body += ( + ( + f"--{boundary}\r\nContent-Disposition: form-data; " + 'name="datei"; filename="synthetic.pdf"\r\n' + "Content-Type: application/pdf\r\n\r\n" + ).encode() + + b"%PDF-1.4" + + b"x" * (config["document_bytes"] - 8) + + f"\r\n--{boundary}--\r\n".encode() + ) + headers["Content-Type"] = f"multipart/form-data; boundary={boundary}" + else: + body = urllib.parse.urlencode(fields).encode() + headers["Referer"] = base_url + path + req = urllib.request.Request( + base_url + path, data=body, headers=headers, method=method.upper() + ) + try: + response = opener.open(req, timeout=config["timeout_seconds"]) + except urllib.error.HTTPError as exc: + response = exc + received = len(response.read()) + status = response.status + ok = status == expected + if transfer and method == "get": + ok = ok and received == config["document_bytes"] + response.close() + except Exception: + status, ok, received = None, False, 0 + rows.append( + { + "phase": phase["name"], + "user": i, + "operation": operation, + "transfer": transfer, + "seconds": time.perf_counter() - started, + "status": status, + "ok": ok, + "response_bytes": received, + } + ) + return ok + + request("login-form", "get", "/accounts/login/") + barrier.wait(timeout=30) + request( + "login", + "post", + "/accounts/login/", + {"username": users[i], "password": password}, + 302, + ) + for n in range(config["iterations"]): + if time.monotonic() >= deadline: + break + title = f"Workload-{phase['name']}-{i}-{n}" + tender = lot = task = document = None + base = None + for index, operation in enumerate(active_plan): + dependency = DEPENDENCIES[operation] + entity = { + "tender-create": tender, + "lot-create": lot, + "task-create": task, + "document-upload": document, + } + if dependency and entity[dependency] is None: + rows.append( + { + "phase": phase["name"], + "user": i, + "operation": operation, + "transfer": operation.startswith("document-"), + "seconds": 0, + "status": None, + "ok": False, + "response_bytes": 0, + "reason": "dependency operation failed", + } + ) + continue + if operation == "list": + request(operation, "get", "/ausschreibungen/") + elif operation == "search": + request(operation, "get", "/ausschreibungen/?q=Synthetic") + elif operation == "tender-create": + if request( + operation, + "post", + "/ausschreibungen/neu/", + {"titel": title, "ausschreiber": "Synthetic"}, + 302, + ): + tender = Ausschreibung.objects.filter(titel=title).first() + base = f"/ausschreibungen/{tender.pk}/" if tender else None + elif operation == "detail": + request(operation, "get", base) + elif operation == "tender-edit": + changed = f"{title} edited-{index}" + request( + operation, + "post", + base + "bearbeiten/", + {"titel": changed, "ausschreiber": "Synthetic edited"}, + 302, + ) + tender.refresh_from_db() + rows[-1]["ok"] &= tender.titel == changed + elif operation == "lot-create": + request( + operation, + "post", + base + "lose/neu/", + {"losnummer": "1", "lostitel": "Synthetic lot"}, + 302, + ) + lot = Los.objects.filter(ausschreibung=tender).first() + elif operation == "lot-edit": + changed = f"Edited lot-{index}" + request( + operation, + "post", + base + f"lose/{lot.pk}/bearbeiten/", + {"losnummer": "1", "lostitel": changed}, + 302, + ) + lot.refresh_from_db() + rows[-1]["ok"] &= lot.lostitel == changed + elif operation == "task-create": + request( + operation, + "post", + base + "aufgaben/neu/", + {"titel": "Synthetic task", "typ": "fachlich", "prioritaet": 2}, + 302, + ) + task = Aufgabe.objects.filter(ausschreibung=tender).first() + elif operation == "task-edit": + changed = f"Edited task-{index}" + request( + operation, + "post", + base + f"aufgaben/{task.pk}/bearbeiten/", + {"titel": changed, "typ": "fachlich", "prioritaet": 1}, + 302, + ) + task.refresh_from_db() + rows[-1]["ok"] &= task.titel == changed and task.prioritaet == 1 + elif operation == "document-upload": + request( + operation, + "post", + base + "dokumente/hochladen/", + {"kategorie": "intern", "version": "1.0"}, + 302, + True, + ) + document = Dokument.objects.filter(ausschreibung=tender).first() + elif operation == "document-download": + request(operation, "get", document.datei.url, transfer=True) + completed[i] += 1 + time.sleep(active_phase["think_seconds"]) + connections.close_all() + return rows + + started = datetime.now(UTC).isoformat() + before = time.perf_counter() + rows = [] + for active_phase in plan: + phase.update(name=active_phase["name"], kind=active_phase["kind"]) + phase_started = time.monotonic() + phase_started_at = datetime.now(UTC).isoformat() + if active_phase["kind"] == "restart": + old_url = base_url + with sampling_lock: + if remote_mode: + base_url = restart_kubernetes_pod( + base_url, os.environ["SYNTHETIC_RESTART_SELECTOR"] + ) + else: + base_url = restart_container(app_container) + transport_rebinds.append( + {"phase": active_phase["name"], "before": old_url, "after": base_url} + ) + phase_results.append( + { + "name": active_phase["name"], + "kind": "restart", + "seconds": time.monotonic() - phase_started, + "started_at": phase_started_at, + "finished_at": datetime.now(UTC).isoformat(), + "ready": True, + } + ) + continue + active_plan = active_phase["operations"] + deadline = time.monotonic() + active_phase["duration_seconds"] + completed = [0] * config["users"] + barrier = threading.Barrier(config["users"]) + with concurrent.futures.ThreadPoolExecutor(max_workers=config["users"]) as pool: + phase_rows = [ + r for group in pool.map(worker, range(config["users"])) for r in group + ] + phase_completed[active_phase["name"]] = completed + phase_ordinary = summarize([r for r in phase_rows if not r["transfer"]]) + phase_transfers = summarize([r for r in phase_rows if r["transfer"]]) + expected = expected_requests(completed, active_plan, config["users"]) + phase_results.append( + { + "name": active_phase["name"], + "kind": "load", + "seconds": time.monotonic() - phase_started, + "started_at": phase_started_at, + "finished_at": datetime.now(UTC).isoformat(), + "operations": active_plan, + "expected_requests": expected, + "actual_requests": len(phase_rows), + "complete": all(completed) and len(phase_rows) == expected, + "ordinary": phase_ordinary, + "document_transfer": phase_transfers, + } + ) + rows.extend(phase_rows) + ordinary = summarize([r for r in rows if not r["transfer"]]) + transfers = summarize([r for r in rows if r["transfer"]]) + complete = all(p.get("complete", p.get("ready", False)) for p in phase_results) + result = { + "schema_version": 2, + "startup_seconds": startup_seconds, + "idle_window": idle_window, + "transport_rebinds": transport_rebinds, + "phase_results": phase_results, + "started_at": started, + "finished_at": datetime.now(UTC).isoformat(), + "duration_seconds": time.perf_counter() - before, + "config": config, + "environment": { + "python": platform.python_version(), + "django": django.get_version(), + "platform": platform.platform(), + "database": os.environ.get( + "SYNTHETIC_DATABASE_DESCRIPTION", "disposable PostgreSQL 16 container" + ), + "transport": os.environ.get( + "SYNTHETIC_TRANSPORT_DESCRIPTION", "loopback HTTP Gunicorn" + ), + "workers": config["workers"], + }, + "ordinary": ordinary, + "document_transfer": transfers, + "complete": complete, + "provisional_pass": complete + and ordinary["errors"] == 0 + and transfers["errors"] == 0 + and all( + p["ordinary"]["p95_seconds"] <= config["ordinary_p95_seconds"] + for p in phase_results + if p["kind"] == "load" + ), + "limitations": [ + "No browser, ingress, TLS or SSO", + "No CPU/memory allocation recommendation or human acceptance", + "No deployed-release hardware or shared-service contention acceptance", + ], + "operations": rows, + "runtime_samples": samples, + "database_samples": db_samples, + "completed_iterations": phase_completed, + } + sampling_done.set() + for thread in sampler_threads: + thread.join(timeout=7) + gaps = sampling_gaps(samples, db_samples, sampler_errors, remote=remote_mode) + if remote_mode: + result["resource_sampling"] = "external; align with phase UTC windows" + if any(thread.is_alive() for thread in sampler_threads): + gaps.append({"sampler": "cleanup", "reason": "thread did not stop"}) + result["measurement_gaps"] = gaps + result["measurement_complete"] = not gaps + if container_mode: + result["app_container"] = json.loads( + subprocess.check_output( + ["docker", "inspect", "--format", "{{json .}}", app_container], + text=True, + timeout=10, + ) + ) + # Retain only public runtime identifiers/limits, never full container environment. + info = result.pop("app_container") + result["app_runtime"] = { + "image_id": info["Image"], + "nano_cpus": info["HostConfig"]["NanoCpus"], + "memory_bytes": info["HostConfig"]["Memory"], + "memory_kind": "cgroup-memory-current includes page cache", + "oom_killed": info["State"]["OOMKilled"], + "dockerfile_sha256": hashlib.sha256(Path("Dockerfile").read_bytes()).hexdigest(), + } + return result + except Exception as exc: + if failure_output is not None: + failure = { + "schema_version": 2, + "status": "failed", + "complete": False, + "provisional_pass": False, + "measurement_complete": False, + "error_type": type(exc).__name__, + "phase": locals().get("phase", {"name": "startup"}), + "config": config, + "phase_results": locals().get("phase_results", []), + "operations": locals().get("rows", []), + "runtime_samples": locals().get("samples", []), + "database_samples": locals().get("db_samples", []), + "measurement_gaps": [{"reason": "runtime failure; partial evidence only"}], + "driver_sha256": hashlib.sha256(Path(__file__).read_bytes()).hexdigest(), + } + failure_output.write_text(json.dumps(failure, indent=2) + "\n") + raise + finally: + sampling_done.set() + for thread in sampler_threads: + if thread.ident is not None: + thread.join(timeout=7) + stop_process(server) + if app_container is not None: + subprocess.run( + ["docker", "rm", "--force", "--volumes", app_container], + timeout=15, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + server_log.close() + connections.close_all() + + +def host_facts(config): + return { + "logical_cpus": os.cpu_count(), + "affinity_cpus": len(os.sched_getaffinity(0)), + "cpu_model": next( + ( + x.split(":", 1)[1].strip() + for x in Path("/proc/cpuinfo").read_text().splitlines() + if x.startswith("model name") + ), + "unknown", + ), + "memory_total": next( + x for x in Path("/proc/meminfo").read_text().splitlines() if x.startswith("MemTotal:") + ), + "cgroup_cpu_max": Path("/sys/fs/cgroup/cpu.max").read_text().strip() + if Path("/sys/fs/cgroup/cpu.max").exists() + else "unavailable", + "app_cpu_quota": config.get("app_cpu_limit", "not imposed by harness"), + } + + +def main_remote(config, args): + """Drive an existing isolated synthetic deployment; never a shared database.""" + for name in ("SYNTHETIC_BASE_URL", "SYNTHETIC_DATABASE_URL"): + if not os.environ.get(name): + raise SystemExit(f"{name} is required for remote runtime") + with tempfile.TemporaryDirectory(prefix="vergabe-synthetic-") as directory: + result = run(config, Path(directory), args.output) + result["source_revision"] = os.environ.get("SYNTHETIC_SOURCE_REVISION", "unrecorded") + result["driver_sha256"] = hashlib.sha256(Path(__file__).read_bytes()).hexdigest() + result["host"] = host_facts(config) + result["config_sha256"] = hashlib.sha256(args.config.read_bytes()).hexdigest() + args.output.write_text(json.dumps(result, indent=2) + "\n") + keys = ("ordinary", "document_transfer", "complete", "provisional_pass") + print(json.dumps({k: result[k] for k in keys})) + return 0 if result["provisional_pass"] and result["measurement_complete"] else 1 + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--config", type=Path, required=True) + parser.add_argument("--output", type=Path, required=True) + args = parser.parse_args() + config = validate(json.loads(args.config.read_text())) + sys.path.insert(0, str(Path(__file__).resolve().parents[1])) + if config.get("runtime") == "remote": + sys.exit(main_remote(config, args)) + name = "vergabe-synthetic-" + uuid.uuid4().hex[:12] + network = name + "-network" + network_args = [] + try: + if config.get("runtime") == "container": + subprocess.run( + ["docker", "network", "create", network], + check=True, + timeout=15, + stdout=subprocess.DEVNULL, + ) + os.environ["SYNTHETIC_NETWORK"] = network + network_args = ["--network", network, "--network-alias", "db"] + # Cached image only, loopback random host port, no existing volume or database. + subprocess.run( + [ + "docker", + "run", + "--detach", + "--pull=never", + "--name", + name, + "--publish", + "127.0.0.1::5432", + "--env", + "POSTGRES_DB=synthetic", + "--env", + "POSTGRES_USER=synthetic", + "--env", + "POSTGRES_PASSWORD=synthetic-local-only", + *network_args, + "postgres:16-alpine", + ], + check=True, + stdout=subprocess.DEVNULL, + ) + for _ in range(100): + ready = subprocess.run( + ["docker", "exec", name, "pg_isready", "-U", "synthetic"], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + if ready.returncode == 0: + break + time.sleep(0.1) + else: + raise RuntimeError("isolated PostgreSQL startup failed") + port = ( + subprocess.check_output(["docker", "port", name, "5432/tcp"], text=True) + .strip() + .split(":")[-1] + ) + os.environ["SYNTHETIC_CONTAINER"] = name + os.environ["SYNTHETIC_DATABASE_URL"] = ( + f"postgres://synthetic:synthetic-local-only@127.0.0.1:{port}/synthetic" + ) + with tempfile.TemporaryDirectory(prefix="vergabe-synthetic-") as directory: + result = run(config, Path(directory), args.output) + result["postgres_image_id"] = subprocess.check_output( + ["docker", "inspect", "--format", "{{.Image}}", name], text=True + ).strip() + result["postgres_final_stats"] = json.loads( + subprocess.check_output( + ["docker", "stats", "--no-stream", "--format", "{{json .}}", name], + text=True, + ) + ) + finally: + subprocess.run( + ["docker", "rm", "--force", "--volumes", name], + timeout=15, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + if network_args: + subprocess.run( + ["docker", "network", "rm", network], + check=True, + timeout=15, + stdout=subprocess.DEVNULL, + ) + result["source_revision"] = subprocess.check_output( + ["git", "rev-parse", "HEAD"], text=True + ).strip() + result["driver_sha256"] = hashlib.sha256(Path(__file__).read_bytes()).hexdigest() + app_files = sorted(Path("vergabe_teilnahme").rglob("*.py")) + [ + Path("uv.lock"), + Path("pyproject.toml"), + ] + result["app_source_sha256"] = hashlib.sha256( + b"".join(str(p).encode() + b"\0" + p.read_bytes() for p in app_files) + ).hexdigest() + result["host"] = { + "logical_cpus": os.cpu_count(), + "affinity_cpus": len(os.sched_getaffinity(0)), + "cpu_model": next( + ( + x.split(":", 1)[1].strip() + for x in Path("/proc/cpuinfo").read_text().splitlines() + if x.startswith("model name") + ), + "unknown", + ), + "memory_total": next( + x for x in Path("/proc/meminfo").read_text().splitlines() if x.startswith("MemTotal:") + ), + "cgroup_cpu_max": Path("/sys/fs/cgroup/cpu.max").read_text().strip() + if Path("/sys/fs/cgroup/cpu.max").exists() + else "unavailable", + "app_cpu_quota": config.get("app_cpu_limit", "not imposed by harness"), + } + result["config_sha256"] = hashlib.sha256(args.config.read_bytes()).hexdigest() + args.output.write_text(json.dumps(result, indent=2) + "\n") + print( + json.dumps( + { + k: result[k] + for k in ( + "ordinary", + "document_transfer", + "complete", + "provisional_pass", + ) + } + ) + ) + raise SystemExit(0 if result["provisional_pass"] and result["measurement_complete"] else 1) diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/harness/orchestrate.sh b/docs/evidence/2026-10-21-vergabe-target-replay/harness/orchestrate.sh new file mode 100755 index 0000000..5bbc6e7 --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/harness/orchestrate.sh @@ -0,0 +1,15 @@ +#!/bin/bash +NS=vergabe-sizing-20261021; W=$SCRATCH; R=$W/raw; STOP=$R/stop; rm -f $STOP +$SCRATCH/sampler.sh app=vergabe-sizing-app app $R/app-cgroup.txt $STOP & +$SCRATCH/sampler.sh app=vergabe-sizing-db postgres $R/db-cgroup.txt $STOP & +$SCRATCH/sampler.sh app=vergabe-sizing-driver driver $R/driver-cgroup.txt $STOP & +$SCRATCH/top.sh $R/kubectl-top.txt $STOP & +echo "baseline_start $(date -u +%FT%T.%NZ)" > $R/windows.txt +sleep 120 +echo "driver_start $(date -u +%FT%T.%NZ)" >> $R/windows.txt +kubectl -n $NS exec synthetic-driver -- python /driver/synthetic_pilot.py --config /driver/config.json --output /out/result.json > $R/driver-stdout.txt 2>&1 +echo "driver_exit $? $(date -u +%FT%T.%NZ)" >> $R/windows.txt +sleep 60 +echo "post_end $(date -u +%FT%T.%NZ)" >> $R/windows.txt +touch $STOP; sleep 3; wait +echo done diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/harness/prom.py b/docs/evidence/2026-10-21-vergabe-target-replay/harness/prom.py new file mode 100644 index 0000000..2dde2be --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/harness/prom.py @@ -0,0 +1,25 @@ +import json, subprocess, sys, urllib.parse +start, end, out = sys.argv[1], sys.argv[2], sys.argv[3] +P = "/api/v1/namespaces/telemetry/services/telemetry-prometheus:9090/proxy/api/v1/query_range?" +def q(expr, step="15s"): + url = P + urllib.parse.urlencode({"query": expr, "start": start, "end": end, "step": step}) + return json.loads(subprocess.check_output(["kubectl", "get", "--raw", url])) +res = {"window": [start, end], "queries": {}} +for name, expr in { + "cpu_by_namespace_cores": 'sum by (namespace) (rate(container_cpu_usage_seconds_total{container!="",image!=""}[1m]))', + "throttled_ratio_by_namespace": 'sum by (namespace) (rate(container_cpu_cfs_throttled_periods_total{container!=""}[1m])) / sum by (namespace) (rate(container_cpu_cfs_periods_total{container!=""}[1m]))', + "memory_working_set_by_namespace_bytes": 'sum by (namespace) (container_memory_working_set_bytes{container!="",image!=""})', + "apps_pg_cpu_cores": 'sum by (pod) (rate(container_cpu_usage_seconds_total{namespace="databases",container!="",image!=""}[1m]))', + "live_vergabe_cpu_cores": 'sum (rate(container_cpu_usage_seconds_total{namespace="vergabe-demo-company",container!="",image!=""}[1m]))', +}.items(): + r = q(expr) + res["queries"][name] = {"expr": expr, "result": r["data"]["result"]} +json.dump(res, open(out, "w")) +# summary: mean per namespace cpu +s = {} +for series in res["queries"]["cpu_by_namespace_cores"]["result"]: + v = [float(x[1]) for x in series["values"]] + s[series["metric"].get("namespace", "?")] = (round(1000*sum(v)/len(v)), round(1000*max(v))) +tot = sum(a for a, b in s.values()) +print("container_total_mean_m", tot) +for k, v in sorted(s.items(), key=lambda kv: -kv[1][0])[:15]: print(k, "mean_m", v[0], "max_m", v[1]) diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/harness/sampler.sh b/docs/evidence/2026-10-21-vergabe-target-replay/harness/sampler.sh new file mode 100755 index 0000000..dd469c6 --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/harness/sampler.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# usage: sampler.sh +NS=vergabe-sizing-20261021; SEL=$1; C=$2; OUT=$3; STOP=$4 +LOOP='while :; do echo "S $(date +%s.%N)"; cat /sys/fs/cgroup/cpu.stat; echo "M $(cat /sys/fs/cgroup/memory.current)"; echo "P $(head -1 /sys/fs/cgroup/cpu.pressure)"; echo "N $(head -1 /proc/stat)"; echo "L $(cat /proc/loadavg)"; sleep 1; done' +while [ ! -e "$STOP" ]; do + POD=$(kubectl -n $NS get pod -l "$SEL" --field-selector=status.phase=Running -o jsonpath='{.items[0].metadata.name}' 2>/dev/null) + if [ -n "$POD" ]; then + echo "POD $POD $(date +%s.%N)" >> "$OUT" + timeout 1500 kubectl -n $NS exec "$POD" -c "$C" -- sh -c "$LOOP" >> "$OUT" 2>>"$OUT.err" & + PID=$! + while kill -0 $PID 2>/dev/null && [ ! -e "$STOP" ]; do sleep 1; done + kill $PID 2>/dev/null + echo "DETACH $(date +%s.%N)" >> "$OUT" + fi + sleep 0.5 +done diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/harness/synthetic_settings.py b/docs/evidence/2026-10-21-vergabe-target-replay/harness/synthetic_settings.py new file mode 100644 index 0000000..2260675 --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/harness/synthetic_settings.py @@ -0,0 +1,12 @@ +from vergabe_teilnahme.settings.base import * +DEBUG = False +ALLOWED_HOSTS = ['vergabe-app'] +NETKINGDOM_ENABLED = False +MEDIA_ROOT = '/app/media' +ISSUE_FACADE_LOCAL_DB = '/app/.issue-facade/issues.db' +ISSUE_FACADE_GITEA = None +FORCE_SCRIPT_NAME = None +MEDIA_URL = "/media/" +EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend" +SESSION_COOKIE_SECURE = False +CSRF_COOKIE_SECURE = False diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/harness/top.sh b/docs/evidence/2026-10-21-vergabe-target-replay/harness/top.sh new file mode 100755 index 0000000..8366b81 --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/harness/top.sh @@ -0,0 +1,3 @@ +#!/bin/bash +OUT=$1; STOP=$2 +while [ ! -e "$STOP" ]; do echo "T $(date -u +%s)"; kubectl top pods -A --no-headers 2>&1; kubectl top node --no-headers 2>&1; sleep 15; done >> $OUT diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/raw/app-cgroup.txt.gz b/docs/evidence/2026-10-21-vergabe-target-replay/raw/app-cgroup.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..7a1b12be8669b8b1b415aac554d0ea81aeaa0455 GIT binary patch literal 30529 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�$Uu1!lssg%T)J@y2c#*W&8jg)D(-b+aQ} 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 U@W+k*R`RiQQdCup)?{lAX9jf8$tjq{th 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

|aJ3p^3{Z0w?jo?`v*e4M>xz;Cj4>*&`gR zp-eKcSbEO2t%ukKG;!aB!AN(PwjnXx^HX-SQFD)7h)?_>sz&C&v1fvu_cQG#KO;;A zC^?_BE{|){cHQbS-uL#?EV|mrx9My#2E&uVg^GV9&W#`>+R?~Ox#ys-~G3yd0wfaL=8 z%JXsr$=%>-1JQz?CUuRxMmUd0v;Ku^9tGr`As9};0_BST1(7ao$@2c2VW4mhFb6y-AWKn;V#4v|`KV(>pJ8e~3tRt!5@ zB{Sigj+_aDN7R_xgPOWPV6e7t{OmV|XQ8@6vhZM}4#kp2j`oBZglw{vk|c-8iuFj`t;sWI>pqI0Wq+Fkvr5IXQvSOZOMSiI z+8ij(b$z?uBDPzyVItK>EGa-jgQk3KMg&?1VepJ6WZ`Fd@{-JPhi<9Q!02&Xs`Y<9 z(%^t?fDh4B;jC2q@o4790UnCS6RKifL@KHD#C#~S3O!}ZI-l-NjXsQP8)d1uqH&vU z_rcu$cTE93cZwhE1^sOc%2wG1Re&%EtsWQ!Cv3c_UDa;D>Erd9nid1Jfa~$`sk3QZ zq3k417+DGP;fLL7Kek)&b(~Rd2+$>?gngIGjPt@g$+`DMa<|5&eO?C=K=@{e=r~g# z*$jQgSwb5${SqmoXz;yS=vBBt#xe*R$$U(TR`mN8e@Xoi3l1Q{qYjDk$b$_*FA}qe z4jwOW1DsS4CPyY@SGiEniJ5q65icI^(LYX>6e}jBMwdBUEwbEx3WSVb@t%Ifi%&E0 z+reRi?=8l(3y1xzi-m3Vhta*8edGWq1?zis1W-c>eK6WLjp%(M<+p)MNP_u12pYDw zL5g1I22~hE@P$13etu+w7u^}5Iw;u0Hj#?mO*r_hT{R~%m$-MRos)=iV?c$8_xj~y z=P3@A4~KS4UhyhYn3o!KTB0zb8nF~Njxe!B|S%#0* zle?^-9;-wvMOPER`1=Mr6fDIQzN0v|ehCMwYB6F`=XDH|#YmdW^dQ$_$j=Q1RWhjR z2XU9?wQEW|JMF&x(V99VkpYk)dfLl~NF&0VJCmp58-yeCSEl`A&qCBI*oZ>_zF?H` zvH^GS)%8d3jfh7cJ-@!pS=6+`;;Xex&g=I(I$PRT>e&sBo6Lfz?<|RwBP00T-{l>qx+@!_!C6KKgHqU%p5+mM5o$z%;>)X0ctqkH?A zuHj=nM3w(zlZS!~?H5PM27)RFiG#T87X?0Kw^HYbC*H{cY=YZ$#B)A^!xIyviWw2MuQ!_9$^fvP6%rmn81ib=NKGaJyb K)?=yRVEqqjbpMe6 literal 0 HcmV?d00001 diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/raw/driver-cgroup.txt.gz b/docs/evidence/2026-10-21-vergabe-target-replay/raw/driver-cgroup.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..1676805e805ed3344cefadb3ab04fe2127bb8c4e GIT binary patch literal 28201 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 Scheduled vergabe-app-579448bf49-2fsn2 Successfully assigned vergabe-sizing-20261021/vergabe-app-579448bf49-2fsn2 to 239.62.205.92.host.secureserver.net + Scheduled vergabe-db-7c4bffdd48-w4jz4 Successfully assigned vergabe-sizing-20261021/vergabe-db-7c4bffdd48-w4jz4 to 239.62.205.92.host.secureserver.net + Scheduled synthetic-driver Successfully assigned vergabe-sizing-20261021/synthetic-driver to 239.62.205.92.host.secureserver.net + Scheduled vergabe-app-579448bf49-plp4j Successfully assigned vergabe-sizing-20261021/vergabe-app-579448bf49-plp4j to 239.62.205.92.host.secureserver.net +2026-10-21T06:26:14Z ScalingReplicaSet vergabe-db Scaled up replica set vergabe-db-7c4bffdd48 from 0 to 1 +2026-10-21T06:26:14Z SuccessfulCreate vergabe-db-7c4bffdd48 Created pod: vergabe-db-7c4bffdd48-w4jz4 +2026-10-21T06:26:14Z WaitForFirstConsumer bench-media waiting for first consumer to be created before binding +2026-10-21T06:26:16Z SuccessfulCreate vergabe-app-579448bf49 Created pod: vergabe-app-579448bf49-2fsn2 +2026-10-21T06:26:16Z ScalingReplicaSet vergabe-app Scaled up replica set vergabe-app-579448bf49 from 0 to 1 +2026-10-21T06:26:16Z Pulled vergabe-db-7c4bffdd48-w4jz4 Container image "docker.io/library/postgres@sha256:4b7183ac05f8ef417db21fd72d71047a4238340c261d3cc3ddb6d579ab5071ae" already present on machine and can be accessed by the pod +2026-10-21T06:26:16Z Created vergabe-db-7c4bffdd48-w4jz4 Container created +2026-10-21T06:26:16Z Provisioning bench-media External provisioner is provisioning volume for claim "vergabe-sizing-20261021/bench-media" +2026-10-21T06:26:16Z Started vergabe-db-7c4bffdd48-w4jz4 Container started +2026-10-21T06:26:19Z Unhealthy vergabe-db-7c4bffdd48-w4jz4 Readiness probe failed: /var/run/postgresql:5432 - no response + +2026-10-21T06:26:21Z Created synthetic-driver Container created +2026-10-21T06:26:21Z ExternalProvisioning bench-media Waiting for a volume to be created either by the external provisioner 'rancher.io/local-path' or manually by the system administrator. If volume creation is delayed, please verify that the provisioner is running and correctly registered. +2026-10-21T06:26:21Z Pulled synthetic-driver Container image "forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91" already present on machine and can be accessed by the pod +2026-10-21T06:26:22Z Started synthetic-driver Container started +2026-10-21T06:26:25Z ProvisioningSucceeded bench-media Successfully provisioned volume pvc-a23ccb84-ecd8-47af-9832-6d8b09c48e38 +2026-10-21T06:26:26Z Started vergabe-app-579448bf49-2fsn2 Container started +2026-10-21T06:26:26Z Created vergabe-app-579448bf49-2fsn2 Container created +2026-10-21T06:26:26Z Pulled vergabe-app-579448bf49-2fsn2 Container image "forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91" already present on machine and can be accessed by the pod +2026-10-21T06:26:32Z Started vergabe-app-579448bf49-2fsn2 Container started +2026-10-21T06:26:32Z Created vergabe-app-579448bf49-2fsn2 Container created +2026-10-21T06:26:32Z Pulled vergabe-app-579448bf49-2fsn2 Container image "forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91" already present on machine and can be accessed by the pod +2026-10-21T06:32:03Z SuccessfulCreate vergabe-app-579448bf49 Created pod: vergabe-app-579448bf49-plp4j +2026-10-21T06:32:03Z Killing vergabe-app-579448bf49-2fsn2 Stopping container app +2026-10-21T06:32:04Z Started vergabe-app-579448bf49-plp4j Container started +2026-10-21T06:32:04Z Created vergabe-app-579448bf49-plp4j Container created +2026-10-21T06:32:04Z Pulled vergabe-app-579448bf49-plp4j Container image "forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91" already present on machine and can be accessed by the pod +2026-10-21T06:32:04Z Unhealthy vergabe-app-579448bf49-2fsn2 Readiness probe failed: Get "http://10.42.0.96:8000/health/": dial tcp 10.42.0.96:8000: connect: connection refused +2026-10-21T06:32:09Z Started vergabe-app-579448bf49-plp4j Container started +2026-10-21T06:32:09Z Created vergabe-app-579448bf49-plp4j Container created +2026-10-21T06:32:09Z Pulled vergabe-app-579448bf49-plp4j Container image "forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91" already present on machine and can be accessed by the pod diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/raw/pod-provenance.txt b/docs/evidence/2026-10-21-vergabe-target-replay/raw/pod-provenance.txt new file mode 100644 index 0000000..0ca72f5 --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/raw/pod-provenance.txt @@ -0,0 +1,4 @@ +synthetic-driver driver forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91 0 {} ['running'] +vergabe-app-579448bf49-plp4j migrate forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91 0 {} ['terminated'] +vergabe-app-579448bf49-plp4j app forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91 0 {} ['running'] +vergabe-db-7c4bffdd48-w4jz4 postgres docker.io/library/postgres@sha256:4b7183ac05f8ef417db21fd72d71047a4238340c261d3cc3ddb6d579ab5071ae 0 {} ['running'] diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/raw/prometheus-baseline.json.gz b/docs/evidence/2026-10-21-vergabe-target-replay/raw/prometheus-baseline.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..f246eec9fcefcbbeb0346e4a260847b17d0d1710 GIT binary patch literal 7943 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%0D9Oc3iuA+1qlVBfO(5fIuKG^M+ye^jVRb=0|knP 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 literal 0 HcmV?d00001 diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/raw/prometheus-workload.json.gz b/docs/evidence/2026-10-21-vergabe-target-replay/raw/prometheus-workload.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..c589397d6a0e60e58eb2254cbbe8c3dba68973db GIT binary patch literal 10883 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 FzW`vhrdt32 literal 0 HcmV?d00001 diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/raw/result.json.gz b/docs/evidence/2026-10-21-vergabe-target-replay/raw/result.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..7128c41085cca2445e1d3af7a5b8a72d2e779014 GIT binary patch literal 58759 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 Y@8vGHTi1(U{MRr38$Dg&iwYeN0PVd#g#Z8m literal 0 HcmV?d00001 diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/raw/teardown.txt b/docs/evidence/2026-10-21-vergabe-target-replay/raw/teardown.txt new file mode 100644 index 0000000..85aa06d --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/raw/teardown.txt @@ -0,0 +1,7 @@ +delete_requested 2026-10-21T06:35:25Z +namespace "vergabe-sizing-20261021" deleted +delete_returned 2026-10-21T06:36:18Z +Error from server (NotFound): namespaces "vergabe-sizing-20261021" not found +Error from server (NotFound): persistentvolumes "pvc-a23ccb84-ecd8-47af-9832-6d8b09c48e38" not found +0 +live generation=4 image=forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91 ready=1 diff --git a/docs/evidence/2026-10-21-vergabe-target-replay/raw/windows.txt b/docs/evidence/2026-10-21-vergabe-target-replay/raw/windows.txt new file mode 100644 index 0000000..8e3d24d --- /dev/null +++ b/docs/evidence/2026-10-21-vergabe-target-replay/raw/windows.txt @@ -0,0 +1,4 @@ +baseline_start 2026-10-21T06:27:14.447540583Z +driver_start 2026-10-21T06:29:26.175778371Z +driver_exit 0 2026-10-21T06:33:22.885983171Z +post_end 2026-10-21T06:34:28.753426744Z diff --git a/workplans/RAPPS-WP-0014-vergabe-invited-pilot.md b/workplans/RAPPS-WP-0014-vergabe-invited-pilot.md index d1cfe51..af15267 100644 --- a/workplans/RAPPS-WP-0014-vergabe-invited-pilot.md +++ b/workplans/RAPPS-WP-0014-vergabe-invited-pilot.md @@ -9,7 +9,7 @@ flavor: implementation owner: the-custodian topic_slug: railiance created: "2026-09-11" -updated: "2026-10-19" +updated: "2026-10-21" related: [VERGABE-WP-0019, VERGABE-WP-0018, HFACT-WP-0001, CUST-WP-0071] state_hub_workstream_id: "c7fdaa7e-cab8-5d1d-86c2-f1aad7927c57" --- @@ -252,7 +252,7 @@ all remaining work; no task or workplan was opened. ```task id: RAPPS-WP-0014-T04 -status: todo +status: done priority: high assignee: railiance-apps state_hub_task_id: "c53fcaa9-859c-5b37-a17b-0a4cd2fb0e26" @@ -293,3 +293,18 @@ coverage/gaps and a bounded recommendation to `RESOURCE-WP-0008-T02` for headroo and allocation review and `CUST-WP-0071-T02` for sizing acceptance. T03 remains unchanged: operator/customer recovery and human acceptance are not inferred from these synthetic results. + +2026-10-21 result: isolated replay run on railiance01 under the founder's +2026-10-21 decision, in throwaway namespace `vergabe-sizing-20261021` (deleted +06:36:18Z, PV removed; live deployment unchanged). Deployed digest +`sha256:a26444f5…` (source `c067993`, chart 0.2.1, 3 Gunicorn workers, +60m/256Mi request, 1000m/1Gi limit) against a fresh PostgreSQL 16 pod, phased +profile with in-cluster driver. 3675 ordinary requests p95 0.192s and 814 +transfers p95 0.076s, zero errors, restart ready in 19s. App CPU 775m mean under +load, 36% of CFS periods throttled (66% in burst), memory peak 483 MiB; isolated +DB +~320m mean; node free CPU 1.2 cores mean, ~150m at p5 (largely self-induced). +Recommendation: keep 1000m/1Gi limits and the 60m request for the two-user pilot; +consider 512Mi memory request at allocation review. Gaps: synthetic settings (no +SSO/ingress/TLS), standalone DB rather than shared `apps-pg`, synthetic closed +loop, one run at a quiet hour. Evidence and revisit triggers: +`docs/evidence/2026-10-21-vergabe-target-replay/README.md`. T03 is unchanged.