feat: add closeout checklist for Phase A1 implementation
This commit is contained in:
@@ -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 "<utente-runner>: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 "<utente-runner>:(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.
|
||||
Reference in New Issue
Block a user