docs: record the LinuxRust2404 template, its failure modes and open decisions
- AGENTS.md: LinuxRust2404 reference, plus errors #14-#16 -- deploy --force against a powered-on VM, the three distinct causes behind the identical "VMware Tools are not running" message, and the orphan snapshot deltas --force leaves behind after deleting the .vmsd. - docs/RUNBOOK.md §16: triage for a Step 7 IP timeout, ordered cheapest check first, with a Quick Reference entry. - docs/RUNBOOK-PhaseC.md: deploy-rust/prepare-rust, the ownership and non-login shell constraints on /opt/rust, --then-prepare, and how to route a label to a template (a second runner instance, with the verification step). - TODO.md §2.9: retention run covers only artifacts, logs and IP leases, so it warned about low disk while freeing 0.0 GB two runs in a row. Mitigated by hand; the automated policy is still blind to what actually weighs. - TODO.md §6.5: act_runner v1.0.4 -> v2.x evaluated and deferred, with the trigger for reopening. v2.1.0 exposes no RUNNER_LABELS either (checked against the binary), so the two-runner design is not a stopgap.
This commit is contained in:
@@ -174,6 +174,47 @@ Variante **WinBuild2022**: path `F:\CI\Templates\WinBuild2022\WinBuild2022.vmx`,
|
||||
| Toolchain | GCC, G++, Clang, CMake, Ninja, Python 3, Git, 7-Zip |
|
||||
| CI dirs | `/opt/ci/{build,output,scripts,cache}` — owner `ci_build` |
|
||||
|
||||
### Linux Rust (LinuxRust2404)
|
||||
|
||||
Variante di `LinuxBuild2404` per workspace Rust (es. app Tauri): stessa cloud
|
||||
image e stesso layout guest, provisioning via
|
||||
`template/Install-CIToolchain-LinuxRust2404.sh` che aggiunge le librerie
|
||||
webview/GTK di Tauri v2 e una toolchain Rust system-wide sotto `/opt/rust`
|
||||
(rustup + rustfmt + clippy + binario `cargo-audit`; il DB advisory di
|
||||
cargo-audit NON e' bakato, viene fetchato a runtime).
|
||||
|
||||
| Parametro | Valore |
|
||||
| -------------- | ------------------------------------------------------------- |
|
||||
| OS | Ubuntu 24.04 LTS (cloud image) |
|
||||
| VMX | `LinuxRust2404/LinuxRust2404.vmx` (sotto la dir templates) |
|
||||
| Snapshot clone | `BaseClean-LinuxRust` |
|
||||
| Transport | SSH porta 22, utente `ci_build`, stessa chiave di LinuxBuild2404 |
|
||||
| Toolchain | quella di LinuxBuild2404 + webview/GTK Tauri + Rust in `/opt/rust` |
|
||||
| Comandi | `ci template deploy-rust` / `ci template prepare-rust` |
|
||||
|
||||
`--rust-channel` (default `stable`) controlla la toolchain bakata: pinnare una
|
||||
versione esatta (es. `1.97.1`) per uno snapshot deterministico; con `stable`
|
||||
rustup riscarica a runtime ad ogni nuova stable. Rigenerare lo snapshot quando
|
||||
cambia il pin o la baseline apt di sicurezza.
|
||||
|
||||
Due vincoli sull'albero `/opt/rust`, entrambi regressioni gia' occorse:
|
||||
|
||||
1. **`chown` DOPO l'installazione.** Lo script gira come root, quindi tutto
|
||||
cio' che rustup/cargo creano nasce root-owned: un `chown` fatto solo prima
|
||||
copre le due directory vuote e nient'altro. Senza il `chown` finale
|
||||
`ci_build` non puo' scrivere ne' in `RUSTUP_HOME` ne' in
|
||||
`CARGO_HOME/registry`, e **ogni** build Rust con dipendenze esterne muore
|
||||
con `Permission denied (os error 13)`. Gli assert devono verificare la
|
||||
**scrivibilita'** (`sudo -u ci_build test -w`), non solo `test -x` sui
|
||||
binari: altrimenti il template rotto passa la sua build e fallisce nei job
|
||||
dei consumatori.
|
||||
2. **`/etc/profile.d` da solo non basta.** L'orchestratore esegue i comandi
|
||||
con paramiko `exec_command` + `sh -c` (`transport/ssh.py`,
|
||||
`commands/build.py`): shell **non di login**, `profile.d` non viene mai
|
||||
sorgiato. `RUSTUP_HOME`/`CARGO_HOME` vanno anche in `/etc/environment`
|
||||
(letto da `pam_env` all'apertura della sessione SSH) e i proxy rustup
|
||||
symlinkati in `/usr/local/bin`.
|
||||
|
||||
---
|
||||
|
||||
## Transport layer
|
||||
@@ -236,3 +277,9 @@ Configurazione in `PSScriptAnalyzerSettings.psd1`. Regole principali:
|
||||
11. **Machine-id identico tra clone Linux** — le cloud image Ubuntu hanno un `/etc/machine-id` fisso. VMware DHCP assegna l'IP tramite DHCP client-id derivato da machine-id: se tutti i clone hanno lo stesso machine-id ottengono lo stesso IP e si bloccano per "IP collision". Fix nel template (prima di prendere lo snapshot): `sudo truncate -s 0 /etc/machine-id && sudo rm -f /var/lib/dbus/machine-id && sudo shutdown -h now`, poi ricreare lo snapshot `BaseClean-Linux` da stato powered-off.
|
||||
12. **`& nativecmd 2>$null` NON sopprime stderr in PS 5.1 con `$ErrorActionPreference='Stop'`** — la stderr del processo nativo viene convertita in ErrorRecord nel pipeline di PowerShell; sotto `'Stop'` questo diventa un errore terminante PRIMA che `2>$null` possa scartarlo. Esempio: `ssh-keygen -R <ip> -f <file>` stampa "Host X not found in file" su stderr → eccezione terminante. Fix: usare `$ErrorActionPreference = 'SilentlyContinue'` attorno alla chiamata oppure `2>&1 | Out-Null`. Per i job CI su VM ephemere locali, usare direttamente `StrictHostKeyChecking=no UserKnownHostsFile=NUL` (default in `_Transport.psm1` con `KnownHostsFile=''`) — nessun `ssh-keygen` necessario.
|
||||
13. **Quote WinRM/desktop-heap troppo basse per builds Windows paralleli** — sintomo: `MSBuild error MSB6003: CL.exe could not be run. System.ComponentModel.Win32Exception (0x80004005): Not enough quota is available to process this command` (oppure le altre tool MSVC: link.exe, mt.exe) quando il build interno fa fan-out parallelo (es. matrix x86/x64/x86-ansi, MSBuild `/maxcpucount`). Causa: il plugin endpoint Microsoft.PowerShell del guest ha `MaxMemoryPerShellMB=150` di default e l'heap del desktop non-interattivo (Session 0) ha `SharedSection 3rd field=768 KB` — entrambi insufficienti per più CL.exe concorrenti via WinRM. **Non emerge** in pre-migration Win→Win perché `Invoke-Command` su `PSSession` localhost-style eredita quote più larghe; emerge appena il path passa per `pypsrp` Linux→Win. Fix nel template (Deploy-WinBuild2025.ps1 / 2022 lo fa, Install-CIToolchain lo valida): `Set-Item WSMan:\localhost\Plugin\Microsoft.PowerShell\Quotas\MaxMemoryPerShellMB 2048`, `Set-Item WSMan:\localhost\Shell\MaxProcessesPerShell 100`, registry `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems\Windows` patch del 3° campo `SharedSection` a 4096, **reboot** (csrss legge SharedSection solo al boot), nuovo `BaseClean`. Dettagli e procedura completa in `docs/WINDOWS-TEMPLATE-SETUP.md § "WinRM quotas e desktop heap"`.
|
||||
|
||||
14. **`deploy-* --force` lanciato mentre la VM target è ACCESA** — corrompe la VM in esecuzione e produce un timeout allo Step 7 che *sembra* un problema di rete. Occorso il 2026-07-22 su `LinuxRust2404`, con un `prepare-rust` ancora in corso sulla stessa VMX. Meccanica: (a) Step 1 vede `<disk>.vmdk.lck` e lo cancella come "stale artifact" — **non era stale**, apparteneva al processo vivo; (b) Step 4 riscrive il VMDK base sotto il guest in esecuzione, che muore; (c) Step 6 lancia il power-on, il nuovo `vmware-vmx` muore subito perché la VMX è già occupata, ma il controllo `[OK] VM appears in vmrun list` **passa lo stesso** perché vede l'istanza vecchia; (d) Step 7 interroga per 10 minuti un guest morto e riporta `Error: The VMware Tools are not running in the virtual machine`. Diagnosi in 5 secondi: `ps -eo pid,lstart,etime,args | grep vmware-vmx` — se il `vmware-vmx` vivo è più vecchio del deploy appena lanciato, è questo il caso. Recupero: `vmrun stop <vmx> hard`, rimuovere i delta orfani `<disk>-00000*.vmdk`, verificare `vmrun list` = 0, poi rilanciare. **Non** interpretarlo come DHCP incastrato (vedi #15) e non risolverlo con un retry automatico: riavviare una VM già corrotta ripete il fallimento con la causa ormai illeggibile.
|
||||
|
||||
15. **Step 7 in timeout: distinguere tre cause diverse che danno lo stesso messaggio** — `getGuestIPAddress` risponde `The VMware Tools are not running` sia quando il guest non ha IP, sia quando ha l'IP ma i Tools non rispondono. Ordine di verifica, dal più veloce: (a) **collisione** — `ps | grep vmware-vmx`, processo più vecchio del deploy corrente → vedi #14; (b) **DHCP host incastrato** — `ip -4 addr show vmnet8` deve dare `192.168.79.1/24` e `ps -ef | grep vmnet-dhcpd` deve mostrarlo vivo; se no, `sudo systemctl restart vmware-networks` (o `vmware-host.service`); (c) **guest senza lease o Tools non pronti** — cercare il MAC della VMX in `/etc/vmware/vmnet8/dhcpd/dhcpd.leases` e in `ip neigh show dev vmnet8`: se un lease c'è, il guest è vivo e mancano solo i Tools, quindi sondare TCP/22 direttamente invece di aspettare `getGuestIPAddress`.
|
||||
|
||||
16. **Delta di snapshot orfani dopo `--force`** — `deploy-*` cancella `<vm>.vmsd` (il database snapshot) per evitare l'errore di resize sulla catena, ma **non** cancella i file delta `<disk>-00000N.vmdk`. Restano su disco con un `parentCID` che non corrisponde più al base ricreato: innocui (fuori dal percorso di boot, la VMX punta al base con `parentCID=ffffffff`) ma confondono la diagnosi e vanno rimossi a mano. Verifica della catena: `head -c 2000 <disk>.vmdk | strings | grep -E '^CID|parentCID'`.
|
||||
|
||||
Reference in New Issue
Block a user