feat(b6): add Phase B user checklist for CI migration to Linux Mint

This commit is contained in:
2026-05-14 18:21:59 +02:00
parent 0bd3b52fb5
commit bd61258a42
+484
View File
@@ -0,0 +1,484 @@
# Fase B — Checklist finale per l'utente
La Fase B è la migrazione del runner CI dall'host Windows attuale a un
nuovo host **Linux Mint LTS** con VMware Workstation Pro Linux.
> **Stato repo**: solo lo step **B5** (unit `systemd` per i task
> periodici) è già committato in `deploy/systemd/` sul branch
> `feature/python-rewrite-phase-a` (commit `50d37b5`).
> Tutti gli altri step (B1B4, B6B8) sono **operazioni hardware**
> sull'host Linux nuovo e devono essere eseguiti dall'utente.
> **Pre-requisito**: la Fase A deve essere `done` (vedi
> `plans/PhaseA-user-checklist.md` Passo 9, merge + tag).
> B1, B2, B3 possono partire in parallelo a A3/A4/A5; B4B8 sono
> sequenziali e iniziano solo dopo "A done".
> **Tempo stimato totale**: 12 giorni di lavoro distribuiti su una
> finestra di 12 settimane (per consentire il burn-in tra B6 e B8).
---
## Passo 1 — Setup host Linux Mint (B1)
**Obiettivo**: hardware target con Linux Mint LTS, VMware Workstation
Pro Linux, layout storage e venv Python pronti.
- [ ] Installare Linux Mint LTS sull'hardware target.
- [ ] `sudo apt update && sudo apt full-upgrade -y && sudo reboot`
- [ ] Scaricare e installare VMware Workstation Pro Linux (bundle
`.bundle` da Broadcow):
```bash
sudo bash VMware-Workstation-Full-*.bundle
vmrun -T ws --version # deve ritornare versione coerente
```
- [ ] Smoke test Workstation (UI): creare VM trivia, clone, start,
stop, delete.
- [ ] Configurare `vmnet8` NAT range `192.168.79.0/24` (allineato a
Windows) editando `/etc/vmware/vmnet8/dhcpd/dhcpd.conf` o via
`vmware-netcfg`.
- [ ] Creare utente di servizio `ci-runner`:
```bash
sudo useradd -r -m -s /bin/bash ci-runner
```
- [ ] Creare layout storage:
```bash
sudo mkdir -p /var/lib/ci/{build-vms,artifacts,templates,keys}
sudo chown -R ci-runner:ci-runner /var/lib/ci
sudo chmod 750 /var/lib/ci /var/lib/ci/*
sudo setfacl -d -m u:ci-runner:rwX /var/lib/ci/build-vms
```
- [ ] Installare Python 3.11+ e creare venv produzione:
```bash
sudo apt install -y python3.11 python3.11-venv git
sudo mkdir -p /opt/ci
sudo python3.11 -m venv /opt/ci/venv
sudo chown -R ci-runner:ci-runner /opt/ci
```
- [ ] Clonare il repo e installare il package nel venv:
```bash
sudo -u ci-runner git clone https://gitea.emulab.it/Simone/local-ci-cd-system.git /opt/ci/local-ci-cd-system
sudo -u ci-runner /opt/ci/venv/bin/pip install -e /opt/ci/local-ci-cd-system
sudo -u ci-runner /opt/ci/venv/bin/python -m ci_orchestrator --help
```
Atteso: lista degli 11 sub-comandi.
- [ ] Installare PowerShell Core (richiesto da `Invoke-RetentionPolicy.ps1`
e `Backup-CITemplate.ps1`):
```bash
sudo apt install -y wget apt-transport-https software-properties-common
source /etc/os-release
wget -q https://packages.microsoft.com/config/ubuntu/${VERSION_ID}/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update && sudo apt install -y powershell
pwsh --version
```
---
## Passo 2 — Trasferimento template VM (B2)
**Obiettivo**: copiare i template VMware da `F:\CI\Templates\` su
`/var/lib/ci/templates/` mantenendo gli snapshot.
> ⚠️ AGENTS.md errore #9: i template devono essere **fully
> powered-off** prima della copia. Verificare assenza di `*.vmem` /
> `*.vmsn` di runtime.
- [ ] Sull'host Windows:
```powershell
Get-ChildItem 'F:\CI\Templates' -Recurse -Include *.vmem,*.vmsn
# atteso: nessun risultato
```
- [ ] Sull'host Linux, eseguire rsync via SSH dall'host Windows
(richiede OpenSSH Server attivo su Windows o, in alternativa,
`scp -r` lanciato da Windows verso Linux):
```bash
sudo -u ci-runner rsync -av --progress \
user@windows-host:/cygdrive/f/CI/Templates/ \
/var/lib/ci/templates/
```
- [ ] Validare integrità snapshot:
```bash
find /var/lib/ci/templates -name '*.vmx' -exec vmrun -T ws listSnapshots {} \;
```
Atteso: `BaseClean` su `WinBuild2025.vmx` e `WinBuild2022.vmx`,
`BaseClean-Linux` su `LinuxBuild2404.vmx`.
- [ ] Aprire ciascun `.vmx` su Workstation Linux per registrarli;
al prompt rispondere "**I copied it**".
- [ ] Smoke test pipeline VM:
```bash
sudo -u ci-runner /opt/ci/venv/bin/python -m ci_orchestrator vm new \
--template /var/lib/ci/templates/WinBuild2025/WinBuild2025.vmx \
--snapshot BaseClean --name smoke-b2-win
sudo -u ci-runner /opt/ci/venv/bin/python -m ci_orchestrator wait-ready \
--vmx /var/lib/ci/build-vms/smoke-b2-win/smoke-b2-win.vmx \
--guest-os windows --timeout 180
sudo -u ci-runner /opt/ci/venv/bin/python -m ci_orchestrator vm remove \
--vmx /var/lib/ci/build-vms/smoke-b2-win/smoke-b2-win.vmx --force
```
Ripetere per `LinuxBuild2404` (snapshot `BaseClean-Linux`,
`--guest-os linux`).
---
## Passo 3 — Trasferimento credenziali e chiavi (B3)
**Obiettivo**: chiavi SSH e credenziali guest disponibili al user
`ci-runner` headless.
- [ ] Copiare le chiavi SSH guest Linux:
```bash
sudo mkdir -p /etc/ci/keys
sudo scp user@windows-host:/cygdrive/f/CI/keys/ci_linux /etc/ci/keys/
sudo scp user@windows-host:/cygdrive/f/CI/keys/ci_linux.pub /etc/ci/keys/
sudo chown ci-runner:ci-runner /etc/ci/keys/*
sudo chmod 600 /etc/ci/keys/ci_linux
sudo chmod 644 /etc/ci/keys/ci_linux.pub
```
- [ ] Re-store credenziale guest Windows (sostituire la password al
prompt — **NON** inserirla in chat o issue):
```bash
sudo -u ci-runner secret-tool store --label='BuildVMGuest' service ci target BuildVMGuest
```
- [ ] Re-store Gitea PAT:
```bash
sudo -u ci-runner secret-tool store --label='GiteaPAT' service ci target GiteaPAT
```
- [ ] Validare lettura interattiva:
```bash
sudo -u ci-runner /opt/ci/venv/bin/python -c \
"import keyring; print(keyring.get_credential('BuildVMGuest', None))"
```
- [ ] **PoC headless** (critico): verificare lettura keyring da
contesto systemd (no D-Bus user session):
```bash
sudo systemd-run --uid=ci-runner --pipe \
/opt/ci/venv/bin/python -c \
"import keyring; print(keyring.get_credential('BuildVMGuest', None))"
```
Se fallisce → implementare backend keyring file-based con `age` o
`sops` come fallback. Documentare la scelta finale in
`docs/HOST-SETUP.md` prima di proseguire.
---
## Passo 4 — Setup act_runner come systemd service (B4)
**Obiettivo**: act_runner Linux registrato verso Gitea, gestito da
systemd.
- [ ] Scaricare il binario act_runner Linux ≥ v1.0.2:
```bash
sudo mkdir -p /opt/ci/act_runner
sudo wget -O /opt/ci/act_runner/act_runner \
https://gitea.com/gitea/act_runner/releases/download/v1.0.2/act_runner-1.0.2-linux-amd64
sudo chmod +x /opt/ci/act_runner/act_runner
sudo chown -R ci-runner:ci-runner /opt/ci/act_runner
```
- [ ] Generare token registrazione su Gitea (Admin → Runners → Create new runner).
- [ ] Registrare il runner (sostituire `<TOKEN>`):
```bash
sudo -u ci-runner mkdir -p /var/lib/ci/runner
cd /var/lib/ci/runner
sudo -u ci-runner /opt/ci/act_runner/act_runner register \
--no-interactive \
--instance https://gitea.emulab.it \
--token <TOKEN> \
--name ci-linux \
--labels windows-build:host,linux-build:host
```
> ⚠️ Lasciare il runner in stato **paused** lato Gitea UI fino al
> cutover (Passo 6), per non intercettare job di produzione.
- [ ] Creare `/etc/systemd/system/act-runner.service`:
```ini
[Unit]
Description=Gitea Act Runner
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=ci-runner
WorkingDirectory=/var/lib/ci/runner
Environment="PYTHONIOENCODING=utf-8"
Environment="CI_ROOT=/var/lib/ci"
Environment="CI_TEMPLATES=/var/lib/ci/templates"
Environment="CI_BUILD_VMS=/var/lib/ci/build-vms"
Environment="CI_ARTIFACTS=/var/lib/ci/artifacts"
Environment="CI_KEYS=/etc/ci/keys"
ExecStart=/opt/ci/act_runner/act_runner daemon
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
```
- [ ] Creare `/etc/ci/environment` (letto dalle unit dei task periodici
di B5; vedi `deploy/systemd/README.md`):
```bash
sudo tee /etc/ci/environment <<'EOF'
PYTHONIOENCODING=utf-8
CI_ROOT=/var/lib/ci
CI_TEMPLATES=/var/lib/ci/templates
CI_BUILD_VMS=/var/lib/ci/build-vms
CI_ARTIFACTS=/var/lib/ci/artifacts
CI_KEYS=/etc/ci/keys
EOF
sudo chmod 644 /etc/ci/environment
```
- [ ] Abilitare e avviare:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now act-runner.service
sudo systemctl status act-runner
sudo journalctl -u act-runner -f # Ctrl+C dopo conferma OK
```
- [ ] Smoke job: triggerare manualmente `self-test.yml` selezionando
il runner Linux (mettere temporaneamente in pausa quello Windows
o usare label distinte). Atteso: PASS.
---
## Passo 5 — Installare i timer systemd (B5)
**Obiettivo**: attivare le coppie `.service`+`.timer` già committate
in `deploy/systemd/` per replicare i task periodici di
`Register-CIScheduledTasks.ps1`.
- [ ] Copiare le unit:
```bash
cd /opt/ci/local-ci-cd-system
sudo cp deploy/systemd/ci-*.service deploy/systemd/ci-*.timer /etc/systemd/system/
sudo systemctl daemon-reload
```
- [ ] Abilitare e avviare tutti i timer:
```bash
for t in ci-cleanup-orphans ci-retention-policy \
ci-watch-disk-space ci-watch-runner-health \
ci-backup-template; do
sudo systemctl enable --now "${t}.timer"
done
```
- [ ] Verificare lo schedule:
```bash
systemctl list-timers --all 'ci-*'
```
Atteso: 5 timer in stato `active`.
- [ ] Trigger manuale di ciascun service per validare l'esecuzione
one-shot:
```bash
for s in ci-cleanup-orphans ci-watch-disk-space ci-watch-runner-health; do
sudo systemctl start "${s}.service"
sudo systemctl status "${s}.service" --no-pager
done
```
> `ci-retention-policy` e `ci-backup-template` chiamano `pwsh`:
> eseguirli solo dopo aver verificato che `pwsh --version` funzioni
> sotto user `ci-runner`.
- [ ] Per maggiori dettagli (mapping Windows→Linux, troubleshooting,
rollback) vedi `deploy/systemd/README.md`.
---
## Passo 6 — Cutover (B6)
**Obiettivo**: spostare la produzione dall'host Windows a Linux in una
finestra di manutenzione concordata.
> ⚠️ Eseguire solo dopo che i Passi 15 sono tutti `[x]` PASS.
- [ ] Annunciare la finestra di manutenzione (durata stimata: 3060 min).
- [ ] Verificare nessun job in coda lato Gitea (Admin → Actions → Tasks).
- [ ] **Stop** act_runner sull'host Windows:
```powershell
Stop-Service actions-runner
Get-Service actions-runner # atteso: Stopped
```
- [ ] **Disabilitare** scheduled task Windows:
```powershell
Get-ScheduledTask -TaskName 'CI-*' | Unregister-ScheduledTask -Confirm:$false
```
- [ ] Rsync incrementale finale degli artifact:
```bash
sudo -u ci-runner rsync -av --delete \
user@windows-host:/cygdrive/f/CI/Artifacts/ \
/var/lib/ci/artifacts/
```
- [ ] Sbloccare il runner Linux su Gitea UI (rimuovere `paused` o
ripristinare le label di produzione `windows-build:host,linux-build:host`).
- [ ] Verificare runner Linux online su Gitea UI.
- [ ] Smoke trigger:
- [ ] `self-test.yml` → PASS dal runner Linux
- [ ] `build-nsInnoUnp.yml` matrix Win+Linux → PASS dal runner Linux
- [ ] Monitorare per ≥30 min:
```bash
sudo journalctl -u act-runner -f --since "30min ago"
```
Nessun errore di severità critica atteso.
> **Rollback (entro 30 min se PASS critico fallisce)**:
> 1. `sudo systemctl stop act-runner` su Linux
> 2. `Start-Service actions-runner` su Windows
> 3. Re-registrare scheduled task con `scripts\Register-CIScheduledTasks.ps1`
> 4. Documentare incidente in `TODO.md` e tornare a B1B5 per fix
---
## Passo 7 — Capacity burn-in (B7)
**Obiettivo**: validare il carico target con tempi paragonabili al
baseline Windows (entro ±20%).
- [ ] Burn-in 4 job concorrenti × 10 round su `WinBuild2025`
(lo script `Test-CapacityBurnIn.ps1` ora delega via shim alla CLI
Python `job` e gira anche da `pwsh` su Linux):
```bash
pwsh /opt/ci/local-ci-cd-system/scripts/Test-CapacityBurnIn.ps1 \
-Concurrency 4 -Rounds 10 -Template /var/lib/ci/templates/WinBuild2025/WinBuild2025.vmx
```
- [ ] Burn-in 4 × 10 su `LinuxBuild2404` (analogo, `--Template`
sul VMX Linux).
- [ ] Misurare:
- [ ] Tempo medio per job, confronto con baseline A5
- [ ] Tutti i 80 job (2 × 4 × 10) PASS
- [ ] Zero VM orfane in `/var/lib/ci/build-vms/`:
```bash
sudo -u ci-runner /opt/ci/venv/bin/python -m ci_orchestrator vm cleanup --dry-run
```
- [ ] Spazio disco `/var/lib/ci/build-vms/` torna al baseline post-cleanup
- [ ] Documentare i risultati in `docs/RUNBOOK.md` (sezione "Linux
host baseline").
- [ ] Se delta > 20% vs baseline Windows: aprire issue in `TODO.md`
con dettagli per profiling (probabile candidato: filesystem ext4
vs NTFS — valutare XFS/BTRFS).
---
## Passo 8 — Stabilità ≥1 settimana (gate per B8)
**Obiettivo**: verificare ≥1 settimana di esercizio Linux senza
incidenti critici prima di dismettere l'host Windows.
- [ ] Esercizio normale per ≥7 giorni con runner Linux primario.
- [ ] Verifica giornaliera (bastano 2 minuti):
```bash
sudo systemctl --failed # nessun service in failed
systemctl list-timers --all 'ci-*' # tutti gli ultimi run OK
sudo journalctl -u act-runner --since "24h ago" -p err
```
- [ ] Nessun rollback effettuato durante la settimana.
---
## Passo 9 — Decommissioning host Windows (B8, opzionale)
> ⚠️ Procedere solo dopo Passo 8 `[x]`. L'host Windows va lasciato
> spento ma intatto per ≥1 mese come rollback.
- [ ] Backup finale di `F:\CI\` su archivio esterno:
```powershell
$stamp = Get-Date -Format 'yyyyMMdd'
$archive = "E:\Backup\CI-$stamp.tar"
& 'C:\Program Files\Git\usr\bin\tar.exe' -cf $archive 'F:\CI\'
Get-FileHash $archive -Algorithm SHA256 | Tee-Object "$archive.sha256"
```
- [ ] Verifica integrità (estrazione di prova in tmp):
```powershell
$test = "$env:TEMP\ci-restore-test"
& 'C:\Program Files\Git\usr\bin\tar.exe' -tf $archive | Select-Object -First 20
```
- [ ] Spegnere host Windows (`shutdown /s /t 0`).
- [ ] Lasciare hardware integro e spento per ≥1 mese.
- [ ] Aggiornare `docs/RUNBOOK.md` con la procedura di riaccensione +
ri-registrazione scheduled task come rollback.
- [ ] Dopo 1 mese senza rollback: riallocare hardware.
---
## Tracciamento globale
| Passo | Step | Descrizione | Stato |
| ----- | ---- | -------------------------------------------------- | ----- |
| 1 | B1 | Setup host Linux Mint (OS, Workstation, venv, ACL) | [ ] |
| 2 | B2 | Trasferimento template VM + smoke `vm new` | [ ] |
| 3 | B3 | Chiavi SSH + keyring (PoC headless) | [ ] |
| 4 | B4 | act_runner systemd service registrato | [ ] |
| 5 | B5 | Timer systemd installati e attivi | [ ] |
| 6 | B6 | Cutover (stop Windows, runner Linux primario) | [ ] |
| 7 | B7 | Capacity burn-in 4 × 10 (Win + Linux) | [ ] |
| 8 | — | ≥1 settimana di stabilità senza rollback | [ ] |
| 9 | B8 | Decommissioning host Windows (opzionale) | [ ] |
Quando tutti i passi sono `[x]`, la **Fase B è chiusa** e si può
valutare l'apertura della Fase C (backend ESXi, vedi
`plans/idea-3-esxi-support.md`).