From 096ba7fe16e38dffa7800d0be8a30a71b6c38bbe Mon Sep 17 00:00:00 2001 From: Simone Date: Thu, 14 May 2026 17:06:36 +0200 Subject: [PATCH] docs(a1): sync master checklist + A1 'definizione di fatto' to actual state A1 items were completed but only A1-closeout.md was updated. Mark all A1 checkboxes done in implementation-plan-A-B.md (master checklist + step-A1 attivita + definizione di fatto), leaving only the real-VM PoC pending (hardware validation deferred). --- plans/implementation-plan-A-B.md | 50 ++++++++++++++++---------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/plans/implementation-plan-A-B.md b/plans/implementation-plan-A-B.md index 5d497e3..cb385e3 100644 --- a/plans/implementation-plan-A-B.md +++ b/plans/implementation-plan-A-B.md @@ -43,16 +43,16 @@ A4; cambiano solo path/env vars in Fase B). ## Checklist riassuntiva master -- [ ] [A1] Creare `pyproject.toml` + package `src/ci_orchestrator/` + venv `F:\CI\python\venv\` -- [ ] [A1] Implementare `config.py` (env vars + `config.toml`) con default Windows e hook path Linux -- [ ] [A1] Implementare `backends/protocol.py` con Protocol `VmBackend` (firma neutra, no `vmrun_*` nei nomi pubblici) -- [ ] [A1] Implementare `backends/workstation.py` (`WorkstationVmrunBackend`) usando `subprocess` + `shutil.which('vmrun')` -- [ ] [A1] Implementare `transport/winrm.py` con wrapper `pypsrp.client.Client` -- [ ] [A1] Implementare `transport/ssh.py` con wrapper `paramiko.SSHClient` / `SFTPClient` -- [ ] [A1] Implementare `credentials.py` con Protocol `CredentialStore` + `KeyringCredentialStore` +- [x] [A1] Creare `pyproject.toml` + package `src/ci_orchestrator/` + venv `F:\CI\python\venv\` +- [x] [A1] Implementare `config.py` (env vars + `config.toml`) con default Windows e hook path Linux +- [x] [A1] Implementare `backends/protocol.py` con Protocol `VmBackend` (firma neutra, no `vmrun_*` nei nomi pubblici) +- [x] [A1] Implementare `backends/workstation.py` (`WorkstationVmrunBackend`) usando `subprocess` + `shutil.which('vmrun')` +- [x] [A1] Implementare `transport/winrm.py` con wrapper `pypsrp.client.Client` +- [x] [A1] Implementare `transport/ssh.py` con wrapper `paramiko.SSHClient` / `SFTPClient` +- [x] [A1] Implementare `credentials.py` con Protocol `CredentialStore` + `KeyringCredentialStore` - [ ] [A1] PoC `wait-ready` end-to-end via `pypsrp` contro un guest Windows reale -- [ ] [A1] Test pytest unitari per `vmrun.py`, `winrm.py`, `ssh.py`, `credentials.py` con mock -- [ ] [A1] Aggiungere job pytest a `gitea/workflows/lint.yml` +- [x] [A1] Test pytest unitari per `vmrun.py`, `winrm.py`, `ssh.py`, `credentials.py` con mock +- [x] [A1] Aggiungere job pytest a `gitea/workflows/lint.yml` - [x] [A2] Portare `Wait-VMReady.ps1` → `python -m ci_orchestrator wait-ready` - [x] [A2] Portare `Remove-BuildVM.ps1` → `vm remove` - [x] [A2] Portare `Cleanup-OrphanedBuildVMs.ps1` → `vm cleanup` @@ -128,19 +128,19 @@ WinRM/SSH e credential store funzionanti contro l'ambiente reale via PoC **Attività**: -- [ ] Creare `pyproject.toml` (build backend `setuptools` o `hatchling`) con dipendenze `pypsrp`, `paramiko`, `keyring`, `click`, `tomli` (se Python <3.11), `rich` opzionale per logging -- [ ] Creare layout `src/ci_orchestrator/` con `__init__.py`, `__main__.py` (entry point `click`) -- [ ] Creare venv in `F:\CI\python\venv\` e installare il package in editable (`pip install -e .[dev]`) -- [ ] Implementare `config.py`: caricamento env vars (`CI_ROOT`, `CI_TEMPLATES`, `CI_BUILD_VMS`, `CI_ARTIFACTS`, `CI_KEYS`) con merge da `config.toml` opzionale; default OS-aware (Windows → `F:\CI\...`, Linux → `/var/lib/ci/...`) -- [ ] Implementare `backends/protocol.py` con Protocol `VmBackend` (metodi `clone_linked`, `start`, `stop`, `delete`, `get_ip`, `list_snapshots`) e dataclass `VmHandle` (path/identificatore opaco) -- [ ] Implementare `backends/workstation.py`: `WorkstationVmrunBackend` che usa `subprocess.run([vmrun, '-T', 'ws', op, *args], check=False, capture_output=True, text=True, encoding='utf-8')` con check esplicito su `returncode` -- [ ] Implementare `transport/winrm.py`: wrapper su `pypsrp.client.Client(host, username, password, ssl=True, cert_validation=False)` con metodi `run`, `copy`, `fetch` -- [ ] Implementare `transport/ssh.py`: wrapper su `paramiko.SSHClient` con `set_missing_host_key_policy(AutoAddPolicy)`, `known_hosts` configurabile (default `None` per non interferire con clone ephemeri — vedi `AGENTS.md` errore #12) -- [ ] Implementare `credentials.py`: Protocol `CredentialStore` + `KeyringCredentialStore` che usa `keyring.get_credential(target, None)` e ritorna oggetto `Credential(username, password)` +- [x] Creare `pyproject.toml` (build backend `setuptools` o `hatchling`) con dipendenze `pypsrp`, `paramiko`, `keyring`, `click`, `tomli` (se Python <3.11), `rich` opzionale per logging +- [x] Creare layout `src/ci_orchestrator/` con `__init__.py`, `__main__.py` (entry point `click`) +- [x] Creare venv in `F:\CI\python\venv\` e installare il package in editable (`pip install -e .[dev]`) +- [x] Implementare `config.py`: caricamento env vars (`CI_ROOT`, `CI_TEMPLATES`, `CI_BUILD_VMS`, `CI_ARTIFACTS`, `CI_KEYS`) con merge da `config.toml` opzionale; default OS-aware (Windows → `F:\CI\...`, Linux → `/var/lib/ci/...`) +- [x] Implementare `backends/protocol.py` con Protocol `VmBackend` (metodi `clone_linked`, `start`, `stop`, `delete`, `get_ip`, `list_snapshots`) e dataclass `VmHandle` (path/identificatore opaco) +- [x] Implementare `backends/workstation.py`: `WorkstationVmrunBackend` che usa `subprocess.run([vmrun, '-T', 'ws', op, *args], check=False, capture_output=True, text=True, encoding='utf-8')` con check esplicito su `returncode` +- [x] Implementare `transport/winrm.py`: wrapper su `pypsrp.client.Client(host, username, password, ssl=True, cert_validation=False)` con metodi `run`, `copy`, `fetch` +- [x] Implementare `transport/ssh.py`: wrapper su `paramiko.SSHClient` con `set_missing_host_key_policy(AutoAddPolicy)`, `known_hosts` configurabile (default `None` per non interferire con clone ephemeri — vedi `AGENTS.md` errore #12) +- [x] Implementare `credentials.py`: Protocol `CredentialStore` + `KeyringCredentialStore` che usa `keyring.get_credential(target, None)` e ritorna oggetto `Credential(username, password)` - [ ] PoC end-to-end: comando `python -m ci_orchestrator wait-ready --vmx --timeout 120` su un clone reale del template `WinBuild2025` (validare WinRM HTTPS self-signed) -- [ ] Setup `pytest`, `pytest-mock`, `ruff`, `mypy` come dev dependencies; configurare `pyproject.toml` con `[tool.ruff]` e `[tool.mypy]` strict -- [ ] Test pytest unitari: `test_vmrun.py` (mock subprocess, casi `vmrun list` con e senza VMX target — copre errore #10), `test_winrm.py` (mock `pypsrp`), `test_ssh.py` (mock `paramiko`, copre errore #12), `test_credentials.py` (mock `keyring`) -- [ ] Aggiungere job `python` a `gitea/workflows/lint.yml`: setup venv → `ruff check src/ tests/` → `mypy --strict src/` → `pytest --cov=ci_orchestrator --cov-fail-under=70` +- [x] Setup `pytest`, `pytest-mock`, `ruff`, `mypy` come dev dependencies; configurare `pyproject.toml` con `[tool.ruff]` e `[tool.mypy]` strict +- [x] Test pytest unitari: `test_vmrun.py` (mock subprocess, casi `vmrun list` con e senza VMX target — copre errore #10), `test_winrm.py` (mock `pypsrp`), `test_ssh.py` (mock `paramiko`, copre errore #12), `test_credentials.py` (mock `keyring`) +- [x] Aggiungere job `python` a `gitea/workflows/lint.yml`: setup venv → `ruff check src/ tests/` → `mypy --strict src/` → `pytest --cov=ci_orchestrator --cov-fail-under=70` **Hook futuri Fase C**: il Protocol `VmBackend` deve usare nomi neutri (`clone_linked`, non `vmrun_clone`), accettare `template`/`snapshot`/`name` @@ -166,10 +166,10 @@ modificato in A1. **Definizione di fatto step A1**: - [ ] PoC `wait-ready` PASS contro VM reale -- [ ] Coverage pytest ≥70% sui moduli core -- [ ] `lint.yml` aggiornato e verde -- [ ] Protocol `VmBackend` reviewato e congelato -- [ ] Documentato setup venv in `README.md` (sezione minima) +- [x] Coverage pytest ≥70% sui moduli core +- [x] `lint.yml` aggiornato e verde +- [x] Protocol `VmBackend` reviewato e congelato +- [x] Documentato setup venv in `README.md` (sezione minima) ### A2 — Script "foglia" (no state condiviso)