Cron, Terminal, and Hardware Sensors
Server Mode Phase 7 bundles three small but frequently-requested
infrastructure features: a GUI for cron, an embeddable web-terminal
widget, and a hardware-sensors readout on the dashboard. All three are
available by default on every node — nothing to install, nothing to
enable.
Cron GUI
The Cron page (Infra → Cron) shows every entry in the Cloud OS daemon user’s crontab and lets you edit them without dropping into a shell.
Features
| Feature | Description |
|---|---|
| Preset schedules | Pick “Every 5 minutes”, “Every day at 3am”, “At reboot”, etc. — the raw expression auto-fills. |
| Custom expressions | Any standard 5-field cron expression works, plus @reboot / @daily shortcuts. |
| Live preview | The editor parses your expression and shows the next 3 firing times so you catch typos before saving. |
| Inline editing | Click the pencil to edit a row; the schedule switches to the editor, the command to a text field. |
| Audit trail | Every save goes through the sysctl chokepoint — all mutations show up in the sysctl_audit log alongside systemctl/docker calls. |
API
GET /api/cron— returns{jobs: [{schedule, command, comment}]}. Parsing is tolerant: free-standing comment lines survive, malformed lines come back as opaque commands so the UI can flag them.PUT /api/cron— writes back the full list. All-or-nothing, matching howcrontab -behaves under the hood.
Upcoming Cron widget
The dashboard ships an Upcoming Cron widget by default — it shows the next 5 jobs to fire sorted by computed run time, so you see your imminent backups/refreshes without leaving the dashboard.
Web Terminal widget
The existing full-screen Terminal modal is joined by a compact dashboard widget that runs an xterm shell inside a single dashboard tile. Handy for “I just need to paste one command” moments where popping the modal feels heavy.
- Connects to
/api/terminal/ws(same PTY-over-websocket endpoint the full-screen terminal uses) - Resize-aware — dragging dashboard section dividers reflows the shell automatically
- Session-authed; idle sessions close after 30 minutes
The widget is hidden by default — enable it from the Widget Catalogue sidebar when you want an embedded shell on the dashboard.
Hardware Sensors widget
Pulls lm-sensors / nvidia-smi / SMART / apcaccess output into a single chip-style card on the dashboard.
What’s shown
- CPU temp — hottest core across
coretemp-*chips, falling back toacpitz-virtual-0when coretemp isn’t available. - GPU temp —
nvidia-smi --query-gpu=temperature.gpuoutput. - Disk temps — every
nvme-*anddrivetemp-*chip lm-sensors exposes, one row per device. - Fans — non-zero
fanN_inputvalues from the super-I/O chip. - UPS — charge % and runtime minutes from
apcaccess status.
Colour coding
Temperature chips flip colour by thermal band so a glance tells you if anything is baking:
| Band | Colour |
|---|---|
| below 60°C | green |
| 60–80°C | amber |
| 80°C or higher | red |
Missing tools mean missing fields
Every probe is best-effort. If sensors / nvidia-smi / apcaccess
isn’t installed — or the command fails because of permissions — the
corresponding field is simply omitted from the snapshot. You won’t see
an error, just a shorter list. That keeps the dashboard resilient to
partial installs on mixed fleets.
To enable more sensors on a stock Debian/Ubuntu node:
sudo apt install lm-sensors smartmontools apcupsd
sudo sensors-detect --autoNVIDIA GPU temps need the proprietary driver (nvidia-smi must be on
$PATH).
API
GET /api/sensors— returns the Snapshot JSON:
{
"cpu_temp_c": 52.0,
"gpu_temp_c": 65.0,
"disks_temp_c": [{ "name": "nvme", "temp_c": 41.85 }],
"fans_rpm": [{ "name": "fan1", "rpm": 1200 }],
"ups": { "present": true, "charge_pct": 98.0, "runtime_min": 45.2 }
}The endpoint is cached in-process for 5 seconds so multiple dashboard
tabs polling it don’t each shell out to sensors.