docs: Phase 7 — update docs to reflect optional services migration
Email, calendar, and files are now optional store services, not always-on builtins. Updated README, QUICKSTART, Wiki, and service-developer-guide to reflect: dynamic nav, optional service install flow, correct egress identifiers (wireguard_ext/default vs wireguard/cell_internet), removed builtin/store distinction from manifest reference, 7 core containers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -52,7 +52,7 @@ Browser / WireGuard peer
|
||||
└── SetupManager first-run wizard state
|
||||
```
|
||||
|
||||
All 12 service containers run on a Docker bridge network (`cell-network`, `172.20.0.0/16` default). Static IPs per container are defined in `docker-compose.yml`.
|
||||
The 7 core containers run on a Docker bridge network (`cell-network`, `172.20.0.0/16` default). Static IPs per container are defined in `docker-compose.yml`. Installed optional services join the same network via their own compose projects, managed by `ServiceComposer`.
|
||||
|
||||
Runtime configuration lives in `config/api/cell_config.json`, managed by `ConfigManager`. All service managers read and write through `ConfigManager`, which validates and backs up automatically.
|
||||
|
||||
@@ -101,7 +101,7 @@ The wizard collects:
|
||||
- **Cell name** — used for hostnames and DDNS subdomain (e.g. `myhome` → `myhome.pic.ngo`)
|
||||
- **Domain mode** — determines TLS certificate source: `lan` (internal CA), `pic_ngo`, `cloudflare`, `duckdns`, `http01`
|
||||
- **Timezone**
|
||||
- **Initial services to enable**
|
||||
- **Services to install** — optional services (email, calendar, files) to install after setup; each starts a background install via `ServiceStoreManager`
|
||||
- **Admin password** — minimum 12 characters
|
||||
|
||||
On completion:
|
||||
@@ -109,6 +109,7 @@ On completion:
|
||||
2. Cell identity is written to `config/api/cell_config.json`
|
||||
3. Caddy config is generated
|
||||
4. If domain mode is `pic_ngo`, the cell registers `<name>.pic.ngo` with the DDNS service
|
||||
5. Each selected service is installed in a background thread
|
||||
|
||||
Wizard endpoints: `GET/POST /api/setup/step`, `GET /api/setup/status`, `POST /api/setup/complete`.
|
||||
|
||||
@@ -182,17 +183,17 @@ DNS records, DHCP leases and reservations, NTP status, network connectivity test
|
||||
|
||||
Peer add/remove, key generation, QR code export, per-peer routing policy, WireGuard status.
|
||||
|
||||
### Email (`/api/email/`)
|
||||
### Email (`/api/email/`) _(available when email service is installed)_
|
||||
|
||||
User account management, mailbox config, alias management, connectivity test.
|
||||
User account management, mailbox config, alias management, connectivity test. Returns HTTP 404 when the email service is not installed (except `/api/email/status`).
|
||||
|
||||
### Calendar (`/api/calendar/`)
|
||||
### Calendar (`/api/calendar/`) _(available when calendar service is installed)_
|
||||
|
||||
User, calendar, and contacts (CardDAV) management.
|
||||
User, calendar, and contacts (CardDAV) management. Returns HTTP 404 when the calendar service is not installed (except `/api/calendar/status`).
|
||||
|
||||
### Files (`/api/files/`)
|
||||
### Files (`/api/files/`) _(available when files service is installed)_
|
||||
|
||||
WebDAV user management, file upload/download/delete, folder management.
|
||||
WebDAV user management, file upload/download/delete, folder management. Returns HTTP 404 when the files service is not installed (except `/api/files/status`).
|
||||
|
||||
### Routing (`/api/routing/`)
|
||||
|
||||
@@ -252,7 +253,7 @@ Supported providers: `pic_ngo`, `cloudflare`, `duckdns`, `noip`, `freedns`.
|
||||
|
||||
### Navigation
|
||||
|
||||
The left-hand navigation contains a **Services** group (previously labelled "Store"). Both admin and peer users see this group. It has three collapsible sub-items: **Email**, **Calendar**, and **Files**.
|
||||
The left-hand navigation contains a **Services** group. Both admin and peer users see it. Sub-items for installed services (Email, Calendar, Files, etc.) are added dynamically: the UI fetches `GET /api/services/active` on load and after each install/uninstall. Services not yet installed do not appear in the nav.
|
||||
|
||||
Legacy paths redirect to their new canonical locations:
|
||||
|
||||
@@ -265,9 +266,13 @@ Legacy paths redirect to their new canonical locations:
|
||||
|
||||
### Services page (`/services`)
|
||||
|
||||
The top of the page shows a **Built-in** section with three cards — Email, Calendar, and Files. Each card has a **Manage** link that navigates to the corresponding sub-page.
|
||||
A single unified catalog of all available services from the store index. Each card shows:
|
||||
- Service name, description, version
|
||||
- **Install** button (not installed) or **Uninstall** button (installed)
|
||||
- **Open** link for installed services (navigates to the service sub-page)
|
||||
- Running/stopped status dot for installed services
|
||||
|
||||
Below the Built-in section, the optional add-on store lists third-party services that can be installed or removed (see [Service Store (Add-ons)](#service-store-add-ons)).
|
||||
The `pic-services-changed` custom DOM event is dispatched after install/uninstall, causing the nav to re-fetch active services immediately.
|
||||
|
||||
### Service sub-pages — admin view
|
||||
|
||||
@@ -276,19 +281,18 @@ Each sub-page at `/services/email`, `/services/calendar`, and `/services/files`
|
||||
1. **Connection info** — hostnames, ports, and protocol details (e.g. IMAP/SMTP/Webmail, CalDAV/CardDAV, WebDAV/Filegator).
|
||||
2. **Service status** — current running state fetched from the API.
|
||||
3. **Users list** — accounts registered with that service.
|
||||
4. **Inline config form** — editable fields for that service's settings:
|
||||
- Email: ports and mail domain.
|
||||
- Calendar: port and data directory.
|
||||
- Files: ports, data directory, and per-user quota.
|
||||
4. **Inline config form** — editable fields for that service's settings.
|
||||
|
||||
Config forms save automatically with an 800 ms debounce after the last change. Dirty state persists through navigation: if a user edits the form and navigates away before the debounce fires, clicking **Apply Now** on return still saves the pending changes.
|
||||
If the service is not installed, the page shows a `ServiceNotInstalledBanner` with a link to the catalog for admins, or a "contact your admin" message for peer users. All non-status API routes for uninstalled services return HTTP 404.
|
||||
|
||||
Config forms save automatically with an 800 ms debounce after the last change.
|
||||
|
||||
### Service sub-pages — peer view
|
||||
|
||||
Peers access the same URLs without an admin gate. The peer view shows only:
|
||||
Peers access the same URLs. The peer view shows only:
|
||||
|
||||
- Connection info (hostnames, ports, copy buttons).
|
||||
- Personal credentials for that service (email address, CalDAV username, or WebDAV username), fetched from `/api/peer/*`.
|
||||
- Personal credentials for that service, fetched from `/api/peer/*`.
|
||||
|
||||
The config form and users list are not shown to peers.
|
||||
|
||||
@@ -296,22 +300,36 @@ The config form and users list are not shown to peers.
|
||||
|
||||
The Email, Calendar, and Files configuration forms have been removed from the Settings page. Settings now covers: Identity, DDNS, Network (DNS/DHCP/NTP), WireGuard, Routing & Firewall, Vault & Trust, and Backup & Restore.
|
||||
|
||||
### API change
|
||||
### Relevant API endpoints
|
||||
|
||||
`GET /api/config` now includes an `installed_services` field — a dict keyed by service ID — listing services currently installed on the cell.
|
||||
| Method | Path | Description |
|
||||
|---|---|---|
|
||||
| GET | `/api/services/active` | List installed services with id, name, subdomain, capabilities |
|
||||
| GET | `/api/config` | Full cell config, includes `installed_services` dict |
|
||||
|
||||
---
|
||||
|
||||
## Service Store (Add-ons)
|
||||
|
||||
`ServiceStoreManager` fetches a manifest index from `http://git.pic.ngo/roof/pic-services/raw/branch/main/index.json`. Each manifest declares:
|
||||
- Container image
|
||||
- Caddy routes (added to the Caddyfile)
|
||||
- iptables rules
|
||||
- Environment variables
|
||||
- Health check endpoint
|
||||
Email, calendar, and file storage are store services — not part of the core stack. All optional functionality ships through this mechanism.
|
||||
|
||||
`POST /api/store/install` pulls the image, writes the Caddy route, applies iptables rules, and starts the container. `POST /api/store/remove` reverses this.
|
||||
`ServiceStoreManager` fetches a manifest index from `https://git.pic.ngo/roof/pic-services/raw/branch/main/index.json`. Each manifest (`schema_version: 3`) declares:
|
||||
|
||||
- Container image and compose template
|
||||
- Caddy subdomain routes
|
||||
- Capabilities: `has_subdomain`, `has_accounts`, `has_admin_config`, `has_storage`, `has_egress`
|
||||
- Account provisioning interface (`accounts.manager`)
|
||||
- Backup declarations (`backup.volumes`, `backup.config_paths`)
|
||||
- Egress routing policy (`egress.allowed`)
|
||||
- Per-peer connection info template (`peer_config_template`)
|
||||
|
||||
`POST /api/store/install` fetches the manifest and compose template, validates them, renders the template with PIC-specific variables (`${PIC_DOMAIN}`, `${PIC_DATA_DIR}`, etc.), writes a per-service compose file, and brings the containers up via `ServiceComposer`. Caddy routes and DNS entries are applied automatically.
|
||||
|
||||
`POST /api/store/remove` checks for dependent services, stops and removes containers, and regenerates Caddy.
|
||||
|
||||
**`ServiceComposer`** (`api/service_composer.py`) manages the per-service compose lifecycle independently of the main stack. Each service gets its own compose project at `data/services/<id>/docker-compose.yml`. On startup, `reapply_active_services()` brings up containers for all recorded installs.
|
||||
|
||||
See `docs/service-developer-guide.md` for the full manifest schema reference and submission process.
|
||||
|
||||
---
|
||||
|
||||
@@ -354,7 +372,7 @@ Routing uses fwmark and `ip rule` / `ip route` in separate routing tables. Confi
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
make test # unit tests (pytest, ~1500 functions)
|
||||
make test # unit tests (pytest, ~1900+ functions)
|
||||
make test-coverage # coverage report in htmlcov/
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user