- 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>
9.8 KiB
Fase C — Eliminazione dipendenza PowerShell dall'host Linux
Stato: codice completato (C1–C8 implementati + docs C9, 2026-06-07); resta solo la parte operativa di C9 (cutover ≥1 settimana +
apt-get remove powershellsull'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.ps1 — unico 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.yml → shell: 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, pathF:\. 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 inkeyrings.alt.file.PlaintextKeyring(B3,secret-toolscartato). Serve uncreds setLinux-nativo.Test-CIGuestWinRM.ps1— diagnostica WinRM,RunAsAdministrator.Start-BurnInTest.ps1,Test-NsinnounpBuild.ps1,Test-E2E-Section3.3.ps1— wrapper Windows (pathF:\, 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 rununificaTest-CapacityBurnIn.ps1+Start-BurnInTest*.ps1: lancia N job concorrenti (riusandocommands/job.pyin-process o come subprocess del CLI Python — nienteStart-Job/pwsh), per R round, e asserisce dopo ogni round: tutti exit 0, nessuna clone-dir orfana inCI_BUILD_VMS, nessunvm-start.lockstale. Emette report JSON.bench measureportaMeasure-CIBenchmark.ps1(fasi clone/start/IP/transport/destroy) → consente di retirare_Common.psm1e_Transport.psm1(nessun altro consumatore).smoke runportaTest-Smoke.ps1+ iTest-*Build-Linux.ps1(build E2E reali come preset opzionali del build-command).validate hostè un nuovo equivalente Linux (non un porting diValidate-HostState.ps1): verificavmrun, presenza snapshot template, leggibilità keyring file-based, permessi/var/lib/ci/..., unitact-runner/ci-*attive.creds setsostituisceSet-CIGuestCredential.ps1su Linux usando direttamente il backendkeyringletto daci_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:
- (Consigliata) Spostare il job
pssasu un runner Windows (runs-on: windows-build,shell: powershellPS 5.1) — coerente col fatto che i.ps1target sono Windows-native. Richiede un runner Windows registrato (dual-boot Passo 9) o eseguirlo solo on-demand. - Mantenere
pwshsolo 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". - 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 installpwsh; flag--with-pwshper opt-in) o rimuovere lo step..gitea/workflows/lint.yml: applicare la decisione del §4.tests/_Common.Tests.ps1: rimuovere insieme ai moduli.psm1quandobench measureli 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 comandopwsh Test-CapacityBurnIn.ps1è superato dabench run.TODO.md: chiudere la voce shim$IsWindowsbug (f22b142) — sparisce con la rimozione diStart-Job/pwshnel burn-in.
6. Prerequisiti
- Fase B completata e stabile (≥1 settimana, Passo 8 ✅).
pwshancora installato durante il porting (per confronto output A/B).- Nessuna dipendenza da
pwshnei timer systemd (già soddisfatta da B5).
7. Criteri di "C done"
bench run --concurrency 4 --rounds 10(Win + Linux) produce esito equivalente aTest-CapacityBurnIn.ps1(stesse asserzioni di cleanup).bench measureriproduce le fasi diMeasure-CIBenchmark.ps1; i moduli_Common.psm1/_Transport.psm1etests/_Common.Tests.ps1rimossi.smoke run --guest-os linuxe--guest-os windowspassano.validate hostesce 0 su host configurato correttamente.creds setsostituisceSet-CIGuestCredential.ps1sull'host Linux.- Decisione §4 applicata: nessun job CI su runner Linux richiede
pwsh. setup-host-linux.shnon installa piùpwshdi default.pwsh --versionpuò 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.