Files
grenadeandClaude Opus 5 97073b0971
ci / fmt (pull_request) Successful in 23s
bench / build (pull_request) Successful in 1m19s
ci / clippy (pull_request) Successful in 2m23s
ci / doc (pull_request) Successful in 2m29s
bench / measure (pull_request) Failing after 2m23s
ci / test (pull_request) Successful in 8m30s
deploy: tie the GPU profile to the miner's lifecycle
The power limit and 810 MHz memory lock were applied at boot as a host
setting, so they outlived the miner: a host switched back to LLM
inference kept the lock and decoded at a sixth of its measured speed,
with nothing reporting as throttled.

- quantus-miner.service applies the profile in ExecStartPre and resets
  to driver defaults in ExecStopPost (nvidia-power-limit.sh, installed
  by lair/quantus). ExecStopPost runs on stop, crash and failed start.
- deploy: on a host with neuron.service enabled, ship the files but do
  not enable or start the miner; validate passes there without checking
  hashing. neuron conflicts with the miner, so starting it would stop
  inference behind the operator's back.
- bench-on-host.sh: stopping the unit now resets the clocks, so apply
  the miner profile for the measurement window (and read the asserted
  power limit after it), restore the prior profile afterwards, and
  refuse to measure on a host where neuron is active.
- infra-setup.sh: sudoers for the two script invocations the bench
  needs. Re-run it on the mining hosts before the next deploy; the
  preflight will name the missing path until then.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XViS3RVfGTRaRSopLN68MA
2026-09-22 16:01:51 +03:00
..

deploy

Everything the CI deploy of the miner ships or needs (.gitea/workflows/deploy.yaml). Moved from lair/quantus on 2026-09-03 so that one repo owns the deployed miner; the fleet's monitoring, GPU power limits and nvidia metrics stay there.

File Lands at
quantus-miner.service /etc/systemd/system/quantus-miner.service
quantus-miner.sysusers.conf /etc/sysusers.d/quantus-miner.conf
quantus-miner-metrics.xml /etc/firewalld/services/quantus-miner-metrics.xml
miner.env.tmpl rendered to /etc/quantus-miner/miner.env
infra-setup.sh operator-run once per host; installs the gitea_ci sudoers

The miner's credentials are generated by the node and copied host-to-host by the deploy on every run. Nothing secret lives here.

Traps, all previously hit

  • Adding a file or privileged command means re-running infra-setup.sh. The deploy preflights the host's sudo -n -l against the script's SUDO block and names the missing paths, instead of failing partway with sudo: a password is required.
  • Deploys must be no-ops when nothing changed. push() uses rsync -ic (checksum). The artifact is rebuilt every run so mtimes always differ. Restart only on an itemised content change.
  • --node-addr takes an IP, not a name. It parses as a Rust SocketAddr with no DNS. The deploy resolves the node on the miner host and renders the literal; the 10.x never enters the repo.
  • Pipes in validate steps. The shell is bash -e -o pipefail; a reader that exits early (awk ... exit, grep -q, head) SIGPIPEs the writer, exit 141. Capture into a variable and parse with a here-string.
  • ssh argument quoting. run() is ssh ... "$@" and the remote shell re-splits; any argument with a space is passed as one pre-quoted string.
  • PrivateDevices=false in the unit is deliberate: the miner needs /dev/nvidia*.
  • systemctl is-active is not evidence of mining. A miner that found no adapter, or never got a job, is active. Validate asserts miner_hashes_total advances and miner_gpu_devices matches the matrix.
  • Binaries must be built on cuda-13.0 (Fedora 43, like the hosts). The rust runner is Fedora 44; its binaries fail with GLIBC_2.43 not found.
  • The GPU profile lives and dies with the unit. quantus-miner.service applies the power limit and 810 MHz memory lock in ExecStartPre and resets to driver defaults in ExecStopPost, via nvidia-power-limit.sh from lair/quantus. The lock cuts LLM inference to a sixth of its speed with nothing reporting as throttled, so it must not outlive the miner. Stopping the unit therefore also resets the clocks — the benchmark re-applies the profile for its window.
  • An inference host is left alone. When neuron.service is enabled on a host, the deploy ships the miner's files but does not enable or start it, and validate passes without checking hashing. neuron conflicts with the miner, so starting it would stop inference. Switch hosts deliberately: systemctl disable --now neuron && systemctl enable --now quantus-miner.
  • A benchmark (bench.yaml) stops the miner on its host. A deploy landing on the same host during a measurement would find the unit down and start it mid-window. Both are serialised only by not running them together.