Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions scripts/ci/docker/linux-runner/persist/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ n'a pas ete remplacee. Un `git pull` ne deploie pas `persist/`.
| `po-2026/pool.sh` | **po-2026** | `/home/jesse/CoursIA-runners-p0/pool.sh` (WSL Ubuntu) | **deploye et vivant** -- superviseur du pool, **8 slots** et **borne depuis le 2026-09-22** (cf. `po-2026/README.md`) |
| `po-2026/run-pool-po2026.sh` | **po-2026** (hote Windows) | `C:\dev\CoursIA-runners-p0\run-pool-po2026.sh` | **deploye et vivant** -- lanceur de la tache planifiee, porte la borne CPU/memoire. **Attention : ce fichier vit sous `C:\dev\...`, pas sous `D:\Dev\CoursIA-runners-p0\`** (cf. `po-2026/README.md`) |
| `po-2026/README.md` | -- | -- | **document** : architecture, dimensionnement, piege du verrou |
| `po-2024/coursia-ci.slice` | **po-2024** | `/etc/systemd/system/coursia-ci.slice` | **a deployer** (2026-10-08, amendement J+7 : valeurs 20G/22G -> 14G/16G, budget 21 -> 15) -- le mur kernel qui manquait a cette machine : `MemoryHigh=14G`, `MemoryMax=16G`, `MemorySwapMax=0`. Homonyme de la slice ai-01, valeurs differentes (cf. section `po-2024/`) |
| `po-2024/coursia-waiters.service.d/10-sizing.conf` | **po-2024** | `/etc/systemd/system/coursia-waiters.service.d/10-sizing.conf` | **a deployer** (2026-10-08) -- 12 -> 6 slots waiters pour po-2024 seulement, par drop-in, parce que `coursia-waiters.service` est le fichier d'**ai-01** que les deux machines executent |
| `po-2024/coursia-ci.slice` | **po-2024** | `/etc/systemd/system/coursia-ci.slice` | **a deployer** (2026-10-12, arbitrage c2153 : 14G/16G -> **20G/22G**, budget 15 -> **21** apres #20174 -- la composition vive 8x1536 + 6x512 + 1x6144 = 21 504 Mo n'avait pas ete comptee depuis le J+7) -- le mur kernel de cette machine : `MemoryHigh=20G`, `MemoryMax=22G`, `MemorySwapMax=0`. Homonyme de la slice ai-01, valeurs differentes (cf. section `po-2024/`) |
| `po-2024/coursia-waiters.service.d/10-sizing.conf` | **po-2024** | `/etc/systemd/system/coursia-waiters.service.d/10-sizing.conf` | **a deployer** (2026-10-12, arbitrage c2153 : budget 15 -> **21**, meme nombre que les wrappers) -- 12 -> 6 slots waiters pour po-2024 seulement, par drop-in, parce que `coursia-waiters.service` est le fichier d'**ai-01** que les deux machines executent |

Le sous-repertoire `ai-01/` existe parce que les deux machines ont des fichiers
**homonymes et incompatibles**. Les melanger a plat, comme c'etait le cas, revient
Expand Down
14 changes: 9 additions & 5 deletions scripts/ci/docker/linux-runner/persist/coursia-lean-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ export COURSIA_LEAN_RUNNER_NAME_PREFIX="${COURSIA_LEAN_RUNNER_NAME_PREFIX:-myia-
export COURSIA_RUNNER_STATE_DIR="${COURSIA_RUNNER_STATE_DIR:-/var/lib/coursia-lean}"
mkdir -p "$COURSIA_RUNNER_STATE_DIR"

# MEME BUDGET QUE LES DEUX AUTRES JAMBES DE CETTE MACHINE -- 15 Go depuis le
# 2026-10-08, amendement J+7 (le 42 etait devenu faux deux fois : VM revenue
# de 40 110 a 24 032 Mo, et son arithmetique comptait « 12x1536 waiters »
# pour des waiters a 512 Mo -- detail complet en tete de coursia-runner-start.sh).
# MEME BUDGET QUE LES DEUX AUTRES JAMBES DE CETTE MACHINE -- 21 Go depuis le
# 2026-10-12, arbitrage c2153 d'ai-01 (le J+7 du 2026-10-08 avait pose 15 pour
# 4x1536 + 6x512 + 1x6144 = 15 360 Mo de caps ; #20174 du 2026-10-10 a
# reetiquete 4 slots persist, la composition vive est revenuee a
# 8x1536 + 6x512 + 1x6144 = 21 504 Mo sans que le budget suive -- detail
# complet en tete de coursia-runner-start.sh).
#
# CETTE JAMBE EST CELLE QUI REND LE BUDGET VISIBLE, et c'est pour ca qu'elle
# doit le declarer : son slot a 6 Go demande 6 144 Mo a lui seul. Sous
Expand All @@ -76,7 +78,9 @@ mkdir -p "$COURSIA_RUNNER_STATE_DIR"
#
# Les trois jambes doivent annoncer le meme nombre : assert_memory_budget
# somme les familles entre elles, une divergence refuserait des slots sans
# nommer sa cause.
# nommer sa cause. Sous 15 Go avec 4 slots persist revenus (#20174), la somme
# des caps vivants (21 504 Mo) depassait le budget declare : le garde
# refusait TOUT demarrage -- la famine CI du 2026-10-12.
export COURSIA_RUNNER_BUDGET_GB="${COURSIA_RUNNER_BUDGET_GB:-21}"

# AUCUN SWAP POUR LA JAMBE LEAN (2026-10-08) -- memory-swap = memory.
Expand Down
54 changes: 32 additions & 22 deletions scripts/ci/docker/linux-runner/persist/coursia-runner-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,29 @@ export COURSIA_RUNNER_TOOLCACHE_VOLUME="coursia-runner-toolcache"
# rend auditable : la valeur effective vit dans un fichier que l'operateur ouvre,
# pas dans un defaut de shell que personne ne lit.
#
# 15 POUR po-2024 (2026-10-08, amendement J+7) -- LE 42 EST TOMBE, ET IL
# ETAIT DEVENU FAUX DEUX FOIS. Il avait ete pose le 2026-09-21 pour une VM de
# 40 110 Mo (.wslconfig memory=40GB, arbitrage user, mission
# msg-20260921T203652-qxg3en). Depuis, la VM est revenue a 24 Go : `.wslconfig
# memory=24GB` et `free -m` (24 032 Mo) le mesurent tous les deux. Et son
# arithmetique de 43 008 Mo n'a jamais ete la vraie : elle comptait
# « 12x1536 waiters » alors que WAITER_MEMORY vaut 512m (supervise.sh l.180).
# La composition REELLE etait 6x1536 + 12x512 + 2x6144 = 27 648 Mo de caps sur
# une VM de 24 032 -- une somme de caps superieure a la RAM, qui se paie en
# swap. Mesure du jour : 6 285 Mo de swap consommes, 104 GiB ecrits depuis le
# boot en moins de 11 h, DriveFS et la coordination de la flotte en premier.
# 21 POUR po-2024 (2026-10-12, arbitrage c2153 d'ai-01) -- la composition
# persist n'avait pas ete comptee depuis le J+7. Historique complet : le 42
# du 2026-09-21 (VM de 40 110 Mo) etait devenu faux deux fois (VM revenuee a
# 24 Go ; arithmetique comptant « 12x1536 waiters » pour des waiters a
# 512 Mo) ; le J+7 du 2026-10-08 a pose 15 pour la composition
# 4x1536 + 6x512 + 1x6144 = 15 360 Mo. Puis #20174 (2026-10-10) a reetiquete
# 4 slots persist -- la famille docker est revenuee a 8 slots de 1536 Mo SANS
# que le budget suive : la somme des caps vivants (21 504 Mo) depassait le
# budget declare (15 360), et assert_memory_budget refusait de DEMARRER tout
# nouveau slot. C'est la famine CI constatee au cycle du 2026-10-12 : le
# garde ne jugeait plus la composition, il la bloquait.
#
# LA COMPOSITION QUE CE BUDGET DECLARE, ET CE QU'ELLE LAISSE :
# 4 slots docker x 1536 Mo = 6 144 Mo (cap unitaire INCHANGE)
# 6 waiters x 512 Mo = 3 072 Mo (cap unitaire INCHANGE)
# 1 slot lean x 6144 Mo = 6 144 Mo (2 -> 1, verdict J+7 ci-dessous)
# 8 slots docker x 1536 Mo = 12 288 Mo (4 docker + 4 persist, #20174)
# 6 waiters x 512 Mo = 3 072 Mo (cap unitaire INCHANGE)
# 1 slot lean x 6144 Mo = 6 144 Mo (2 -> 1, verdict J+7)
# --------------------------------------
# total CAPS 15 360 Mo sur 24 032 -> marge 8 672 Mo
# total CAPS 21 504 Mo sur 24 032 -> marge 2 528 Mo
#
# La regle de #19802 tranche la valeur : LE BUDGET EST LA SOMME DES CAPS de
# la composition vive. 21 504 Mo = 21 Go, deja valide par #19802 sur cette VM
# de 24 Go (marge 2,5 Go, swap 0 -- la marge etroite est payee par le mur
# kernel MemorySwapMax=0, qui tue le job debordant au lieu de swapper).
#
# ON REDUIT DES NOMBRES DE SLOTS, JAMAIS DES CAPS. Mesure du 2026-10-08 :
# 3 des 6 conteneurs docker touchaient leur cap de 1536 Mo a 99 %, donc le cap
Expand All @@ -67,19 +72,24 @@ export COURSIA_RUNNER_TOOLCACHE_VOLUME="coursia-runner-toolcache"
# ne l'abaisse nulle part.
#
# LE BUDGET RESTE UN PLAFOND D'ADMISSION, PAS UN MUR. Il refuse de DEMARRER un
# slot au-dela de 15 Go ; il ne borne pas ce qu'un slot deja lance consomme.
# slot au-dela de 21 Go ; il ne borne pas ce qu'un slot deja lance consomme.
# Le mur kernel est desormais pose sur cette machine : voir
# persist/po-2024/coursia-ci.slice (MemoryHigh=14G, MemoryMax=16G,
# MemorySwapMax=0), et COURSIA_RUNNER_CGROUP_PARENT plus bas, qui y fait entrer
# les conteneurs.
# persist/po-2024/coursia-ci.slice (MemoryHigh=20G, MemoryMax=22G,
# MemorySwapMax=0 -- REMONTE en meme temps que ce budget, arbitrage c2153 : un
# mur 14G/16G sous une composition de 21 504 Mo de caps tuerait au kernel des
# jobs que le budget d'admission laisse partir), et COURSIA_RUNNER_CGROUP_PARENT
# plus bas, qui y fait entrer les conteneurs.
#
# LES TROIS JAMBES DOIVENT ANNONCER LE MEME NOMBRE. `assert_memory_budget`
# somme les conteneurs label `coursia-ci=1` de TOUTES les familles : deux jambes
# qui divergeraient refuseraient leurs slots l'une contre l'autre, et le message
# d'erreur ne nommerait pas la divergence -- il parlerait de memoire en vol.
# Les trois jambes de po-2024 portent 21 : celle-ci, la jambe lean, et la jambe
# waiters (par le drop-in persist/po-2024/coursia-waiters.service.d/10-sizing.conf,
# dont le wrapper appartient a ai-01 et ne declare aucun budget).
# La divergence a existe de fait (mesure du 2026-10-12 : process docker/lean a
# 15 herite d'avant l'edition des wrappers, waiters a 21 redemarre a 04:06 --
# la composition a bouge sous des processus vivants). Les trois jambes de
# po-2024 portent 21 : celle-ci, la jambe lean, et la jambe waiters (par le
# drop-in persist/po-2024/coursia-waiters.service.d/10-sizing.conf, dont le
# wrapper appartient a ai-01 et ne declare aucun budget).
export COURSIA_RUNNER_BUDGET_GB=21

# PARENT CGROUP -- LE MUR KERNEL QUI MANQUAIT A CETTE MACHINE (2026-10-08).
Expand Down
53 changes: 35 additions & 18 deletions scripts/ci/docker/linux-runner/persist/po-2024/coursia-ci.slice
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@
# pas etre tenue : elle se paie en swap. C'est la definition du probleme, et
# aucun garde userspace ne peut le resoudre seul -- il fallait un mur kernel.
#
# L'ARITHMETIQUE RETENUE (budget 15 Go, amendement J+7, meme nombre sur les
# trois jambes)
# L'ARITHMETIQUE RETENUE (budget 21 Go, arbitrage c2153 du 2026-10-12, meme
# nombre sur les trois jambes)
# ---------------------------------------------------------------------
# 4 slots docker x 1536 Mo = 6 144 Mo
# 8 slots docker x 1536 Mo = 12 288 Mo (4 docker + 4 persist, #20174)
# 6 waiters x 512 Mo = 3 072 Mo
# 1 slot lean x 6144 Mo = 6 144 Mo (2 -> 1, verdict J+7 ci-dessous)
# 1 slot lean x 6144 Mo = 6 144 Mo (2 -> 1, verdict J+7)
# ---------------------------------------
# total CAPS 15 360 Mo sous 24 032 Mo -> marge 8 672 Mo
# total CAPS 21 504 Mo sous 24 032 Mo -> marge 2 528 Mo
#
# L'AMENDEMENT J+7 (2026-10-08) : le point de retour prevu par l'arbitrage
# CPU du 2026-10-01 a ete joue -- characterize_runner_variance.py --days 7,
Expand All @@ -64,6 +64,18 @@
# (2 -> 1 slots). La memoire suit le meme mouvement : la composition etait
# 21 504 Mo avec 2 slots lean, elle est 15 360 Mo avec 1.
#
# LE RETOUR DES 4 SLOTS PERSIST (#20174, 2026-10-10) A REMONTE LA COMPOSITION
# sans que le budget suive : la famille docker est revenuee a 8 slots de
# 1536 Mo, soit 21 504 Mo de caps vivants sous un budget userspace reste a
# 15 360 -- assert_memory_budget refusait de DEMARRER tout nouveau slot, et le
# mur kernel 14G/16G du J+7 tuait au kernel des jobs que ce meme budget
# n'admettait meme plus. L'arbitrage c2153 d'ai-01 (2026-10-12, option b)
# remonte les DEUX garde a la composition vive : budget 21 (la regle de
# #19802 : le budget EST la somme des caps) et mur 20G/22G. La marge hors
# caps se resserre de 8 672 a 2 528 Mo -- c'est le prix du retour des slots
# persist, et MemorySwapMax=0 reste ce qui le rend tenable : un job qui
# depasse meurt localement (exit 137) au lieu de swapper la VM et DriveFS.
#
# MARGES PRISES, ET CE QU'ELLES COUVRENT :
# - le cap docker unitaire est INCHANGE a 1536 Mo. Il n'est pas en trop : 3
# conteneurs sur 6 le touchaient a 99 % au moment de la mesure. On reduit
Expand All @@ -78,10 +90,13 @@
# unitaire INCHANGE). Elle reste assumee : c'est le goulot du parc, et le
# volume chaud coursia-runner-work-lean-2 reste en place -- remettre le
# second slot est un `ExecStart ... 2` + restart, pas une reconstruction ;
# - 8 672 Mo restent hors caps pour le noyau WSL2, dockerd et le page cache.
# Mesure du jour du premier depot : le systeme hors conteneurs pesait
# ~3 200 Mo, dont 2 429 Mo de `buff/cache` -- reclaimable, et c'est
# precisement ce que MemoryHigh met sous pression avant le mur.
# - 2 528 Mo restent hors caps pour le noyau WSL2, dockerd et le page cache
# (8 672 avant le retour des slots persist, #20174). La marge etroite est
# tenable parce que le page cache est reclaimable sous pression -- c'est
# precisement ce que MemoryHigh met sous pression avant le mur -- et que
# MemorySwapMax=0 fait mourir le debordant au lieu de swapper. Mesure du
# premier depot : le systeme hors conteneurs pesait ~3 200 Mo, dont
# 2 429 Mo de `buff/cache`.
#
# CPU : CETTE SLICE NE LE TRANCHE PAS, ET LE DIT
# ----------------------------------------------
Expand All @@ -95,8 +110,8 @@
# ----------------------------------------------------------------
# 1. sudo cp persist/po-2024/coursia-ci.slice /etc/systemd/system/
# sudo systemctl daemon-reload && sudo systemctl start coursia-ci.slice
# 2. redeployer les wrappers et les unites (budget 15, start 4, waiters 6,
# lean 1 depuis l'amendement J+7)
# 2. redeployer les wrappers et les unites (budget 21 depuis l'arbitrage
# c2153, start 4 + 4 persist, waiters 6, lean 1 depuis l'amendement J+7)
# 3. sudo systemctl daemon-reload
# 4. redemarrer les trois jambes -- un conteneur DEJA VIVANT ne migre PAS
# dans la slice : seul un cycle de conteneur l'y met. Les slots en vol
Expand Down Expand Up @@ -146,12 +161,14 @@ IOReadBandwidthMax=/var/lib/docker 419430400
# impute au cgroup qui le faute, donc c'est lui, et pas MemoryMax, qui
# declenche la recuperation au lieu de tuer le job dessus.
#
# 14G : sous les 15 360 Mo de caps declares, pour que la pression arrive avant
# 20G : sous les 21 504 Mo de caps declares, pour que la pression arrive avant
# que la somme des caps soit atteinte -- c'est la que le reclaim doit
# travailler.
# 16G : le filet de dernier recours, 1 Go au-dessus du budget userspace et
# 8 Go sous la VM. Franchir les deux gardes a la fois demanderait que le
# garde userspace (qui refuse de DEMARRER un slot au-dela de 15 Go) et
# travailler. (Le 14G du J+7 etait calibre sur 15 360 Mo de caps ; il est
# remonte avec le retour des slots persist, arbitrage c2153 : un mur sous
# la composition tue au kernel des jobs que le budget laisse partir.)
# 22G : le filet de dernier recours, 1 Go au-dessus du budget userspace et
# 2 Go sous la VM. Franchir les deux gardes a la fois demanderait que le
# garde userspace (qui refuse de DEMARRER un slot au-dela de 21 Go) et
# le reclaim du cache echouent tous les deux.
#
# MemorySwapMax=0 -- AUCUN SWAP AUTORISE POUR LA CI.
Expand All @@ -175,6 +192,6 @@ IOReadBandwidthMax=/var/lib/docker 419430400
# lean-axiom.yml) -- meme raisonnement que le commentaire de supervise.sh, dont
# la conclusion est reprise mot pour mot.
MemoryAccounting=yes
MemoryHigh=14G
MemoryMax=16G
MemoryHigh=20G
MemoryMax=22G
MemorySwapMax=0
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,12 @@
# approcher 6, c'est le budget de la machine qu'il faudrait rouvrir -- pas ce
# nombre qu'il faudrait deviner a la hausse sans mesure.
#
# `COURSIA_RUNNER_BUDGET_GB=21` (amendement J+7 du 2026-10-08 ; 15 avant) :
# le wrapper waiters appartient a ai-01 et ne declare pas de budget. Le garde
# `COURSIA_RUNNER_BUDGET_GB=21` (arbitrage c2153 du 2026-10-12 ; 15 depuis
# l'amendement J+7 du 2026-10-08, 21 avant lui) : le J+7 avait cale le budget
# sur 15 360 Mo de caps, puis #20174 (2026-10-10) a reetiquete 4 slots persist
# -- la composition vive est revenuee a 8x1536 + 6x512 + 1x6144 = 21 504 Mo
# sans que le budget suive, et le garde refusait tout demarrage de slot. Le
# wrapper waiters appartient a ai-01 et ne declare pas de budget. Le garde
# de memoire (assert_memory_budget, l.2194) somme les conteneurs en vol de
# TOUTES les familles contre cette valeur : sans elle ici, cette jambe
# retomberait sur le defaut 12 et refuserait des slots sains. Les trois jambes
Expand Down
7 changes: 5 additions & 2 deletions scripts/tests/test_assert_memory_budget.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,15 @@ def test_lookup_slice_machine_override_wins_on_real_po2024():
#19802. Le test precedent affirmait le repli sur la generique en se
fondant sur l'absence de ce fichier : son postulat a disparu avec le
deploiement, il n'etait donc plus un test de l'organe mais un test de
l'etat du depot.
l'etat du depot. La valeur attendue suit l'etat du depot : 16.0 pose
par #19802 (J+7, budget 15), 22.0 depuis l'arbitrage c2153 du
2026-10-12 (budget 21, mur 20G/22G -- le mur suit la composition,
#20174).
"""
path = lookup_slice("po-2024")
assert path == REPO_SLICE.parent / "po-2024" / "coursia-ci.slice"
assert path.is_file()
assert parse_memory_max_gib(path) == 16.0
assert parse_memory_max_gib(path) == 22.0


def test_lookup_slice_falls_back_to_generic_for_unknown_machine():
Expand Down
Loading