Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Failing after 3s
First slice of Phase 6. Ships a minimal, feature-gated `claw-fuse` binary that mounts the local blob store read-only as a POSIX filesystem: <mount>/blobs/<blob-id-hex> ← file, content = assembled blob <mount>/blobs/ ← dir, ls shows all blob-ids <mount>/ ← dir, contains `blobs` Lets an operator `tar -tvzf`, `md5sum`, or grep at a cached tarball without wiring a client. Debug + audit tool for now; warm-tier git-worktrees + write path come in later slices. Feature-gated so my macOS dev box doesn't need macFUSE headers to build the rest of the tree: * Cargo.toml declares `[[bin]] name = "claw-fuse"` with `required-features = ["fuse"]`. * Feature `fuse` pulls in `fuser = "0.15"`, target-restricted to `cfg(target_os = "linux")` — dep resolution never considers fuser on other platforms. * `cargo build` (default) leaves claw-fuse out entirely. `cargo build --features fuse --bin claw-fuse` on Linux builds it. Design notes baked into the impl: * Inode allocation is lazy — first `lookup` for a hex assigns an inode. Avoids pre-indexing the full blob store at mount time which would be O(blobs) fs walk before FUSE is even ready. * getattr / read validate that the manifest exists on every call — no stale-inode reads if a blob is GC'd out from under us mid-mount. Extra read cost is negligible against the per-request FUSE overhead. * size = manifest.total_size (bytes reported without touching chunk files) so `ls -l` is cheap. * runtime = current-thread tokio, block_on per callback. fuser is sync; a full tokio worker pool would just add scheduling overhead when callbacks are already serialized by the kernel. No new tests here — Filesystem impls are integration-heavy and the underlying BlobStore methods are already covered. The `fuse` feature build itself will be smoke-tested on tank. 381 tests pass unchanged (feature-gated bin doesn't affect the existing test surface).
103 lines
4.3 KiB
TOML
103 lines
4.3 KiB
TOML
[package]
|
||
name = "claw-store"
|
||
version = "0.3.0"
|
||
edition = "2021"
|
||
|
||
[[bin]]
|
||
name = "claw-store"
|
||
path = "src/main.rs"
|
||
|
||
# Phase 5b: fingerprint-keyed cargo build cache CLI. Wraps `cargo build`
|
||
# with a peer-cache lookup: hit → download+restore, miss → build+capture+upload.
|
||
# Uses the same identity/config surface as claw-store daemon.
|
||
[[bin]]
|
||
name = "claw-cargo"
|
||
path = "src/claw_cargo.rs"
|
||
|
||
# Phase 6 (2026-07-14): read-only FUSE mount that exposes the blob
|
||
# store as a filesystem. Gated behind the `fuse` cargo feature +
|
||
# Linux-only in dep resolution so my macOS dev box doesn't need
|
||
# macFUSE headers installed to build the other bins.
|
||
#
|
||
# Build with: cargo build --features fuse --bin claw-fuse
|
||
[[bin]]
|
||
name = "claw-fuse"
|
||
path = "src/claw_fuse.rs"
|
||
required-features = ["fuse"]
|
||
|
||
[features]
|
||
default = []
|
||
# Phase 6: enables the claw-fuse binary + pulls in the fuser dep.
|
||
fuse = ["dep:fuser"]
|
||
|
||
[target.'cfg(target_os = "linux")'.dependencies]
|
||
# v0.15 — Rust FUSE bindings. Only pulled on Linux + only when
|
||
# the `fuse` feature is on; keeps macOS + non-fuse builds clean.
|
||
fuser = { version = "0.15", optional = true }
|
||
|
||
[dependencies]
|
||
clap = { version = "4", features = ["derive", "env"] }
|
||
serde = { version = "1", features = ["derive"] }
|
||
toml = "0.8"
|
||
tokio = { version = "1", features = ["full"] }
|
||
sysinfo = "0.30"
|
||
anyhow = "1"
|
||
tracing = "0.1"
|
||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||
chrono = { version = "0.4", features = ["serde"] }
|
||
axum = { version = "0.7", features = ["macros"] }
|
||
tower-http = { version = "0.5", features = ["cors", "fs"] }
|
||
tokio-stream = "0.1"
|
||
serde_json = "1"
|
||
# v0.2.0 — flock(2) wrapper for atomic+locked manifest writes
|
||
# (manifest.rs). Already a transitive dep; declaring it directly
|
||
# makes the call site obvious.
|
||
libc = "0.2"
|
||
# v0.2.0 — sibling-tempfile + rename for atomic manifest persistence.
|
||
# Was previously dev-dep only; promoted to main.
|
||
tempfile = "3"
|
||
# v0.11.1 — cluster membership via scuttlebutt gossip + phi-accrual failure
|
||
# detection. Wraps in cluster/gossip.rs. UDP transport, keyed KV state per
|
||
# node, seed_nodes bootstrap from [[cluster.peers]] config.
|
||
chitchat = "0.11"
|
||
# v0.11 — QUIC transport for peer RPC (Phase 1c). UDP-based; runs on a
|
||
# separate port from chitchat gossip. TLS 1.3 by default; we wire mTLS
|
||
# against a fleet root CA in cluster/transport.rs.
|
||
quinn = { version = "0.11", default-features = false, features = ["runtime-tokio", "rustls-ring"] }
|
||
# v0.23 — TLS 1.3 provider driving quinn's crypto. Pinned to the ring
|
||
# provider so a single CryptoProvider is installed process-wide.
|
||
rustls = { version = "0.23", default-features = false, features = ["ring"] }
|
||
# v0.13 — X.509 cert generation for the fleet CA + per-node leaf certs.
|
||
# Used both by production bootstrap (writes PEM to /etc/claw-store/tls/)
|
||
# and by tests (in-memory ephemeral CA).
|
||
rcgen = { version = "0.13", features = ["pem", "x509-parser"] }
|
||
# v2 — parse PEM files into DER for rustls consumption. Used in
|
||
# NodeIdentity::from_pem_files (Phase 1d) so persistent identity round-trips
|
||
# through the file system on daemon restart.
|
||
rustls-pemfile = "2"
|
||
# v1 — content-addressed hashing for the Phase 2 blob store. BLAKE3 is
|
||
# used both for whole-blob addressing (BlobId) and for per-chunk
|
||
# addressing (dedup). Fast enough that a full-blob rehash on read
|
||
# verification stays cheap.
|
||
blake3 = "1"
|
||
# v0.4 — tar archive writer/reader for the Phase 5 build-artifact
|
||
# capture flow (cargo target/deps → tar → BlobPutStream). Preserves
|
||
# file metadata (mtimes, perms) which cargo relies on for its own
|
||
# incremental-rebuild fingerprint checks.
|
||
tar = "0.4"
|
||
# v0.13 — zstd wrapping around the tar stream. Level 3 is the default;
|
||
# gets 5-10× compression on cargo .rlib without noticeable CPU cost.
|
||
zstd = "0.13"
|
||
# v0.12 — HTTP client for the Phase 7f Gitea live-refs adapter.
|
||
# `rustls-tls` reuses the same rustls stack already pulled in by
|
||
# quinn — no additional TLS impls in the binary. `json` unlocks
|
||
# serde parsing of the /branches + /tags responses without a
|
||
# hand-rolled decoder. `default-features=false` drops native-tls
|
||
# and the openssl dep chain we don't need.
|
||
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "json"] }
|
||
|
||
[dev-dependencies]
|
||
tempfile = "3"
|
||
tower = { version = "0.5", features = ["util"] }
|
||
http-body-util = "0.1"
|