From 8bba285f563f5d7f21996ee955d462e749d9c34e Mon Sep 17 00:00:00 2001 From: Niranjan Date: Tue, 7 Apr 2026 04:20:13 +0530 Subject: [PATCH] new changes --- YakPanel-server/backend/app/api/soft.py | 40 +++++++++++++++++++++---- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/YakPanel-server/backend/app/api/soft.py b/YakPanel-server/backend/app/api/soft.py index 902725a2..b9248438 100644 --- a/YakPanel-server/backend/app/api/soft.py +++ b/YakPanel-server/backend/app/api/soft.py @@ -1,4 +1,9 @@ """YakPanel - App Store / Software API""" +import asyncio +import os +import shlex +import subprocess + from fastapi import APIRouter, Depends, HTTPException from app.core.utils import exec_shell_sync @@ -26,6 +31,31 @@ SOFTWARE_LIST = [ ] +def _apt_env() -> dict[str, str]: + env = os.environ.copy() + env.setdefault("DEBIAN_FRONTEND", "noninteractive") + env.setdefault("APT_LISTCHANGES_FRONTEND", "none") + return env + + +def _run_apt_shell(script: str, timeout: int) -> None: + """Run apt/dpkg shell snippet; raise HTTPException if command fails.""" + result = subprocess.run( + script, + shell=True, + capture_output=True, + text=True, + timeout=timeout, + env=_apt_env(), + ) + if result.returncode == 0: + return + out = (result.stdout or "").strip() + err = (result.stderr or "").strip() + msg = err or out or f"Command failed (exit {result.returncode})" + raise HTTPException(status_code=500, detail=msg[:4000]) + + def _check_installed(pkg: str) -> tuple[bool, str]: """Check if package is installed. Returns (installed, version_or_error).""" out, err = exec_shell_sync(f"dpkg -l {pkg} 2>/dev/null | grep ^ii", timeout=5) @@ -60,9 +90,8 @@ async def soft_install( pkg = next((s["pkg"] for s in SOFTWARE_LIST if s["id"] == pkg_id), None) if not pkg: raise HTTPException(status_code=404, detail="Package not found") - out, err = exec_shell_sync(f"apt-get update && apt-get install -y {pkg}", timeout=300) - if err and "error" in err.lower() and "E: " in err: - raise HTTPException(status_code=500, detail=err.strip() or out.strip()) + quoted = shlex.quote(pkg) + _run_apt_shell(f"apt-get update -qq && apt-get install -y {quoted}", timeout=600) return {"status": True, "msg": "Installed"} @@ -75,7 +104,6 @@ async def soft_uninstall( pkg = next((s["pkg"] for s in SOFTWARE_LIST if s["id"] == pkg_id), None) if not pkg: raise HTTPException(status_code=404, detail="Package not found") - out, err = exec_shell_sync(f"apt-get remove -y {pkg}", timeout=120) - if err and "error" in err.lower() and "E: " in err: - raise HTTPException(status_code=500, detail=err.strip() or out.strip()) + quoted = shlex.quote(pkg) + await asyncio.to_thread(_run_apt_shell, f"apt-get remove -y {quoted}", 180) return {"status": True, "msg": "Uninstalled"}