Task graph covers all Phase 1 concerns: config system, TLS termination, proxy handler, operations (rate limiting, logging, health check, admin socket, signals, shutdown, body size limit), deployment artifacts, and two review checkpoints. No circular dependencies. Critical path length of 7. Risk distribution: 3 high-risk (ACME, TLS listener setup, startup orchestration), 7 medium, 11 low, 2 trivial.
74 lines
3.0 KiB
Markdown
74 lines
3.0 KiB
Markdown
---
|
|
id: ops/admin-socket
|
|
name: Implement Unix domain socket admin API for config reload with feedback and status
|
|
status: pending
|
|
depends_on: [config/dynamic-config]
|
|
scope: moderate
|
|
risk: medium
|
|
impact: component
|
|
level: implementation
|
|
---
|
|
|
|
## Description
|
|
|
|
Implement the Unix domain socket admin API for programmatic config reload with success/failure feedback. This is an alternative to SIGHUP that provides structured responses.
|
|
|
|
### Protocol
|
|
|
|
- **Connection lifecycle**: One command per connection. Client connects, sends one newline-terminated command, receives one newline-terminated JSON response, then the server closes the connection.
|
|
- **Message framing**: Newline-delimited (`\n`). Responses end with `\n`.
|
|
|
|
### Commands
|
|
|
|
- `reload` — Re-read config file, validate, and swap DynamicConfig. Returns:
|
|
- Success: `{"status": "ok"}`
|
|
- Failure: `{"status": "error", "message": "..."}`
|
|
- `status` — Return basic process info. Returns:
|
|
- `{"status": "ok", "uptime_secs": 1234, "sites": 2}`
|
|
|
|
### Error Responses
|
|
|
|
- Unrecognized commands: `{"status": "error", "message": "unknown command: <cmd>"}`
|
|
- Invalid or empty input: `{"status": "error", "message": "invalid input"}`
|
|
|
|
### Socket Lifecycle
|
|
|
|
- Socket path from `admin_socket_path` config (default: `/run/reverse-proxy/admin.sock`)
|
|
- Empty string disables the admin socket
|
|
- Remove any existing socket file at startup before binding
|
|
- If the socket file exists and another process is listening, log a warning and disable the admin socket (but continue starting)
|
|
|
|
### Concurrency
|
|
|
|
- Multiple clients can connect simultaneously
|
|
- Reload operations are serialized via the same `tokio::sync::Mutex` used by SIGHUP reload
|
|
- If a reload is in progress, subsequent reload requests wait, then re-read the config file (getting the latest version)
|
|
|
|
## Acceptance Criteria
|
|
|
|
- [ ] Unix domain socket bound at `admin_socket_path`
|
|
- [ ] `reload` command triggers config reload and returns structured JSON response
|
|
- [ ] `status` command returns process uptime and site count
|
|
- [ ] Unknown commands return `{"status": "error", "message": "unknown command: ..."}`
|
|
- [ ] Empty/invalid input returns `{"status": "error", "message": "invalid input"}`
|
|
- [ ] One command per connection, server closes connection after response
|
|
- [ ] Stale socket file removed at startup
|
|
- [ ] If socket file exists and is active (another process), log warning and continue
|
|
- [ ] `admin_socket_path = ""` disables admin socket
|
|
- [ ] Reload operations serialized with same Mutex as SIGHUP reload
|
|
- [ ] Integration test: connect to socket, send `reload`, receive JSON response
|
|
- [ ] Integration test: connect to socket, send `status`, receive JSON response
|
|
|
|
## References
|
|
|
|
- docs/architecture/operations.md — admin socket section
|
|
- docs/architecture/decisions/014-unix-socket-reload.md — admin socket rationale
|
|
- docs/architecture/config.md — reload serialization
|
|
|
|
## Notes
|
|
|
|
> The admin socket and SIGHUP converge on the same reload code path. The only difference is that the admin socket returns a structured response while SIGHUP provides no feedback.
|
|
|
|
## Summary
|
|
|
|
> To be filled on completion |