Files
CyberPanel/plogical/cyberpanel_python.py

68 lines
1.8 KiB
Python
Raw Permalink Normal View History

# -*- coding: utf-8 -*-
"""
Resolve the Python interpreter for CyberPanel CLI and cron jobs.
Some installs omit /usr/local/CyberCP/bin/python (no venv). We symlink that path
to a working interpreter when missing so existing crontab lines keep working.
"""
from __future__ import annotations
import os
_CANDIDATES = (
"/usr/local/CyberPanel/bin/python",
"/usr/local/CyberCP/bin/python",
"/usr/bin/python3",
"/usr/local/bin/python3",
)
def resolve_cyberpanel_python() -> str:
"""Return first existing executable candidate, else /usr/bin/python3."""
for path in _CANDIDATES:
if path == "/usr/local/CyberCP/bin/python":
continue
if path and os.path.isfile(path) and os.access(path, os.X_OK):
return path
return "/usr/bin/python3"
def ensure_cyberpanel_bin_python_shim() -> None:
"""
If /usr/local/CyberCP/bin/python is missing or a broken symlink, replace with
symlink to resolve_cyberpanel_python(). Non-destructive for a real venv file.
"""
bin_dir = "/usr/local/CyberCP/bin"
legacy = os.path.join(bin_dir, "python")
try:
os.makedirs(bin_dir, exist_ok=True)
except OSError:
return
if os.path.isfile(legacy) and os.access(legacy, os.X_OK) and not os.path.islink(legacy):
return
if os.path.islink(legacy):
real = os.path.realpath(legacy)
if os.path.isfile(real) and os.access(real, os.X_OK):
return
try:
os.unlink(legacy)
except OSError:
return
if os.path.lexists(legacy):
try:
os.remove(legacy)
except OSError:
try:
os.unlink(legacy)
except OSError:
return
target = resolve_cyberpanel_python()
try:
os.symlink(target, legacy)
except OSError:
pass