docs: update documentation for Linux VM support (Sprint 9)

AGENTS.md (new):
- Environment reference for AI agents: host specs, PS 5.1 constraints,
  dir structure, VM templates, transport layer, style rules
- Lessons #9 (snapshot cold state) and #10 (vmrun list vs getGuestIPAddress)

ARCHITECTURE.md:
- Add SSH/SCP transport section (Linux VMs)
- Update system diagram to include _Transport.psm1, SSH transport path
- Network layout: add SSH port 22 for Linux VMs
- Timeline: Linux readiness check phases documented

CI-FLOW.md:
- Prerequisites table: add Template VM (Linux), SSH key row
- Step 6 (readiness): document Windows vs Linux phases
- Step 7 (build) and Step 8 (artifacts): document Linux/SSH paths
- ci-report-ip guestinfo mechanism referenced

HOST-SETUP.md:
- Directory tree: add LinuxBuild2404 template dir and keys/
- Post-setup checklist: add step 5 (SSH key generation + Linux template)
- Fix duplicate step numbering (56, 67)
- Reference Paths table: add Linux template VMX, snapshot, SSH key

LINUX-TEMPLATE-SETUP.md:
- Rewritten as implementation record (no longer a plan)
- Fase A user-data: minimal (user+SSH key only, no packages/runcmd)
- All phases marked complete with actual paths and snapshot names

WINDOWS-TEMPLATE-SETUP.md: minor updates for consistency

TODO.md:
- Summary: update last-updated to 2026-05-11, Sprint 9 description
- Linux Build VM row: all 5 items complete
- Prossimi passi: Test Plan + §6.6 Tier-2 as next priorities
This commit is contained in:
Simone
2026-05-11 18:35:11 +02:00
parent 383d6864ce
commit 1c8fdcf028
7 changed files with 376 additions and 165 deletions
+56 -56
View File
@@ -11,16 +11,16 @@ credenziali archiviate, ISO Windows Server presente).
## Architettura: tre script
| Script | Dove gira | Scopo |
| ---------------------------------------- | --------------- | ------------------------------------------------------------------- |
| `template/Deploy-WinBuild2025.ps1` | **Host** | Opzionale: crea VM e installa Windows Server 2025 unattended da ISO |
| `template/Prepare-WinBuild2025.ps1` | **Host** | Orchestratore: copia + esegue Setup nel guest via WinRM (2025) |
| `template/Setup-WinBuild2025.ps1` | **Dentro VM** | CI toolchain (user, .NET, Python, VS) + validazione hardening Deploy |
| `template/Deploy-WinBuild2022.ps1` | **Host** | Opzionale: crea VM e installa Windows Server 2022 unattended da ISO |
| `template/Prepare-WinBuild2022.ps1` | **Host** | Orchestratore: copia + esegue Setup nel guest via WinRM (2022) |
| `template/Setup-WinBuild2022.ps1` | **Dentro VM** | CI toolchain per Windows Server 2022 (stesso flusso del 2025) |
| `template/Validate-DeployState.ps1` | **Host** | Valida stato post-Deploy prima di eseguire Prepare (2025 e 2022) |
| `template/Validate-SetupState.ps1` | **Host** | Valida stato post-Setup (Deploy + Setup) prima dello snapshot |
| Script | Dove gira | Scopo |
| ----------------------------------- | ------------- | -------------------------------------------------------------------- |
| `template/Deploy-WinBuild2025.ps1` | **Host** | Opzionale: crea VM e installa Windows Server 2025 unattended da ISO |
| `template/Prepare-WinBuild2025.ps1` | **Host** | Orchestratore: copia + esegue Setup nel guest via WinRM (2025) |
| `template/Setup-WinBuild2025.ps1` | **Dentro VM** | CI toolchain (user, .NET, Python, VS) + validazione hardening Deploy |
| `template/Deploy-WinBuild2022.ps1` | **Host** | Opzionale: crea VM e installa Windows Server 2022 unattended da ISO |
| `template/Prepare-WinBuild2022.ps1` | **Host** | Orchestratore: copia + esegue Setup nel guest via WinRM (2022) |
| `template/Setup-WinBuild2022.ps1` | **Dentro VM** | CI toolchain per Windows Server 2022 (stesso flusso del 2025) |
| `template/Validate-DeployState.ps1` | **Host** | Valida stato post-Deploy prima di eseguire Prepare (2025 e 2022) |
| `template/Validate-SetupState.ps1` | **Host** | Valida stato post-Setup (Deploy + Setup) prima dello snapshot |
**Confine Deploy / Setup** (refactor §7, 2026-05-10):
- `Deploy-WinBuild2025.ps1` si occupa dell'**OS hardening** (Firewall, WinRM, UAC, Defender, UX tweaks, autologin Administrator, WU GPO locks). Se usato, Setup valida questi come Assert-Step senza re-applicarli.
@@ -33,15 +33,15 @@ credenziali archiviate, ISO Windows Server presente).
## Specifiche VM
| Parametro | Valore |
| ----------------------- | --------------------------------------------------------------- |
| OS | Windows Server 2025 Standard/Datacenter (Core o Desktop OK) |
| vCPU | 4 |
| RAM | 6144 MB (6 GB) |
| Disco | 80 GB thin provisioned |
| NIC | **VMnet8 (NAT)** — internet richiesto per WU + installer |
| VMX path | `F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` |
| ISO | Windows Server 2025 (da `F:\CI\ISO\`) |
| Parametro | Valore |
| --------- | ----------------------------------------------------------- |
| OS | Windows Server 2025 Standard/Datacenter (Core o Desktop OK) |
| vCPU | 4 |
| RAM | 6144 MB (6 GB) |
| Disco | 80 GB thin provisioned |
| NIC | **VMnet8 (NAT)** — internet richiesto per WU + installer |
| VMX path | `F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` |
| ISO | Windows Server 2025 (da `F:\CI\ISO\`) |
---
@@ -137,17 +137,17 @@ Ogni step ha validazione `Assert-Step` (throw on failure, `[OK]` su pass):
### Parametri principali
| Parametro | Default | Note |
| --------------------- | -------------- | ----------------------------------------------------------------------------- |
| `-VMIPAddress` | (mandatory) | IP DHCP della VM su VMnet8 |
| `-AdminUsername` | Administrator | Account admin built-in nella VM |
| `-AdminPassword` | (prompt) | Se vuoto, prompt SecureString |
| `-BuildPassword` | (prompt) | Password per `ci_build` — mai hard-codare |
| `-BuildUsername` | ci_build | Account CI dentro la VM |
| `-DotNetSdkVersion` | 10.0 | Channel .NET SDK |
| `-SkipWindowsUpdate` | (off) | Pass-through a Setup-WinBuild2025.ps1 |
| `-StoreCredential` | (off) | Registra `BuildUsername`/`BuildPassword` in Windows Credential Manager |
| `-CredentialTarget` | BuildVMGuest | Target Credential Manager (deve corrispondere a quanto usato da Invoke-CIJob) |
| Parametro | Default | Note |
| -------------------- | ------------- | ----------------------------------------------------------------------------- |
| `-VMIPAddress` | (mandatory) | IP DHCP della VM su VMnet8 |
| `-AdminUsername` | Administrator | Account admin built-in nella VM |
| `-AdminPassword` | (prompt) | Se vuoto, prompt SecureString |
| `-BuildPassword` | (prompt) | Password per `ci_build` — mai hard-codare |
| `-BuildUsername` | ci_build | Account CI dentro la VM |
| `-DotNetSdkVersion` | 10.0 | Channel .NET SDK |
| `-SkipWindowsUpdate` | (off) | Pass-through a Setup-WinBuild2025.ps1 |
| `-StoreCredential` | (off) | Registra `BuildUsername`/`BuildPassword` in Windows Credential Manager |
| `-CredentialTarget` | BuildVMGuest | Target Credential Manager (deve corrispondere a quanto usato da Invoke-CIJob) |
---
@@ -193,23 +193,23 @@ Final Pre-snapshot gate — 7 check cross-cutting + no installer leftover
### Validazioni per step (sintesi)
| Step | Natura | Check chiave |
| ---- | ---------- | ------------------------------------------------------------------------------ |
| 1 | Assert | `Get-NetFirewallProfile -Profile Domain/Private/Public → Enabled=False` |
| 2 | Assert | GPO DisableAntiSpyware=1 (set da Deploy) |
| 3 | Assert | WinRM Running+Automatic, AllowUnencrypted=false (HTTPS-only), Auth/Basic=true, MaxMem≥2048 |
| 4 | Operativo | User exists, enabled, PasswordNeverExpires, member of Administrators |
| 4b | Assert | EnableLUA=0, LocalAccountTokenFilterPolicy=1 |
| 5 | Operativo | Ogni dir Test-Path -PathType Container |
| 5b | Assert | HKCU LaunchTo=1 |
| 5c | Assert+Op | NoLockScreen=1, SM policy DoNotOpenAtLogon=1, SM task Disabled, DisableCAD=1, OOBE DisablePrivacyExperience=1, AllowTelemetry=0; AutoAdminLogon=1+DefaultUserName=Administrator re-affermati se assenti (Windows OOBE può resettarli al primo boot) |
| 6 | Operativo | ResultCode ∈ {0,2,3}, no reboot required (else exit 3010) |
| 6b | Operativo | wuauserv StartType=Disabled, NoAutoUpdate=1, DisableWindowsUpdateAccess=1 |
| 7 | Operativo | `dotnet --version` channel match, machine PATH contiene `C:\dotnet` |
| 8 | Operativo | `C:\Python\python.exe` esiste, version match esatto, PATH contiene `C:\Python` |
| 9 | Operativo | MSBuild.exe esiste, esegue, PATH, `\VC\` dir presente |
| 10 | Operativo | dotnet+python+msbuild tutti risolvibili (throw) |
| Final| Cross-cut | WinRM, firewall, user+admin, UAC, WU disabled, tutti tool, no leftover installer in `C:\CI` |
| Step | Natura | Check chiave |
| ----- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Assert | `Get-NetFirewallProfile -Profile Domain/Private/Public → Enabled=False` |
| 2 | Assert | GPO DisableAntiSpyware=1 (set da Deploy) |
| 3 | Assert | WinRM Running+Automatic, AllowUnencrypted=false (HTTPS-only), Auth/Basic=true, MaxMem≥2048 |
| 4 | Operativo | User exists, enabled, PasswordNeverExpires, member of Administrators |
| 4b | Assert | EnableLUA=0, LocalAccountTokenFilterPolicy=1 |
| 5 | Operativo | Ogni dir Test-Path -PathType Container |
| 5b | Assert | HKCU LaunchTo=1 |
| 5c | Assert+Op | NoLockScreen=1, SM policy DoNotOpenAtLogon=1, SM task Disabled, DisableCAD=1, OOBE DisablePrivacyExperience=1, AllowTelemetry=0; AutoAdminLogon=1+DefaultUserName=Administrator re-affermati se assenti (Windows OOBE può resettarli al primo boot) |
| 6 | Operativo | ResultCode ∈ {0,2,3}, no reboot required (else exit 3010) |
| 6b | Operativo | wuauserv StartType=Disabled, NoAutoUpdate=1, DisableWindowsUpdateAccess=1 |
| 7 | Operativo | `dotnet --version` channel match, machine PATH contiene `C:\dotnet` |
| 8 | Operativo | `C:\Python\python.exe` esiste, version match esatto, PATH contiene `C:\Python` |
| 9 | Operativo | MSBuild.exe esiste, esegue, PATH, `\VC\` dir presente |
| 10 | Operativo | dotnet+python+msbuild tutti risolvibili (throw) |
| Final | Cross-cut | WinRM, firewall, user+admin, UAC, WU disabled, tutti tool, no leftover installer in `C:\CI` |
---
@@ -292,15 +292,15 @@ toolchain (.NET, VS Build Tools, Python).
## Troubleshooting
| Sintomo | Diagnosi / Fix |
| ------------------------------------------- | ----------------------------------------------------------------------- |
| `Cannot reach $VMIPAddress via WinRM` | VM non avviata, WinRM non abilitato, IP errato — verifica con ipconfig |
| `Setup-WinBuild2025.ps1 exited with code 3010`| Reboot richiesto post-WU. Re-run con `-SkipWindowsUpdate` |
| `[Defender] Validation failed: GPO key` | Defender riattivato da Windows Update — disabilita via gpedit + reboot |
| `VS Build Tools installation timed out` | Network slow o cache corrotta. Re-run con cache pulita (`C:\ProgramData\Microsoft\VisualStudio\Packages`) |
| `Python version match` fail | `$PythonVersion` ≠ versione installata. Aggiorna param o reinstalla |
| Post-setup `MSBuild not found` | VS install fallita silenziosa. Check `C:\CI\vs_log.txt` |
| Pre-snapshot Final check fail | Stato VM rotto — non prendere snapshot. Re-run o ricomincia da zero |
| Sintomo | Diagnosi / Fix |
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `Cannot reach $VMIPAddress via WinRM` | VM non avviata, WinRM non abilitato, IP errato — verifica con ipconfig |
| `Setup-WinBuild2025.ps1 exited with code 3010` | Reboot richiesto post-WU. Re-run con `-SkipWindowsUpdate` |
| `[Defender] Validation failed: GPO key` | Defender riattivato da Windows Update — disabilita via gpedit + reboot |
| `VS Build Tools installation timed out` | Network slow o cache corrotta. Re-run con cache pulita (`C:\ProgramData\Microsoft\VisualStudio\Packages`) |
| `Python version match` fail | `$PythonVersion` ≠ versione installata. Aggiorna param o reinstalla |
| Post-setup `MSBuild not found` | VS install fallita silenziosa. Check `C:\CI\vs_log.txt` |
| Pre-snapshot Final check fail | Stato VM rotto — non prendere snapshot. Re-run o ricomincia da zero |
---