Fix nginx status detection and cert check for root-owned files

nginx config files written by sudo are root-only (rw-------), so
nginx_domain() was silently failing to read them. Now uses 'sudo -n cat'
with fallback to direct read for world-readable files.

Also fix PermissionError on cert_path.exists() — /etc/letsencrypt/live/
requires root, so use 'sudo test -f' instead of Path.exists().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Paul Trowbridge 2026-04-05 17:08:49 -04:00
parent 61fe8f630b
commit 4b8864edd9

View File

@ -147,12 +147,14 @@ def ui_build_time():
return None return None
def nginx_domain(port): def nginx_domain(port):
"""Find nginx site proxying to our port.""" """Find nginx site proxying to our port. Uses sudo to read root-owned configs."""
if not NGINX_DIR.exists(): if not NGINX_DIR.exists():
return None return None
for f in NGINX_DIR.iterdir(): for f in NGINX_DIR.iterdir():
try: try:
text = f.read_text() r = subprocess.run(['sudo', '-n', 'cat', str(f)],
capture_output=True, text=True)
text = r.stdout if r.returncode == 0 else f.read_text()
if f':{port}' in text: if f':{port}' in text:
for line in text.splitlines(): for line in text.splitlines():
if 'server_name' in line: if 'server_name' in line:
@ -430,8 +432,11 @@ def action_setup_nginx(cfg):
conf_path = NGINX_DIR / conf_name conf_path = NGINX_DIR / conf_name
cert_path = Path(f'/etc/letsencrypt/live/{domain}/fullchain.pem') cert_path = Path(f'/etc/letsencrypt/live/{domain}/fullchain.pem')
# /etc/letsencrypt/live/ requires root — check with sudo
cert_exists = sudo_run(['test', '-f', str(cert_path)], capture_output=True).returncode == 0
print() print()
if cert_path.exists(): if cert_exists:
info(f'SSL certificate found at {cert_path} — will configure HTTPS with redirect from HTTP.') info(f'SSL certificate found at {cert_path} — will configure HTTPS with redirect from HTTP.')
conf = f"""server {{ conf = f"""server {{
listen 80; listen 80;
@ -505,7 +510,7 @@ server {{
sudo_run(['systemctl', 'reload', 'nginx']) sudo_run(['systemctl', 'reload', 'nginx'])
ok('nginx reloaded — site is now active') ok('nginx reloaded — site is now active')
if not cert_path.exists(): if not cert_exists:
warn(f'No SSL certificate found for {domain} — site is HTTP only.') warn(f'No SSL certificate found for {domain} — site is HTTP only.')
if confirm(f'Run certbot to obtain an SSL certificate for {domain} and switch to HTTPS?'): if confirm(f'Run certbot to obtain an SSL certificate for {domain} and switch to HTTPS?'):
print(f' Running certbot for {domain}...') print(f' Running certbot for {domain}...')