167 строки
6.4 KiB
Markdown
167 строки
6.4 KiB
Markdown
# Worker Host Inventory
|
|
|
|
## Purpose And Boundary
|
|
|
|
Inventory connects checks to the host, service, Compose project, domain, and
|
|
deployment that they observe. The worker collects facts; the RSMon control
|
|
plane validates identity, applies account scope, reconciles lifecycle, and
|
|
persists the inventory projection.
|
|
|
|
The control-plane inventory entities remain `Server`, `ServerIp`, `Site`,
|
|
`Deployment`, `Domain`, `Repo`, and `site_repos`. Their API and legacy stream
|
|
projection are control-plane concerns. This repository owns only local
|
|
discovery and worker-originated reports.
|
|
|
|
## Existing Collectors
|
|
|
|
Current state:
|
|
|
|
- `internal/webapp/inventory.go` discovers Linux processes, command lines,
|
|
working directories, TCP listeners, and basic resource facts.
|
|
- snapshots are stored in the local web-console SQLite database;
|
|
- `internal/distworker/server_metrics.go` reports bounded process/network host
|
|
snapshots, but not normalized application inventory;
|
|
- external `deploymentd` remains the implemented authoritative collector for
|
|
nginx, Docker Compose, and host inventory on the control plane.
|
|
|
|
The worker does not currently send an inventory report to the control plane.
|
|
It must not claim deploymentd parity until the protocol, ingestion, and
|
|
reconciliation tests below are complete.
|
|
|
|
## Target Package Layout
|
|
|
|
Move collection ownership out of `internal/webapp`:
|
|
|
|
```text
|
|
internal/inventory/
|
|
collector.go orchestration and partial-success envelope
|
|
process_linux.go procfs process and listener discovery
|
|
docker.go Docker and Compose discovery behind capability
|
|
nginx.go read-only nginx virtual-host discovery
|
|
systemd.go allowlisted unit discovery
|
|
normalize.go stable IDs and control-plane report conversion
|
|
store.go optional local snapshot interface
|
|
```
|
|
|
|
The web console consumes a read-only snapshot interface. The runner consumes a
|
|
bounded report interface. Collectors return per-section errors; one failed
|
|
section does not discard successful sections.
|
|
|
|
## Report Contract
|
|
|
|
Add a typed `WorkerInventoryReport` branch to `internal/wire`:
|
|
|
|
```json
|
|
{
|
|
"kind": "result",
|
|
"inventory": {
|
|
"schema": "rsmon.worker.inventory.v1",
|
|
"report_id": "uuid",
|
|
"server_id": 42,
|
|
"collected_at": "2026-07-13T15:00:00Z",
|
|
"full_snapshot": true,
|
|
"host": {},
|
|
"addresses": [],
|
|
"processes": [],
|
|
"compose_projects": [],
|
|
"nginx_sites": [],
|
|
"systemd_units": [],
|
|
"errors": [{"section": "docker", "code": "unavailable"}]
|
|
}
|
|
}
|
|
```
|
|
|
|
Constraints:
|
|
|
|
- `report_id` is stable across transport retries and unique across collection
|
|
runs.
|
|
- `server_id` comes from authenticated `WorkerInit.ServerID`, never local env.
|
|
- A full snapshot permits missing-item reconciliation; partial reports do not.
|
|
- Section and total item counts, strings, labels, and serialized bytes are
|
|
bounded before enqueue.
|
|
- Environment variable values, file contents, process environments, container
|
|
secrets, and Compose `.env` values are never included.
|
|
- The control plane rejects a report when the worker is not linked to the
|
|
server or the private worker's account does not own it.
|
|
|
|
## Normalization
|
|
|
|
Stable local identity keys:
|
|
|
|
- process app: executable plus canonical working directory;
|
|
- Compose site: Docker Compose project name plus canonical project directory;
|
|
- Compose deployment: project plus service name;
|
|
- nginx deployment: canonical config path;
|
|
- domain: normalized lowercase hostname without trailing dot;
|
|
- systemd service: unit name.
|
|
|
|
Container IDs and PIDs are observations, not stable entity IDs. Never use them
|
|
as the sole upsert key. Every deployment includes `last_seen_at`; only a full
|
|
successful section can mark previously observed entities missing.
|
|
|
|
## Collector Requirements
|
|
|
|
### Processes
|
|
|
|
- Group related processes deterministically by executable, working directory,
|
|
and parent relationship.
|
|
- Parse TCP and UDP listeners for IPv4 and IPv6.
|
|
- Do not read another process's environment.
|
|
- Exclude kernel threads and the worker itself from application suggestions.
|
|
|
|
### Docker And Compose
|
|
|
|
- Disabled without an explicit Docker capability.
|
|
- Prefer Docker/Compose JSON output and labels; do not parse human tables.
|
|
- Collect project, service, image, state, ports, mount paths, health, and
|
|
Traefik host rules. Exclude environment values and registry credentials.
|
|
- Treat Docker socket access as root-equivalent and report the capability to
|
|
the operator.
|
|
|
|
### Nginx
|
|
|
|
- Read only configured allowlisted roots.
|
|
- Collect config path, listen values, server names, auth presence, root path,
|
|
and proxy presence. Do not send certificate private-key paths or contents.
|
|
|
|
### Host And Server IPs
|
|
|
|
- Collect hostname, OS/kernel summary, and valid non-loopback addresses.
|
|
- Do not guess a primary address; report interface and route metadata so the
|
|
control plane can apply policy.
|
|
|
|
## Relationship To deploymentd And RSLogin
|
|
|
|
Worker reports and deploymentd ingest are complementary producers of the same
|
|
control-plane projection. During migration:
|
|
|
|
- deploymentd remains authoritative for sections it currently reports;
|
|
- worker inventory is feature-gated per server;
|
|
- every row records source and source report ID;
|
|
- reconciliation occurs per source and section to prevent one producer from
|
|
deleting another producer's observations;
|
|
- the former rstuff stream direction is superseded; RSMon owns inventory and
|
|
RSLogin supplies trusted project and SSH-access input through a separate
|
|
control-plane integration, never a worker protocol.
|
|
|
|
## Delivery Phases
|
|
|
|
1. Start and stop the existing process collector; move it behind an interface.
|
|
2. Add typed report and control-plane ingestion for process/host/address data.
|
|
3. Add read-only Docker and Compose discovery.
|
|
4. Add nginx and systemd discovery.
|
|
5. Add source-aware reconciliation and deploymentd comparison mode.
|
|
6. Enable monitor suggestions only after operators confirm discovered targets.
|
|
|
|
## Acceptance Tests
|
|
|
|
- A worker restart preserves no false stable identity based on PID/container ID.
|
|
- A failed Docker section does not erase successful nginx or process data.
|
|
- Partial reports never mark absent deployments missing.
|
|
- Full reports reconcile only rows owned by the same source and section.
|
|
- Cross-account and worker/server mismatch reports are rejected.
|
|
- Fixture snapshots prove no environment values or credential-like fields are
|
|
serialized.
|
|
- Worker and deploymentd fixtures normalize equivalent Compose/nginx entities
|
|
to the same control-plane identity without deleting each other's rows.
|