# B5 — Closeout (parziale: artefatti repo) Fase B5 di `plans/implementation-plan-A-B.md`: conversione scheduled task Windows in coppie `*.service` + `*.timer` systemd su Linux. ## Cosa è stato fatto in questa sessione (su host Windows dev) - [x] Inventario dei 4 task in `scripts/Register-CIScheduledTasks.ps1` (cadenze + comandi) - [x] 5 coppie `*.service` + `*.timer` create in `deploy/systemd/`: - `ci-cleanup-orphans.{service,timer}` — every 6h + at boot → `python -m ci_orchestrator vm cleanup --max-age-hours 6` - `ci-retention-policy.{service,timer}` — daily 03:00 + 30min jitter → `pwsh Invoke-RetentionPolicy.ps1` - `ci-watch-disk-space.{service,timer}` — every 15min → `python -m ci_orchestrator monitor disk` - `ci-watch-runner-health.{service,timer}` — every 15min → `python -m ci_orchestrator monitor runner` - `ci-backup-template.{service,timer}` — weekly Sun 02:00 + 1h jitter → `pwsh Backup-CITemplate.ps1` (NEW, non era in Register-CIScheduledTasks.ps1) - [x] `deploy/systemd/README.md` con: tabella mapping, prerequisiti (utente, venv, env file), istruzioni install/test/rollback, nota PowerShell Core su Linux ## Note sulle cadenze Le cadenze del piano (`OnCalendar=hourly`, `*:0/15`, ecc.) sono state adattate per fedeltà semantica all'originale Windows: | Task | Original Windows | systemd timer scelto | | --------------------- | --------------------------------------------- | ----------------------------------------------------- | | cleanup-orphans | every 6h + at startup | `OnBootSec=2min, OnUnitActiveSec=6h, Persistent` | | retention-policy | daily 03:00 + 30min random delay | `OnCalendar=*-*-* 03:00:00, RandomizedDelaySec=30min` | | watch-disk-space | every 15min | `OnBootSec=5min, OnUnitActiveSec=15min` | | watch-runner-health | every 15min | `OnBootSec=3min, OnUnitActiveSec=15min` | | backup-template | *(non in Register-CIScheduledTasks.ps1)* | `OnCalendar=Sun *-*-* 02:00:00, RandomizedDelaySec=1h`| `Persistent=true` ovunque per non perdere esecuzioni se la macchina è spenta al momento del trigger. ## Decisione — script che restano in PowerShell `Invoke-RetentionPolicy.ps1` e `Backup-CITemplate.ps1` non sono stati portati a Python (resta scelta documentata in `AGENTS.md` "Mappatura"). Su Linux quindi le rispettive `.service` invocano `pwsh` (PowerShell Core). Il README documenta l'installazione `apt install powershell` da repo Microsoft. Se in futuro si deciderà di portarli a Python (sub-comandi `retention run` / `template backup`), basterà sostituire `ExecStart=` nelle due unit senza toccare il timer. ## Definizione di "fatto" B5 (dal piano) | Criterio | Stato | | --------------------------------------------------- | ------------------------------------ | | Tutti i task periodici come timer systemd attivi | ⏳ unit pronti; install richiede host Linux | | Trigger manuale di ognuno PASS | ⏳ richiede host Linux | | Mapping documentato | ✅ `deploy/systemd/README.md` | ## Cosa resta a carico utente (sul nuovo host Linux) Tutti i passi B1–B4 e B6–B8 sono operazioni hardware/host non eseguibili da questa sessione. Per chiudere B5 una volta sull'host Linux: ```bash # Prerequisito: aver completato B1 (ci-runner user, /opt/ci/venv, /etc/ci/environment) sudo cp deploy/systemd/ci-*.service deploy/systemd/ci-*.timer /etc/systemd/system/ sudo systemctl daemon-reload 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 systemctl list-timers --all 'ci-*' # Trigger manuale di smoke sudo systemctl start ci-cleanup-orphans.service journalctl -u ci-cleanup-orphans.service -n 50 --no-pager ``` ## Riferimenti - Spec systemd timer: `man systemd.timer`, `man systemd.time` - Original PS task scheduler: `scripts/Register-CIScheduledTasks.ps1` - Mapping completo: `deploy/systemd/README.md` - Piano: `plans/implementation-plan-A-B.md` sezione B5