docs: document operations/+web/ layers and live ci-web.service deployment
CLAUDE.md and docs/ARCHITECTURE.md were still missing the operations/ and web/ packages added by the web-UI plan (W0-W7). Also records that ci-web.service is now live on this host (LAN + Gitea OIDC) in docs/WEB-UI.md and closes plans/web-ui-management-plan.md with a status header.
This commit is contained in:
@@ -92,9 +92,22 @@ The host **never executes build tools directly** — it only orchestrates VM lif
|
|||||||
| `commands/wait.py` | `wait-ready` |
|
| `commands/wait.py` | `wait-ready` |
|
||||||
| `commands/monitor.py` | `monitor disk / runner` |
|
| `commands/monitor.py` | `monitor disk / runner` |
|
||||||
| `commands/report.py` | `report job` |
|
| `commands/report.py` | `report job` |
|
||||||
|
| `operations/vms.py`, `cache.py`, `host.py`, `audit.py` | Pure logic layer shared by the CLI and the web UI — dataclasses only, zero `click`/`print`. `commands/*` and `web/routes.py` both call these; never duplicate logic in either caller. |
|
||||||
|
| `commands/web.py` | `web serve` — `ci web serve --host --port` launches the dashboard (`uvicorn`/`fastapi` imported lazily so the core CLI stays dep-light without the `[web]` extra) |
|
||||||
|
| `web/app.py`, `auth.py`, `routes.py`, `security.py` | FastAPI dashboard: read-only VM/cache/disk/runner view, Gitea OIDC login (Authlib, fail-closed allowlist), CSRF-protected confirm-gated mutating actions (VM remove/cleanup, cache purge, template backup), JSONL audit trail. In-process only — imports `operations/` + `backends.load_backend` directly, never shells the CLI. See `docs/WEB-UI.md`. |
|
||||||
|
|
||||||
**Key design rule**: Application code (especially `commands/job.py`) must import `backends.load_backend` only — never `WorkstationVmrunBackend` directly. This keeps the Phase D ESXi extension path open.
|
**Key design rule**: Application code (especially `commands/job.py`) must import `backends.load_backend` only — never `WorkstationVmrunBackend` directly. This keeps the Phase D ESXi extension path open.
|
||||||
|
|
||||||
|
### Web management dashboard
|
||||||
|
|
||||||
|
`ci web serve` (package `web/`, optional `[web]` extra) is a server-rendered
|
||||||
|
FastAPI dashboard for VM/host management — see `docs/WEB-UI.md` for install,
|
||||||
|
Gitea OIDC setup, and operations, and `plans/web-ui-management-plan.md` for
|
||||||
|
the design history (steps W0–W7, all closed). Deployed live on this host as
|
||||||
|
`ci-web.service` (systemd, `ci-runner` user), bound to the LAN with Gitea
|
||||||
|
OIDC auth active — never bind `0.0.0.0`, and never bind non-loopback without
|
||||||
|
`[web.oidc]` configured (enforced at startup by `commands/web.py`).
|
||||||
|
|
||||||
### Transport selection
|
### Transport selection
|
||||||
|
|
||||||
`commands/job.py` reads `guestOS = "..."` from the cloned VMX. `ubuntu-*` → Linux/SSH (`transport/ssh.py`); anything else → Windows/WinRM (`transport/winrm.py`).
|
`commands/job.py` reads `guestOS = "..."` from the cloned VMX. `ubuntu-*` → Linux/SSH (`transport/ssh.py`); anything else → Windows/WinRM (`transport/winrm.py`).
|
||||||
|
|||||||
@@ -239,6 +239,22 @@ src/ci_orchestrator/
|
|||||||
│ ├── ssh.py # SSH/SFTP transport via paramiko (replaces ssh.exe/scp.exe)
|
│ ├── ssh.py # SSH/SFTP transport via paramiko (replaces ssh.exe/scp.exe)
|
||||||
│ └── errors.py # TransportConnectError / TransportCommandError
|
│ └── errors.py # TransportConnectError / TransportCommandError
|
||||||
│
|
│
|
||||||
|
├── operations/ # Pure logic layer, shared by the CLI and the web UI
|
||||||
|
│ ├── vms.py # list/remove VMs, cleanup orphans, IP-lease reconcile
|
||||||
|
│ ├── cache.py # cargo cache status/purge
|
||||||
|
│ ├── host.py # disk status, act_runner status, template backup
|
||||||
|
│ └── audit.py # append-only JSONL audit log
|
||||||
|
│ # ZERO click/print — returns frozen dataclasses only;
|
||||||
|
│ # commands/*.py and web/routes.py both call these.
|
||||||
|
│
|
||||||
|
├── web/ # Optional `[web]` extra — FastAPI management dashboard
|
||||||
|
│ ├── app.py # create_app(config); read-only VM/cache/disk/runner routes
|
||||||
|
│ ├── auth.py # Gitea OIDC (Authlib) + signed session + fail-closed allowlist
|
||||||
|
│ ├── routes.py # confirm-gated mutating actions (remove/cleanup/purge/backup)
|
||||||
|
│ └── security.py # synchronizer-token CSRF
|
||||||
|
│ # In-process only: imports operations/ + load_backend directly,
|
||||||
|
│ # never shells the CLI. See docs/WEB-UI.md.
|
||||||
|
│
|
||||||
└── commands/ # One module per `click` sub-command group
|
└── commands/ # One module per `click` sub-command group
|
||||||
├── wait.py # `wait-ready`
|
├── wait.py # `wait-ready`
|
||||||
├── vm.py # `vm new` / `vm remove` / `vm cleanup`
|
├── vm.py # `vm new` / `vm remove` / `vm cleanup`
|
||||||
@@ -246,6 +262,7 @@ src/ci_orchestrator/
|
|||||||
├── artifacts.py # `artifacts collect`
|
├── artifacts.py # `artifacts collect`
|
||||||
├── monitor.py # `monitor disk` / `monitor runner`
|
├── monitor.py # `monitor disk` / `monitor runner`
|
||||||
├── report.py # `report job`
|
├── report.py # `report job`
|
||||||
|
├── web.py # `web serve` — launches the dashboard (lazy fastapi/uvicorn import)
|
||||||
└── job.py # `job` — full end-to-end orchestrator
|
└── job.py # `job` — full end-to-end orchestrator
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,18 @@ config key referenced below.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 0. Current deployment on this host
|
||||||
|
|
||||||
|
Live since 2026-07-23: `ci-web.service` is enabled + running, bound to the
|
||||||
|
LAN (`192.168.10.11:8800`), authenticating against `https://gitea.emulab.it`
|
||||||
|
via OIDC. Only the allowlisted Gitea user(s) in `/var/lib/ci/config.toml`'s
|
||||||
|
`[web].allowed_users` can log in. Manage it exactly as described in §4 below
|
||||||
|
(`systemctl status/restart ci-web.service`, `journalctl -u ci-web.service -f`).
|
||||||
|
`WebSessionSecret` and `WebOidcClientSecret` are already stored in the
|
||||||
|
`ci-runner` keyring — no action needed unless they're rotated (§3/§6).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 1. Prerequisites
|
## 1. Prerequisites
|
||||||
|
|
||||||
- The Linux host already bootstrapped by `setup-host-linux.sh` (`ci-runner`
|
- The Linux host already bootstrapped by `setup-host-linux.sh` (`ci-runner`
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
# Interfaccia web di gestione VM/host — Piano di applicazione
|
# Interfaccia web di gestione VM/host — Piano di applicazione
|
||||||
|
|
||||||
|
> **Stato: PIANO CHIUSO (2026-07-23).** Tutti i passi W0–W7 completati,
|
||||||
|
> mergeati in `main` e pushati. `ci-web.service` è **live in produzione** su
|
||||||
|
> questo host: `http://192.168.10.11:8800`, auth Gitea OIDC attiva
|
||||||
|
> (`https://gitea.emulab.it`), allowlist in `/var/lib/ci/config.toml`.
|
||||||
|
> Dettagli operativi in `docs/WEB-UI.md` §0. Gate finale: 611 test,
|
||||||
|
> coverage 93.98 %, `ruff`/`mypy --strict` puliti.
|
||||||
|
|
||||||
> Piano operativo per una interfaccia web di **gestione** (non solo
|
> Piano operativo per una interfaccia web di **gestione** (non solo
|
||||||
> monitoraggio) del sistema CI/CD. Generato il **2026-07-23**.
|
> monitoraggio) del sistema CI/CD. Generato il **2026-07-23**.
|
||||||
> Eseguire i passi **in ordine**: ogni passo è autonomo, testabile e con
|
> Eseguire i passi **in ordine**: ogni passo è autonomo, testabile e con
|
||||||
|
|||||||
Reference in New Issue
Block a user