Skip to content

Commit e7532be

Browse files
committed
test(gateway): make the certbot phase survive the locks it races
Two things a current-only cluster hits that an upgraded one never does. `max_dns_wait: 0` is rejected by current code at credential creation -- an issuance that never waits for propagation cannot succeed against a real provider -- and only 0.5.8 ever accepted it. The upgrade phase configures the cluster while the nodes still run 0.5.8, so the value survives into current code as stored state and the validation is never reached. One second is as good as none against a Pebble configured to validate unconditionally. Adding a ZT domain starts an issuance, and on a fresh cluster that issuance registers the shared ACME account -- so an operator's SetCaa, issued right after, races it for the cluster-wide lock and is refused. That refusal is deliberate and says to retry after the holder finishes, which is seconds for a registration. So retry, the way this suite already retries the per-domain certificate lock. Any other error still fails immediately.
1 parent 0fedbb8 commit e7532be

1 file changed

Lines changed: 26 additions & 6 deletions

File tree

  • test-suites/full-stack-compose/scripts

test-suites/full-stack-compose/scripts/runner.sh

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -435,14 +435,18 @@ bootstrap_gateway() {
435435
# Certbot/DNS/ZT-Domain configuration only. Split out of the first issuance so a
436436
# phase can put something between them -- a fresh cluster reconciling CAA before
437437
# it holds an ACME account, for one.
438+
# `max_dns_wait` is one second rather than zero: current code rejects zero at
439+
# creation (an issuance that never waits for propagation cannot succeed against
440+
# a real provider), and only 0.5.8 ever accepted it. Pebble is configured to
441+
# validate unconditionally, so one second is as good as none here.
438442
configure_gateway_certbot() {
439443
log "configuring Gateway cluster through node 1"
440444
admin_curl 1 SetCertbotConfig \
441445
"$(jq -cn --arg u "http://10.0.2.2:${PEBBLE_HTTP_PORT}/dir" \
442446
'{acme_url:$u, renew_before_expiration_secs:3600}')" >/dev/null
443447
admin_curl 1 CreateDnsCredential \
444448
"$(jq -cn --arg u "http://10.0.2.2:${MOCK_CF_HTTP_PORT}/client/v4" \
445-
'{name:"mock-cloudflare",provider_type:"cloudflare",cf_api_token:"test-token",cf_api_url:$u,set_as_default:true,dns_txt_ttl:1,max_dns_wait:0}')" \
449+
'{name:"mock-cloudflare",provider_type:"cloudflare",cf_api_token:"test-token",cf_api_url:$u,set_as_default:true,dns_txt_ttl:1,max_dns_wait:1}')" \
446450
>/dev/null
447451
admin_curl 1 AddZtDomain \
448452
"$(jq -cn --arg d "$BASE_DOMAIN" '{domain:$d,port:443,priority:100}')" \
@@ -626,12 +630,28 @@ assert_gateway_caa_records() {
626630
# every issuance path this suite already exercises, because nothing else calls
627631
# SetCaa.
628632
assert_gateway_caa_reconcile() {
629-
local node=$1 expect=${2:-}
633+
local node=$1 expect=${2:-} deadline=$((SECONDS + 180)) out rc
630634
log "reconciling CAA through Gateway node $node"
631-
admin_curl "$node" SetCaa >/dev/null \
632-
|| die "Gateway node $node could not reconcile CAA records"
633-
assert_gateway_caa_records "$expect"
634-
log "Gateway node $node pinned CAA to $(cat "$WORK_DIR/gateway-caa-account")"
635+
# A fresh cluster registers its shared ACME account from whichever path
636+
# reaches it first, and adding a ZT domain starts an issuance that does
637+
# exactly that. Both take the cluster-wide ACME lock, and the loser is
638+
# refused rather than queued -- deliberately: the refusal says to retry after
639+
# the holder finishes, which is seconds for a registration. Retry, the way
640+
# this suite already retries the per-domain certificate lock.
641+
while (( SECONDS < deadline )); do
642+
rc=0
643+
out=$(admin_curl "$node" SetCaa 2>&1) || rc=$?
644+
if (( rc == 0 )); then
645+
assert_gateway_caa_records "$expect"
646+
log "Gateway node $node pinned CAA to $(cat "$WORK_DIR/gateway-caa-account")"
647+
return
648+
fi
649+
grep -q "holds the shared ACME lock" <<<"$out" \
650+
|| die "Gateway node $node could not reconcile CAA records: $out"
651+
log "Gateway node $node is waiting for the shared ACME lock"
652+
sleep 3
653+
done
654+
die "Gateway node $node never acquired the shared ACME lock"
635655
}
636656

637657
# Rotate the shared ACME account, then require the cluster to issue with it.

0 commit comments

Comments
 (0)