fix(plugins): Add verification and retry logic to uninstall process

- Verify plugin directory is actually removed after removeFiles()
- If directory still exists, retry with ProcessUtilities.normalExecutioner()
- Return error if directory still exists after all attempts
- Prevents silent failures where uninstall appears successful but plugin remains

Fixes: Plugins showing as installed after 'successful' uninstall
This commit is contained in:
master3395
2026-01-26 03:20:56 +01:00
parent 1911de75ec
commit e92f3a7f17

View File

@@ -619,7 +619,31 @@ def uninstall_plugin(request, plugin_name):
pluginInstaller.removeMigrations(plugin_name)
# Remove installed directory (but keep source in /home/cyberpanel/plugins/)
pluginInstaller.removeFiles(plugin_name)
try:
pluginInstaller.removeFiles(plugin_name)
# Verify removal succeeded
pluginInstalled = '/usr/local/CyberCP/' + plugin_name
if os.path.exists(pluginInstalled):
# Removal failed - try again with more aggressive method
logging.writeToFile(f'Plugin directory still exists after removeFiles, trying ProcessUtilities')
try:
from plogical.processUtilities import ProcessUtilities
rm_cmd = f'rm -rf {pluginInstalled}'
ProcessUtilities.normalExecutioner(rm_cmd)
# Verify again
if os.path.exists(pluginInstalled):
raise Exception(f'Plugin directory still exists after ProcessUtilities removal: {pluginInstalled}')
except Exception as e2:
logging.writeToFile(f'ProcessUtilities removal also failed: {str(e2)}')
raise Exception(f'Failed to remove plugin directory. Tried removeFiles() and ProcessUtilities. Directory still exists: {pluginInstalled}')
except Exception as e:
logging.writeToFile(f'Error removing plugin files: {str(e)}')
return JsonResponse({
'success': False,
'error': f'Failed to remove plugin directory: {str(e)}'
}, status=500)
# DON'T call informCyberPanelRemoval - we want to keep the source directory
# so users can reinstall the plugin later