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>
This commit is contained in:
@@ -1,103 +1,198 @@
|
||||
# Fase C — Eliminazione dipendenza PowerShell dall'host Linux
|
||||
|
||||
> **Stato**: **pianificata**, da avviare dopo che Fase B è stabile in
|
||||
> produzione (≥1 settimana di burn-in, Passo 8 completato).
|
||||
> Vedi [overview](ideas-overview.md).
|
||||
> **Stato**: **codice completato** (C1–C8 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](ideas-overview.md) e il
|
||||
> [piano di applicazione](idea-3-implementation-plan.md) (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)
|
||||
è già Python puro. Rimangono script PS usati per test manuali, burn-in e
|
||||
validazione host che richiedono `pwsh` installato.
|
||||
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; `pwsh` può essere disinstallato senza
|
||||
impatti operativi. I `.ps1` rimangono nel repo come riferimento storico
|
||||
e per il runner Windows (fallback dual-boot).
|
||||
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. Script da portare
|
||||
## 2. Superficie `pwsh` reale sull'host Linux
|
||||
|
||||
| Script PS | Uso attuale (Linux host) | Target Python |
|
||||
| ---------------------------- | -------------------------------- | -------------------------------------------------------- |
|
||||
| `Test-CapacityBurnIn.ps1` | burn-in B7: 4 job × 10 round | `python -m ci_orchestrator bench run` |
|
||||
| `Start-BurnInTest.ps1` | burn-in Windows single-shot | `python -m ci_orchestrator bench run --guest-os windows` |
|
||||
| `Start-BurnInTest-Linux.ps1` | burn-in Linux single-shot | `python -m ci_orchestrator bench run --guest-os linux` |
|
||||
| `Validate-HostState.ps1` | verifica stato host pre-cutover | `python -m ci_orchestrator validate host` |
|
||||
| `Measure-CIBenchmark.ps1` | raccolta metriche timing | integrato in `bench run --collect-metrics` |
|
||||
| `Test-Smoke.ps1` | smoke end-to-end manuale | `python -m ci_orchestrator smoke run` |
|
||||
| `Test-CapacityBurnIn.ps1` | già referenziato in B7 checklist | vedi sopra |
|
||||
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.
|
||||
|
||||
Script **non da portare** (girano solo su Windows o sono già shim):
|
||||
- `Register-CIScheduledTasks.ps1` — Windows Scheduler, non serve su Linux
|
||||
- `Invoke-RetentionPolicy.ps1` / `Backup-CITemplate.ps1` — già portati in B5
|
||||
- Tutti gli script shim in `scripts/` — 3 righe che chiamano Python, restano
|
||||
- Script guest (`Install-CIToolchain-*.ps1`, `Prepare-*.ps1`, ecc.) — girano
|
||||
dentro le VM Windows, non sull'host
|
||||
### 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, 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 sub-comandi CLI sotto due nuovi gruppi:
|
||||
## 3. Architettura prevista (nuovi gruppi CLI)
|
||||
|
||||
```
|
||||
python -m ci_orchestrator bench run --guest-os windows|linux
|
||||
--template <path>
|
||||
--concurrency N
|
||||
--rounds N
|
||||
--collect-metrics
|
||||
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 validate host # verifica stato host
|
||||
python -m ci_orchestrator smoke run # end-to-end smoke test
|
||||
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]
|
||||
```
|
||||
|
||||
Il gruppo `bench` sostituisce i tre script `*BurnIn*.ps1` con logica
|
||||
unificata: avvia N clone in parallelo, misura tempo per job, confronta
|
||||
con baseline, emette un report JSON in `CI_ARTIFACTS/bench/`.
|
||||
- **`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`.
|
||||
|
||||
Il gruppo `validate` porta `Validate-HostState.ps1`: verifica vmrun,
|
||||
template snapshot, credenziali, permessi directory, act-runner attivo.
|
||||
**Vincolo di design**: i nuovi comandi devono importare
|
||||
`backends.load_backend` e i transport esistenti, **mai**
|
||||
`WorkstationVmrunBackend` diretto (rotta ESXi Fase D aperta).
|
||||
|
||||
---
|
||||
|
||||
## 4. Aggiornamenti collaterali
|
||||
## 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):
|
||||
sostituire il comando `pwsh Test-CapacityBurnIn.ps1` con
|
||||
`python -m ci_orchestrator bench run`.
|
||||
- `deploy/systemd/README.md`: nessun riferimento a `pwsh`.
|
||||
- `CLAUDE.md`: rimuovere nota "PowerShell 5.1 Constraints" se non più
|
||||
rilevante per l'host (rimane valida per gli script guest Windows).
|
||||
- `docs/RUNBOOK.md`: aggiornare procedure di burn-in e smoke test.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## 5. Prerequisiti
|
||||
## 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).
|
||||
|
||||
---
|
||||
|
||||
## 6. Criteri di "C done"
|
||||
## 7. Criteri di "C done"
|
||||
|
||||
- `python -m ci_orchestrator bench run --concurrency 4 --rounds 10` esegue
|
||||
burn-in completo (Win + Linux) con output equivalente a `Test-CapacityBurnIn.ps1`.
|
||||
- `python -m ci_orchestrator validate host` esce con 0 su host configurato
|
||||
correttamente.
|
||||
- `pwsh --version` può essere assente sull'host Linux senza che nessun
|
||||
test, timer o script CI fallisca.
|
||||
- `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.
|
||||
|
||||
---
|
||||
|
||||
## 7. Rollback
|
||||
## 8. Rollback
|
||||
|
||||
I `.ps1` originali rimangono nel repo e funzionano su host Windows o su
|
||||
Linux con `pwsh` installato. Il rollback è semplicemente reinstallare
|
||||
`pwsh` e usare gli script esistenti.
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user