Skip to content

Commit ad4ffa9

Browse files
committed
fix(dstack-ingress): reload haproxy only when a certificate was actually renewed
certman.py distinguishes 'renewed' (0) from 'nothing to renew' (2), but renew-certificate.sh collapsed both to exit 0, so the renewal daemon rebuilt the PEMs and reloaded haproxy on every 12-hour check cycle even though certificates renew roughly every 60 days. Propagate exit 2 and make the daemon treat only a real renewal as reload-worthy. entrypoint.sh runs under set -e and calls renew-certificate.sh unguarded during bootstrap, where the certificate has just been issued and the second call now exits 2 — tolerate that explicitly so bootstrap does not abort.
1 parent 9744eab commit ad4ffa9

3 files changed

Lines changed: 23 additions & 9 deletions

File tree

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,11 @@ process_domain() {
356356

357357
set_alias_record "$domain"
358358
set_txt_record "$domain"
359-
renew-certificate.sh "$domain" || echo "First certificate renewal failed for $domain, will retry after set CAA record"
359+
# renew-certificate.sh exits 0 on renewal, 2 when nothing needed renewal
360+
# (not a failure — this script runs under `set -e`), 1 on real failure.
361+
renew-certificate.sh "$domain" || [ $? -eq 2 ] || echo "First certificate renewal failed for $domain, will retry after set CAA record"
360362
set_caa_record "$domain"
361-
renew-certificate.sh "$domain"
363+
renew-certificate.sh "$domain" || [ $? -eq 2 ]
362364
}
363365

364366
bootstrap() {

custom-domain/dstack-ingress/scripts/renew-certificate.sh

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,17 @@ SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
88
python3 "$SCRIPT_DIR/certman.py" auto --domain "$DOMAIN" --email "$CERTBOT_EMAIL"
99
CERT_STATUS=$?
1010

11-
if [ $CERT_STATUS -eq 1 ]; then
12-
echo "Certificate management failed" >&2
13-
exit 1
14-
elif [ $CERT_STATUS -eq 2 ]; then
11+
if [ $CERT_STATUS -eq 2 ]; then
1512
echo "No certificates need renewal, skipping evidence generation"
13+
# Propagate "nothing renewed" so the renewal daemon does not rebuild
14+
# PEMs and reload haproxy on every check cycle.
15+
exit 2
16+
elif [ $CERT_STATUS -ne 0 ]; then
17+
# 1 is certman's failure exit; anything else (127 missing interpreter,
18+
# 130 signal, ...) is just as much a failure — never let it fall through
19+
# to "renewed", which would trigger a spurious PEM rebuild + reload.
20+
echo "Certificate management failed (status $CERT_STATUS)" >&2
21+
exit 1
1622
fi
1723

1824
exit 0

custom-domain/dstack-ingress/scripts/renewal-daemon.sh

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ while true; do
1010
while IFS= read -r domain; do
1111
[[ -n "$domain" ]] || continue
1212
echo "[$(date)] Checking renewal for domain: $domain"
13-
if renew-certificate.sh "$domain"; then
13+
renew-certificate.sh "$domain"
14+
status=$?
15+
# 0 = a certificate was actually renewed; 2 = nothing to renew.
16+
# Only a real renewal warrants a PEM rebuild + haproxy reload —
17+
# reloading on every check cycle replaced the worker (and its
18+
# accumulated state) twice a day for no reason.
19+
if [ $status -eq 0 ]; then
1420
renewal_occurred=true
15-
else
16-
echo "Certificate renewal check failed for $domain with status $?"
21+
elif [ $status -ne 2 ]; then
22+
echo "Certificate renewal check failed for $domain with status $status"
1723
fi
1824
done <<<"$all_domains"
1925

0 commit comments

Comments
 (0)