No description
  • Python 92.3%
  • HTML 5.9%
  • CSS 1.3%
  • Shell 0.3%
  • Just 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-15 11:15:24 -04:00
deploy deploy: help page, systemd units and install 2026-10-15 01:31:13 -04:00
src/shelfcheck warranty: save the BPID's last 4 for Seagate checks 2026-10-15 11:15:24 -04:00
tests warranty: save the BPID's last 4 for Seagate checks 2026-10-15 11:15:24 -04:00
.gitignore scaffold: uv project, justfile, config 2026-10-14 20:17:44 -04:00
.pre-commit-config.yaml scaffold: uv project, justfile, config 2026-10-14 20:17:44 -04:00
justfile deploy: help page, systemd units and install 2026-10-15 01:31:13 -04:00
Procfile.dev scaffold: uv project, justfile, config 2026-10-14 20:17:44 -04:00
pyproject.toml runner: real-device badblocks integration test 2026-10-14 23:37:34 -04:00
README.md deploy: help page, systemd units and install 2026-10-15 01:31:13 -04:00
uv.lock scaffold: uv project, justfile, config 2026-10-14 20:17:44 -04:00

shelfcheck

Test and catalog used hard drives on a homelab box. Plug a drive into one of the 12 hot-swap bays, open the web UI, and shelfcheck recognizes it by serial, runs a quick test (minutes, read-only) or a deep test (about a week, destructive: SMART long self-tests around four badblocks write passes), and reduces the result to a green / yellow / red status next to the drive's size and serial. Every drive that passes through stays in a permanent catalog with its full history and raw logs. Webhooks report events to your alerting.

Two processes, both run as root by systemd:

  • shelfcheck-runner owns everything that touches disks: tests, hotplug, webhook delivery. Restarting it interrupts running tests (they can be resumed).
  • shelfcheck-web is the FastAPI UI on port 8080. Restarting it never touches a test.

The in-app Help page documents the webhook payloads, the rating rules and thresholds, the test stages, every environment variable, resuming interrupted runs, and bay calibration.

Commands

Python goes through uv; the justfile is the entrypoint.

Command What it does
just setup uv sync and install the pre-commit hook
just test the test suite (no real disks touched)
just test-root real loop/device-mapper tests, as root (sudo)
just lint the pinned pre-commit hooks (ruff, ruff-format, ty)
just install install and start both systemd services (idempotent, sudo)
just uninstall stop and remove the services; config and data stay
just dev both processes under overmind with data in ./.data

just install runs uv sync, creates /etc/shelfcheck and /var/lib/shelfcheck (mode 0700), installs deploy/shelfcheck-runner.service and deploy/shelfcheck-web.service into /etc/systemd/system, and enables both. The units run the .venv of this checkout, so run just install from the checkout (/home/xnet-admin/lab/shelfcheck). The first run creates the env file and prints the generated login once; later runs never overwrite or print it.

Where things live

Path What
/etc/shelfcheck/shelfcheck.env configuration (deploy/shelfcheck.env.example documents every variable), mode 0600, root
/var/lib/shelfcheck/ database (shelfcheck.db), raw run artifacts, browse mounts, session key (secret_key)
/etc/systemd/system/shelfcheck-{runner,web}.service the units
journalctl -u shelfcheck-runner -u shelfcheck-web logs

Changing the password

Edit SHELFCHECK_PASSWORD in /etc/shelfcheck/shelfcheck.env, then sudo systemctl restart shelfcheck-web. Only the web service uses the login, so the runner (and any running test) is left alone. Settings the runner reads (thresholds, webhook URL, bay count) need sudo systemctl restart shelfcheck-runner as well, which interrupts running tests: change them between tests.