From 44a99af14f08440082253cbbdbc97a261c00f9be Mon Sep 17 00:00:00 2001 From: Simone Date: Wed, 13 May 2026 16:40:07 +0200 Subject: [PATCH] feat: add closeout checklist for Phase A1 implementation --- plans/A1-closeout.md | 146 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 plans/A1-closeout.md diff --git a/plans/A1-closeout.md b/plans/A1-closeout.md new file mode 100644 index 0000000..4161f80 --- /dev/null +++ b/plans/A1-closeout.md @@ -0,0 +1,146 @@ +# Fase A1 — Closeout operativo + +Checklist per chiudere lo step **A1** di [implementation-plan-A-B](implementation-plan-A-B.md) +prima di iniziare A2. Il codice è già committato sul branch +`feature/python-rewrite-phase-a` (commit `9fbe952`); manca solo la +validazione contro l'ambiente reale. + +## Stato attuale + +- [x] Codice + 35 unit test (coverage 82.65%) committati +- [x] `ruff` clean, `mypy --strict` clean su 12 file sorgente +- [x] Job `python` aggiunto a `gitea/workflows/lint.yml` +- [ ] PoC `wait-ready` PASS contro VM reale Windows +- [ ] PoC `wait-ready` PASS contro VM reale Linux +- [ ] Job `python` di `lint.yml` PASS su act_runner + +## Perché completare A1 prima di A2 + +A2 riusa `WorkstationVmrunBackend`, `WinRmTransport`, `SshTransport` e +`KeyringCredentialStore` esattamente come sono ora. Se uno di questi ha +un bug di integrazione (TLS, encoding, parsing output `vmrun list`, +permessi venv, ecc.), trovarlo dopo A2 costa: **1 fix nei moduli core + +retest di tutti i 6 comandi portati in A2**. Trovarlo ora costa: 1 fix. + +## 1. PoC `wait-ready` su VM Windows reale + +**Obiettivo**: validare il path `vmrun.is_running` → `get_ip` → WinRM +HTTPS con cert self-signed end-to-end. + +```powershell +# 1. Setup venv (una tantum) sull'host CI +python -m venv F:\CI\python\venv +F:\CI\python\venv\Scripts\python.exe -m pip install --upgrade pip +F:\CI\python\venv\Scripts\python.exe -m pip install -e ".[dev]" + +# 2. Clone manuale di una VM smoke da template +$vmrun = 'C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe' +$tpl = 'F:\CI\Templates\WinBuild2025\WinBuild2025.vmx' +$dst = 'F:\CI\BuildVMs\smoke-a1\smoke-a1.vmx' +& $vmrun -T ws clone $tpl $dst linked -snapshot=BaseClean -cloneName=smoke-a1 +if ($LASTEXITCODE -ne 0) { throw "clone fallito" } +& $vmrun -T ws start $dst nogui +if ($LASTEXITCODE -ne 0) { throw "start fallito" } + +# 3. PoC wait-ready +$env:PYTHONIOENCODING = 'utf-8' +F:\CI\python\venv\Scripts\python.exe -m ci_orchestrator wait-ready ` + --vmx $dst --guest-os windows --timeout 300 + +# 4. Cleanup +& $vmrun -T ws stop $dst hard +& $vmrun -T ws deleteVM $dst +``` + +**Atteso**: + +- Exit code `0` +- Ultima riga stdout: `[wait-ready] WinRM ready.` +- Tempo totale tra start VM e WinRM ready: 60–180 s + +**Failure mode più probabili e fix**: + +| Sintomo | Causa probabile | Fix | +| -------------------------------------------------- | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------- | +| `is_running` resta `False` per sempre | Path mismatch in `vmrun list` (slash diversi, casing) | Aggiungere normalizzazione `os.path.normcase` in `WorkstationVmrunBackend.is_running` | +| `get_ip` ritorna sempre `None` | VMware Tools non ancora pronti | Atteso nei primi 30–60 s; se persiste >180 s, problema nel template | +| `WinRM probe failed: ... certificate verify` | `cert_validation=False` non basta su TLS handshake | Ispezionare cipher; eventualmente pinnare versione `pypsrp` o passare `auth='ntlm'` esplicito | +| `KeyError: 'BuildVMGuest'` | Credenziale non leggibile dall'utente che lancia il PoC | Eseguire come l'utente del runner (`runas /user:ci-runner ...`) o re-store credential nel suo profilo | +| `KeyringCredentialStore` ritorna username vuoto | Backend keyring usa `get_password`-only | Verificato in `test_credentials.py::test_get_falls_back_to_password`; in tal caso impostare username separatamente nel target | + +## 2. PoC `wait-ready` su VM Linux reale + +```powershell +$tpl = 'F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx' +$dst = 'F:\CI\BuildVMs\smoke-a1-lnx\smoke-a1-lnx.vmx' +& $vmrun -T ws clone $tpl $dst linked -snapshot=BaseClean-Linux -cloneName=smoke-a1-lnx +& $vmrun -T ws start $dst nogui + +$env:CI_SSH_KEY_PATH = 'F:\CI\keys\ci_linux' +F:\CI\python\venv\Scripts\python.exe -m ci_orchestrator wait-ready ` + --vmx $dst --guest-os linux --ssh-user ci_build --timeout 300 + +& $vmrun -T ws stop $dst hard +& $vmrun -T ws deleteVM $dst +``` + +**Atteso**: ultima riga `[wait-ready] SSH ready.` entro 60–120 s. + +**Failure mode più probabili**: + +| Sintomo | Causa | Fix | +| ------------------------------------ | ---------------------------------------------------- | ---------------------------------------------------------------------------------- | +| `SSH connection ... timed out` | DHCP collision (vedi `AGENTS.md` errore #11) | Verificare snapshot `BaseClean-Linux` con machine-id resettato | +| `paramiko.AuthenticationException` | Permessi chiave SSH errati (Windows ACL su `ci_linux`) | `icacls F:\CI\keys\ci_linux /inheritance:r /grant:r ":R"` | +| `is_ready()` False ma SSH manuale OK | `BatchMode=yes` lato `ssh.exe` non equivalente in paramiko | Già coperto: paramiko non chiede prompt; verificare `look_for_keys=False` settato | + +## 3. Job `python` di `lint.yml` su act_runner + +```powershell +# Push del branch +git push -u origin feature/python-rewrite-phase-a +``` + +Poi su Gitea: aprire una PR contro `main` (o trigger manuale del +workflow). Verificare che il job `python` completi entro +`timeout-minutes: 15`. + +**Failure mode più probabili**: + +| Sintomo | Causa | Fix | +| ------------------------------------------------------ | -------------------------------------------------------- | ------------------------------------------------------------------------------ | +| `python: command not found` | `python` non in PATH dell'utente del runner | Installare Python 3.11+ machine-wide o aggiornare `PATH` del servizio | +| `pip install -e .[dev]` >15 min al primo run | Cache assente, network lento | Bumpare `timeout-minutes: 30` solo per il primo run; cache stabile dopo | +| `Access denied` su `F:\CI\python\venv` | Utente del runner senza scrittura su `F:\CI\python` | `icacls F:\CI\python /grant ":(OI)(CI)F"` | +| Coverage <70% | Differenza Python 3.14 (locale) vs 3.11 (CI) | Rilanciare con `--cov-report=term-missing` per identificare branch mancante | + +## 4. Definizione di "A1 done" + +Spuntabile solo quando **tutti** e tre i punti sopra sono PASS: + +- [ ] PoC Windows: `wait-ready` exit 0 contro `WinBuild2025` reale +- [ ] PoC Linux: `wait-ready` exit 0 contro `LinuxBuild2404` reale +- [ ] CI: workflow `lint.yml` job `python` PASS su act_runner + +A quel punto: + +1. Aggiornare la checklist master in [implementation-plan-A-B](implementation-plan-A-B.md) + spuntando le righe `[A1]`. +2. Mergeare `feature/python-rewrite-phase-a` su `main` (o lasciare il + branch live se A2 verrà committato sopra). +3. Procedere con A2 (script "foglia": `Wait-VMReady`, `Remove-BuildVM`, + `Cleanup-OrphanedBuildVMs`, `Watch-DiskSpace`, `Watch-RunnerHealth`, + `Get-CIJobSummary`). + +## 5. Workaround se A1 non si può chiudere ora + +Se l'hardware/VM template non sono accessibili in questo momento: + +- **Non rimuovere** alcuno script PS in A2. +- Marcare A1 come "code-complete, validation pending" in + [implementation-plan-A-B](implementation-plan-A-B.md). +- Procedere con A2 ma trattare ogni bug scoperto su `WorkstationVmrunBackend` + / `WinRmTransport` / `SshTransport` come **fix di A1** (commit separato, + no nuove feature A2 nello stesso commit). +- Riservare una sessione dedicata di smoke testing prima di A3 (pipeline + di build), perché A3 introduce `clone_linked` + `start` reali.