deploy: never start the replacement while the predecessor holds the port

The 2026-09-16 halogen restore failed exactly here. The ik root unit stopped,
systemd logged "Deactivated successfully", pasta tried to bind 7770 about a
second later, reported "Address already in use", and the quadlet exited 126.
Only Restart=on-failure recovered it -- minutes later, which is not a deploy.

The handler now waits for every socket on the port to clear (listener, accepted
and TIME_WAIT) before installing and starting the quadlet, and fails loudly with
the socket table attached if it never does. The retirement also reports when the
unit file was already gone, because this host's `disable` deletes it.
This commit is contained in:
Frank
2026-09-16 14:06:03 -07:00
parent 79cca19919
commit 7403bd3d50
3 changed files with 43 additions and 1 deletions
+9
View File
@@ -102,3 +102,12 @@ REMOTE_DEPLOY="$REPO_ROOT/scripts/deploy-remote.sh"
[ ! -e "$REPO_ROOT/scripts/frank-large.service" ]
[ ! -e "$REPO_ROOT/scripts/serve-frank-large.sh" ]
}
@test "the deploy handler waits for the predecessor to release the port" {
# The 2026-09-16 cutover failed at exactly this: the ik server's socket was
# still on 7770 when pasta tried to bind it ("Address already in use"), and
# the container died on it. Restart=on-failure recovered minutes later, but
# a deploy that starts a doomed container has not deployed anything.
grep -q 'wait_port_free 7770' "$REMOTE_DEPLOY"
grep -q '^wait_port_free() {' "$REMOTE_DEPLOY"
}
+3 -1
View File
@@ -52,7 +52,9 @@ QUADLET_LARGE="$REPO_ROOT/dankclaw/frank-large/quadlet/frank-large.container"
# MTP tensors at all, so MTP is a property of the file, not of the flags.
grep -q '^MODEL_FILE=.*-mtp\.gguf$' "$ENV_FILE"
# A separate draft model would load a second 12 GiB copy of a 12 GiB model.
! grep -q -- '--model-draft' "$SERVE"
# Only the effective configuration counts: the script's own comment explains
# why there is no draft path, and a textual grep would match that prose.
! grep -vE '^[[:space:]]*#' "$SERVE" | grep -q -- '--model-draft'
}
@test "frank-small carries the fleet's image path, and only it" {