Files
local-ci-cd-system/plans/idea-3-powershell-removal.md
Simone 962a69d287 docs: record Phase C cutover; close $IsWindows shim bug (Phase C9)
- CLAUDE.md: Linux host no longer runs pwsh; PS 5.1 constraints scoped to
  Windows guests + Windows runner.
- RUNBOOK: add "Phase C — Python equivalents" table; §6-§13 benchmark records
  kept as historical provenance.
- TODO §3.7: close $IsWindows shim bug (resolved-by-replacement — bench run
  bypasses the shim).
- plans: mark C1-C8 done + docs C9; flag operational cutover/uninstall pending.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 20:15:10 +02:00

9.8 KiB
Raw Permalink Blame History

Fase C — Eliminazione dipendenza PowerShell dall'host Linux

Stato: codice completato (C1C8 implementati + docs C9, 2026-06-07); resta solo la parte operativa di C9 (cutover ≥1 settimana + apt-get remove powershell sull'host reale). Vedi overview e il piano di applicazione (checklist operativa).

Analisi rifatta il 2026-06-07 sullo stato reale del repo (la versione precedente proponeva gruppi CLI inesistenti e ometteva metà della superficie pwsh).


1. Obiettivo

Rendere l'host Linux completamente indipendente da PowerShell Core (pwsh). Dopo la Fase B l'orchestrazione ordinaria (job, timer, monitoring, backup, retention, deploy template) è già Python puro. Restano script .ps1 eseguiti manualmente sull'host Linux con pwsh per: burn-in di capacità, benchmark di timing, smoke/E2E test, validazione stato host e setup credenziali. Inoltre il job di lint CI usa shell: pwsh.

C done: nessuno script in scripts/*.ps1 viene più eseguito direttamente sull'host Linux, e nessun job CI che gira su un runner Linux richiede pwsh; pwsh può essere disinstallato dall'host Linux senza impatti operativi. I .ps1 restano nel repo come riferimento storico e per l'eventuale runner Windows (fallback dual-boot Passo 9).


2. Superficie pwsh reale sull'host Linux

Lo stato CLI attuale (src/ci_orchestrator/__main__.py) espone i gruppi: wait-ready, vm, build, artifacts, monitor, report, retention, template, job. Non esistono gruppi bench, smoke, validate, creds — vanno creati.

2.1 Cosa blocca davvero la disinstallazione di pwsh

# Dipendenza Dove Tipo
1 Burn-in di capacità (4 job × N round) Test-CapacityBurnIn.ps1 + wrapper Start-BurnInTest-Linux.ps1 (lanciato via sudo -u ci-runner -H pwsh …, vedi PhaseB-user-checklist §B7) host Linux, manuale
2 Benchmark timing fasi (clone/start/IP/transport/destroy) Measure-CIBenchmark.ps1unico consumatore di scripts/_Common.psm1 e scripts/_Transport.psm1 host Linux, manuale
3 Smoke end-to-end Test-Smoke.ps1 -GuestOS Linux host Linux, manuale
4 Build E2E reali (validazione pipeline) Test-Ns7zipBuild-Linux.ps1, Test-NsinnounpBuild-Linux.ps1 host Linux, manuale
5 Lint CI (PSScriptAnalyzer) .gitea/workflows/lint.ymlshell: pwsh, runs-on: linux-build runner Linux, automatico
6 Installazione pwsh di default setup-host-linux.sh step 6/6 (opt-out --skip-pwsh) provisioning host
7 Pester (test dei moduli PS) tests/_Common.Tests.ps1 host/CI, manuale
8 Setup credenziali guest Set-CIGuestCredential.ps1 (equivalente Linux mancante in CLI) host Linux, manuale

2.2 Script Windows-only (NON bloccano pwsh su Linux)

Hardcodano F:\, richiedono #Requires -RunAsAdministrator o usano il Windows Credential Manager: non girano sull'host Linux, quindi non vanno portati per l'obiettivo di Fase C. Restano per il runner Windows.

  • Validate-HostState.ps1 — logica Credential Manager/ACL NTFS, path F:\. Serve però un equivalente Linux (validate host), non un porting 1:1.
  • Set-CIGuestCredential.ps1 — scrive nel vault SYSTEM via scheduled task. Su Linux le credenziali stanno in keyrings.alt.file.PlaintextKeyring (B3, secret-tool scartato). Serve un creds set Linux-nativo.
  • Test-CIGuestWinRM.ps1 — diagnostica WinRM, RunAsAdministrator.
  • Start-BurnInTest.ps1, Test-NsinnounpBuild.ps1, Test-E2E-Section3.3.ps1 — wrapper Windows (path F:\, template WinBuild).

2.3 Già fuori scope (confermato)

  • Register-CIScheduledTasks.ps1 — Windows Scheduler.
  • Invoke-RetentionPolicy.ps1 / Backup-CITemplate.ps1 — portati in B5 (retention run / template backup).
  • Shim in scripts/ (3 righe → Python) — restano.
  • Script guest (Install-CIToolchain-*, Prepare-*, Deploy-*, template/guest-setup/windows/*) — girano dentro le VM, non sull'host.

3. Architettura prevista (nuovi gruppi CLI)

python -m ci_orchestrator bench run      --guest-os windows|linux
                                         --concurrency N        # default 4
                                         --rounds N             # default 10
                                         --build-command "..."
                                         --json-out PATH
python -m ci_orchestrator bench measure  --guest-os windows|linux
                                         --iterations N
                                         --json-out PATH        # append a benchmark.jsonl

python -m ci_orchestrator smoke run      --guest-os windows|linux
                                         [--build-command "..."]   # default: marker no-op

python -m ci_orchestrator validate host  # vmrun, snapshot template, keyring,
                                         # permessi dir, act-runner systemd attivo
python -m ci_orchestrator validate guest --host IP [--winrm|--ssh]  # diag transport

python -m ci_orchestrator creds set      --target BuildVMGuest --user ... [--password-stdin]
  • bench run unifica Test-CapacityBurnIn.ps1 + Start-BurnInTest*.ps1: lancia N job concorrenti (riusando commands/job.py in-process o come subprocess del CLI Python — niente Start-Job/pwsh), per R round, e asserisce dopo ogni round: tutti exit 0, nessuna clone-dir orfana in CI_BUILD_VMS, nessun vm-start.lock stale. Emette report JSON.
  • bench measure porta Measure-CIBenchmark.ps1 (fasi clone/start/IP/transport/destroy) → consente di retirare _Common.psm1 e _Transport.psm1 (nessun altro consumatore).
  • smoke run porta Test-Smoke.ps1 + i Test-*Build-Linux.ps1 (build E2E reali come preset opzionali del build-command).
  • validate host è un nuovo equivalente Linux (non un porting di Validate-HostState.ps1): verifica vmrun, presenza snapshot template, leggibilità keyring file-based, permessi /var/lib/ci/..., unit act-runner/ci-* attive.
  • creds set sostituisce Set-CIGuestCredential.ps1 su Linux usando direttamente il backend keyring letto da ci_orchestrator.

Vincolo di design: i nuovi comandi devono importare backends.load_backend e i transport esistenti, mai WorkstationVmrunBackend diretto (rotta ESXi Fase D aperta).


4. Nodo aperto — lint PSScriptAnalyzer (dipendenza #5)

Gli script .ps1 restano nel repo (guest + fallback Windows), quindi il lint PSSA ha ancora valore. Ma lint.yml lo esegue con shell: pwsh su runs-on: linux-build, il che reintroduce pwsh sul runner Linux. Decisione applicata (C7, 2026-06-07): opzione 1. Il job pssa gira ora su runs-on: windows-build, shell: powershell (PS 5.1), con guardia if: github.event_name == 'workflow_dispatch' così non si accoda su push/PR se il runner Windows non è registrato. Il job python resta su linux-build. Nessun job su runner Linux usa più pwsh.

Tre opzioni considerate:

  1. (Consigliata) Spostare il job pssa su un runner Windows (runs-on: windows-build, shell: powershell PS 5.1) — coerente col fatto che i .ps1 target sono Windows-native. Richiede un runner Windows registrato (dual-boot Passo 9) o eseguirlo solo on-demand.
  2. Mantenere pwsh solo nel container/runner di lint, non sull'host orchestratore: l'obiettivo "host Linux senza pwsh" resta soddisfatto se il job gira in un runner isolato. Pragmatica ma ambigua sul "C done".
  3. Rimuovere il job PSSA da CI e affidare il lint PS a un hook locale manuale. Riduce copertura.

5. Aggiornamenti collaterali

  • setup-host-linux.sh: invertire il default dello step 6 (no install pwsh; flag --with-pwsh per opt-in) o rimuovere lo step.
  • .gitea/workflows/lint.yml: applicare la decisione del §4.
  • tests/_Common.Tests.ps1: rimuovere insieme ai moduli .psm1 quando bench measure li retira (Passo C3); la copertura passa a pytest.
  • CLAUDE.md: la sezione "PowerShell 5.1 Constraints" resta valida per gli script guest Windows; aggiungere nota che l'host Linux non usa più pwsh.
  • docs/RUNBOOK.md: aggiornare procedure burn-in / smoke / validazione ai nuovi comandi Python.
  • plans/archived/2026-06-07/PhaseB-user-checklist.md §B7 (archiviato): nota che il comando pwsh Test-CapacityBurnIn.ps1 è superato da bench run.
  • TODO.md: chiudere la voce shim $IsWindows bug (f22b142) — sparisce con la rimozione di Start-Job/pwsh nel burn-in.

6. Prerequisiti

  • Fase B completata e stabile (≥1 settimana, Passo 8 ).
  • pwsh ancora installato durante il porting (per confronto output A/B).
  • Nessuna dipendenza da pwsh nei timer systemd (già soddisfatta da B5).

7. Criteri di "C done"

  • bench run --concurrency 4 --rounds 10 (Win + Linux) produce esito equivalente a Test-CapacityBurnIn.ps1 (stesse asserzioni di cleanup).
  • bench measure riproduce le fasi di Measure-CIBenchmark.ps1; i moduli _Common.psm1/_Transport.psm1 e tests/_Common.Tests.ps1 rimossi.
  • smoke run --guest-os linux e --guest-os windows passano.
  • validate host esce 0 su host configurato correttamente.
  • creds set sostituisce Set-CIGuestCredential.ps1 sull'host Linux.
  • Decisione §4 applicata: nessun job CI su runner Linux richiede pwsh.
  • setup-host-linux.sh non installa più pwsh di default.
  • pwsh --version può essere assente sull'host Linux senza che alcun test, timer, job CI o procedura di RUNBOOK fallisca.
  • Suite pytest ≥90% coverage, verde.

8. Rollback

I .ps1 originali restano nel repo e funzionano su host Windows o su Linux con pwsh reinstallato (setup-host-linux.sh --with-pwsh). Il rollback è reinstallare pwsh e usare gli script esistenti. Nessuna distruzione di dati: il porting aggiunge comandi, non rimuove i .ps1 finché il burn-in di validazione non è verde.