new changes

This commit is contained in:
Niranjan
2026-04-07 10:29:29 +05:30
parent 09d0e2e033
commit 097087519b
3 changed files with 88 additions and 16 deletions

View File

@@ -2,6 +2,7 @@
import os import os
import shutil import shutil
import subprocess import subprocess
import sys
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select from sqlalchemy import select
@@ -17,15 +18,83 @@ from app.services.site_service import regenerate_site_vhost
router = APIRouter(prefix="/ssl", tags=["ssl"]) router = APIRouter(prefix="/ssl", tags=["ssl"])
_CERTBOT_PATH_CANDIDATES = (
"/usr/bin/certbot",
"/usr/local/bin/certbot",
"/snap/bin/certbot",
)
def _certbot_executable() -> str:
w = shutil.which("certbot") def _certbot_command() -> list[str] | None:
if w: """Resolve argv prefix to run certbot: [binary] or [python, -m, certbot]."""
return w env = environment_with_system_path()
for p in ("/usr/bin/certbot", "/usr/local/bin/certbot"): path_var = env.get("PATH", "")
if os.path.isfile(p):
return p exe = getattr(sys, "executable", None) or ""
return "certbot" if exe and os.path.isfile(exe):
try:
r = subprocess.run(
[exe, "-m", "certbot", "--version"],
capture_output=True,
text=True,
timeout=20,
env=env,
)
if r.returncode == 0:
return [exe, "-m", "certbot"]
except (FileNotFoundError, OSError, subprocess.TimeoutExpired):
pass
tried: list[str] = []
w = shutil.which("certbot", path=path_var)
if w and os.path.isfile(w):
tried.append(w)
for p in _CERTBOT_PATH_CANDIDATES:
if p not in tried and os.path.isfile(p):
tried.append(p)
for exe in tried:
try:
r = subprocess.run(
[exe, "--version"],
capture_output=True,
text=True,
timeout=15,
env=env,
)
if r.returncode == 0:
return [exe]
except (FileNotFoundError, OSError, subprocess.TimeoutExpired):
continue
for py_name in ("python3", "python"):
py = shutil.which(py_name, path=path_var)
if not py or not os.path.isfile(py):
continue
try:
r = subprocess.run(
[py, "-m", "certbot", "--version"],
capture_output=True,
text=True,
timeout=20,
env=env,
)
if r.returncode == 0:
return [py, "-m", "certbot"]
except (FileNotFoundError, OSError, subprocess.TimeoutExpired):
continue
return None
def _certbot_missing_message() -> str:
return (
"certbot is not installed or not reachable from the panel process. "
"On the server, run one of: apt install certbot | dnf install certbot | yum install certbot | snap install certbot. "
"Alternatively: pip install certbot (panel can use python3 -m certbot). "
"If certbot is already installed, ensure /usr/bin is on PATH for the YakPanel service."
)
@router.get("/domains") @router.get("/domains")
@@ -75,9 +144,11 @@ async def ssl_request_cert(
raise HTTPException(status_code=400, detail="Webroot must be under www_root or setup_path") raise HTTPException(status_code=400, detail="Webroot must be under www_root or setup_path")
dom = body.domain.split(":")[0].strip() dom = body.domain.split(":")[0].strip()
certbot_bin = _certbot_executable() prefix = _certbot_command()
cmd = [ if not prefix:
certbot_bin, raise HTTPException(status_code=500, detail=_certbot_missing_message())
cmd = prefix + [
"certonly", "certonly",
"--webroot", "--webroot",
"-w", "-w",
@@ -93,19 +164,17 @@ async def ssl_request_cert(
"--no-eff-email", "--no-eff-email",
] ]
env = environment_with_system_path()
try: try:
proc = subprocess.run( proc = subprocess.run(
cmd, cmd,
capture_output=True, capture_output=True,
text=True, text=True,
timeout=180, timeout=180,
env=environment_with_system_path(), env=env,
) )
except FileNotFoundError: except FileNotFoundError:
raise HTTPException( raise HTTPException(status_code=500, detail=_certbot_missing_message()) from None
status_code=500,
detail="certbot not found. Install it (e.g. apt install certbot) and ensure it is on PATH.",
) from None
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
raise HTTPException(status_code=500, detail="certbot timed out (180s)") from None raise HTTPException(status_code=500, detail="certbot timed out (180s)") from None

View File

@@ -20,6 +20,9 @@ python-dotenv>=1.0.0
redis>=5.0.0 redis>=5.0.0
celery>=5.3.0 celery>=5.3.0
# Let's Encrypt (optional if system certbot/snap not used; enables python -m certbot from panel venv)
certbot>=3.0.0
# Utils # Utils
psutil>=5.9.0 psutil>=5.9.0
croniter>=2.0.0 croniter>=2.0.0