From c27352721913e2b5104d7ff5fd2a9a466280bb4f Mon Sep 17 00:00:00 2001 From: atlas Date: Sun, 1 Nov 2026 15:09:13 +0100 Subject: [PATCH] outlast openbao's cold restart in the agent ca unit's start limit --- nix/host-modules/swarm-bao.nix | 10 +++++++--- nix/module-eval/bao-basics.nix | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/nix/host-modules/swarm-bao.nix b/nix/host-modules/swarm-bao.nix index 20711fb0..bef4cf57 100644 --- a/nix/host-modules/swarm-bao.nix +++ b/nix/host-modules/swarm-bao.nix @@ -59,6 +59,9 @@ let openbaoStartSec = 240; containerStartSec = openbaoStartSec + 60; + # systemd's default stop limit, which bounds the stop half of a restart. + openbaoStopSec = 90; + # Upstream's own default, kept so its documentation matches. The raft data # lives INSIDE the container on `ephemeral = false`, the same way # ./swarm-grafana.nix keeps its sqlite database — no sibling service binds @@ -3950,9 +3953,10 @@ in Restart = "on-failure"; RestartSec = 30; # An attempt may generate a 4096-bit RSA root and then wait on a - # blocking restart of openbao: its stop and its start, 90s each by - # systemd's defaults. - TimeoutStartSec = "5min"; + # blocking restart of openbao: its stop (`openbaoStopSec`) and its + # start (`openbaoStartSec`), plus 120s for the key generation and + # the calls around it. 90 + 240 + 120 = 450s. + TimeoutStartSec = "${toString (openbaoStopSec + openbaoStartSec + 120)}s"; }; script = '' set -euo pipefail diff --git a/nix/module-eval/bao-basics.nix b/nix/module-eval/bao-basics.nix index 8aa2a291..623937b1 100644 --- a/nix/module-eval/bao-basics.nix +++ b/nix/module-eval/bao-basics.nix @@ -255,6 +255,20 @@ let && !(lib.hasInfix "certificate=@${tlsDir}/listener-client-ca.pem" scripts) && !(lib.hasInfix "certificate=@${tlsDir}/agent-ca.pem" scripts); } + { + # The unit's blocking `systemctl restart openbao.service` stops (90 s) + # then starts openbao (240 s), so its own limit must exceed both or a + # slow cold open kills the job mid-restart. Control: openbao's own limit + # is read from the same container, so a wrong path fails the 240 arm. + name = "the agent CA unit's start limit outlasts the restart of openbao it waits on"; + ok = + let + limit = lib.toInt ( + lib.removeSuffix "s" baoPkcs11.systemd.services.swarm-bao-agent-pki.serviceConfig.TimeoutStartSec + ); + in + (baoUnits baoPkcs11).openbao.serviceConfig.TimeoutStartSec == 240 && limit >= 90 + 240 + 60; + } { # Both writers compose the bundle through one function, which refuses # a result that does not begin with the store CA and replaces the file