container detection implemented

This commit is contained in:
Антон
2026-02-07 14:51:15 +03:00
parent 195d40daa2
commit 961de020fb
3 changed files with 85 additions and 19 deletions

View File

@@ -6,13 +6,19 @@ import psutil
logger = logging.getLogger(__name__)
def get_os_type():
def is_container():
"""
Simple check to distinguish Alpine from others.
Checks if the application is running inside a Docker container.
"""
if os.path.exists("/etc/alpine-release"):
return "alpine"
return "debian" # default fallback to systemctl
if os.path.exists('/.dockerenv'):
return True
try:
with open('/proc/self/cgroup', 'rt') as f:
if 'docker' in f.read():
return True
except:
pass
return False
def control_service(action: str):
"""
@@ -21,7 +27,63 @@ def control_service(action: str):
if action not in ["start", "stop", "restart"]:
raise ValueError("Invalid action")
CONFIG_PATH = "/etc/openvpn/server.conf"
PID_FILE = "/run/openvpn.pid"
# In Container: Use direct execution to avoid OpenRC/cgroups issues
if is_container():
logger.info(f"[PROCESS] Container detected, using direct execution for {action}")
def start_vpn_direct():
if not os.path.exists(CONFIG_PATH):
# Check for alternative location in dev/non-root environments
if os.path.exists("staging/server.conf"):
alt_path = os.path.abspath("staging/server.conf")
logger.info(f"[PROCESS] Using alternative config: {alt_path}")
config = alt_path
else:
return {"status": "error", "message": f"Configuration not found at {CONFIG_PATH}. Please generate it first."}
else:
config = CONFIG_PATH
# Check if already running
for proc in psutil.process_iter(['name']):
if proc.info['name'] == 'openvpn':
return {"status": "success", "message": "OpenVPN is already running"}
cmd = ["openvpn", "--config", config, "--daemon", "--writepid", PID_FILE]
try:
subprocess.run(cmd, check=True)
return {"status": "success", "message": "OpenVPN started successfully (direct)"}
except subprocess.CalledProcessError as e:
return {"status": "error", "message": f"Failed to start OpenVPN: {str(e)}"}
def stop_vpn_direct():
stopped = False
for proc in psutil.process_iter(['name']):
if proc.info['name'] == 'openvpn':
proc.terminate()
stopped = True
if os.path.exists(PID_FILE):
try: os.remove(PID_FILE)
except: pass
if stopped:
return {"status": "success", "message": "OpenVPN stopped successfully"}
else:
return {"status": "success", "message": "OpenVPN was not running"}
if action == "start": return start_vpn_direct()
elif action == "stop": return stop_vpn_direct()
elif action == "restart":
stop_vpn_direct()
time.sleep(1)
return start_vpn_direct()
# On Host OS: Use system service manager
os_type = get_os_type()
logger.info(f"[PROCESS] Host OS detected ({os_type}), using service manager for {action}")
cmd = []
if os_type == "alpine":
@@ -30,27 +92,27 @@ def control_service(action: str):
cmd = ["systemctl", action, "openvpn"]
try:
# Capture output to return it or log it
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
return {
"status": "success",
"message": f"Service {action} executed successfully",
"message": f"Service {action} executed successfully via {cmd[0]}",
"stdout": result.stdout
}
except subprocess.CalledProcessError as e:
logger.error(f"Service control failed: {e.stderr}")
return {
"status": "error",
"message": f"Failed to {action} service",
"message": f"Failed to {action} service via {cmd[0]}",
"stderr": e.stderr
}
except FileNotFoundError:
# Happens if rc-service or systemctl is missing (e.g. dev env)
return {
"status": "error",
"message": f"Command not found found for OS type {os_type}"
"message": f"Command {cmd[0]} not found found for OS type {os_type}"
}
def get_process_stats():
"""
Returns dict with pid, cpu_percent, memory_mb, uptime.