# Snapshot store The swarm's `btrfs receive` endpoint. Hives push agent snapshots to it over the WireGuard mesh; a destination hive later pulls one back to complete a migration. Two things it is not, both worth stating because both are easy to assume: - **It is not the swarm controller**, and does not depend on one. It is a NixOS host role: a btrfs subvolume tree, a socket-activated receiver, and the `wg-hive` interface the swarm module already brings up. That is why it can be deployed before any controller exists. - **It is not a backup product.** It happens to hold the data a backup would hold, and it should be operated accordingly (see [Operating it](#operating-it)) --- but nothing in it does scheduling, verification, or restore orchestration. ## Enabling it ```nix services.hyperhive.snapshotStore = { enable = true; path = "/var/lib/hyperhive-snapshots"; # must be on btrfs port = 51821; }; # The mesh is a hard requirement, and is asserted: services.hyperhive.swarm.wireguard = { enable = true; address = "10.100.0.9/24"; privateKeyFile = "/etc/wireguard/hive.key"; }; ``` The store host is a swarm member like any other: it gets an entry in `services.hyperhive.swarm.hives`, the same directory every host holds. See [swarm/](swarm/README.md) for the mesh itself. Note that the mesh is gated on `swarm.wireguard.enable`, **not** on `c0re.enable` --- a store host runs no hive and would otherwise get no `wg-hive` interface at all. ## Pointing a hive at it The block above configures the host that *receives*. Every hive that *pushes* separately needs to be told where the store is: ```nix services.hyperhive.swarm.snapshotStore = { address = "10.100.0.9"; # the store's mesh address, no prefix port = 51821; # optional; must match the receiver's port }; ``` Two deliberate asymmetries in that pair, both easy to misread as inconsistency: - **`address` has no default.** It is a deployment fact a pushing hive cannot derive, and a wrong guess means streaming an agent's state at whatever happens to answer. Unset, a push fails naming this option. - **`port` does default** (`51821`), because it is a convention both ends read from the same option docs --- a default there is coordination, not a guess. Note the option lives under `swarm.*` while the receiving host's lives under `services.hyperhive.snapshotStore`. That is the distinction the two namespaces carry throughout: `swarm.*` describes *the swarm* as seen from this host, and a bare `services.hyperhive.` describes *a role this host performs*. A store host sets both --- one to run the receiver, one only if it also runs a hive that pushes. With it set, `hivectl agent subvol snapshot push