Files
Simone 425d8bc4f3 docs: align documentation with session fixes
Reconcile docs with the end-to-end pipeline fixes:
- upload/download-artifact @v4 -> @v3 (Gitea GHES) in WORKFLOW-AUTHORING
  and workflow-example.yml; add Common Mistakes rows (v4, action ref
  form + DEFAULT_ACTIONS_URL, public action repo).
- BEST-PRACTICES / README / HOST-SETUP: guest credential must live in
  the LocalSystem vault with a host-qualified username; document
  Set-CIGuestCredential.ps1 / Test-CIGuestWinRM.ps1 and auth=ntlm.
- README / AGENTS / HOST-SETUP: production venv install is NON-editable
  (LocalSystem); no CI workflow may install into it.
- HOST-SETUP: add DEFAULT_ACTIONS_URL=github + full-URL uses: + public
  repo + @main requirements discovered during validation.
- Correct stale repo name local-ci-system -> local-ci-cd-system.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 16:09:15 +02:00

244 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Host Setup — Local CI/CD
Procedura di bootstrap della macchina host Windows (i9-10900X, 64 GB RAM, NVMe).
Eseguire **una volta** prima di qualsiasi provisioning del template VM o esecuzione di job CI.
---
## Prerequisiti host
| Componente | Versione/Note |
| ------------------ | ----------------------------------------------------------------- |
| OS | Windows 11 (host fisico) o Windows Server 2022+ |
| VMware Workstation | Pro 17.x — necessario per `vmrun.exe` e supporto linked clone |
| Storage | NVMe dedicato (consigliato `F:\` riservato a CI, ≥ 500 GB libero) |
| RAM | ≥ 32 GB (4 VM parallele × 6-8 GB) |
| Rete | VMnet8 (NAT) configurato in VMware Workstation |
| PowerShell | 5.1+ (built-in) o 7.x |
| Privilegi | Account amministrativo per Setup-Host.ps1 |
Software opzionali installati on-demand dallo script:
- **NSSM** — installazione automatica via Chocolatey se presente; altrimenti install manuale da https://nssm.cc
- **CredentialManager** module — installato automaticamente (scope CurrentUser)
---
## Directory layout
`Setup-Host.ps1` crea l'intera struttura sotto `$CIRoot` (default `F:\CI\`):
```
F:\CI\
├── BuildVMs\ # cloni temporanei delle VM build (auto-cleanup post-job)
├── Artifacts\ # output build raccolti dall'host
├── Logs\ # log per-job (retention: 30 giorni)
├── Templates\
│ ├── WinBuild2025\ # VMX template Windows (immutabile dopo snapshot)
│ └── LinuxBuild2404\ # VMX template Linux Ubuntu 24.04 (immutabile dopo snapshot)
├── keys\
│ ├── ci_linux # chiave privata SSH per Linux VMs (ed25519, no passphrase)
│ └── ci_linux.pub # chiave pubblica corrispondente
├── config.toml # configurazione Python orchestrator (ssh_key_path, ecc.)
├── act_runner\
│ ├── act_runner.exe # binario runner Gitea
│ ├── config.yaml # config runner (path, label, capacity)
│ └── logs\ # stdout/stderr del servizio
├── Cache\
│ └── NuGet\ # cache NuGet condivisa via shared folder (§3.1 — DONE 2026-05-10, vedi scripts/Set-TemplateSharedFolders.ps1)
├── RunnerWork\ # working dir di act_runner (job staging)
└── ISO\ # ISO di installazione (Windows Server 2025, ecc.)
```
---
## Procedura — esecuzione
### Step 1 — Clonare il repository
```powershell
git clone https://gitea.emulab.it/Simone/Local-CI-CD-System.git N:\Code\Workspace\Local-CI-CD-System
cd N:\Code\Workspace\Local-CI-CD-System
```
### Step 2 — Eseguire Setup-Host.ps1 (elevato)
Apri PowerShell **come Administrator**, poi:
```powershell
# Esecuzione minimale (crea dirs, archivia credenziali, salta install runner)
.\Setup-Host.ps1 -SkipRunnerInstall
# Setup completo con registrazione runner
.\Setup-Host.ps1 -GiteaRunnerToken 'abc123token'
# CI root su drive diverso
.\Setup-Host.ps1 -CIRoot 'D:\CI' -GiteaRunnerToken 'abc123token'
```
### Cosa fa Setup-Host.ps1 — passo per passo
1. **Crea albero directory** sotto `$CIRoot` (vedi layout sopra)
2. **Verifica VMware Workstation** — controlla presenza di `C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe`
3. **Installa modulo CredentialManager** (scope CurrentUser, se non presente)
4. **Archivia credenziali guest VM** in Windows Credential Manager (target `BuildVMGuest`)
- Se non passa `-GuestPassword`, prompt interattivo (SecureString)
- Se credenziale già esistente, non sovrascrive — istruzioni per update
5. **Copia `runner/config.yaml`** in `$CIRoot\act_runner\config.yaml` (se non esistente)
6. **Installa act_runner come servizio Windows** via NSSM:
- Verifica presenza NSSM in PATH; tenta install via `choco install nssm -y`
- Registra runner con Gitea (`act_runner register --no-interactive --instance ... --token ... --name local-windows-runner --labels windows-build:host,dotnet:host,msbuild:host`) se token fornito
- Crea servizio: `AppDirectory`, `AppParameters daemon --config <path>`, log rotation 10 MB
- Avvia servizio (`SERVICE_AUTO_START`)
7. **Configura SSH alias `gitea-ci`** in `~/.ssh/config` (HostName, Port, User git)
### Note operative (scoperte in validazione end-to-end)
Setup-Host.ps1 da solo **non basta** per la pipeline Python su runner
LocalSystem. Dopo Setup-Host:
- **Credenziale guest nel vault SYSTEM, username host-qualificato.** Lo
step 4 scrive in Windows Credential Manager dell'utente interattivo →
invisibile ad act_runner (LocalSystem). Esegui (elevato):
`\.\scripts\Set-CIGuestCredential.ps1 -UserName 'WINBUILD-2025\ci_build'`.
Bare `ci_build` viene rifiutato da NTLM (`SEC_E_UNKNOWN_CREDENTIALS`):
usa il computer name del guest (= CN del cert WinRM). Diagnostica:
`\.\scripts\Test-CIGuestWinRM.ps1 -IpAddress <guest-ip>`.
- **venv di produzione = install non-editable.** Popola
`F:\CI\python\venv` con `python -m pip install .` dal repo reale —
**mai** `pip install -e .` (il `.pth` punta a un path che LocalSystem
non risolve → `No module named ci_orchestrator`). Vedi
`plans/PhaseA-user-checklist.md` Passo 1. Nessun workflow CI deve
installare in quel venv (lint usa un venv effimero per-job).
- **Gitea `app.ini`:** imposta `[actions] DEFAULT_ACTIONS_URL = github`
e referenzia l'action col **URL completo**
(`https://gitea.emulab.it/Simone/local-ci-cd-system/.gitea/actions/local-ci-build@main`)
così le action GitHub (checkout, upload-artifact) restano risolvibili
e l'action locale punta all'istanza. Il repo `local-ci-cd-system` deve
essere **pubblico** (il runner clona l'action senza autenticazione) e
l'action deve esistere su `@main` (il ref che il runner clona).
---
## Parametri principali
| Parametro | Default | Note |
| ------------------------ | ------------------------------------ | ------------------------------------- |
| `-CIRoot` | `F:\CI` | Base directory per tutti i dati CI |
| `-GuestCredentialTarget` | `BuildVMGuest` | Target Credential Manager |
| `-GuestUsername` | `ci_build` | Account build dentro la VM |
| `-GuestPassword` | (prompt) | Mai hard-codare |
| `-ActRunnerExe` | `<CIRoot>\act_runner\act_runner.exe` | Path binario runner |
| `-ActRunnerConfigYaml` | `<repo>\runner\config.yaml` | Source del config da copiare |
| `-GiteaUrl` | `http://10.10.20.11:3100` | URL Gitea per registrazione |
| `-GiteaRunnerToken` | (vuoto) | Token registrazione (Admin → Runners) |
| `-SkipRunnerInstall` | `$false` | Salta installazione servizio |
| `-SkipSSHConfig` | `$false` | Salta scrittura SSH alias |
| `-GiteaSSHHost` | `10.10.20.11` | Hostname SSH Gitea |
| `-GiteaSSHPort` | `2222` | Porta SSH Gitea |
---
## Post-setup checklist
Allo `Setup-Host.ps1` exit 0:
1. **Posiziona binario act_runner** se non già fatto:
- Path: `F:\CI\act_runner\act_runner.exe`
- Download: https://gitea.com/gitea/act_runner/releases/tag/v1.0.2
2. **Posiziona ISO Windows Server 2025** in `F:\CI\ISO\`
(es. `26100.1742.240906-0331.ge_release_svc_refresh_SERVER_VOL_x64FRE_en-us.iso`)
3. **Configura host WinRM client** (necessario per Prepare-WinBuild2025.ps1):
```powershell
# AllowUnencrypted non serve — Prepare usa HTTPS/5986 (nessun testo in chiaro)
Set-Item WSMan:\localhost\Client\TrustedHosts -Value '192.168.79.*' -Force -Concatenate
```
*Note*: Prepare-WinBuild2025.ps1 aggiunge l'IP specifico della VM in modo transitorio e lo ripristina nel `finally`.
4. **Provisiona il template VM Windows** — vedi [WINDOWS-TEMPLATE-SETUP.md](WINDOWS-TEMPLATE-SETUP.md)
5. **(Opzionale) Genera chiave SSH CI per Linux VMs** — necessaria solo se si vuole usare `linux-build`:
```powershell
New-Item -ItemType Directory -Force F:\CI\keys | Out-Null
ssh-keygen -t ed25519 -f F:\CI\keys\ci_linux -N '""' -C 'ci-linux-runner'
# Risultato: F:\CI\keys\ci_linux (privata) + F:\CI\keys\ci_linux.pub (pubblica)
```
Poi **provisiona il template VM Linux** — vedi [LINUX-TEMPLATE-SETUP.md](LINUX-TEMPLATE-SETUP.md)
6. **Crea `F:\CI\config.toml`** — necessario affinché il Python orchestrator trovi la chiave SSH e le altre impostazioni:
```powershell
Copy-Item N:\Code\Workspace\Local-CI-CD-System\config.example.toml F:\CI\config.toml
```
Il file `config.example.toml` contiene già i path corretti per Windows (`F:\CI\...`). Modificare solo se si usa un `$CIRoot` diverso da `F:\CI`.
Valori chiave configurati:
| Chiave | Valore default | Scopo |
| -------------------- | ----------------------- | -------------------------------------------- |
| `ssh_key_path` | `F:/CI/keys/ci_linux` | Chiave privata per SSH verso Linux guest |
| `guest_cred_target` | `BuildVMGuest` | Target Windows Credential Manager (WinRM) |
| `backend.type` | `workstation` | Backend VMware (solo `workstation` in Phase A) |
Le variabili d'ambiente `CI_SSH_KEY_PATH`, `CI_VMRUN_PATH`, `CI_GUEST_CRED_TARGET` sovrascrivono i valori del TOML se presenti.
6. **Registra chiave SSH con Gitea**:
- Gitea UI → User Settings → SSH Keys → Add Key
- Chiave pubblica: `%USERPROFILE%\.ssh\id_rsa.pub`
7. **Verifica runner online** in Gitea:
- `<GiteaUrl>/-/admin/runners`
- Status atteso: **Online**, label `windows-build:host,dotnet:host,msbuild:host`
---
## Reference Paths
| Item | Path / Value |
| ------------------------- | ------------------------------------------------------------ |
| vmrun.exe | `C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe` |
| act_runner exe | `F:\CI\act_runner\act_runner.exe` (servizio: `act_runner`) |
| act_runner config | `F:\CI\act_runner\config.yaml` |
| act_runner logs | `F:\CI\act_runner\logs\` (stdout.log, stderr.log) |
| Template VMX (Windows) | `F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` |
| Template VMX (Linux) | `F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx` |
| Snapshot name (Windows) | `BaseClean` |
| Snapshot name (Linux) | `BaseClean-Linux` |
| SSH key (Linux VMs) | `F:\CI\keys\ci_linux` (privata), `F:\CI\keys\ci_linux.pub` |
| Orchestrator config TOML | `F:\CI\config.toml` (copia di `config.example.toml`) |
| Clone base dir | `F:\CI\BuildVMs\` |
| Artifact dir | `F:\CI\Artifacts\` |
| Log dir | `F:\CI\Logs\` (retention: 30 giorni) |
| Gitea URL (LAN) | `http://10.10.20.11:3100` |
| Gitea URL (ext) | `https://gitea.emulab.it` |
| Runner name | `local-windows-runner` (ID: 1) |
| Build VM subnet | `192.168.79.0/24` (VMnet8 — NAT, internet access per build) |
| Credential Manager target | `BuildVMGuest` |
| Guest username | `ci_build` |
---
## Maintenance & operational tasks
Task schedulati (vedi `scripts/Register-CIScheduledTasks.ps1` per il bootstrap):
- **§2.2** Cleanup VM orfane (`scripts/Cleanup-OrphanedBuildVMs.ps1`, ogni 6h, `-MaxAgeHours 4`)
- **§2.3** Retention artifact + log (`scripts/Invoke-RetentionPolicy.ps1`, daily)
- **§2.6** Backup template (`scripts/Backup-CITemplate.ps1`, weekly)
- **§2.7** Health check runner (`scripts/Watch-RunnerHealth.ps1`, ogni 15 min)
- **§4.3** Disk space alert (`scripts/Watch-DiskSpace.ps1`, ogni ora)
---
## Troubleshooting
| Sintomo | Diagnosi / Fix |
| ------------------------------- | ---------------------------------------------------------------- |
| `vmrun.exe NOT found` | Installa VMware Workstation Pro, riesegui |
| `NSSM not available` | Install manuale da https://nssm.cc, aggiungi a PATH, riesegui |
| Runner registration `exit != 0` | Verifica token Gitea + URL raggiungibile da host |
| Service `act_runner` non parte | Check `F:\CI\act_runner\logs\stderr.log` |
| `New-StoredCredential` fail | Verifica modulo CredentialManager importato + scope corretto |
| Job CI fallisce su `Test-WSMan` | TrustedHosts host non include subnet VM, AllowUnencrypted=$false |
| `wait-ready` SSH: `No authentication methods available` | `F:\CI\config.toml` mancante o `ssh_key_path` non configurato. Crea il file (vedi step 6) oppure passa `--ssh-key-path F:\CI\keys\ci_linux` |