Files
local-ci-cd-system/plans/idea-3-implementation-plan.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.0 KiB
Raw Permalink Blame History

Fase C — Piano di applicazione (eliminazione pwsh dall'host Linux)

Piano operativo per idea-3-powershell-removal.md. Generato il 2026-06-07. Eseguire i passi in ordine: ogni passo è autonomo, testabile e con rollback banale (i .ps1 non vengono rimossi finché C9 non chiude il burn-in di validazione).


Summary — checklist master

Stato passi (spunta man mano):

  • C1 — Scaffolding gruppi CLI bench / smoke / validate / creds + test skeleton
  • C2bench run: porting burn-in concorrenza (Test-CapacityBurnIn + Start-BurnInTest*)
  • C3bench measure: porting timing fasi (Measure-CIBenchmark) + retire _Common.psm1/_Transport.psm1/_Common.Tests.ps1
  • C4smoke run: porting smoke + build E2E (Test-Smoke, Test-*Build-Linux)
  • C5validate host: equivalente Linux di Validate-HostState
  • C6creds set (rimpiazza Set-CIGuestCredential) + validate guest (diag transport)
  • C7 — Lint CI: risolvere dipendenza pwsh di lint.yml (decisione §4 dell'analisi)
  • C8setup-host-linux.sh: pwsh non più installato di default (--with-pwsh opt-in)
  • [~] C9 — Docs + cutover/burn-in ≥1 settimana + disinstallazione pwsh (operativi, vedi sotto)

Definition of done globale: tutti i criteri del §7 dell'analisi verificati; pwsh rimosso dall'host Linux; pytest verde ≥90%.


Convenzioni trasversali (valgono per ogni passo)

  • Codice nuovo solo in src/ci_orchestrator/. click.echo, no print(), no subprocess(..., shell=True), type hints completi, mypy --strict.
  • Importare solo backends.load_backend + transport esistenti (transport/ssh.py, transport/winrm.py). Mai WorkstationVmrunBackend.
  • Ogni nuovo comando ha test in tests/python/test_commands_<gruppo>.py con backend e transport mockati (no VM reali in unit test).
  • Gate coverage 90% per ogni PR. ruff + mypy --strict verdi.
  • Un passo = una PR. Non toccare il branch WinRM e SSH nello stesso commit (gotcha CLAUDE.md): se un comando ha entrambi i rami, separarli o isolare dietro if guest_os == "linux".

C1 — Scaffolding

Obiettivo: registrare i gruppi vuoti e i file, senza logica reale, per fissare l'interfaccia CLI e i test.

  • Creare commands/bench.py con @click.group("bench") e i comandi stub run / measure (firma completa, corpo raise NotImplementedError dietro --dry-run per i test).
  • Creare commands/smoke.py (@click.group("smoke")run).
  • Creare commands/validate.py (@click.group("validate")host, guest).
  • Creare commands/creds.py (@click.group("creds")set).
  • Registrarli in __main__.py (cli.add_command(...)).
  • tests/python/test_commands_bench.py ecc.: verificare --help e registrazione comandi (smoke test CLI).
  • Done: python -m ci_orchestrator bench --help ecc. funzionano; pytest verde.

C2 — bench run (burn-in concorrenza)

Sostituisce: Test-CapacityBurnIn.ps1, Start-BurnInTest.ps1, Start-BurnInTest-Linux.ps1.

  • Implementare il lancio di N job concorrenti in-process (concurrent.futures su commands/job.py) o come N subprocess del CLI Python — niente Start-Job/pwsh/$IsWindows (chiude il bug shim f22b142).
  • Per ogni round, asserire: tutti i job exit 0; nessuna clone-dir orfana in CI_BUILD_VMS; nessun vm-start.lock stale (>5 min).
  • Report JSON in CI_ARTIFACTS/bench/ + tabella riepilogo a video.
  • Default lab: --concurrency 4 --rounds 10, build-command no-op (ping/sleep ~30s) come negli wrapper.
  • Test: round con job mockati (PASS/FAIL), rilevamento orfani e lock.
  • Done: output equivalente a Test-CapacityBurnIn.ps1 su Win e Linux.

C3 — bench measure (timing fasi) + retire moduli PS

Sostituisce: Measure-CIBenchmark.ps1 (+ _Common.psm1, _Transport.psm1, tests/_Common.Tests.ps1).

  • Misurare fasi clone / start / IP acquire / transport ready / destroy via load_backend + transport, su 1+ VM effimere.
  • Append a benchmark.jsonl (stesso formato, per continuità trend).
  • Test con backend/transport mockati che simulano i tempi di fase.
  • Rimuovere scripts/_Common.psm1, scripts/_Transport.psm1, tests/_Common.Tests.ps1 (nessun altro consumatore — verificato).
  • Aggiornare lint.yml se elencava esplicitamente quei path.
  • Done: bench measure riproduce le metriche; moduli PS rimossi; pytest verde.

C4 — smoke run

Sostituisce: Test-Smoke.ps1, Test-Ns7zipBuild-Linux.ps1, Test-NsinnounpBuild-Linux.ps1 (e i corrispettivi Win restano per fallback).

  • smoke run esegue un job no-op (marker file) end-to-end e verifica: exit 0, dir artifact creata, evento job-success nel JSONL.
  • --guest-os windows|linux; preset build-command per le build reali ns7zip / nsinnounp (opzionali, dietro flag o --build-command).
  • Test: pipeline mockata, asserzioni su artifact dir + evento.
  • Done: smoke run --guest-os linux e --guest-os windows passano.

C5 — validate host

Nuovo equivalente Linux (non porting 1:1 di Validate-HostState.ps1).

  • Verificare: vmrun presente/eseguibile; snapshot template presenti (BaseClean / BaseClean-Linux); keyring file-based leggibile (keyring.get_credential); permessi /var/lib/ci/...; unit act-runner / ci-* attive (systemctl is-active).
  • Exit 0 = tutto ok; non-zero + report per check fallito.
  • Test: ogni check mockato (pass/fail) → exit code corretto.
  • Done: validate host esce 0 su host configurato.

C6 — creds set + validate guest

Sostituisce: Set-CIGuestCredential.ps1 (host Linux) e Test-CIGuestWinRM.ps1 (parte diagnostica host-side).

  • creds set --target ... --user ... --password-stdin: scrive nel backend keyring letto da ci_orchestrator (keyrings.alt.file.PlaintextKeyring). Password mai su command line.
  • validate guest --host IP [--winrm|--ssh]: tenta connessione + comando banale, riporta causa esplicita su fallimento (la sonda is_ready ingoia gli errori — vedi gotcha).
  • Test: scrittura/lettura credenziale (keyring mockato); diag con transport mockato (connect ok / auth fail / connect fail).
  • Done: credenziali settabili e transport diagnosticabile senza pwsh.

C7 — Lint CI (decisione pwsh)

Risolve dipendenza #5. Applicare l'opzione scelta nel §4 dell'analisi.

  • Decidere: (1) spostare job pssa su runner Windows / on-demand [consigliata]; (2) isolare pwsh nel solo runner di lint; (3) rimuovere PSSA da CI.
  • Aggiornare .gitea/workflows/lint.yml di conseguenza.
  • Verificare che nessun job che gira su runs-on: linux-build invochi più shell: pwsh.
  • Done: pipeline lint verde senza pwsh su runner Linux.

C8 — setup-host-linux.sh

  • Invertire lo step 6: non installare pwsh di default; aggiungere flag --with-pwsh per opt-in (mantenere --skip-pwsh come alias no-op deprecato o rimuoverlo).
  • Aggiornare l'help e gli esempi d'uso nello script.
  • Done: setup-host-linux.sh su host pulito non installa pwsh.

C9 — Docs, cutover, burn-in, disinstallazione

Parte docs completata in codice (2026-06-07). Parte operativa (cutover

  • burn-in di validazione + disinstallazione) resta da eseguire sull'host reale.
  • docs/RUNBOOK.md: aggiunta tabella «Phase C — Python equivalents» + nota che i record §6–§13 restano provenance storica; op-note §13 punto 3 aggiornato.
  • CLAUDE.md: nota "host Linux non usa più pwsh" (constraints PS 5.1 restano per script guest Windows + runner Windows).
  • TODO.md: chiusa voce bug shim $IsWindows (§3.7, risolto-per-rimpiazzo).
  • Cutover (operativo): usare esclusivamente i comandi Python per ≥1 settimana (burn-in bench run periodico + smoke), pwsh ancora installato.
  • Burn-in verde ≥1 settimanasudo apt-get remove powershell sull'host Linux.
  • Riconfermare i criteri "C done" del §7 dell'analisi sull'host reale.
  • Done (codice/docs): porting C1C8 mergeabile, suite verde ≥90%.
  • Done (operativo, pendente): pwsh assente dall'host dopo burn-in verde.

Ordine consigliato e parallelizzabilità

C1 prima di tutto. C2C6 indipendenti tra loro (parallelizzabili in PR separate, ognuna sopra C1). C3 deve precedere la rimozione dei moduli .psm1. C7 e C8 indipendenti dai porting. C9 ultimo, dopo che C2C8 sono merge-ati e il burn-in di validazione è verde.

Rischi

  • WinRM 4× concorrenza instabile (TODO noto): può far fallire bench run su Windows con concorrenza alta — non è regressione del porting. Tarare --concurrency e annotare.
  • Equivalenza output: validare A/B (.ps1 vs Python) finché pwsh è ancora installato (prerequisito §6) prima della disinstallazione in C9.