summaryrefslogtreecommitdiff
path: root/src/conf_mode/service_https.py
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2026-10-10 21:24:16 +0200
committerChristian Breunig <christian@breunig.cc>2026-10-10 21:24:16 +0200
commit1d180225536b8e92a05f2b0710a115dd71a40cc1 (patch)
tree7e6f5fdca249c32b410fcf178a11673f83590122 /src/conf_mode/service_https.py
parentc8d344fd8954035c840a0991a97c6653a72c7c54 (diff)
downloadvyos-1x-1d180225536b8e92a05f2b0710a115dd71a40cc1.tar.gz
vyos-1x-1d180225536b8e92a05f2b0710a115dd71a40cc1.zip
http-api: T9453: wait for the API server to be ready after a reload
A commit that changes an already running HTTP API only signals the server and returns at once. The server then restarts uvicorn asynchronously, and until it listens again requests through nginx fail. A fixed one-second sleep was meant to cover this but is too short on slow systems, making the https smoketest fail intermittently and API clients see errors right after a commit. The server now creates a readiness marker once it accepts requests. The commit clears the marker before reloading and waits for it to reappear, warning if that takes longer than 30 seconds.
Diffstat (limited to 'src/conf_mode/service_https.py')
-rwxr-xr-xsrc/conf_mode/service_https.py11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/conf_mode/service_https.py b/src/conf_mode/service_https.py
index 10e0afe49..1a9ab0b75 100755
--- a/src/conf_mode/service_https.py
+++ b/src/conf_mode/service_https.py
@@ -19,7 +19,6 @@ import socket
import sys
import json
-from time import sleep
from vyos.base import Warning
from vyos.config import Config
@@ -30,6 +29,7 @@ from vyos.configverify import verify_pki_ca_certificate
from vyos.configverify import verify_pki_dh_parameters
from vyos.configdiff import get_config_diff
from vyos.defaults import api_config_state
+from vyos.defaults import api_ready_state
from vyos.pki import encode_certificate
from vyos.pki import find_chain
from vyos.pki import load_certificate
@@ -42,6 +42,7 @@ from vyos.utils.process import is_systemd_service_active
from vyos.utils.network import check_port_availability
from vyos.utils.network import is_listen_port_bind_service
from vyos.utils.file import write_file
+from vyos.utils.misc import wait_for
from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -292,9 +293,13 @@ def apply(https):
return
if 'api' in https:
+ # A reload is only signalled; the server restarts asynchronously and
+ # nginx answers 502 until it listens again. Wait for it.
+ if os.path.exists(api_ready_state):
+ os.unlink(api_ready_state)
call(f'systemctl reload-or-restart {http_api_service_name}')
- # Let uvicorn settle before (possibly) restarting nginx
- sleep(1)
+ if not wait_for(os.path.exists, api_ready_state, interval=0.1, timeout=30):
+ Warning('HTTP API server did not become ready within 30 seconds')
elif is_systemd_service_active(http_api_service_name):
call(f'systemctl stop {http_api_service_name}')