Files
homelab/hosts/mars/configuration.nix
T
darmanandClaude Opus 5 a8a1cffa3e mars: mirror luna's Obsidian vault to disk with livesync-bridge
Gives the Hermes agent a real directory of markdown for the luna_wiki
vault, at /var/lib/livesync-bridge/vault and mounted into her container at
/opt/data/vault (inside HERMES_WRITE_SAFE_ROOT, so she can write, not only
read). Obsidian itself is an Electron GUI with no headless mode, and an
agent wants files rather than an app.

livesync-bridge is Deno, not packaged, and publishes no image — upstream
ships only a `build: .` compose file. So it comes in as a pinned non-flake
input and runs under systemd. Two things that are not obvious:

  - The source is COPIED to a fixed path rather than run from /nix/store.
    Deno keys localStorage — where the bridge records per-file sync state —
    by the main module's origin. Verified by running one source tree from
    two paths against a single DENO_DIR: two origin directories appear. Run
    from the store, every input bump would silently reset both peers to a
    full rescan.
  - It runs as uid 986/gid 983, the same identity the hermes container
    uses. Two uids in a shared group only works while every file stays
    group-writable, and one 0644 file dropped by the agent would stall sync
    on that path.

Talks to CouchDB over the tailnet (jupiter.orbit.sol:5984), so neptun's
vhost, its TLS and its path allowlist are all out of the picture.

Verified before deploying: `deno check` passes on nixpkgs' 2.8.3 (upstream
pins 2.6.9), and the bridge starts, reads LSB_CONFIG, detects a file and
writes its health heartbeat. Both directions confirmed working on mars
afterwards.

Credentials are currently the `obsidian` admin account and the personal
vault's passphrase, which means mars can decrypt every vault database and
not just luna's. Deliberate reuse of what existed; hosts/mars/secrets.nix
records the two independent ways to narrow it.

⚠️ Upstream has three open, unanswered issues on the storage->couchdb
direction (#50, #23, #46) and all fail silently — the log reports the
upload and the database is never updated. Do not treat this directory as
durable storage for anything luna cannot regenerate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TLN5nkLBtCciD3ZnUwtw2b
2026-08-26 00:10:34 +02:00

56 lines
2.3 KiB
Nix

{ config, pkgs, ... }:
# mars — on-site x86_64 box, single-purpose: runs Hermes Agent only.
# See hermes-agent.nix for what that is and why it moved here from jupiter.
{
imports = [
./hardware-configuration.nix
./disk-config.nix # disko: OS-disk partitions + filesystems
./secrets.nix # sops-nix: samba/tailscale/hermes secrets
./hermes-agent.nix
./livesync-bridge.nix
../../common.nix # shared base: user / ssh / nix / firewall
../../services/containers.nix
../../services/vpn/tailscale.nix
../../services/monitoring/node-exporter.nix
];
networking.hostName = "mars";
networking.networkmanager.enable = true; # DHCP on-site, same as jupiter
users.users.darman.extraGroups = [ "docker" ]; # merges with common.nix; podman debug access
# ---- Boot (UEFI, confirmed) ----
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# jupiter's samba share (services/network/samba.nix) — mounted on demand so
# mars doesn't stall boot/login when jupiter is off or unreachable. This is
# also where Hermes's shared dropbox lives now (hermes-agent.nix). Modes are
# tighter than terra's equivalent mount (0770 not 0755, gid=hermes not
# gid=users) since the hermes-agent container (uid 986, gid 983 — no podman
# userns remapping, see services/network/pihole.nix) needs group write into
# it, not just darman.
fileSystems."/mnt/jupiter" = {
device = "//jupiter/data";
fsType = "cifs";
options = [
"credentials=${config.sops.templates."jupiter-smb.credentials".path}"
"uid=1000"
"gid=983"
"file_mode=0770"
"dir_mode=0770"
"nofail"
"x-systemd.automount" # lazy-mount so boot doesn't stall if jupiter's down
# NO idle-timeout here (unlike terra's equivalent mount): hermes-agent's
# podman-hermes-agent.service RequiresMountsFor this path, so an idle
# auto-unmount tears the container down with it — confirmed the hard
# way, it killed the service ~60-70s after every start with no crash
# or error, just "Unmounting /mnt/jupiter" right before the stop.
"x-systemd.mount-timeout=10s"
"_netdev"
];
};
system.stateVersion = "26.05"; # set at install time; do NOT bump on upgrades
}