hive-c0re pulls closures through the nix daemon; hive-priv verifies the swarm signature before applying
This commit is contained in:
parent
448b703995
commit
ecd4445680
2 changed files with 1257 additions and 584 deletions
|
|
@ -15,6 +15,8 @@ let
|
|||
hive = "alpha";
|
||||
host = "cache.example";
|
||||
dir = "@DIR@/attic";
|
||||
url = "https://cache.example/swarm";
|
||||
confFile = "@DIR@/nix/cache.conf";
|
||||
}
|
||||
);
|
||||
in
|
||||
|
|
|
|||
|
|
@ -45,15 +45,30 @@ case "\$1 \$2" in
|
|||
esac
|
||||
STUB
|
||||
chmod +x "$dir/bin/bao"
|
||||
|
||||
# `systemctl` answers for nix-daemon.service: DAEMON_STARTED is when it last
|
||||
# became active (empty: never) and every restart request is logged.
|
||||
cat >"$dir/bin/systemctl" <<STUB
|
||||
#!$BASH
|
||||
echo "systemctl \$*" >>"$dir/systemctl"
|
||||
case "\$1" in
|
||||
show) printf '%s\n' "\${DAEMON_STARTED-}" ;;
|
||||
is-failed) exit 1 ;;
|
||||
try-restart) ;;
|
||||
*) echo "unexpected call: \$*" >&2; exit 98 ;;
|
||||
esac
|
||||
STUB
|
||||
chmod +x "$dir/bin/systemctl"
|
||||
export PATH="$dir/bin:$PATH"
|
||||
|
||||
KEYLEAF=secret_swarm_hives_alpha_attic_public-key
|
||||
TOKENLEAF=secret_swarm_hives_alpha_attic_pull-token
|
||||
|
||||
reset() {
|
||||
rm -rf "$dir/store" "$dir/attic" "$calls"
|
||||
rm -rf "$dir/store" "$dir/attic" "$dir/nix" "$calls" "$dir/systemctl"
|
||||
mkdir -p "$dir/store"
|
||||
: >"$calls"
|
||||
: >"$dir/systemctl"
|
||||
}
|
||||
|
||||
seed() { # <key> <token>
|
||||
|
|
@ -66,6 +81,7 @@ run() {
|
|||
env "$@" bash "$dir/script.sh" >"$dir/out" 2>"$dir/err"
|
||||
}
|
||||
|
||||
restarts() { grep -c '^systemctl try-restart' "$dir/systemctl"; }
|
||||
mode() { stat -c %a "$1" 2>/dev/null || echo missing; }
|
||||
ino() { stat -c %i "$1" 2>/dev/null || echo missing; }
|
||||
body() { cat "$1" 2>/dev/null || echo missing; }
|
||||
|
|
@ -80,14 +96,22 @@ expect "netrc" "$(body "$dir/attic/netrc")" "machine cache.example password tok-
|
|||
expect "key mode" "$(mode "$dir/attic/public-key")" 600
|
||||
expect "netrc mode" "$(mode "$dir/attic/netrc")" 600
|
||||
expect "dir mode" "$(mode "$dir/attic")" 700
|
||||
expect "fragment" "$(body "$dir/nix/cache.conf")" "extra-trusted-substituters = https://cache.example/swarm
|
||||
extra-trusted-public-keys = swarm:S0VZ
|
||||
netrc-file = $dir/attic/netrc"
|
||||
expect "fragment mode" "$(mode "$dir/nix/cache.conf")" 644
|
||||
expect "fragment dir mode" "$(mode "$dir/nix")" 755
|
||||
expect "no secret in the fragment" "$(grep -c tok-1 "$dir/nix/cache.conf")" 0
|
||||
|
||||
case="a second run with the same facts rewrites nothing"
|
||||
k=$(ino "$dir/attic/public-key")
|
||||
n=$(ino "$dir/attic/netrc")
|
||||
c=$(ino "$dir/nix/cache.conf")
|
||||
run
|
||||
expect "exit" $? 0
|
||||
expect "key untouched" "$(ino "$dir/attic/public-key")" "$k"
|
||||
expect "netrc untouched" "$(ino "$dir/attic/netrc")" "$n"
|
||||
expect "fragment untouched" "$(ino "$dir/nix/cache.conf")" "$c"
|
||||
|
||||
case="a rotated token replaces the netrc and leaves the key"
|
||||
seed "swarm:S0VZ" "tok-2"
|
||||
|
|
@ -170,6 +194,54 @@ run
|
|||
expect "exit" $? 1
|
||||
intact
|
||||
|
||||
# A restart of nix-daemon is asked for only when the fragment was written after
|
||||
# the daemon last started; `now` is when the daemon "started", read between runs.
|
||||
now() { date -u '+%a %Y-%m-%d %H:%M:%S.%6N UTC'; }
|
||||
|
||||
case="a new fragment restarts a daemon that started before it"
|
||||
reset
|
||||
seed "swarm:S0VZ" "tok-1"
|
||||
run DAEMON_STARTED="Sat 2000-01-01 00:00:00.000000 UTC"
|
||||
expect "exit" $? 0
|
||||
expect "restart asked" "$(grep -c '^systemctl try-restart --no-block nix-daemon.service' "$dir/systemctl")" 1
|
||||
|
||||
case="the same facts leave the fragment and the daemon alone"
|
||||
started=$(now)
|
||||
: >"$dir/systemctl"
|
||||
run DAEMON_STARTED="$started"
|
||||
expect "exit" $? 0
|
||||
expect "no restart" "$(restarts)" 0
|
||||
|
||||
case="a rotated token changes the netrc but not the fragment, so no restart"
|
||||
started=$(now)
|
||||
seed "swarm:S0VZ" "tok-2"
|
||||
run DAEMON_STARTED="$started"
|
||||
expect "exit" $? 0
|
||||
expect "netrc" "$(body "$dir/attic/netrc")" "machine cache.example password tok-2"
|
||||
expect "no restart" "$(restarts)" 0
|
||||
|
||||
case="a rotated key rewrites the fragment and restarts the daemon"
|
||||
started=$(now)
|
||||
seed "swarm:Tk9XCg" "tok-2"
|
||||
run DAEMON_STARTED="$started"
|
||||
expect "exit" $? 0
|
||||
expect "key in the fragment" "$(grep -c 'extra-trusted-public-keys = swarm:Tk9XCg' "$dir/nix/cache.conf")" 1
|
||||
expect "restart asked" "$(restarts)" 1
|
||||
|
||||
case="a store with no facts writes no fragment and restarts nothing"
|
||||
reset
|
||||
run DAEMON_STARTED="Sat 2000-01-01 00:00:00.000000 UTC"
|
||||
expect "exit" $? 0
|
||||
expect "no fragment" "$(body "$dir/nix/cache.conf")" missing
|
||||
expect "no restart" "$(restarts)" 0
|
||||
|
||||
case="a key that is refused writes no fragment"
|
||||
reset
|
||||
seed "swarm:S0 VZ" "tok-1"
|
||||
run
|
||||
expect "exit" $? 1
|
||||
expect "no fragment" "$(body "$dir/nix/cache.conf")" missing
|
||||
|
||||
if [ "$failures" -ne 0 ]; then
|
||||
echo "$failures of $count checks failed" >&2
|
||||
exit 1
|
||||
|
|
|
|||
Loading…
Reference in a new issue