5bff7b4f0c
Concurrent capacity burn-in run on the Linux host as ci-runner with the static-IP pool: WinBuild2025 40/40 PASS (~78.6s/round) and LinuxBuild2404 40/40 PASS (~70.2s/round) — 80/80 jobs, 20/20 rounds, near-deterministic (static IP eliminates the DHCP IP-acquire variance of the §6/§7 baselines). - RUNBOOK §9: concurrent burn-in result + ip-pool reset/recovery note. - PhaseB-user-checklist Passo 7/8 marked done; fixed two checklist bugs: run as ci-runner (the simone path needs g+w on the /var/lib/ci root for ip-pool.tmp, not just the sub-dirs), and the Linux command was missing -SnapshotName BaseClean-Linux (default BaseClean is Windows-only). - idea-2-linux-host §8 DoD: Phase B complete (B1–B7 + >2 weeks stability). - TODO §2.8 [P2]: ip-pool is not reconciled against live clones; a killed job leaks its lease permanently and exhausts the 4-IP pool. Proposed fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
225 lines
12 KiB
Markdown
225 lines
12 KiB
Markdown
# Fase B — Migrazione host su Linux Mint
|
||
|
||
> **Stato**: piano esecutivo (parte committed della roadmap).
|
||
> Prerequisito: [Fase A](idea-1-python-rewrite.md) completata.
|
||
> Vedi [overview](ideas-overview.md).
|
||
> Hypervisor scelto: **VMware Workstation Pro Linux** (zero conversione template).
|
||
|
||
---
|
||
|
||
## 1. Obiettivo
|
||
|
||
Spostare l'host CI/CD da Windows 11 + Workstation Pro a **Linux Mint** +
|
||
**Workstation Pro Linux**, mantenendo:
|
||
|
||
- act_runner / Gitea (binario Linux ufficiale)
|
||
- workflow YAML invariati (path generalizzati via env vars introdotte in Fase A)
|
||
- template VM Windows e Linux **identici** (stessi `.vmx`, `.vmdk`, snapshot)
|
||
- artifact layout (cambia solo la radice: `F:\CI\` → `/var/lib/ci/`)
|
||
- transport WinRM/SSH ai guest (pypsrp + paramiko già cross-platform da Fase A)
|
||
|
||
Cambia: OS host, service manager, credential store, percorsi, ownership filesystem.
|
||
|
||
---
|
||
|
||
## 2. Decisione hypervisor: perché Workstation Pro Linux
|
||
|
||
Confronto sintetico (decisione presa, non più aperta):
|
||
|
||
| Opzione | Verdetto |
|
||
| ---------------------------------- | -------------------------------------------------------------------- |
|
||
| **VMware Workstation Pro Linux** | **SCELTA.** `vmrun` identico, VMX template riutilizzabili 1:1, free per uso personale e commerciale dal 2024. Plumbing-only port. |
|
||
| KVM + libvirt | Rimandato. Richiederebbe conversione VMDK→qcow2, virtio injection nei guest Windows, rewrite backend hypervisor. Resta come piano B se Broadcom dismette Workstation. |
|
||
| VirtualBox | Scartato. Performance/snapshot inferiori. |
|
||
|
||
---
|
||
|
||
## 3. Mappa di adattamento
|
||
|
||
| Componente attuale | Equivalente Linux + Workstation Pro |
|
||
| --------------------------------------------------- | ------------------------------------------------------------ |
|
||
| `vmrun.exe` (`C:\Program Files (x86)\...`) | `/usr/bin/vmrun` (binario senza `.exe`, installato dal package Workstation) |
|
||
| File `.vmx` / `.vmdk` | **identici, copiati così come sono** |
|
||
| Snapshot `BaseClean` / `BaseClean-Linux` | preservati nella copia |
|
||
| `F:\CI\BuildVMs\` | `/var/lib/ci/build-vms/` |
|
||
| `F:\CI\Artifacts\` | `/var/lib/ci/artifacts/` |
|
||
| `F:\CI\Templates\` | `/var/lib/ci/templates/` |
|
||
| `F:\CI\keys\ci_linux` | `/etc/ci/keys/ci_linux` (perms `600`, owner `ci-runner`) |
|
||
| Credential Manager (`BuildVMGuest`, `GiteaPAT`) | `secret-tool` / GNOME Keyring / KWallet (backend `keyring`) |
|
||
| WinRM HTTPS verso guest Windows | identico (pypsrp parla con WinRM da Linux senza modifiche) |
|
||
| SSH verso guest Linux | identico (paramiko) |
|
||
| act_runner come Windows Service | systemd unit `act-runner.service` |
|
||
| Task Scheduler (`Register-CIScheduledTasks.ps1`) | systemd `*.timer` + `*.service` units |
|
||
| PowerShell 5.1 | `pwsh` 7 (solo per ricostruire template, raro) |
|
||
| `vmnet8` NAT (`192.168.79.0/24`) | `vmnet8` NAT su Workstation Pro Linux (stesso concetto, IP range configurabile) |
|
||
|
||
---
|
||
|
||
## 4. Strategia di migrazione
|
||
|
||
### Step B1 — Setup host Linux Mint in parallelo (no impatto produzione)
|
||
|
||
- Installazione Linux Mint LTS + aggiornamenti
|
||
- Installazione VMware Workstation Pro per Linux (bundle ufficiale Broadcom)
|
||
- Verifica `vmrun` con una VM di test (clone, start, stop)
|
||
- Configurazione `vmnet8` NAT range coerente o equivalente
|
||
- Creazione utente di servizio `ci-runner` (uid dedicato)
|
||
- Creazione storage layout `/var/lib/ci/{build-vms,artifacts,templates,keys}`
|
||
con ownership `ci-runner:ci-runner` (mode 750)
|
||
- Installazione Python 3.11+ + venv in `/opt/ci/venv/` con `pip install -e .`
|
||
del package `ci_orchestrator` portato in Fase A
|
||
|
||
Validazione: `python -m ci_orchestrator --help` funziona da utente `ci-runner`.
|
||
|
||
### Step B2 — Trasferimento template VM
|
||
|
||
- Spegnere i template Workstation sull'host Windows (devono essere
|
||
fully powered-off — vedi `AGENTS.md` errore #9)
|
||
- Copia bit-by-bit di `F:\CI\Templates\` → `/var/lib/ci/templates/`
|
||
(`scp -r` o `rsync`)
|
||
- Aprire i `.vmx` su Workstation Linux per registrarli (`vmrun start ... nogui`
|
||
con stop immediato, oppure `vmrun -T ws snapshot list`) — risolverà
|
||
eventuali path interni se Workstation li chiede
|
||
- Verifica snapshot presenti: `vmrun listSnapshots <vmx>` deve mostrare
|
||
`BaseClean` / `BaseClean-Linux`
|
||
- Smoke test manuale: clone linked + start + WinRM/SSH dal host Linux
|
||
|
||
### Step B3 — Trasferimento credenziali e chiavi
|
||
|
||
- Copia chiave SSH guest Linux: `F:\CI\keys\ci_linux*` → `/etc/ci/keys/`
|
||
(mode 600, owner `ci-runner`)
|
||
- Re-store delle credenziali guest Windows nel keyring Linux:
|
||
`secret-tool store --label='BuildVMGuest' service ci target BuildVMGuest`
|
||
- Re-store Gitea PAT: `secret-tool store --label='GiteaPAT' service ci target GiteaPAT`
|
||
- Verifica via Python: `keyring.get_credential('BuildVMGuest', None)` non None
|
||
|
||
### Step B4 — Setup act_runner come systemd service
|
||
|
||
- Download act_runner Linux binary (versione allineata a v1.0.2 o successiva)
|
||
- Registrazione runner verso Gitea con label `windows-build:host` e
|
||
`linux-build:host` (stesse label di oggi → workflow non cambiano)
|
||
- File unit `/etc/systemd/system/act-runner.service`:
|
||
- `User=ci-runner`
|
||
- `WorkingDirectory=/var/lib/ci/runner`
|
||
- `Environment=PYTHONIOENCODING=utf-8`
|
||
- env vars `CI_*` per il config Python
|
||
- `systemctl enable --now act-runner.service`
|
||
- Validazione: `journalctl -u act-runner -f` mostra connessione a Gitea OK
|
||
|
||
### Step B5 — Conversione scheduled tasks → systemd timers
|
||
|
||
`Register-CIScheduledTasks.ps1` definisce N task periodici. Per ognuno
|
||
creare:
|
||
- `/etc/systemd/system/ci-<task>.service` (oneshot, chiama
|
||
`python -m ci_orchestrator <cmd>`)
|
||
- `/etc/systemd/system/ci-<task>.timer` (`OnCalendar=...` equivalente)
|
||
- `systemctl enable --now ci-<task>.timer`
|
||
|
||
Task tipici da convertire:
|
||
- `cleanup-orphaned-vms` (ogni ora)
|
||
- `retention-policy` (giornaliero)
|
||
- `watch-disk-space` (ogni 15 min)
|
||
- `watch-runner-health` (ogni 5 min)
|
||
- `backup-template` (settimanale)
|
||
|
||
### Step B6 — Cutover
|
||
|
||
Finestra di manutenzione concordata:
|
||
|
||
1. Stop act_runner sull'host Windows (`Stop-Service actions-runner`)
|
||
2. Rsync incrementale finale degli artifact recenti:
|
||
`F:\CI\Artifacts\` → `/var/lib/ci/artifacts/`
|
||
3. Verificare nessun job in coda lato Gitea
|
||
4. Avviare act_runner Linux (`systemctl start act-runner`)
|
||
5. Trigger manuale di un workflow di smoke test
|
||
6. Trigger del workflow matrix `build-ns7zip.yml` (Win + Linux build)
|
||
|
||
Se PASS → cutover confermato. Se FAIL → rollback (riavvio runner Windows,
|
||
nessun dato è stato distrutto).
|
||
|
||
### Step B7 — Capacity burn-in sul nuovo host
|
||
|
||
Eseguire `Test-CapacityBurnIn` (versione Python) con N=4 concorrenti × R=10
|
||
round, sia per template Windows che Linux. Confronto tempi vs baseline
|
||
Windows host pre-migrazione (aspettativa: paragonabili, eventuali differenze
|
||
vanno indagate ma non sono blocker se entro ±20%).
|
||
|
||
### Step B8 — Decommissioning host Windows (opzionale)
|
||
|
||
Dopo 1-2 settimane di stabilità sul nuovo host:
|
||
- Backup finale di `F:\CI\` su archivio
|
||
- Spegnimento runner Windows (lasciato installato per un mese come
|
||
rollback option)
|
||
- Riallocazione hardware
|
||
|
||
---
|
||
|
||
## 5. Adattamenti al codice Python (residui dopo Fase A)
|
||
|
||
Se Fase A ha rispettato le regole di §2 di [idea-1-python-rewrite.md](idea-1-python-rewrite.md),
|
||
il codice **non cambia**. Modifiche residue attese:
|
||
|
||
- `config.example.toml`: aggiungere sezione `[paths.linux]` con default
|
||
`/var/lib/ci/...` (la sezione `[paths.windows]` resta per chi ricostruisce
|
||
template da Win)
|
||
- `runner/config.yaml`: path env vars aggiornati a POSIX
|
||
- Eventuali test pytest che assumevano `Path('F:\\CI')` → usare fixture
|
||
parametrizzata
|
||
- Workflow `lint.yml`: rimuovere o relegare a job opzionale la parte PSSA
|
||
(utile solo se si tocca ancora codice PS dei template)
|
||
|
||
---
|
||
|
||
## 6. Rischi specifici Fase B
|
||
|
||
| Rischio | Severità | Mitigazione |
|
||
| -------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------- |
|
||
| `vmrun` su Workstation Linux ha differenze sottili nel parsing output `list` / `getGuestIPAddress` | Media | Test del modulo `vmrun.py` su Linux durante Step B1; eventuali fix dietro feature flag. |
|
||
| Performance I/O linked clone su filesystem ext4 vs NTFS | Bassa | Misurare con burn-in (Step B7). Eventualmente XFS o BTRFS con CoW per il dataset template. |
|
||
| `vmnet8` NAT range configurato diversamente su Linux: IP collision con altri host LAN | Media | Allineare il range a quello attuale Windows (`192.168.79.0/24`) in `vmware-vmnet.conf`. |
|
||
| WinRM HTTPS self-signed: pypsrp da Linux può negoziare TLS 1.2 con cipher non supportati dal Windows guest | Media | Già testato in Fase A (lo stesso codice gira anche da Windows host). Validare con smoke test prima del cutover. |
|
||
| Permessi su `/var/lib/ci/build-vms/`: vmrun gira come `ci-runner` ma deve scrivere VMDK CoW | Media | ACL POSIX: `setfacl -d -m u:ci-runner:rwX` sulla directory. Test in Step B1. |
|
||
| `secret-tool` headless: act_runner come systemd service non ha sessione D-Bus per accedere al keyring | Alta | Usare backend `keyring` file-based + `age`/`sops` (vault file) oppure `keyring.backends.SecretService` con D-Bus user@.service. Decidere in Step B3 con PoC. |
|
||
| Errore #11 `AGENTS.md` (machine-id Linux clone) | Bassa | Identico comportamento, fix identico (reset machine-id pre-snapshot). Già documentato. |
|
||
| Errore #12 `AGENTS.md` (stderr nativa + `'Stop'`) | N/A | Sparisce: il codice non è più PowerShell. |
|
||
|
||
---
|
||
|
||
## 7. Path alternativo "dual-host" (se la Fase B si blocca)
|
||
|
||
Se durante la migrazione si scopre un blocker grave (es. WinRM da Linux
|
||
non funzionante affidabilmente verso il template Windows specifico), si
|
||
può ripiegare su:
|
||
|
||
- mantenere host Windows per i job `windows-build:host`
|
||
- usare host Linux Mint solo per `linux-build:host` (label dedicata)
|
||
- runner doppio registrato verso Gitea
|
||
|
||
Costo: codebase divisa in due ambienti, maggiore overhead operativo.
|
||
**Soluzione di emergenza, non target finale.**
|
||
|
||
---
|
||
|
||
## 8. Definizione di "fatto" (Fase B)
|
||
|
||
> **Stato 2026-06-07**: Fase B COMPLETATA. B1–B7 + stabilità ≥1 settimana
|
||
> (host live dal cutover ~24 mag, >2 settimane senza incidenti). Tracking di
|
||
> dettaglio in [PhaseB-user-checklist.md](../../PhaseB-user-checklist.md)
|
||
> (Passi 1–8 `[x]`). Resta solo Passo 9 (doc dual-boot, non bloccante).
|
||
|
||
- [x] act_runner gira come systemd service `act-runner.service` su Linux Mint
|
||
- [x] Tutti i template VM (`WinBuild2025`, `WinBuild2022`, `LinuxBuild2404`)
|
||
operativi dal nuovo host con snapshot integri
|
||
- [x] Build Win+Linux PASS dal nuovo host — burn-in B7 concorrente
|
||
(WinBuild2025 + LinuxBuild2404, 80/80 job PASS); vedi RUNBOOK §9
|
||
- [x] Burn-in capacity 4 job concorrenti PASS, tempi near-deterministici
|
||
(static-IP pool, σ < 1.5 s) — RUNBOOK §9
|
||
- [x] Storage migrato a `/var/lib/ci/`; host Windows in stand-by come rollback
|
||
- [x] Tutti i timer systemd attivi e schedulati (watch-disk-space,
|
||
watch-runner-health, cleanup-orphans, backup-template, retention-policy)
|
||
- [x] Credenziali guest accessibili da `ci-runner` headless
|
||
(backend `PlaintextKeyring` file-based, no D-Bus)
|
||
- [x] `README.md`, `AGENTS.md`, `docs/HOST-SETUP.md` aggiornati per host Linux
|
||
- [x] Almeno 1 settimana di esercizio in produzione senza incidenti
|
||
(>2 settimane dal cutover ~24 mag; salute 7 giu OK)
|