Commit Graph
9 Commits
Author SHA1 Message Date
Omar Sobh f33468b7c2 dashboard-v2 PR 2: frontend SPA + serve integration
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Successful in 16s
React 19 + Vite + Tailwind + wouter (tiny router, no external
state library). Consumes the /api/v2/* endpoints shipped in PR 1.
Serves under /v2/* so the legacy dashboard at / stays live.

Pages:
* CommandCenter (/)      — fleet strip + this-node stat tiles
* NodeDetail (/nodes/:name) — per-node deep dive
* StorageBrowser (/storage/{blobs,tags,refs,snapshots}) — tables
  with prefix filter
* RefTrackingPage (/refs/tracking) — grouped by repo

Backend changes:
* claw-store serve grows --v2-static-dir <path>
* build_app split into build_app_with_v2 for the extra static
  mount
* /v2/* falls through to index.html so wouter client routing works

New systemd unit: clawstor-dashboard.service. Points at both
static dirs; installs on any node.

dashboard/ (legacy) untouched. dashboard-v2/ built to
target/dashboard-v2/dist for deploy.

Deploy sequence per node:
1. cp target/release/claw-store  ~/clawstor-deploy/
2. rsync dashboard-v2/dist/      ~/clawstor-deploy/dashboard-v2/
3. cp deploy/systemd/clawstor-dashboard.service ~/.config/systemd/user/
4. systemctl --user daemon-reload && enable --now clawstor-dashboard.service

Cross-node fan-out for /api/v2/node/:name/status is PR 3.
Action POSTs (scrub/gc/snapshot/pin) are PR 4.
2026-07-14 15:59:47 -07:00
Omar Sobh c46206c6dd Polish: minimal clawstor-fuse.service (fixes morpheus mount EPERM)
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Failing after 3s
Live smoke on morpheus with the previous unit failed:
  Error: mounting FUSE at /home/osobh/clawstor-mount
  Caused by: Operation not permitted (os error 1)

But 'systemd-run --user' with the exact same binary worked, and
the manual invocation worked. The delta was our ExecStartPre
chain (mkdir + fusermount3 -u -z) — on some Ubuntu 24.04 builds
that combination poisons the subsequent mount syscall even with
the -z lazy flag + ignored exit code.

Fix: drop the pre-mkdir + pre-unmount. Operator creates the
mount dir manually once (documented in README). Restart handling
falls to systemd's Restart=on-failure + ExecStop unmount.

Verified live on morpheus with the minimal unit — active +
mount visible in <3s.
2026-07-14 14:31:41 -07:00
Omar Sobh 9d7e62bcee Polish: enable claw-fuse on macOS via macFUSE + deploy/macos docs
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Successful in 15s
Cargo.toml: fuser dep now target-gated to Linux + macOS. macOS
build requires macFUSE (brew install --cask macfuse) + pkg-config
before 'cargo build --features fuse' works.

deploy/macos/README.md — one-time prereqs, build steps, mount /
umount, known differences (no AllowOther, unmount is 'umount'
not fusermount3 -u).

deploy/macos/claw-fuse.plist — launchd agent template
(RunAtLoad + KeepAlive) so ghost / macbook / smith can run the
mount the same way tank/architect do under systemd.

Default 'cargo build' (no --features fuse) still works on macOS
with no macFUSE installed — feature gate keeps the dep opt-in.
2026-07-14 13:16:17 -07:00
Omar Sobh 7a3c04bed7 Polish: daily snapshot rotation script + systemd timer
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Successful in 10s
deploy/scripts/rotate-snapshots.sh creates daily-YYYY-MM-DD
snapshot + prunes daily-* older than RETAIN_DAYS. Only touches
its own daily-* namespace so hand-created snapshots (release
anchors etc) never get reaped.

02:00 timer runs ahead of the 03:15 ref-sweep + 03:30 gc so
tonight's fresh snapshot pins protect its blobs from eviction.

DRY_RUN=1 for preview.
2026-07-14 13:12:15 -07:00
Omar Sobh 4c4b587193 Phase 7i: nightly cluster-ref-sweep systemd timer
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Failing after 3s
03:15 local, Persistent=true. Runs ahead of the 03:30 GC so
operators see the stale-fingerprint report before eviction lands.

Environment= drives the Gitea URL; token expected in a drop-in
(clawstor-ref-sweep.service.d/token.conf) so it doesn't sit in
the unit file. README + install recipe updated.
2026-07-14 12:42:02 -07:00
Omar Sobh 74caaed0d1 Phase 7h: nightly cluster-gc systemd timer
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Failing after 3s
03:30 local, Persistent=true. Ordered before the Sun 04:00
scrub so scrub reads a fresh post-GC layout.

Default ExecStart is orphan-chunk sweep only (safe on any
node). Fleets that want LRU size-cap eviction add a drop-in:
  systemctl --user edit clawstor-gc.service
  [Service]
  ExecStart=
  ExecStart=%h/clawstor-deploy/claw-store --config ... cluster-gc --evict-to-gb 200

README updated.
2026-07-14 12:40:20 -07:00
Omar Sobh 3000021ac3 Phase 7g: weekly cluster-scrub systemd timer
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Successful in 11s
Deploy artifact. Sunday 04:00 local, Persistent=true so a
box that missed the wall-clock moment fires on next boot.

Timer + Service pair — both go under
~/.config/systemd/user/. The service is Type=oneshot; timer
drives it. Non-zero exit from cluster-scrub (integrity issue)
surfaces via systemd failed state; journalctl has the details.

README updated with install recipe.
2026-07-14 12:38:59 -07:00
Omar Sobh 6071fdb7d9 Phase 6d hotfix: systemd ExecStart needs %h not ${VAR}
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Successful in 12s
status=203/EXEC means the exec path didn't resolve. systemd
expands %h (home) at parse time but does NOT expand ${VAR}
in the ExecStart executable position — only in ExecStart args.
Rewrote to use %h/clawstor-deploy/claw-fuse directly.
2026-07-14 12:30:52 -07:00
Omar Sobh b1fc463655 Phase 6d: systemd user unit for persistent FUSE mount
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Successful in 15s
Deploy artifact — not built into the binary tree. `deploy/systemd/
clawstor-fuse.service` + README with the install recipe.

Unit shape:
* Type=simple, blocks on the FUSE binary (unmount = SIGTERM).
* ExecStartPre = mkdir -p mount, best-effort lazy unmount of any
  stale prior mount (guards against a hard SIGKILL leaving the
  kernel with a dangling mount).
* Restart=on-failure, RestartSec=5 — recover from transient IO
  errors without operator involvement.
* Environment= for CLAWSTOR_FUSE_BIN / DATA / MOUNT so a
  `systemctl edit` drop-in retargets without editing the unit file.

Dependency chain: clawstor-fuse.service After= + Wants=
clawstor-cluster.service. FUSE reads only the on-disk state so
this is technically not needed for correctness — but keeps the
mount from spinning up on a node where the daemon is broken.
2026-07-14 12:29:32 -07:00