Niveau disque · DerivedData / CocoaPods / Gradle · 3 couches d'artefacts · Runbook 6 étapes · Seuils durs
Ops, plateforme mobile et tech leads contractualisant des SLO disque pour pools Mac partagés voient souvent le même type d'alerte le vendredi soir : Runner en ligne, jobs « No space left » ; DerivedData sature le volume système ; caches CocoaPods/Gradle sans propriétaire ; artefacts restent en local après rsync. D'abord qui rencontre quel problème quand la rotation multi-locataire Mac Mesh manque de niveaux disque observables et contrats de récupération par couche. Puis la conclusion : L1 DerivedData / L2 caches de dépendances / L3 artefacts CI avec runbook en 6 étapes — routine auditable au lieu de pompier. Vous obtenez 5 coûts cachés, tableau de stratégies, champs sonde, 6 étapes, 3 seuils durs, FAQ. Voir aussi : verrous de sièges, checklist dérive image dorée, rsync et stockage objet, matrice SLO trois pools et isolation Git worktree.
Dans les tickets Mac Mesh 2026, le disque n'est pas seulement « 100 Go manquants ». Sans contrat unifié entre rotation locataires, localité cache et cycle de vie des artefacts, APFS semble libre alors qu'Xcode échoue à écrire des fichiers temporaires.
DerivedData sans limite : Plusieurs dépôts partagent ~/Library/Developer/Xcode/DerivedData; index et ModuleCache s'entremêlent par branche ; un clean supprime le ModuleCache du voisin — échecs de link aléatoires, pas « disque plein ».
Cache global CocoaPods/Gradle sans TTL : ~/Library/Caches/CocoaPods et ~/.gradle/caches ne font que croître ; anciens tarballs après mise à jour Pods ; worktree multi-branches la parallélisation amplifie la contention.
Artefacts « uploadés mais restés en local » : stockage objet OK mais $CI_ARTIFACTS_DIR sans politique de rétention ; hook de fin rsync non lié — IPA/dSYM mangent le disque.
Snapshots APFS vs « disponible » : Les snapshots locaux trompent df ; la capacité d'écriture réelle casse aux pics de compilation. Il manque waterline_used_pct par volume/couche.
Nettoyage vs verrou de siège : balayage de répertoire avant fin de bail ou conflit avec TTL verrou de siège, — « disque vide, build rouge ».
Livrables : dictionnaire répertoires 3 couches, double niveau warn/hard, LRU fin de bail, contrôle hebdomadaire dérive image dorée séparé. Sans cela, ne promettez pas « tout monorepo en parallèle » sur pool partagé. Section suivante : trois philosophies de nettoyage — pas de « vendredi ssh rm -rf pour tous ».
La gouvernance disque n'est pas « nettoyer plus fort ». Équilibrez taux de hit build, nettoyage auditable, isolation locataires. Épinglez ce tableau en revue de changement : une stratégie par défaut par couche (L1/L2/L3).
| Stratégie | L1 DerivedData | L2 Pods/Gradle | L3 Artifacts | Adapté à | Risque principal |
|---|---|---|---|---|---|
| Cron manuel | rm global le week-end | pod cache prune occasionnel | find par âge | Petites équipes, faible parallélisme | Suppressions voisin, pas d'audit |
| Daemon de niveau | LRU par hash workspace | Evict à la capacité | 48h après rsync réussi | Défaut pool partagé | Métriques et contrat de verrou requis |
| Reset image | rollback snapshot vide | Rafraîchi avec l'image | Remplacement volume | Dérive hors contrôle, snapshots conformité | Ralentissement compile cold-start |
Règle : les pools partagés doivent par défaut utiliser le « daemon de niveau » ; reset image seulement en secours trimestriel avec la checklist dérive image dorée, pas le LRU quotidien.
Quand pools Dedicated et rotation Shared coexistent, les clés cache L1 doivent porter un tag type de pool, sinon le sweep partagé évince la localité dédiée.
L1: /var/mesh/cache/deriveddata/{workspace_hash}, lié via Xcode DERIVED_DATA_DIR. L2: /var/mesh/cache/cocoapods, /var/mesh/cache/gradle—pas d'écriture vers caches globaux du home utilisateur. L3: /var/mesh/artifacts/{job_id}—après upload, ne garder que sidecar de checksum. Le monitoring rapporte layer_*_bytes par couche au lieu d'un vague « partition / 85 % ».
Ces 6 étapes supposent runners sur labels Mac Mesh et sièges acquis avant job, relâchés après. Ne sautez pas l'ordre : niveaux sans métriques = suppressions aveugles.
Geler le dictionnaire et chemins trois couches : écrire racines L1/L2/L3 et seuils warn (82 %)/hard (92 %) dans le repo mesh-disk-policy.yaml, enregistrer points de montage par défaut dans la checklist image.
déployer la sonde disk-waterline : toutes les 60 s : usage volume et octets par couche ; export Prometheus/OpenTelemetry ; au seuil hard runners en drain et fail-fast des nouveaux jobs.
Isoler DerivedData : la CI définit DERIVED_DATA_DIR vers le compartiment hash workspace ; fin de bail déclenche LRU sur ce compartiment — ne jamais balayer DerivedData global.
Evict cache dépendances L2 : pod cache clean piloté par capacité ; GRADLE_USER_HOME sous mesh ; limiter max-cache-size.
Artefacts et hooks rsync : callback multipart-complete du stockage objet supprime L3 local ; retries échoués 7 jours — champs alignés sur le runbook artefacts.
Contrôle hebdomadaire et exercice : comparer checksums image dorée, simuler rejet job à 90 %, journal d'audit nettoyage ; lors de débordement Burst vider L3 d'abord, puis accepter jobs interruptibles.
hostname pool_type volume_mount waterline_used_pct waterline_warn_threshold waterline_hard_threshold layer_l1_deriveddata_bytes layer_l2_cocoapods_bytes layer_l2_gradle_bytes layer_l3_artifacts_bytes seat_lease_id last_cleanup_ts_unix cleanup_evicted_bytes_1h disk_waterline_hard_stop
Note : La sortie sonde doit être la première ligne Grafana, pas seulement alertes OS. Tracer cleanup_evicted_bytes_1h avec builds réussis pour distinguer vrai nettoyage de « moins de builds donc disque semble mieux ».
Les alertes disque chevauchent souvent SLO file d'attente symptômes. Utilisez le tableau pour voir si le problème est capacité, clés cache ou accumulation d'artefacts avant le périmètre de nettoyage.
| Symptôme | layer_* dominant | Cause probable | Action prioritaire |
|---|---|---|---|
| Seule l'étape Xcode échoue | L1 high | DerivedData contaminé ou index corrompu | Vider compartiment par hash workspace |
| Pool mixte Android/iOS lent | L2 high | Pods/Gradle jamais évictés | resserrer plafond capacité L2 |
| Upload OK, disque plein | L3 high | hook rsync non lié | ajouter callback stockage objet |
| df OK, écriture échoue | Snapshots | APFS local Snapshots | réduire rétention snapshots + sonde |
Attention : Pas de rm -rf au niveau volume en tenant un verrou de siège. Les scripts de nettoyage doivent voir seat_lease_id vide ou bail expiré, sinon ils suppriment un ModuleCache en cours de compilation.
Si L1 se remplit en 24 h après vidage compartiment, vérifier isolation worktree — plusieurs arbres DerivedData complets sur un nœud, avant d'acheter plus de disque.
Compromis terrain de pools partagés 16/24 Go. Joignez aux tickets de changement en annexe SLO externe ; Dedicated peut baisser warn de 5 points pour cache chaud d'index plus stable.
waterline_warn_threshold=82 déclenche éviction L3→L2→L1 ; waterline_hard_threshold=92 refuse nouveaux jobs et pose disk_waterline_hard_stop=1.Sur volumes système 512 Go avec ~60 % pour mesh : plafonner L2 à 80 Go (40 Go soft cap CocoaPods/Gradle chacun), L3 par job 12 Go (dSYM inclus). « Cron week-end seulement » ou « tout le monde supprime le cache en SSH » sans champs d'audit ni contrats de siège — suppressions voisin, cold starts, artefacts à moitié écrits en semaine de release. Pour les équipes qui placent CI iOS/Android et SLO disque sur une capacité Mac Mini cloud contractuelle, la location cloud Mac Mini VpsMesh est en général le meilleur choix. Voir page tarifs, centre d'aide et page commande.
Par défaut : compartiments par hash workspace liés au bail de siège ; fin de bail = LRU. Branches parallèles : isolation worktree article; ne pas laisser le global ~/Library/Developer/Xcode/DerivedData croître sans limite.
Le runner fail-fast et signale disk_waterline_hard_stop ; le planificateur route vers un nœud avec marge ou déclenche Burst. Sémantique des sièges dans l' article verrous de sièges concurrents.
Oui. Le nettoyage disque ne récupère que les déchets runtime ; il ne remplace pas la checklist de dérive snapshot. Intégration : centre d'aide ; offres sur la page tarifs.