Skip to content

snapraid-daemon mode (experimental) - #25

Merged
firsttris merged 1 commit into
masterfrom
claude/trusting-tesla-543ryb
Oct 9, 2026
Merged

firsttris merged 1 commit into
masterfrom
claude/trusting-tesla-543ryb

Conversation

@firsttris

Copy link
Copy Markdown
Owner

Lets running snapraid-daemon instances run the jobs of their arrays instead of SnapRAID UI calling SnapRAID itself. It is built on the engine interface from #23, off by default and marked experimental. Configurations without a daemon keep running on the CLI.

snapraid-daemon settings

Daemon engine (backend/src/engine/daemon-engine.ts)

  • Jobs: sync, scrub, check, fix, diff, smart and probe are queued with POST /v1/schedule. /v1/tasks and /v1/activity are polled for the task's messages (live output) and progress. Abort goes to POST /v1/stop.
  • Fallback: touch and status go to the CLI engine, because the daemon has no task for them.
  • Reports: When the daemon runs on the same machine, the report is read from the task's SnapRAID log, so errors and sync changes are the same as with the CLI. Otherwise it comes from the task's figures.
  • Reads:
    • Status comes from /v1/array and /v2/disks; a disk the daemon rates degraded becomes a "missing" disk issue, which pauses schedules as before.
    • The diff is a diff task, then /v1/array?limit_diffs=….
    • SMART and the power state come from /v2/disks. SMART attribute names are mapped back to ids for the UI's assessment.
  • Interface change: the engine interface gains readLastRuns. The dashboard's last sync and scrub come from the daemon's task history, since its runs are not in the UI's logs.

Several arrays

A daemon serves one array; for several, snapraid-daemon 2.0 runs one instance each (snapraidd@<name>, own config and port). engine.json holds a list of daemons, one per configuration. buildEngine() runs each listed configuration on its daemon and the others on the CLI. One job still runs at a time across all of them.

Switching takes effect without a restart. PUT /api/engine swaps the engine; it refuses while a job runs. Scheduler and spindown follow through activeEngine.

UI

A snapraid-daemon card on the Automation page. Each entry has the configuration it serves, the address and an optional login; the password is masked and stored in engine.json with mode 600. Test connection shows the daemon and SnapRAID version and the array it serves. It warns when the daemon has its own schedule, spindown, Docker pause or notifications set, or serves another array than the one picked.

Known gaps (documented)

  • The daemon does not count files per disk, so the disks table shows "–".
  • Its runs have no log link and are not on the Logs page.
  • Unknown SMART attribute names get id 0.
  • 2.0 and SnapRAID 15 are release candidates.

Tests

  • Contract: engine-contract.ts now also runs against a live daemon when SNAPRAID_TEST_DAEMON_URL and SNAPRAID_TEST_DAEMON_CONF are set. It passes for the fake engine, the CLI engine (SnapRAID 14.10) and the daemon engine (snapraid-daemon 2.0rc2 with SnapRAID 15.0rc2, built here). The output step now runs diff instead of status, which every engine runs itself.
  • CI, without a daemon: daemon-engine.test.ts (14 tests) uses a stand-in that answers like 2.0rc2. It covers a sync with output and progress, scrub arguments, failed runs with and without a readable log, abort, the fallback, a smart job, busy reads, the diff, basic auth, unreachable and 401, the JSON mapping, last runs, and a task the daemon never runs.
  • Settings and routing: engine-settings.test.ts covers masked passwords, validation (one daemon per configuration), which engine runs which configuration, and the connection check with its warnings.
  • Results: deno test 120 passed and 2 ignored (no CLI binary or daemon), 122 passed with both. biome check, npm run typecheck, npm test (24) and npm run build pass, and mkdocs build --strict has no warnings.
  • End to end against two daemon instances (ports 7627 and 7628, two arrays) plus one configuration without a daemon:
    • The connection test reported versions and the served array.
    • A sync from the UI on each array ran as a task on the right daemon.
    • Status came from the right daemon, and the dashboard's last sync came from the daemon's history.
    • The third configuration ran on the CLI.

Docs

docs/automation.md has a new section: setup, one instance per array, which daemon options to turn off, what runs where, and the limitations. architecture.md maps each engine method for both engines and lists the known gaps. development.md explains how to run the contract against a daemon. configuration.md and security.md list engine.json.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JuXnquCPdbG5sBbDyin7yF


Generated by Claude Code

A daemon engine on snapraid-daemon's REST API (tested with 2.0rc2 and
SnapRAID 15.0rc2) implements the SnapRAID engine interface: jobs are
queued with /v1/schedule and followed through /v1/tasks and
/v1/activity for their messages and progress, abort goes to /v1/stop,
status, diff, SMART and the power state come from /v1/array and
/v2/disks. touch and status, which the daemon has no task for, go to
the CLI engine. When the daemon runs on the same machine, the report
of a run is read from its SnapRAID log, otherwise from the task.

A daemon serves one array; several run as snapraidd@<name>. On the
Automation page each configuration can get its daemon (address,
optional login, a connection test that warns about the daemon's own
schedule, spindown, Docker pause or notifications); configurations
without one keep running on the CLI, and one job still runs at a time
across all of them. The settings live in engine.json and switch the
engine without a restart; scheduler and spindown follow through
activeEngine.

The interface gains readLastRuns, as the daemon's runs are not in the
UI's logs. The daemon does not count files per disk, so the disks
table shows a dash there, and runs without a readable log get no log
link.

The engine contract now also runs against a live daemon when
SNAPRAID_TEST_DAEMON_URL is set and passes for the fake, the CLI and
the daemon engine. In CI, without a daemon, a stand-in that answers
like snapraid-daemon 2.0rc2 covers following tasks, progress, abort,
the fallback, auth, errors and the JSON mapping; the settings and which
engine runs which config have their own tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JuXnquCPdbG5sBbDyin7yF
@firsttris
firsttris merged commit 71991c7 into master Oct 9, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants