Files
local-ci-cd-system/plans/idea-1-python-rewrite.md
T

10 KiB

Idea 1 — Conversione del sistema in Python

Stato: proposta / valutazione. Documento esplorativo, non piano esecutivo. Baseline: ~13.000 righe PowerShell 5.1 (41 file .ps1 + 2 .psm1), 2 script bash, 5 workflow Gitea Actions, orchestratore Invoke-CIJob.ps1 + moduli _Common.psm1 / _Transport.psm1.


1. Obiettivo

Riscrivere l'intero sistema CI/CD locale (host orchestrator + script di provisioning template) in Python 3.11+, mantenendo invariati:

  • runtime act_runner + Gitea (consuma comandi via shell, agnostico al linguaggio)
  • template VM (Windows con WinRM, Linux con SSH)
  • formato artifact e layout F:\CI\
  • compatibilità con i workflow YAML esistenti (gitea/workflows/*.yml)

Il punto di ingresso Invoke-CIJob.ps1 viene sostituito da invoke_ci_job.py (o python -m ci_job ...), invocato da gitea/actions/local-ci-build/action.yml.


2. Fattibilità

2.1 Mappa di traduzione dei componenti

Componente PowerShell Equivalente Python Note
Invoke-Vmrun (wrapper vmrun.exe) subprocess.run([vmrun, '-T', 'ws', ...]) Identico, gestione returncode esplicita.
New-PSSession + Invoke-Command (WinRM) pypsrp (pypsrp.client.Client) o pywinrm Rischio basso. pypsrp supporta HTTPS self-signed e PSRP nativo.
Copy-Item -ToSession / -FromSession pypsrp.client.Client.copy() / fetch() Throughput simile a WinRM nativo.
_Transport.psm1 (ssh.exe / scp.exe) paramiko o fabric, oppure subprocess di ssh/scp paramiko elimina dipendenza da OpenSSH client.
Credential Manager (BuildVMGuest) keyring (backend Windows Credential Manager) API cross-platform; stesso store sotto Windows.
Get-StoredCredential keyring.get_credential(target, None) Modulo PyPI keyring.
Pester test pytest + pytest-mock Riscrittura test 1:1 fattibile.
PSScriptAnalyzer ruff + mypy + pylint Profilo lint più rigoroso (tipi statici).
Logging Write-Host logging (stdout handler) act_runner cattura stdout normalmente.
ConvertTo-Json per stato json stdlib
Workflow YAML Invariati Cambia solo lo shell: / il comando invocato.
Script .sh in gitea/burnin-dummy/ Invariati Girano nel guest Linux.

2.2 Aree senza equivalenti dirette / da progettare

  1. Set-StrictMode -Version Latest → in Python si ottiene con mypy --strict
    • from __future__ import annotations. Cambia il modello mentale (non è runtime ma static check).
  2. ShouldProcess / -WhatIf → richiede un flag --dry-run esplicito implementato manualmente in ogni comando state-changing.
  3. PSSessionOption con -SkipCACheckpypsrp accetta cert_validation=False direttamente.
  4. Pipeline objects (es. Get-ChildItem | Where-Object …) → diventano list comprehension / generator. Refactor logico, non meccanico.
  5. PowerShell auto-loading di moduli → in Python serve pyproject.toml + package layout (src/ci_orchestrator/...) e installazione (pip install -e .).

2.3 Dipendenze runtime aggiuntive sull'host

  • Python 3.11+ (Microsoft Store o python.org installer)
  • pacchetti: pypsrp[credssp], paramiko, keyring, pyyaml, click (CLI), rich (output colorato), pytest, ruff, mypy
  • Tutti installabili in un venv isolato (F:\CI\python\venv\) → zero impatto sul Python di sistema.

2.4 Compatibilità con act_runner

act_runner invoca uno step run: con shell: powershell oggi. Cambia in:

- shell: cmd
  run: F:\CI\python\venv\Scripts\python.exe -m ci_orchestrator job ...

oppure si lascia un wrapper .ps1 minimale che chiama Python (più graduale).

2.5 Rischi specifici

Rischio Severità Mitigazione
pypsrp ha edge case con prompt UAC / loopback HTTPS Media PoC isolato su Wait-VMReady equivalente prima di committare alla rewrite.
keyring sotto SYSTEM account (act_runner service) può non vedere credenziali utente Alta Già un problema oggi con Credential Manager; stessa mitigazione (DPAPI machine scope o vault file).
Perdita di know-how dei #11, #12 di AGENTS.md durante refactor Media Riportare ogni "errore frequente" come test pytest prima di portare il codice.
Doppio mantenimento durante la migrazione Alta Migrazione "big bang" per branch sconsigliata; usare strategia 2.6.

2.6 Strategia di migrazione consigliata

Strangler fig, in 4 fasi:

  1. Estrarre _Common.psm1 + _Transport.psm1 in ci_orchestrator/transport.py e ci_orchestrator/vmrun.py; mantenere gli script .ps1 esistenti che chiamano Python via python -c per le primitive critiche. Validazione: workflow lint.yml e self-test.yml continuano a passare.
  2. Portare gli script "foglia" senza state condiviso: Wait-VMReady, Remove-BuildVM, Cleanup-OrphanedBuildVMs, Watch-DiskSpace, Watch-RunnerHealth. Ognuno con i suoi test pytest.
  3. Portare New-BuildVM + Get-BuildArtifacts + Invoke-RemoteBuild.
  4. Portare Invoke-CIJob (orchestratore) per ultimo, switchando il workflow YAML solo a quel punto.

Gli script di template setup (template/Prepare-*.ps1, Deploy-*.ps1, Install-CIToolchain-*.ps1) restano in PowerShell perché girano una tantum e sono fortemente legati a Windows (autounattend.xml, registry, sysprep). Convertirli ha ROI basso.


3. Stima volumi / sforzo (relativa)

Fase Indicatori dimensione Complessità
F1 — Moduli _Common + _Transport ~540 righe PS → ~600 righe Py + test Media
F2 — Script foglia (6 file) ~1.500 righe PS Bassa
F3 — Build pipeline (3 file core) ~2.000 righe PS Media
F4 — Orchestrator + switch workflow ~800 righe PS Alta
F5 — Riscrittura test Pester → pytest 4 file test esistenti + nuovi Media
F6 — Documentazione (AGENTS.md, README, docs/) 24 file md Bassa

Le fasi F1→F4 devono essere sequenziali; F5 si fa in parallelo a ciascuna fase (test della fase prima del merge). F6 si fa a fine F4.


4. Pro / Contro

Pro

  • Cross-platform di base: rimuove il vincolo PS 5.1 (vedi Idea 2).
  • Ecosistema test/typing/lint più ricco (pytest, mypy, ruff).
  • Type hints + dataclass riducono la classe di bug Set-StrictMode non cattura.
  • Libreria pypsrp è attivamente manutenuta; paramiko standard de facto.
  • Più sviluppatori conoscono Python che PS 5.1.

Contro

  • Costo migrazione alto rispetto al beneficio se il sistema resta Windows-only e funziona già (oggi è in production-ready).
  • Doppio mantenimento per ~tutta la durata della migrazione.
  • pypsrp su Windows Server target richiede tuning (CredSSP, message encryption) — possibili sorprese non visibili oggi con WinRM nativo PS.
  • Gli Install-CIToolchain-WinBuild2025.ps1 restano comunque in PS (girano nel guest Windows) → la codebase non sarà mai 100% Python.
  • Documentazione (AGENTS.md, docs/BEST-PRACTICES.md) tutta da riscrivere.

5. Decision checklist

Procedere solo se almeno 2 dei seguenti sono veri:

  • È prevista l'Idea 2 (host Linux) o l'Idea 3 (ESXi) entro 6 mesi.
  • Si vogliono assumere/coinvolgere sviluppatori non-Windows.
  • Si pianifica integrazione con tool Python (es. Ansible per provisioning, librerie pyVmomi per ESXi).
  • Il debito tecnico di PS 5.1 (no async, no ternari, dipendenza da Credential Manager) sta bloccando feature concrete.

Se nessuna è vera, non vale la pena: investire piuttosto in test e osservabilità sul codice PS attuale.


6. Sinergia con Idee 2 e 3

  • Idea 2 (host Linux): la riscrittura Python è prerequisito naturale. PS 7 su Linux funziona ma vmrun non gira nativamente lì (Workstation è Windows-only; serve VMware Player Linux o ovftool). Python rende il porting più semplice se anche il transport cambia (es. libvirt come alternativa).
  • Idea 3 (ESXi): pyVmomi (SDK ufficiale VMware per ESXi/vCenter) è solo Python. Equivalenti PowerShell sono PowerCLI (richiede PS 7+ moduli VMware.PowerCLI installabili anche su PS 5.1, ma con limiti). Andare su Python apre la strada al supporto ESXi in modo idiomatico.

Raccomandazione: se si vuole davvero perseguire Idee 2 o 3, la riscrittura Python diventa quasi obbligata. Se invece il sistema resta su Windows + VMware Workstation, la conversione è opzionale e non urgente.