Return an error from the socket server when another daemon owns the Unix socket or bind setup fails, and broadcast shutdown so the daemon does not stay alive without a control socket. Also format the PR docs.\n\nChecks: cargo fmt --check; ./scripts/check-format.sh; git diff --check; cargo test -p colibri-daemon clear_stale_socket -- --nocapture; cargo test -p colibri-daemon --test sigterm_shutdown -- --nocapture.
101 lines
4.3 KiB
Markdown
101 lines
4.3 KiB
Markdown
# Colibri ISO Service Layout
|
|
|
|
## Service identity
|
|
|
|
| Field | Value |
|
|
| ------------ | ---------------------------------------------- |
|
|
| Service name | `colibri_daemon` |
|
|
| Binary | `/usr/local/bin/colibri-daemon` |
|
|
| User | `colibri` (unprivileged, `/usr/sbin/nologin`) |
|
|
| Group | `colibri` |
|
|
| Supervisor | `daemon(8)` — restart on crash, privilege drop |
|
|
|
|
## Filesystem layout
|
|
|
|
```
|
|
/usr/local/bin/colibri-daemon ← daemon binary (foreground, no self-daemonize)
|
|
/usr/local/bin/colibri ← CLI client (status, create-task, etc.)
|
|
/usr/local/bin/colibri-test-agent ← test agent (fake Pi JSONL)
|
|
/usr/local/etc/rc.d/colibri_daemon ← rc.d service script
|
|
/usr/local/etc/colibri/
|
|
rc.conf.sample ← service config template
|
|
provider.env ← optional API keys (mode 0600, root-owned)
|
|
/usr/local/etc/newsyslog.conf.d/
|
|
colibri.conf ← log rotation (1MB, 7 archives)
|
|
|
|
/var/db/colibri/ ← persistent data (750 colibri:colibri)
|
|
colibri.sqlite ← coordination store
|
|
sessions/ ← JSONL session files
|
|
|
|
/var/run/colibri/ ← tmpfs (recreated each boot)
|
|
colibri.sock ← Unix socket (770 colibri:colibri, set by daemon)
|
|
colibri-daemon.pid ← child pidfile (daemon(8) -p)
|
|
colibri-daemon-supervisor.pid ← supervisor pidfile (daemon(8) -P)
|
|
|
|
/var/log/colibri/ ← persistent logs
|
|
daemon.log ← stdout/stderr from colibri-daemon
|
|
```
|
|
|
|
## Boot-time behavior
|
|
|
|
1. `rc.d` starts `colibri_daemon` after LOGIN + cleanvar
|
|
2. `prestart`: creates `/var/run/colibri/`, `/var/db/colibri/`, `/var/log/colibri/`
|
|
3. `daemon(8)` forks `colibri-daemon` as user `colibri`, redirects logs
|
|
4. `poststart`: waits up to 10s for `/var/run/colibri/colibri.sock` to appear
|
|
5. Daemon binds socket, opens SQLite, starts scheduler loop
|
|
6. CLI clients connect via `colibri` binary → Unix socket
|
|
|
|
## Shutdown behavior
|
|
|
|
1. `rc.d` sends SIGTERM to daemon(8) supervisor (via custom `stop_cmd`)
|
|
2. Supervisor forwards signal to colibri-daemon child and exits (no restart)
|
|
3. Colibri closes socket, flushes SQLite, stops scheduler
|
|
4. `poststop`: removes stale socket from tmpfs
|
|
|
|
## Startup validation
|
|
|
|
```sh
|
|
# Check service status
|
|
service colibri_daemon status
|
|
|
|
# Socket health (nc must be available)
|
|
service colibri_daemon health
|
|
|
|
# CLI check
|
|
colibri status
|
|
colibri create-task --title "iso-check"
|
|
colibri list-tasks --status queued
|
|
```
|
|
|
|
## Config knobs (set in /etc/rc.conf or /etc/rc.conf.d/colibri_daemon)
|
|
|
|
| Variable | Default | Purpose |
|
|
| -------------------------- | --------------------------- | ----------------------- |
|
|
| `colibri_daemon_enable` | NO | Enable at boot (YES/NO) |
|
|
| `colibri_daemon_user` | colibri | Runtime user |
|
|
| `colibri_daemon_group` | colibri | Runtime group |
|
|
| `colibri_daemon_cost_mode` | smart | fast/smart/max |
|
|
| `colibri_daemon_data_dir` | /var/db/colibri | Persistent data |
|
|
| `colibri_daemon_run_dir` | /var/run/colibri | tmpfs runtime |
|
|
| `colibri_daemon_socket` | $run_dir/colibri.sock | Unix socket path |
|
|
| `colibri_daemon_db_path` | $data_dir/colibri.sqlite | SQLite path |
|
|
| `colibri_daemon_logfile` | /var/log/colibri/daemon.log | Log output |
|
|
|
|
## Log rotation
|
|
|
|
`/usr/local/etc/newsyslog.conf.d/colibri.conf`:
|
|
|
|
```
|
|
/var/log/colibri/daemon.log colibri:colibri 640 7 1024 * JC
|
|
```
|
|
|
|
Rotates at 1MB, keeps 7 compressed archives, bzip2 compression.
|
|
|
|
## Secrets policy
|
|
|
|
- No API keys in rc.conf or service environment files.
|
|
- `DEEPSEEK_API_KEY` and other provider keys are set via a separate,
|
|
mode-0600 env file sourced by the daemon (e.g. `/usr/local/etc/colibri/provider.env`).
|
|
- The rc.d script does NOT read or expose secrets.
|
|
- Logs go to `/var/log/colibri/` which is mode 0750 colibri:colibri —
|
|
only the colibri user and root can read them.
|