Files
local-ci-cd-system/plans/idea-3-esxi-support.md
T

14 KiB

Idea 3 — Supporto ESXi per le Build VM

Stato: proposta / valutazione. Modello: host CI (Windows o Linux) continua a fare orchestrazione ma le build VM girano su un server ESXi remoto invece che in VMware Workstation locale.


1. Obiettivo

Permettere a Invoke-CIJob di usare un host ESXi (o cluster vCenter) come backend di virtualizzazione, mantenendo:

  • workflow YAML invariati (eventualmente con nuovo label windows-build:esxi)
  • transport WinRM/SSH verso i guest invariato
  • formato artifact e flusso clone → start → wait → build → collect → destroy identico

Cambia: come si fa clone/start/stop/delete della VM, dove vivono i dischi, come si determina l'IP del guest, come si autenticano i comandi di management.


2. Fattibilità

2.1 API di management ESXi

Opzione Pro Contro Verdetto
A. pyVmomi (Python SDK ufficiale) API completa (cloni, snapshot, power ops, GuestOps); supportata; va anche contro singolo host ESXi senza vCenter. Solo Python. Curva di apprendimento (managed object reference, task tracking). Raccomandata se si va Python (Idea 1).
B. PowerCLI (VMware.PowerCLI PSGallery) Idiomatica per PowerShell; comandi New-VM, Get-Snapshot, ecc. molto leggibili. Modulo grosso (~2 GB), Windows-friendly ma installazione richiede Install-Module. Performance avvio cmdlet non sempre rapida. Buona se si resta in PowerShell.
C. ovftool + REST API ESXi (vSphere API REST) Standard moderno; copre la maggior parte delle operazioni in vSphere 7+. API REST single-host ha gap rispetto a SOAP/pyVmomi; complicata gestione task. Sconsigliata come strato unico.
D. govc (VMware/govmomi CLI) Binario Go portabile, scriptabile da shell qualsiasi. Meno espressivo per logiche complesse (loop, error handling); diventa un "second-class" tooling. Buona per script ad-hoc, non per orchestratore.

Le due strade realistiche sono A (pyVmomi) o B (PowerCLI), in funzione dell'esito dell'Idea 1.

2.2 Mappa di adattamento

Operazione Workstation oggi ESXi domani (pyVmomi)
Linked clone vmrun clone ... linked -snapshot=BaseClean vim.VirtualMachineCloneSpec con linkedClone=True e 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 (tree)
Get guest IP vmrun getGuestIPAddress (errore #10) VirtualMachine.guest.ipAddress (richiede VMware Tools attivi)
Test running vmrun list + path search VirtualMachine.runtime.powerState == 'poweredOn'
Trasferimento file pre-WinRM/SSH non usato GuestOperationsManager (FileManager + ProcessManager) — opzionale, oggi non serve

Il transport _Transport.psm1 (SSH) e le sessioni WinRM non cambiano: una volta che la VM è up con IP raggiungibile, l'host CI parla direttamente col guest come oggi.

2.3 Architettura proposta

   ┌──────────────┐    ┌─────────────────────────────┐
   │  Gitea       │    │  ESXi host(s)               │
   │  act_runner  │    │   ├─ Template Windows (snap BaseClean)  │
   │              │    │   ├─ Template Linux   (snap BaseClean-Linux) │
   └──────┬───────┘    │   └─ Datastore: ci-builds  │
          │            └──────────▲──────────────────┘
          │ orchestrate              │  vSphere API (443)
          ▼                          │
   ┌──────────────────┐              │
   │  CI orchestrator │──────────────┘
   │  (host Win o Lin)│
   └─────┬────────────┘
         │ WinRM/SSH (network L3 ammessa)
         ▼
    Build VM efimera su ESXi

L'host CI continua a esistere come "control plane". Può essere lo stesso hardware di oggi (Windows 11) oppure migrato a Linux (Idea 2). Le build VM non girano più localmente.

2.4 Nuove configurazioni richieste

  • ESXi host raggiungibile da host CI sulla 443/TCP.
  • Account di servizio ESXi (ci-runner@vsphere.local o local user con ruolo custom): permessi minimi su datastore, folder, snapshot, power ops.
  • Datastore dedicato (SSD/NVMe) per cloni e template; quota / monitoring.
  • Resource pool dedicato ci-builds con CPU/memory limits.
  • Portgroup di rete con DHCP raggiungibile (o assegnazione IP statica via cloud-init / Sysprep).
  • Snapshot dei template identico al setup attuale (BaseClean / BaseClean-Linux) — convertire VMX→VMX-su-ESXi via OVF (ovftool).

2.5 Rischi specifici

Rischio Severità Mitigazione
Linked clone su ESXi standalone (senza vCenter) ha limitazioni rispetto a Workstation Alta Validare in PoC: alcune versioni ESXi free non supportano CloneVM_Task via API senza license.
Licenza ESXi: la versione free non espone le API write (solo read-only) — bug noto vSphere Critica Serve almeno vSphere Essentials o licenza valutativa. Verificare PRIMA di pianificare.
Throughput linked clone su NFS/iSCSI datastore inferiore a SSD locale Workstation Media Datastore VMFS su NVMe locale o vSAN; benchmark con Test-CapacityBurnIn.
Tempo medio "clone → IP raggiungibile" più alto rispetto a Workstation locale Media Misurare con Measure-CIBenchmark; ottimizzare warm pool template (Backup-CITemplate non più utile, sostituire con template VM in folder dedicata).
Gestione concorrente cloni: race su nome VM o snapshot revert Media Lock per JobId lato orchestrator; oppure naming con suffisso UUID.
Determinazione IP: VMware Tools deve essere attivo e DHCP funzionante Bassa Già un prerequisito attuale (Wait-VMReady). Documentare in AGENTS.md nuova versione.
Errore #11 (machine-id identico sui clone Linux) si ripropone identico su ESXi Bassa Stessa fix: reset machine-id pre-snapshot. Documentato.
Sicurezza: credenziali vCenter/ESXi nello stesso store delle credenziali guest Media Target Credential Manager separato (ESXiServiceAccount) o keyring + ACL.
Cleanup VM orfane più costoso (richiede chiamata API per ogni VM in folder) Bassa Riscrivere Cleanup-OrphanedBuildVMs per usare folder-scoped query.

2.6 Sequenza di implementazione consigliata

  1. PoC manuale: clonare manualmente un template su ESXi via UI/PowerCLI, avviare, fare WinRM da host CI. Misurare tempi.
  2. PoC scriptato: una versione minimale di New-BuildVM-ESXi.ps1 (o new_build_vm_esxi.py) che fa clone+start. Validare race conditions.
  3. Astrazione IVmBackend: introdurre nei moduli _Common / vmrun.py un'interfaccia a 2 implementazioni (Workstation, ESXi), selezionata via env var (GITEA_CI_VM_BACKEND=workstation|esxi). In questo modo si può fare canary deploy job-per-job.
  4. Migrazione template (export OVF da Workstation, import su ESXi datastore).
  5. Workflow YAML aggiornati con label windows-build:esxi accanto a windows-build:host.
  6. Capacity burn-in concorrente sull'host ESXi.

3. Stima volumi / sforzo (relativa)

Area Indicatori dimensione Complessità
Setup hardware/licenze ESXi 1 host fisico + licenza Essentials Variabile (acquisto)
PoC clone/start/stop via pyVmomi o PowerCLI ~200 righe Media
Astrazione backend (IVmBackend con 2 impl) refactor di _Common, New-BuildVM, Remove-BuildVM, Wait-VMReady Media
Export OVF dei template + import ESXi + ri-validazione snapshot 3 template Media
Riconfigurazione network/DHCP per build VM su ESXi 1 portgroup + DHCP scope Media
Adattamento Cleanup-OrphanedBuildVMs, Watch-DiskSpace (datastore-aware) ~300 righe Bassa
Documentazione (HOST-SETUP.md nuovo capitolo ESXi, OPTIMIZATION.md) 2-3 file md Bassa
Validazione e2e + benchmark vs Workstation piano test esistente esteso Alta

4. Pro / Contro

Pro

  • Scalabilità: un ESXi con CPU/RAM adeguate ospita facilmente 8-16 job concorrenti vs ~4 con Workstation locale (limite testato in Test-CapacityBurnIn).
  • Disaccoppia host CI (control plane) da hardware di build (data plane).
  • Resource pool / shares / reservation: QoS per i job CI.
  • Backup template / DR via snapshot ESXi nativi o appliance Veeam.
  • Permette di avere host CI Linux (Mint) senza dover usare KVM (Idea 2 + Idea 3 sinergiche).
  • Multi-runner futuro più semplice (più host CI puntano allo stesso ESXi).

Contro

  • Costo licenza vSphere (la free non basta per le API write).
  • Hardware aggiuntivo dedicato (o ri-uso di un server esistente).
  • Latenza di rete in più rispetto a in-process locale.
  • Throughput clone dipende da datastore; può essere peggio se non si ha SSD locale ESXi.
  • Backup VMDK template (Backup-CITemplate.ps1) va riprogettato (usare snapshot ESXi nativi o export OVF schedulato).
  • Disaster scenario: se ESXi è giù, tutte le pipeline si fermano. Con Workstation locale il guasto era confinato all'host CI.

5. Sinergia con altre idee

  • Idea 1 (Python): forte sinergia. pyVmomi è Python-only; restando in PowerShell si è costretti a VMware.PowerCLI, che ha overhead di caricamento e dimensioni notevoli.
  • Idea 2 (host Linux): complementare. Idea 3 sposta il "dove girano le VM" ma non vincola il "dove gira l'orchestrator". Si può:
    • Win host + ESXi backend: minima migrazione lato CI script (resta PS).
    • Linux host + ESXi backend: massima modernizzazione, ma somma i rischi delle due migrazioni. Solo dopo Idee 1+2 stabilizzate.
  • Con Idea 3 implementata, l'utilità di Idea 2 (host Linux con KVM locale) cala: la VM locale serve solo per debug, non più per CI in production.

6. Decision checklist

Procedere solo se almeno 3 dei seguenti sono veri:

  • È disponibile (o pianificato) hardware ESXi + licenza Essentials.
  • Si prevede di superare i 4 job concorrenti regolarmente.
  • Si vuole disaccoppiare hardware CI da hardware build (es. CI in ufficio, build in rack).
  • Si è pianificata l'Idea 1 (Python) o si è disposti a usare PowerCLI.
  • Disaster recovery / backup datastore è un requisito esplicito.

Se la concorrenza richiesta è ≤4 job e l'hardware attuale (i9 + 64GB) regge, l'investimento ESXi non si ripaga rispetto a Workstation locale.


7. Path incrementale "minimo": ESXi opzionale

Anziché migrazione totale, supportare entrambi i backend in parallelo:

  • Lasciare default windows-build:host (Workstation locale, situazione attuale).
  • Aggiungere label windows-build:esxi per job specifici (es. burn-in pesanti, regression suite notturna).
  • Naming dei job e folder ESXi prefissati con ci- per filtering.
  • Eventuale rollback semplice (basta disabilitare il label).

Sforzo ~50% rispetto a migrazione totale, debito tecnico controllato perché l'astrazione IVmBackend è già lì per design.