Files
local-ci-cd-system/plans/idea-3-esxi-support.md
T
Simone 6db20d66bf docs: introduce Phase C (pwsh removal), rename ESXi to Phase D
- Add plans/idea-3-powershell-removal.md: Phase C goal is to eliminate
  the pwsh dependency from the Linux host by porting the remaining PS
  scripts (bench run, validate host, smoke run) to Python sub-commands.
- Update idea-3-esxi-support.md header: Fase C → Fase D.
- Update ideas-overview.md: new four-phase table (A/B/C/D) with
  prerequisiti and criteri for Phase C.
- Rename all "Hook futuri Fase C" (ESXi) → "Hook futuri Fase D" in
  implementation-plan-A-B.md; add Phase C/D entries to summary and
  references section.
- Update PhaseB-user-checklist.md end note and CLAUDE.md to point
  Phase C → pwsh removal, Phase D → ESXi.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-21 20:46:01 +02:00

9.0 KiB

Fase D — Supporto ESXi per le Build VM (futuro)

Stato: piano differito, da rivalutare dopo che Fase A (rewrite Python), Fase B (host Linux) e Fase C (eliminazione PowerShell) sono stabili in produzione. Vedi overview.

Questo documento esiste per:

  1. Garantire che il design di Fase A abbia gli hook corretti (astrazione VmBackend).
  2. Avere un piano pronto se/quando si decide di scalare oltre i limiti dell'host singolo Workstation Pro.

1. Quando attivare Fase C

Fase C ha senso solo se si verifica almeno uno di:

  • Saturazione della concorrenza locale (>4 job paralleli regolarmente)
  • Necessità di disaccoppiare hardware CI control plane (ufficio) dal hardware build (rack/datacenter)
  • Disponibilità di hardware ESXi + licenza vSphere Essentials o superiore
  • Richiesta di QoS / resource pool per i job CI vs altri carichi

Se nessuno è vero a 6-12 mesi dal completamento Fase B, non aprire Fase C: Workstation Pro su Linux copre il caso d'uso e l'overhead operativo di un secondo backend non è giustificato.


2. Architettura prevista

   ┌──────────────┐    ┌─────────────────────────────┐
   │  Gitea       │    │  ESXi host(s)               │
   │  act_runner  │    │   ├─ Template Windows (snap BaseClean)        │
   │ (Linux Mint) │    │   ├─ Template Linux   (snap BaseClean-Linux)  │
   │              │    │   └─ Datastore: ci-builds  │
   └──────┬───────┘    └──────────▲──────────────────┘
          │                       │  vSphere API (443)
          ▼                       │
   ┌──────────────────┐           │
   │ ci_orchestrator  │───────────┘
   │ (Python, Linux)  │
   │  ↳ EsxiBackend   │
   └─────┬────────────┘
         │ WinRM/SSH
         ▼
    Build VM efimera su ESXi

L'host CI Linux (Fase B) continua a esistere come control plane. Le build VM girano su ESXi remoto. Il transport WinRM/SSH al guest non cambia.


3. Implementazione: nuovo backend pyVmomi

Sfruttando l'astrazione VmBackend introdotta in Fase A:

# src/ci_orchestrator/backends/esxi.py
class EsxiBackend(VmBackend):
    def __init__(self, host: str, user: str, password: str, datastore: str, folder: str): ...
    def clone_linked(self, template: str, snapshot: str, name: str) -> VmHandle: ...
    def start(self, vm: VmHandle) -> None: ...
    def stop(self, vm: VmHandle, hard: bool = True) -> None: ...
    def delete(self, vm: VmHandle) -> None: ...
    def get_ip(self, vm: VmHandle, timeout: float) -> str: ...

Selezione backend via env / config:

[backend]
type = "esxi"  # oppure "workstation"

[backend.esxi]
host = "esxi.lab.local"
user = "ci-runner@vsphere.local"
datastore = "ci-builds"
folder = "ci"

4. Mappa operazioni Workstation → ESXi

Operazione Workstation (oggi) ESXi (Fase C, pyVmomi)
Linked clone vmrun clone ... linked -snapshot=BaseClean vim.VirtualMachineCloneSpec(linkedClone=True, snapshot=ref)
Start VM vmrun start <vmx> VirtualMachine.PowerOn() (Task)
Stop VM vmrun stop <vmx> hard VirtualMachine.PowerOff() (Task)
Delete VM vmrun deleteVM <vmx> VirtualMachine.Destroy_Task()
List snapshots vmrun listSnapshots VirtualMachine.snapshot.rootSnapshotList
Get guest IP vmrun getGuestIPAddress VirtualMachine.guest.ipAddress (richiede VMware Tools nei guest)
Test running vmrun list VirtualMachine.runtime.powerState == 'poweredOn'

5. Setup ESXi richiesto (Step C0)

Prerequisiti hardware/licenza da verificare PRIMA di pianificare:

  • Licenza: ESXi free non basta (le API write sono bloccate dal 2020). Serve almeno vSphere Essentials o licenza valutativa rinnovabile.
  • Hardware: server con CPU che supporti la versione ESXi target, RAM ≥64 GB, NVMe locale per datastore.
  • Network: portgroup dedicato per le build VM, DHCP raggiungibile.
  • Account: user dedicato con ruolo custom (datastore, folder, snapshot, power, network — minimo set richiesto da clone_linked/destroy).

6. Sequenza implementativa

C1 — Validazione ambiente

  • Setup hardware ESXi + licenza
  • Account vSphere dedicato
  • Test manuale clone+start+stop via UI vSphere
  • Misurazione tempi di clone (baseline)

C2 — Implementazione EsxiBackend

  • pip install pyvmomi aggiunto al pyproject.toml
  • src/ci_orchestrator/backends/esxi.py implementato
  • Test pytest con pyvmomi mock + un test di integrazione opzionale che gira solo se env CI_TEST_ESXI_HOST è settata

C3 — Migrazione template

  • Export OVF dei template Workstation: ovftool ... template.vmx template.ovf
  • Import su datastore ESXi: ovftool template.ovf vi://...
  • Verifica WinRM/SSH raggiungibili dal control plane verso le VM ESXi
  • Snapshot BaseClean / BaseClean-Linux ricreati lato ESXi

C4 — Canary deploy

  • Workflow di test dedicato con label windows-build:esxi o config override backend=esxi
  • Eseguito quotidianamente per ≥1 settimana
  • Confronto metriche (tempo totale, success rate) vs Workstation backend

C5 — Rollout selettivo

  • Workflow di produzione spostati uno a uno su backend ESXi
  • Monitoring tempi via Measure-CIBenchmark equivalente Python
  • Workstation backend resta disponibile come fallback (basta cambiare config)

C6 — Adattamenti tooling secondari

  • Cleanup-OrphanedBuildVMs esteso per query ESXi folder-scoped
  • Watch-DiskSpace esteso a query datastore via API
  • Backup-CITemplate sostituito da snapshot ESXi nativi o ovftool schedulato

7. Rischi specifici Fase C

Rischio Severità Mitigazione
Licenza ESXi free blocca API write (CloneVM_Task non autorizzata) Critica Verificare licenza in C1 prima di qualsiasi sviluppo. Procurare vSphere Essentials.
Linked clone su ESXi standalone (no vCenter) ha gap funzionali Alta PoC manuale in C1; se gap rilevante, valutare full clone vs linked.
Tempo clone+poweron+IP > Workstation locale per latenza rete + overhead vSphere Media Misurare in C1; possibile mitigazione: pool di VM "warm" pre-clonate.
VMware Tools nel guest non sempre rapide a riportare IP via API Bassa Stesso problema oggi (AGENTS.md errore #10). Fallback: parse DHCP lease su ESXi via API.
Concorrenza: race condition su naming VM o folder Media Lock per JobId lato orchestrator; suffisso UUID nel nome VM.
Cleanup VM orfane più costoso (API call per ogni VM in folder) Bassa Riscrivere cleanup come query folder-scoped, non scan globale.
Single point of failure: ESXi giù = tutta la CI giù Media Documentare procedura fallback su backend Workstation locale (basta cambio config).
Errore #11 AGENTS.md (machine-id identico clone Linux) si ripropone Bassa Stessa fix lato template, già documentata.

8. Definizione di "fatto" (Fase C)

  • Hardware ESXi + licenza Essentials operativi
  • EsxiBackend implementato, testato (unit + integration test)
  • Template Windows e Linux importati e funzionanti su ESXi con snapshot
  • Almeno 1 workflow di produzione in canary su backend ESXi per ≥1 settimana senza regressioni
  • Documentazione (docs/HOST-SETUP.md, docs/ARCHITECTURE.md, AGENTS.md) aggiornata con istruzioni multi-backend
  • Procedura di rollback su backend Workstation testata e documentata