Files
worker/docs/web-console-and-observability.md
Gleb Tv fd1a010e31
Все проверки выполнены успешно
CI / test (push) Successful in 30s
Docker / Build and publish worker image (push) Successful in 10m49s
docs: migrate worker implementation plans
2026-07-13 18:19:00 +03:00

5.5 KiB

Web Console And Host Observability

Current Implementation

internal/webapp is a functional embedded HTTP application backed by SQLite. It provides authenticated overview, apps, checks, notifications, logs, status, settings, updates, password rotation, token rotation, audit retention, and cluster status endpoints. Static assets and templates are embedded in the worker binary.

The listener defaults to WORKER_HOST=0.0.0.0 and WORKER_PORT=27401. Compose publishes it on host loopback by default through WORKER_BIND_IP; that variable is a Compose interpolation setting, not a variable read by the binary.

Authentication

Two modes are implemented:

Configuration Behavior
Both WORKER_LOGIN and WORKER_PASSWORD set Basic-auth-backed operator sessions and /web/api/* access
Both empty Local bcrypt user; a one-time password is printed on first start
Only one set Startup error

Sessions are HTTP-only and SameSite strict, with a 30-minute idle and 8-hour absolute lifetime. State-changing browser requests require CSRF validation. Authenticated responses use no-store and restrictive security headers.

OAuth/device authorization is not implemented. Public exposure requires a TLS reverse proxy and network restrictions. Do not claim that WORKER_URL enables TLS; it only advertises the externally reachable URL.

Known Runtime Gap

webapp.New constructs Inventory and Metrics, but Server.Start currently does not start either collector and Server.Close does not stop them. As a result, production /apps and /status pages can remain empty even though collector unit tests pass.

This is the first required web-console change:

  1. Start both collectors with the server context before accepting requests.
  2. Stop and wait for them during Close and context cancellation.
  3. Make collector start idempotent and collector failure observable.
  4. Add a server integration test that observes populated inventory and metrics after startup.

Inventory View

The current local collector reads Linux /proc, process command lines and working directories, TCP listeners, and resource data, then stores snapshots in SQLite. It does not yet provide complete grouping, Docker, Compose, systemd, nginx, UDP, or deploymentd-compatible inventory. The implementation plan is in inventory.md.

Host Metrics

There are two related collectors:

  • internal/distworker/server_metrics.go sends the linked server's CPU, memory, disk, load, uptime, process, and network snapshot to the control plane every five seconds. This path is implemented.
  • internal/webapp/metrics.go drives local status pages and a local ring. It exists but is affected by the lifecycle gap above.

The control-plane report uses interval rates for CPU and aggregate networking. The local metrics implementation currently computes CPU from lifetime totals; align it with interval deltas so local and remote views agree.

Compose Management Target

Compose management remains planned and is opt-in. Implement it after read-only inventory is complete, under a separate internal/composeops package.

Required constraints:

  • fixed stacks root, default /opt/stacks, with canonical path containment;
  • explicit docker compose -f <validated-file> invocation;
  • no shell interpolation and no free-form host command endpoint;
  • per-stack single-flight action lock;
  • async 202 Accepted operations with bounded progress streaming;
  • viewer/operator/admin permissions and audit records;
  • typed confirmation for down, delete, and restore;
  • compose validation before save and backup before deploy;
  • Docker socket treated as root-equivalent and disabled by default.

The first Compose release includes read/list/status/logs only. Mutation, file editing, environment editing, terminal access, backup, and restore are separate release gates rather than one large feature switch.

Host Status Extensions

Implement in this order:

  1. Correct /proc, statfs, and /proc/net/dev interval collection.
  2. Add bounded local 24-hour one-minute aggregates.
  3. Add optional lsblk --json device topology.
  4. Add optional cached SMART and sensors data.
  5. Add Docker daemon and per-container status only when the socket capability is enabled.

Missing commands or permissions produce unavailable sections, not worker startup failure. All subprocesses use fixed argument arrays, deadlines, output limits, and allowlisted executable names.

Health And Updates

GET /healthz is local process liveness. The image healthcheck should call this endpoint, not rsmon-worker health, because the latter probes the control plane /up endpoint. Control-plane outage is a selfcheck/readiness event, not proof that the worker process is dead.

In-place binary replacement from the web UI is not implemented and should not run with ambient root access. The systemd update flow should download a signed artifact to a staging path and require an external privileged installer or explicit operator command to activate it.

Acceptance Tests

  • Starting webapp.Server produces nonempty metrics and process inventory on Linux and stops every collector cleanly.
  • Both auth modes work, XOR credentials fail startup, CSRF protects writes, and unauthenticated API calls fail.
  • A public bind is documented as insecure without TLS; no credential is logged.
  • /healthz remains healthy during a simulated control-plane outage.
  • Every host command has timeout/output-limit tests and rejects user-supplied executable or path traversal.
  • Compose mutation cannot operate outside the configured stacks root.