102 lines
3.3 KiB
Nix
102 lines
3.3 KiB
Nix
# `checks.module-eval-snapshot-store` — see ./lib.nix for the shared
|
|
# rationale (why this suite exists, naming convention, "evaluates not
|
|
# executes").
|
|
#
|
|
# The snapshot store's receiver socket: where it listens, that it can bind
|
|
# before the mesh interface is up, that it refuses a wildcard, and that a
|
|
# silent or stalled transfer is bounded.
|
|
{
|
|
pkgs,
|
|
lib,
|
|
self,
|
|
nixosSystem,
|
|
}:
|
|
let
|
|
inherit
|
|
(import ./lib.nix {
|
|
inherit
|
|
pkgs
|
|
lib
|
|
self
|
|
nixosSystem
|
|
;
|
|
})
|
|
hive
|
|
runGroup
|
|
;
|
|
|
|
# Bare hive: the store and the mesh it needs, nothing else.
|
|
store = hive {
|
|
deploy.wireguard.enable = true;
|
|
deploy.wireguard.address = "10.100.0.1/24";
|
|
snapshotStore.enable = true;
|
|
snapshotStore.port = 51822;
|
|
};
|
|
|
|
# The same with a wildcard where the mesh address goes.
|
|
storeOnWildcard = hive {
|
|
deploy.wireguard.enable = true;
|
|
deploy.wireguard.address = "0.0.0.0/24";
|
|
snapshotStore.enable = true;
|
|
};
|
|
|
|
# The IPv6 wildcard.
|
|
storeOnWildcardV6 = hive {
|
|
deploy.wireguard.enable = true;
|
|
deploy.wireguard.address = "::/64";
|
|
snapshotStore.enable = true;
|
|
};
|
|
|
|
unit = store.systemd.services."swarm-snapshot-store@";
|
|
|
|
moduleSource = builtins.readFile ../host-modules/swarm-snapshot-store.nix;
|
|
|
|
socket = store.systemd.sockets.swarm-snapshot-store.socketConfig;
|
|
|
|
refusedAsWildcard =
|
|
m:
|
|
lib.any (
|
|
a: !a.assertion && lib.hasInfix "refuses a wildcard listen address" a.message
|
|
) m.assertions;
|
|
|
|
cases = [
|
|
{
|
|
# The wg-hive address does not exist when sockets.target binds, so
|
|
# without FreeBind the bind fails with EADDRNOTAVAIL and the receiver
|
|
# never listens. The unit still renders and evaluates either way, which
|
|
# is why only a rendered-config check can see it.
|
|
name = "the receiver socket may bind before the mesh interface has its address";
|
|
ok = socket.FreeBind or false == true;
|
|
}
|
|
{
|
|
# The bare IP and the configured port: the prefix length on
|
|
# `deploy.wireguard.address` must not leak into the listen address.
|
|
name = "the receiver socket listens on the mesh address and the configured port";
|
|
ok = socket.ListenStream == "10.100.0.1:51822";
|
|
}
|
|
{
|
|
# The control for the case below: it is the wildcard that trips the
|
|
# assertion, not the store being on.
|
|
name = "a mesh address on the store raises no wildcard refusal";
|
|
ok = !(refusedAsWildcard store);
|
|
}
|
|
{
|
|
# A wildcard bind is an unauthenticated remote write into agent state.
|
|
name = "a wildcard mesh address, IPv4 or IPv6, is refused";
|
|
ok = refusedAsWildcard storeOnWildcard && refusedAsWildcard storeOnWildcardV6;
|
|
}
|
|
{
|
|
# Without it a stalled `btrfs receive` holds a root instance forever.
|
|
name = "the receiver unit has a runtime ceiling";
|
|
ok = unit.serviceConfig.RuntimeMaxSec or null == "6h";
|
|
}
|
|
{
|
|
# The script is a store path, so its text is not evaluable without
|
|
# building it; the module source is the nearest thing to read. A
|
|
# silent peer must not hold the root instance past the header read.
|
|
name = "the receiver script bounds its header read";
|
|
ok = lib.hasInfix "read -r -t \${toString headerTimeoutSeconds} keyword agent" moduleSource;
|
|
}
|
|
];
|
|
in
|
|
runGroup "snapshot-store" cases
|