Milestone 5: metered awareness, DSCP, systemd, man pages, packaging
Metered detection polls NetworkManager's Metered property over D-Bus (feature "metered", default on; builds without D-Bus via no-default-features). While metered the daemon closes incoming blob connections and defers every fetch; VARDE_FORCE_METERED=true forces the state as a kill switch and test hook. Endpoint UDP sockets get DSCP CS1 best-effort by matching bound ports to /proc/net/udp inodes (iroh hides its fds). systemd socket activation adopts LISTEN_FDS fd 3, readiness is a hand-rolled sd_notify READY=1 (abstract + path sockets), and standalone binding still works unchanged. dist/ ships hardened system and user units (DynamicUser, ProtectSystem=strict, StateDirectory, RestrictAddressFamilies), a commented config example, scdoc man pages validated with scdoc, and an untested PKGBUILD skeleton. Tests: activation-socket round trip via a real fd-3 handoff, READY=1 received on a NOTIFY_SOCKET, metered daemons neither serve nor fetch. Dependencies: zbus (optional, feature-gated D-Bus client for the NetworkManager metered flag). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Vendored
+49
@@ -0,0 +1,49 @@
|
||||
# Maintainer: you
|
||||
#
|
||||
# UNTESTED SKELETON — best-effort Arch packaging for varde. Review before
|
||||
# building; in particular pkgver/source must point at a real release.
|
||||
|
||||
pkgname=varde
|
||||
pkgver=0.1.0
|
||||
pkgrel=1
|
||||
pkgdesc="Content-addressed blob mirror daemon on iroh"
|
||||
arch=('x86_64' 'aarch64')
|
||||
url="https://github.com/bendiklh/varde"
|
||||
license=('MIT OR Apache-2.0')
|
||||
depends=('gcc-libs')
|
||||
optdepends=('networkmanager: metered-connection detection')
|
||||
makedepends=('cargo' 'scdoc')
|
||||
source=("$pkgname-$pkgver.tar.gz::$url/archive/v$pkgver.tar.gz")
|
||||
sha256sums=('SKIP')
|
||||
|
||||
build() {
|
||||
cd "$pkgname-$pkgver"
|
||||
export RUSTUP_TOOLCHAIN=stable
|
||||
export CARGO_TARGET_DIR=target
|
||||
cargo build --release --locked
|
||||
scdoc < dist/varde.8.scd > varde.8
|
||||
scdoc < dist/varde-ctl.1.scd > varde-ctl.1
|
||||
}
|
||||
|
||||
check() {
|
||||
cd "$pkgname-$pkgver"
|
||||
# Integration tests spawn daemons and use the network; keep package
|
||||
# builds to the fast unit tests.
|
||||
cargo test --release --locked --lib -p varde-proto -p varde-daemon
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$pkgname-$pkgver"
|
||||
install -Dm755 target/release/varde-daemon "$pkgdir/usr/bin/varde-daemon"
|
||||
install -Dm755 target/release/varde-ctl "$pkgdir/usr/bin/varde-ctl"
|
||||
|
||||
install -Dm644 dist/varde.service "$pkgdir/usr/lib/systemd/system/varde.service"
|
||||
install -Dm644 dist/varde.socket "$pkgdir/usr/lib/systemd/system/varde.socket"
|
||||
install -Dm644 dist/user/varde.service "$pkgdir/usr/lib/systemd/user/varde.service"
|
||||
install -Dm644 dist/user/varde.socket "$pkgdir/usr/lib/systemd/user/varde.socket"
|
||||
|
||||
install -Dm644 dist/config.toml "$pkgdir/etc/varde/config.toml"
|
||||
|
||||
install -Dm644 varde.8 "$pkgdir/usr/share/man/man8/varde.8"
|
||||
install -Dm644 varde-ctl.1 "$pkgdir/usr/share/man/man1/varde-ctl.1"
|
||||
}
|
||||
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
# varde example configuration — /etc/varde/config.toml (system) or
|
||||
# $XDG_CONFIG_HOME/varde/config.toml (user).
|
||||
#
|
||||
# Every key is optional; the daemon runs with an empty (or absent)
|
||||
# config. Values shown are the defaults. Precedence:
|
||||
# CLI flags > VARDE_* environment > this file > defaults.
|
||||
|
||||
# Directory holding the blob store, metadata and endpoint secret key.
|
||||
# Default: /var/lib/varde (system) or $XDG_DATA_HOME/varde (user).
|
||||
#store_dir = "/var/lib/varde"
|
||||
|
||||
# Unix socket serving the JSON-lines API.
|
||||
# Default: /run/varde/varde.sock (system) or $XDG_RUNTIME_DIR/varde.sock.
|
||||
#socket_path = "/run/varde/varde.sock"
|
||||
|
||||
# Upload cap in bytes/sec. 0 disables serving entirely.
|
||||
#max_upload_bytes_per_sec = 10485760 # 10 MiB/s
|
||||
|
||||
# Download cap in bytes/sec. 0 means unlimited.
|
||||
#max_download_bytes_per_sec = 0
|
||||
|
||||
# LAN peer discovery (mDNS). Discovery is the open tier: being visible
|
||||
# costs nothing; serving is still gated on trust and per-pin policy.
|
||||
#discovery = true
|
||||
|
||||
# Permit WAN traffic (enables the iroh relay for NAT traversal). Off by
|
||||
# default: LAN-only posture, zero WAN upload.
|
||||
#wan_upload = false
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
# varde per-user service (systemctl --user). Pairs with the user
|
||||
# varde.socket; stores under $XDG_DATA_HOME/varde.
|
||||
[Unit]
|
||||
Description=varde content-addressed blob mirror daemon (user)
|
||||
Documentation=man:varde(8)
|
||||
Requires=varde.socket
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
ExecStart=/usr/bin/varde-daemon --user
|
||||
Restart=on-failure
|
||||
NoNewPrivileges=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
# Socket activation for the per-user varde daemon.
|
||||
[Unit]
|
||||
Description=varde API socket (user)
|
||||
|
||||
[Socket]
|
||||
ListenStream=%t/varde.sock
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
varde-ctl(1)
|
||||
|
||||
# NAME
|
||||
|
||||
varde-ctl - control the varde blob mirror daemon
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
*varde-ctl* [*--socket* _PATH_] [*--json*] _COMMAND_ [_ARGS_]
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
Command-line client for *varde*(8), speaking the JSON Lines socket
|
||||
protocol. Doubles as the protocol's reference implementation: every
|
||||
subcommand maps 1:1 onto a request.
|
||||
|
||||
# GLOBAL OPTIONS
|
||||
|
||||
*--socket* _PATH_
|
||||
Daemon socket (env: *VARDE_SOCKET*). Default:
|
||||
_/run/varde/varde.sock_ as root, _$XDG_RUNTIME_DIR/varde.sock_
|
||||
otherwise.
|
||||
|
||||
*--json*
|
||||
Print the raw JSON response envelope instead of human output.
|
||||
|
||||
# COMMANDS
|
||||
|
||||
*add* [-r|--recursive] _PATH_
|
||||
Import a file (or, with *-r*, a directory tree) into the store.
|
||||
Prints the root hash. Content is not pinned by adding — pin it to
|
||||
protect it from *gc*.
|
||||
|
||||
*pin* [--open-lan] _HASH_
|
||||
Standing intent: keep this content, fetch it if absent, serve it to
|
||||
trusted peers. *--open-lan* serves it to any LAN peer.
|
||||
|
||||
*unpin* _HASH_
|
||||
Remove the intent. Data stays until *gc*.
|
||||
|
||||
*materialize* [--mode reflink-or-copy|copy] _HASH_ _DEST_
|
||||
Export content to a path. The default mode reflinks when the
|
||||
filesystem supports it and falls back to copying.
|
||||
|
||||
*status* [_HASH_]
|
||||
Daemon status, or presence/completeness of one hash.
|
||||
|
||||
*list*
|
||||
All pins with policy and completeness.
|
||||
|
||||
*ticket export* _HASH_
|
||||
Print an iroh ticket for out-of-band sharing. Note: exporting
|
||||
grants standing consent to serve that content to anyone (the
|
||||
ticket holder is not on the allowlist).
|
||||
|
||||
*ticket import* [--open-lan] _TICKET_
|
||||
Pin the ticket's content and fetch it from the embedded provider.
|
||||
|
||||
*peer trust* _NODE-ID_
|
||||
Add a peer to the allowlist. Content is served to and auto-fetched
|
||||
from trusted peers only. Applies to connections made after the
|
||||
change.
|
||||
|
||||
*peer untrust* _NODE-ID_
|
||||
Remove a peer from the allowlist.
|
||||
|
||||
*peer list*
|
||||
Trusted peers and whether they are currently present on the LAN.
|
||||
|
||||
*gc*
|
||||
Drop all blobs not reachable from a pin. Never runs implicitly.
|
||||
|
||||
*subscribe*
|
||||
Stream daemon events (transfer progress, peer presence, pin
|
||||
completion) as JSON lines until interrupted.
|
||||
|
||||
# EXIT STATUS
|
||||
|
||||
0 on success; nonzero with a structured error (code and message) on
|
||||
stderr otherwise.
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
*varde*(8)
|
||||
Vendored
+77
@@ -0,0 +1,77 @@
|
||||
varde(8)
|
||||
|
||||
# NAME
|
||||
|
||||
varde-daemon - content-addressed blob mirror daemon on iroh
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
*varde-daemon* [_OPTIONS_]
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
varde owns a content-addressed blob store and mirrors content between
|
||||
consenting peers. Applications talk to it over a unix socket speaking
|
||||
JSON Lines (one request per line, one response per line); *varde-ctl*(1)
|
||||
is the reference client.
|
||||
|
||||
Discovery is open; replication is explicit. The daemon advertises itself
|
||||
via mDNS on the local network (identifiable, never camouflaged), but
|
||||
content is only served to peers on the trust allowlist, plus content
|
||||
deliberately published per-pin (*open-lan*) or via ticket export. All
|
||||
fetched data is BLAKE3-verified regardless of source.
|
||||
|
||||
Default traffic posture: LAN only (no relay), upload capped at 10 MiB/s,
|
||||
UDP sockets marked DSCP CS1 (best effort), and all transfers stop while
|
||||
NetworkManager reports the connection as metered.
|
||||
|
||||
# OPTIONS
|
||||
|
||||
*--config* _PATH_
|
||||
Config file. Default: _/etc/varde/config.toml_ in system mode,
|
||||
_$XDG_CONFIG_HOME/varde/config.toml_ in user mode. The default file
|
||||
may be absent; an explicitly named one must exist.
|
||||
|
||||
*--store* _PATH_
|
||||
Store directory override.
|
||||
|
||||
*--socket* _PATH_
|
||||
API socket path override.
|
||||
|
||||
*--system*, *--user*
|
||||
Force system-mode or user-mode default paths. Default: system when
|
||||
running as root, user otherwise.
|
||||
|
||||
*--version*, *--help*
|
||||
Print version or usage and exit.
|
||||
|
||||
# CONFIGURATION
|
||||
|
||||
See the commented example at _/etc/varde/config.toml_. Precedence:
|
||||
flags > *VARDE_\** environment variables (*VARDE_CONFIG*, *VARDE_STORE*,
|
||||
*VARDE_SOCKET*, *VARDE_MAX_UPLOAD*, *VARDE_MAX_DOWNLOAD*,
|
||||
*VARDE_DISCOVERY*, *VARDE_WAN_UPLOAD*) > config file > defaults.
|
||||
|
||||
# FILES
|
||||
|
||||
_/var/lib/varde_ (system), _$XDG_DATA_HOME/varde_ (user)
|
||||
Store directory: iroh-blobs store under _blobs/_, pins and trust in
|
||||
_meta.json_, endpoint key in _secret.key_ (mode 0600).
|
||||
|
||||
_/run/varde/varde.sock_ (system), _$XDG_RUNTIME_DIR/varde.sock_ (user)
|
||||
API socket. systemd socket activation (LISTEN_FDS) is supported;
|
||||
without it the daemon binds the socket itself.
|
||||
|
||||
# NOTES
|
||||
|
||||
Materialization attempts a reflink (FICLONE) before falling back to a
|
||||
byte copy; store directory and materialization targets must share a
|
||||
filesystem (btrfs/XFS) for reflinks to work. Store files are immutable
|
||||
and never hardlinked out.
|
||||
|
||||
DSCP marking may require CAP_NET_ADMIN on some systems and is silently
|
||||
skipped where unavailable.
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
*varde-ctl*(1)
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
# varde system service. Pairs with varde.socket for socket activation;
|
||||
# also runs standalone (the daemon binds its own socket when not
|
||||
# activated).
|
||||
[Unit]
|
||||
Description=varde content-addressed blob mirror daemon
|
||||
Documentation=man:varde(8)
|
||||
After=network.target
|
||||
Requires=varde.socket
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
ExecStart=/usr/bin/varde-daemon --system
|
||||
Restart=on-failure
|
||||
|
||||
# Hardening
|
||||
DynamicUser=yes
|
||||
StateDirectory=varde
|
||||
RuntimeDirectory=varde
|
||||
NoNewPrivileges=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
PrivateTmp=yes
|
||||
PrivateDevices=yes
|
||||
ProtectKernelTunables=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectControlGroups=yes
|
||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
|
||||
RestrictNamespaces=yes
|
||||
RestrictRealtime=yes
|
||||
RestrictSUIDSGID=yes
|
||||
LockPersonality=yes
|
||||
MemoryDenyWriteExecute=yes
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=@system-service
|
||||
CapabilityBoundingSet=
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
# Socket activation for the varde system daemon.
|
||||
[Unit]
|
||||
Description=varde API socket
|
||||
|
||||
[Socket]
|
||||
ListenStream=/run/varde/varde.sock
|
||||
SocketMode=0666
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
Reference in New Issue
Block a user