0d6486b19b
Moves all A/B closeouts, checklists, idea docs, and implementation plans to plans/archived/2026-05-23/. Both phases are production-stable. Active plans remaining in plans/: - idea-3-powershell-removal.md (Phase C — in progress) - idea-3-esxi-support.md (Phase D — future) - ideas-overview.md (roadmap reference) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
147 lines
8.0 KiB
Markdown
147 lines
8.0 KiB
Markdown
# 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`
|
||
- [x] Job `python` di `lint.yml` PASS su act_runner (commit `8586ff8`)
|
||
- [ ] PoC `wait-ready` PASS contro VM reale Windows
|
||
- [ ] PoC `wait-ready` PASS contro VM reale Linux
|
||
|
||
## 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.
|