plugins: reliable lscpd restart after install and revert

- restartGunicorn: try systemctl as root; else sudo -n then systemctl; log failures
- revert_plugin: call restartGunicorn after successful backup restore
This commit is contained in:
master3395
2026-03-27 23:39:11 +01:00
parent b89ed169ca
commit 5e8f973bb5
2 changed files with 55 additions and 2 deletions

View File

@@ -2009,6 +2009,12 @@ def revert_plugin(request, plugin_name):
# Restore from backup
if _restore_plugin_from_backup(plugin_name, backup_path):
try:
pluginInstaller.restartGunicorn()
except Exception as re:
logging.writeToFile(
'revert_plugin: restartGunicorn after restore failed (non-fatal): %s' % str(re)
)
return JsonResponse({
'success': True,
'message': f'Plugin {plugin_name} reverted successfully to version {backup_version}'

View File

@@ -743,8 +743,55 @@ class pluginInstaller:
@staticmethod
def restartGunicorn():
command = 'systemctl restart lscpd'
ProcessUtilities.normalExecutioner(command)
"""
Reload lscpd so Django reloads pluginHolder.urls and INSTALLED_APPS sync.
When the panel runs as non-root, plain systemctl often fails; try sudo -n then systemctl.
"""
try:
is_root = os.geteuid() == 0
except AttributeError:
is_root = True
if is_root:
candidates = [['systemctl', 'restart', 'lscpd']]
else:
# Prefer non-interactive sudo (NOPASSWD in sudoers); avoid bare sudo — it can hang on password.
candidates = [
['sudo', '-n', 'systemctl', 'restart', 'lscpd'],
['systemctl', 'restart', 'lscpd'],
]
last_detail = None
for cmd in candidates:
try:
proc = subprocess.run(
cmd,
stdin=subprocess.DEVNULL,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=120,
text=True,
)
if proc.returncode == 0:
pluginInstaller.stdOut('lscpd restarted (%s)' % ' '.join(cmd))
return
err = (proc.stderr or proc.stdout or '').strip()
last_detail = 'rc=%s %s' % (proc.returncode, err[:400])
except subprocess.TimeoutExpired:
last_detail = 'timeout after 120s for %s' % ' '.join(cmd)
except Exception as exc:
last_detail = str(exc)[:400]
msg = 'pluginInstaller.restartGunicorn: failed to restart lscpd. %s. Run as root or grant NOPASSWD: sudo systemctl restart lscpd' % (
last_detail or 'no details'
)
pluginInstaller.stdOut(msg)
try:
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as cp_log
cp_log.writeToFile(msg)
except Exception:
pass