/var/lib/ci/ is owned by ci-runner; running as simone causes PermissionError on artifact dir creation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
19 KiB
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
systemdper i task periodici) è già committato indeploy/systemd/sul branchfeature/python-rewrite-and-linux-migration(commit50d37b5). Tutti gli altri step (B1–B4, B6–B8) sono operazioni hardware sull'host Linux nuovo e devono essere eseguiti dall'utente.Avanzamento: B1 ✅ B2 ✅ B3 ✅ B4 ✅ — in corso: B5 (timer systemd).
Pre-requisito: la Fase A deve essere
done(vediplans/PhaseA-user-checklist.mdPasso 9, merge + tag). B1, B2, B3 possono partire in parallelo a A3/A4/A5; B4–B8 sono sequenziali e iniziano solo dopo "A done".
Tempo stimato totale: 1–2 giorni di lavoro distribuiti su una finestra di 1–2 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
.bundleda Broadcow):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
vmnet8NAT range192.168.79.0/24(allineato a Windows) editando/etc/vmware/vmnet8/dhcpd/dhcpd.confo viavmware-netcfg. -
Creare utente di servizio
ci-runner:sudo useradd -r -m -s /bin/bash ci-runner -
Eseguire
setup-host-linux.sh(copre mount disco, layout, Python venv, clone repo, PowerShell Core):# Clonare il repo prima di eseguire lo script git clone https://gitea.emulab.it/Simone/local-ci-cd-system.git /tmp/local-ci-cd-system sudo bash /tmp/local-ci-cd-system/setup-host-linux.sh -d /dev/sdf1Lo script:
- Monta
/dev/sdf1su/var/lib/civia fstab (boot automatico). Se la partizione ha una sottocartellaci/, ne sposta i contenuti alla root della partizione prima del mount definitivo. - Crea il layout
build-vms/,artifacts/,templates/,keys/,logs/,runner/con permessi e ACL corretti. - Installa Python 3.11, crea
/opt/ci/venv, clona il repo in/opt/ci/local-ci-cd-systeme installa il package. - Installa PowerShell Core.
Flag utili se alcune dipendenze sono già presenti:
sudo bash setup-host-linux.sh -d /dev/sdf1 --skip-pwsh --skip-cloneAtteso a fine script:
ci_orchestrator --helplista gli 11 sub-comandi. - Monta
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/*.vmsndi runtime.
-
Sull'host Windows:
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 -rlanciato da Windows verso Linux):sudo -u ci-runner rsync -av --progress \ user@windows-host:/cygdrive/f/CI/Templates/ \ /var/lib/ci/templates/ -
Validare integrità snapshot:
find /var/lib/ci/templates -name '*.vmx' -exec vmrun -T ws listSnapshots {} \;Atteso:
BaseCleansuWinBuild2025.vmxeWinBuild2022.vmx,BaseClean-LinuxsuLinuxBuild2404.vmx. -
Aprire ciascun
.vmxsu Workstation Linux per registrarli; al prompt rispondere "I copied it". -
Prerequisito smoke test Windows: il keyring file-based deve essere configurato e la credenziale
BuildVMGuestdeve essere presente prima di eseguirewait-ready(che prova WinRM). Questo è formalmente il Passo 3 (B3), ma il minimo indispensabile per lo smoke test è:# Configurare il backend file keyring per ci-runner (una sola volta) sudo -u ci-runner mkdir -p ~/.local/share/python_keyring sudo -u ci-runner bash -c "cat > ~/.local/share/python_keyring/keyringrc.cfg << 'EOF' [backend] default-keyring=keyrings.alt.file.PlaintextKeyring EOF" sudo -u ci-runner /opt/ci/venv/bin/pip install keyrings.alt -q # Salvare la credenziale guest Windows sudo -u ci-runner /opt/ci/venv/bin/python /opt/ci/local-ci-cd-system/tools/ci-cred-set.py BuildVMGuest "WINBUILD-2025\\ci_build" # Verificare sudo -u ci-runner /opt/ci/venv/bin/python /opt/ci/local-ci-cd-system/tools/ci-cred-check.py BuildVMGuest # atteso: OK (file) username='WINBUILD-2025\ci_build' password=****Il setup completo delle credenziali (chiavi SSH, GiteaPAT, PoC headless systemd) è nel Passo 3.
-
Smoke test pipeline VM:
# Windows smoke CLONE_VMX=$(sudo -u ci-runner /opt/ci/venv/bin/python -m ci_orchestrator vm new \ --template /var/lib/ci/templates/WinBuild2025/WinBuild2025.vmx \ --snapshot BaseClean \ --clone-base-dir /var/lib/ci/build-vms \ --job-id smoke-b2-win \ --start) echo "Clone VMX: $CLONE_VMX" sudo -u ci-runner /opt/ci/venv/bin/python -m ci_orchestrator wait-ready \ --vmx "$CLONE_VMX" --guest-os windows --timeout 300 sudo -u ci-runner /opt/ci/venv/bin/python -m ci_orchestrator vm remove \ --vmx "$CLONE_VMX" --forceRipetere per
LinuxBuild2404(snapshotBaseClean-Linux,--guest-os linux,--job-id smoke-b2-linux).
Passo 3 — Trasferimento credenziali e chiavi (B3)
Obiettivo: chiavi SSH e credenziali guest disponibili al user
ci-runner headless.
-
Chiavi SSH guest Linux già presenti in
/var/lib/ci/keys/(copiate insieme ai template). Correggere solo i permessi:sudo chown ci-runner:ci-runner /var/lib/ci/keys/ci_linux /var/lib/ci/keys/ci_linux.pub sudo chmod 600 /var/lib/ci/keys/ci_linux sudo chmod 644 /var/lib/ci/keys/ci_linux.pub # verifica ls -la /var/lib/ci/keys/ -
Credenziale guest Windows
BuildVMGuestgià salvata nel prerequisito del Passo 2 conkeyrings.alt.file.PlaintextKeyring(schema a due entry —secret-toolscartato perché non funziona headless senza D-Bus session).Per riscrivere la credenziale se necessario:
sudo -u ci-runner /opt/ci/venv/bin/python /opt/ci/local-ci-cd-system/tools/ci-cred-set.py BuildVMGuest "WINBUILD-2025\\ci_build" sudo -u ci-runner /opt/ci/venv/bin/python /opt/ci/local-ci-cd-system/tools/ci-cred-check.py BuildVMGuest -
Re-store Gitea PAT con lo stesso schema:
sudo -u ci-runner /opt/ci/venv/bin/python /opt/ci/local-ci-cd-system/tools/ci-cred-set.py GiteaPAT ci-runner-linux sudo -u ci-runner /opt/ci/venv/bin/python /opt/ci/local-ci-cd-system/tools/ci-cred-check.py GiteaPAT -
PoC headless: il backend
PlaintextKeyringnon usa D-Bus — funziona già dasudo -u ci-runnere funzionerà daact-runner.service. Verificato durante smoke test Passo 2.
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.4:
sudo mkdir -p /opt/ci/act_runner sudo wget -O /opt/ci/act_runner/act_runner \ https://gitea.com/gitea/runner/releases/download/v1.0.4/gitea-runner-1.0.4-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>):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:[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 --config /var/lib/ci/runner/config.yaml Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target -
Creare
/etc/ci/environment(letto dalle unit dei task periodici di B5; vedideploy/systemd/README.md):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
- [x] 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
-
Generare e configurare
config.yamldel runner:# 1. Generare il file di default (conserva la registrazione in .runner) sudo -u ci-runner /opt/ci/act_runner/act_runner generate-config \ | sudo -u ci-runner tee /var/lib/ci/runner/config.yaml > /dev/null # 2. Sostituire i label Docker generati di default con quelli host corretti # (generate-config scrive label ubuntu-*:docker:// che fanno cercare Docker) sudo -u ci-runner sed -i \ -e 's| - "ubuntu-latest:docker://.*"| - "windows-build:host"|' \ -e '/ubuntu-24.04:docker:\/\//d' \ -e '/ubuntu-22.04:docker:\/\//d' \ /var/lib/ci/runner/config.yaml sudo -u ci-runner sed -i \ '/ - "windows-build:host"/a\ - "linux-build:host"' \ /var/lib/ci/runner/config.yaml # 3. Sostituire le variabili di esempio nella sezione runner.envs con le variabili CI # (generate-config scrive due righe A_TEST_ENV_NAME_* come placeholder) sudo -u ci-runner sed -i \ -e 's/ A_TEST_ENV_NAME_1: a_test_env_value_1/ CI_PYTHON_LAUNCHER: \/opt\/ci\/venv\/bin\/python/' \ -e 's/ A_TEST_ENV_NAME_2: a_test_env_value_2/ GITEA_CI_TEMPLATE_PATH: \/var\/lib\/ci\/templates\/WinBuild2025\/WinBuild2025.vmx\n GITEA_CI_LINUX_TEMPLATE_PATH: \/var\/lib\/ci\/templates\/LinuxBuild2404\/LinuxBuild2404.vmx/' \ /var/lib/ci/runner/config.yaml # 4. Verificare grep -A3 'labels:' /var/lib/ci/runner/config.yaml | head -5 grep -A4 'envs:' /var/lib/ci/runner/config.yamlAtteso:
labels: - "windows-build:host" - "linux-build:host" envs: CI_PYTHON_LAUNCHER: /opt/ci/venv/bin/python GITEA_CI_TEMPLATE_PATH: /var/lib/ci/templates/WinBuild2025/WinBuild2025.vmx GITEA_CI_LINUX_TEMPLATE_PATH: /var/lib/ci/templates/LinuxBuild2404/LinuxBuild2404.vmxLe variabili di sistema (
CI_ROOT,PYTHONIOENCODING, ecc.) restano nel service unit.runner.envsè per la configurazione specifica del runner CI (path template, launcher Python).# 5. Ricaricare e riavviare sudo systemctl daemon-reload sudo systemctl restart act-runner.service sudo journalctl -u act-runner -n 20 # confermare avvio OK — nessun errore Docker -
Smoke job: triggerare manualmente
self-test.ymlselezionando il runner Linux (mettere temporaneamente in pausa quello Windows o usare label distinte). Atteso: PASS.⚠️ Prerequisito: le variabili
GITEA_CI_TEMPLATE_PATHeGITEA_CI_LINUX_TEMPLATE_PATHdevono essere presenti nel service unit prima di avviare lo smoke test, altrimenti il job fallisce con "Got unexpected extra argument".
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.
Nota:
ci-retention-policyeci-backup-templatesono stati portati in Python puro (retention run/template backup) — pwsh non è richiesto. I backup template vengono compressi con7z -mx=1in/var/lib/ci/backups/.ci-watch-runner-healthusa--service-name act-runner(nome Linux, non Windows).
Prerequisiti creati sull'host:
sudo mkdir -p /var/log/ci /var/lib/ci/backups sudo chown ci-runner:ci-runner /var/log/ci
-
Copiare le unit:
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:
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:
systemctl list-timers --all 'ci-*'Atteso: 5 timer in stato
active. ✅ PASS -
Trigger manuale di ciascun service per validare l'esecuzione one-shot:
for s in ci-cleanup-orphans ci-retention-policy \ ci-watch-disk-space ci-watch-runner-health \ ci-backup-template; do sudo systemctl start "${s}.service" sudo systemctl status "${s}.service" --no-pager done✅ Tutti e 5 PASS.
-
Per maggiori dettagli (mapping Windows→Linux, troubleshooting, rollback) vedi
deploy/systemd/README.md.
Passo 6 — Cutover (B6)
Obiettivo: passare all'uso normale di Linux come OS primario di produzione CI. Il cutover è un semplice riavvio — i due sistemi non coesistono mai.
⚠️ Eseguire solo dopo che i Passi 1–5 sono tutti
[x]PASS.
-
Verificare nessun job in coda lato Gitea (Admin → Actions → Tasks).
-
Attendere la fine di eventuali job in esecuzione su Windows.
-
Sbloccare il runner Linux su Gitea UI (rimuovere
paused). -
Riavviare la macchina in Linux.
-
Verificare runner Linux online su Gitea UI e act-runner attivo:
sudo systemctl status act-runner sudo journalctl -u act-runner -n 20 -
Smoke trigger:
self-test.yml→ PASS dal runner Linuxbuild-ns7zip.ymlmatrix Win+Linux → PASS dal runner Linux
-
Monitorare per ≥30 min:
sudo journalctl -u act-runner -f
Rollback: riavviare in Windows — il runner Windows riprende automaticamente. Mettere in pausa il runner Linux su Gitea UI, documentare l'incidente in
TODO.md.
Passo 7 — Capacity burn-in (B7)
Obiettivo: validare il carico target con tempi paragonabili al baseline Windows (entro ±20%). I due burn-in sono sequenziali (dual-boot: un OS alla volta).
-
Avviato in Linux — burn-in 4 job concorrenti × 10 round su
WinBuild2025:sudo -u ci-runner pwsh /opt/ci/local-ci-cd-system/scripts/Test-CapacityBurnIn.ps1 \ -Parallelism 4 -Rounds 10 \ -TemplatePath /var/lib/ci/templates/WinBuild2025/WinBuild2025.vmx \ -RepoUrl 'http://10.10.20.11:3100/Simone/nsis-plugin-ns7zip.git' \ -CloneBaseDir /var/lib/ci/build-vms/ \ -ArtifactBaseDir /var/lib/ci/artifacts/ \ -VmrunPath /usr/bin/vmrun -
Avviato in Linux — burn-in 4 × 10 su
LinuxBuild2404:sudo -u ci-runner pwsh /opt/ci/local-ci-cd-system/scripts/Test-CapacityBurnIn.ps1 \ -Parallelism 4 -Rounds 10 \ -TemplatePath /var/lib/ci/templates/LinuxBuild2404/LinuxBuild2404.vmx \ -RepoUrl 'http://10.10.20.11:3100/Simone/nsis-plugin-ns7zip.git' \ -CloneBaseDir /var/lib/ci/build-vms/ \ -ArtifactBaseDir /var/lib/ci/artifacts/ \ -VmrunPath /usr/bin/vmrun \ -GuestOS 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/:sudo -u ci-runner /opt/ci/venv/bin/python -m ci_orchestrator vm cleanup --what-if -
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.mdcon dettagli per profiling (probabile candidato: filesystem ext4 vs NTFS — valutare XFS/BTRFS).
Passo 8 — Stabilità ≥1 settimana
Obiettivo: verificare ≥1 settimana di esercizio con la macchina avviata abitualmente in Linux senza incidenti critici.
-
Esercizio normale per ≥7 giorni con boot in Linux.
-
Verifica giornaliera (bastano 2 minuti):
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 — Gestione dual-boot
La macchina è dual-boot: Windows e Linux coesistono sullo stesso hardware, non girano mai contemporaneamente. Non c'è dismissione — Windows resta pienamente funzionale e si usa riavviando nel boot entry corrispondente.
-
Aggiornare
docs/RUNBOOK.mdcon la procedura dual-boot: come passare da Linux a Windows e viceversa, e cosa verificare al boot (runner online, act-runner.service attivo). -
(Facoltativo) Verificare che GRUB abbia i timeout e i default corretti per l'uso quotidiano:
sudo nano /etc/default/grub # GRUB_DEFAULT, GRUB_TIMEOUT sudo update-grub
Tracciamento globale
| Passo | Step | Descrizione | Stato |
|---|---|---|---|
| 1 | B1 | Setup host Linux Mint (OS, Workstation, venv, ACL) | [x] |
| 2 | B2 | Trasferimento template VM + smoke vm new |
[x] |
| 3 | B3 | Chiavi SSH + keyring (PoC headless) | [x] |
| 4 | B4 | act_runner systemd service + self-test.yml PASS |
[x] |
| 5 | B5 | Timer systemd installati e attivi | [x] |
| 6 | B6 | Cutover (riavvio in Linux, runner Linux attivo) | [ ] |
| 7 | B7 | Capacity burn-in 4 × 10 (Win + Linux, sequenziale) | [ ] |
| 8 | — | ≥1 settimana di stabilità (boot Linux abituale) | [ ] |
| 9 | — | Gestione dual-boot + RUNBOOK aggiornato | [ ] |
Architettura: la macchina è dual-boot (stesso hardware). Avviata in Linux → runner Linux attivo. Avviata in Windows → runner Windows attivo. I due sistemi non girano mai contemporaneamente.
Quando i passi 1-8 sono [x], la Fase B è chiusa (B8 annullato per
vincolo) e si può valutare l'apertura della Fase C (eliminazione pwsh
dall'host Linux, vedi plans/idea-3-powershell-removal.md). La Fase D
(backend ESXi, plans/idea-3-esxi-support.md) viene dopo.