Skip to content

Commit 5ed94d8

Browse files
authored
Merge pull request #102 from pacoyang/fix/ingress-reload-only-on-renewal
fix(dstack-ingress): retry applying a renewed certificate until it sticks
2 parents ab6d7e1 + 26f4072 commit 5ed94d8

2 files changed

Lines changed: 44 additions & 6 deletions

File tree

custom-domain/dstack-ingress/scripts/dns01.sh

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ collect_evidence() {
288288
evidence_finalize
289289
}
290290

291+
# Set when certificates have been renewed but not yet applied to haproxy.
292+
# Survives across passes, so a failed apply is retried on the next one.
293+
APPLY_PENDING=false
294+
291295
# One pass over every domain: make the DNS records right, then issue or renew.
292296
# Idempotent, so the first pass and every later one are the same code.
293297
run_pass() {
@@ -306,9 +310,24 @@ run_pass() {
306310
done <<<"$(get-all-domains.sh)"
307311

308312
if [ "$changed" -eq 1 ]; then
309-
collect_evidence || echo "Evidence generation failed" >&2
310-
build_combined_pems || echo "Combined PEM build failed" >&2
311-
haproxy_reload || true
313+
APPLY_PENDING=true
314+
fi
315+
316+
# Applying is separate from renewing, and retried until it sticks. A
317+
# renewal that reaches disk but not haproxy is invisible: the next pass
318+
# sees a fresh certificate, reports "nothing to renew", and never reloads
319+
# again -- so haproxy would serve the pre-renewal certificate until it
320+
# expires, which is soon, because being near expiry is why it renewed.
321+
if [ "$APPLY_PENDING" = true ]; then
322+
local applied=true
323+
collect_evidence || { echo "Evidence generation failed" >&2; applied=false; }
324+
build_combined_pems || { echo "Combined PEM build failed" >&2; applied=false; }
325+
haproxy_reload || applied=false
326+
if [ "$applied" = true ]; then
327+
APPLY_PENDING=false
328+
else
329+
echo "[$(date)] Certificate apply incomplete; retrying on the next pass" >&2
330+
fi
312331
fi
313332
[ "$failed" -eq 0 ]
314333
}

custom-domain/dstack-ingress/scripts/tlsalpn.sh

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ process_domain() {
262262
legoman.py auto --domain "$domain" ${ACME_EMAIL:+--email "$ACME_EMAIL"}
263263
}
264264

265+
# Set when certificates have been renewed but not yet applied to haproxy.
266+
# Survives across passes, so a failed apply is retried on the next one.
267+
APPLY_PENDING=false
268+
265269
# One pass over every domain: make sure the records exist, then issue or renew.
266270
# Idempotent, so the first pass and every later one are the same code. There is
267271
# deliberately only one of these -- an earlier split between a one-shot
@@ -285,9 +289,24 @@ run_pass() {
285289
done <<<"$(get-all-domains.sh)"
286290

287291
if [ "$changed" -eq 1 ]; then
288-
collect_evidence || echo "Evidence generation failed" >&2
289-
build_combined_pems || echo "Combined PEM build failed" >&2
290-
haproxy_reload || true
292+
APPLY_PENDING=true
293+
fi
294+
295+
# Applying is separate from renewing, and retried until it sticks. A
296+
# renewal that reaches disk but not haproxy is invisible: the next pass
297+
# sees a fresh certificate, reports "nothing to renew", and never reloads
298+
# again -- so haproxy would serve the pre-renewal certificate until it
299+
# expires, which is soon, because being near expiry is why it renewed.
300+
if [ "$APPLY_PENDING" = true ]; then
301+
local applied=true
302+
collect_evidence || { echo "Evidence generation failed" >&2; applied=false; }
303+
build_combined_pems || { echo "Combined PEM build failed" >&2; applied=false; }
304+
haproxy_reload || applied=false
305+
if [ "$applied" = true ]; then
306+
APPLY_PENDING=false
307+
else
308+
echo "[$(date)] Certificate apply incomplete; retrying on the next pass" >&2
309+
fi
291310
fi
292311
FIRST_PASS=false
293312
[ "$failed" -eq 0 ]

0 commit comments

Comments
 (0)