# 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 ` 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-.service` (oneshot, chiama `python -m ci_orchestrator `) - `/etc/systemd/system/ci-.timer` (`OnCalendar=...` equivalente) - `systemctl enable --now ci-.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-nsInnoUnp.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) - [ ] act_runner gira come systemd service `act-runner.service` su Linux Mint - [ ] Tutti i template VM (`WinBuild2025`, `WinBuild2022`, `LinuxBuild2404`) operativi dal nuovo host con snapshot integri - [ ] Workflow `build-nsInnoUnp.yml` (matrix Win+Linux) PASS dal nuovo host - [ ] Burn-in capacity 4 job concorrenti PASS, tempi entro ±20% del baseline - [ ] Storage migrato a `/var/lib/ci/`, host Windows in stand-by come rollback - [ ] Tutti i timer systemd attivi e schedulati - [ ] Credenziali guest accessibili da `ci-runner` headless - [ ] `README.md`, `AGENTS.md`, `docs/HOST-SETUP.md` aggiornati per host Linux - [ ] Almeno 1 settimana di esercizio in produzione senza incidenti