Files
local-ci-cd-system/plans/A1-closeout.md
T

147 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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: 60180 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 3060 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 60120 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.