From 5d445b0e2314d4805f5d4210f590ee73930873f6 Mon Sep 17 00:00:00 2001 From: Master3395 Date: Sun, 21 Sep 2025 00:27:49 +0200 Subject: [PATCH] Add functionality to switch back to OpenLiteSpeed: Implement server status utility methods, views, and frontend controller for switching from LiteSpeed Enterprise to OpenLiteSpeed. Include status checking and user notifications during the switch process, enhancing user experience and management capabilities. --- serverStatus/serverStatusUtil.py | 113 ++++++++++++++++++ .../static/serverStatus/serverStatus.js | 89 ++++++++++++++ .../serverStatus/litespeedStatus.html | 67 ++++++++++- serverStatus/urls.py | 2 + serverStatus/views.py | 71 +++++++++++ 5 files changed, 338 insertions(+), 4 deletions(-) diff --git a/serverStatus/serverStatusUtil.py b/serverStatus/serverStatusUtil.py index 206093c6b..87bf99edd 100644 --- a/serverStatus/serverStatusUtil.py +++ b/serverStatus/serverStatusUtil.py @@ -469,6 +469,117 @@ class ServerStatusUtil(multi.Thread): except BaseException as msg: logging.CyberCPLogFileWriter.writeToFile(str(msg)) + @staticmethod + def switchToOLS(): + """Switch back to OpenLiteSpeed from LiteSpeed Enterprise""" + try: + os.environ['TERM'] = "xterm-256color" + + statusFile = open(ServerStatusUtil.lswsInstallStatusPath, 'w') + FNULL = open(os.devnull, 'w') + + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Starting switch back to OpenLiteSpeed..\n") + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Stopping LiteSpeed Enterprise..\n", 1) + + # Stop current LiteSpeed Enterprise + ProcessUtilities.killLiteSpeed() + + # Check if backup exists + if not os.path.exists('/usr/local/lswsbak'): + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "No OpenLiteSpeed backup found. Cannot switch back. [404]", 1) + return 0 + + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Removing LiteSpeed Enterprise..\n", 1) + + # Remove current LiteSpeed Enterprise installation + if os.path.exists('/usr/local/lsws'): + shutil.rmtree('/usr/local/lsws') + + # Restore OpenLiteSpeed from backup + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Restoring OpenLiteSpeed from backup..\n", 1) + + command = 'mv /usr/local/lswsbak /usr/local/lsws' + if ServerStatusUtil.executioner(command, statusFile) == 0: + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Failed to restore OpenLiteSpeed. [404]", 1) + return 0 + + # Install OpenLiteSpeed if not already installed + if not os.path.exists('/usr/local/lsws/bin/openlitespeed'): + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Installing OpenLiteSpeed..\n", 1) + + if os.path.exists('/etc/redhat-release'): + command = 'yum -y install openlitespeed' + else: + command = 'apt-get -y install openlitespeed' + + if ServerStatusUtil.executioner(command, statusFile) == 0: + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Failed to install OpenLiteSpeed. [404]", 1) + return 0 + + # Rebuild vhost configurations for OpenLiteSpeed + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Rebuilding vhost configurations..\n", 1) + ServerStatusUtil.rebuildvConf() + + # Start OpenLiteSpeed + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Starting OpenLiteSpeed..\n", 1) + ProcessUtilities.restartLitespeed() + + # Clean up any Enterprise-specific cron jobs + CentOSPath = '/etc/redhat-release' + if os.path.exists(CentOSPath): + cronPath = '/var/spool/cron/root' + else: + cronPath = '/var/spool/cron/crontabs/root' + + if os.path.exists(cronPath): + data = open(cronPath, 'r').readlines() + writeToFile = open(cronPath, 'w') + + for items in data: + if items.find('-maxdepth 2 -type f -newer') > -1: + pass + else: + writeToFile.writelines(items) + + writeToFile.close() + + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Successfully switched back to OpenLiteSpeed. [200]\n", 1) + return 1 + + except BaseException as msg: + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, f"Error switching back to OpenLiteSpeed: {str(msg)}. [404]", 1) + logging.CyberCPLogFileWriter.writeToFile(str(msg)) + return 0 + + @staticmethod + def switchToOLSCLI(): + """CLI version of switch back to OpenLiteSpeed""" + try: + ssu = ServerStatusUtil('') + ssu.start() + + while(True): + command = 'sudo cat ' + ServerStatusUtil.lswsInstallStatusPath + output = ProcessUtilities.outputExecutioner(command) + if output.find('[404]') > -1: + command = "sudo rm -f " + ServerStatusUtil.lswsInstallStatusPath + ProcessUtilities.popenExecutioner(command) + data_ret = {'status': 1, 'abort': 1, 'requestStatus': output, 'installed': 0} + print(str(data_ret)) + return 0 + elif output.find('[200]') > -1: + command = "sudo rm -f " + ServerStatusUtil.lswsInstallStatusPath + ProcessUtilities.popenExecutioner(command) + data_ret = {'status': 1, 'abort': 1, 'requestStatus': 'Successfully switched back to OpenLiteSpeed.', 'installed': 1} + print(str(data_ret)) + return 1 + else: + data_ret = {'status': 1, 'abort': 0, 'requestStatus': output, 'installed': 0} + time.sleep(2) + + except BaseException as msg: + logging.CyberCPLogFileWriter.writeToFile(str(msg)) + def main(): parser = argparse.ArgumentParser(description='Server Status Util.') @@ -479,6 +590,8 @@ def main(): if args.function == "switchTOLSWS": ServerStatusUtil.switchTOLSWS(args.licenseKey) + elif args.function == "switchToOLS": + ServerStatusUtil.switchToOLS() if __name__ == "__main__": diff --git a/serverStatus/static/serverStatus/serverStatus.js b/serverStatus/static/serverStatus/serverStatus.js index a13a0f3d1..5b069b28b 100644 --- a/serverStatus/static/serverStatus/serverStatus.js +++ b/serverStatus/static/serverStatus/serverStatus.js @@ -778,6 +778,95 @@ app.controller('lswsSwitch', function ($scope, $http, $timeout, $window) { }); +/* Controller for switching back to OpenLiteSpeed */ +app.controller('switchToOLS', function ($scope, $http, $timeout, $window) { + + $scope.cyberPanelLoading = true; + $scope.installBoxGen = true; + + $scope.switchToOLS = function () { + $scope.cyberPanelLoading = false; + $scope.installBoxGen = true; + + url = "/serverstatus/switchToOLS"; + + var data = {}; + + var config = { + headers: { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas); + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + if (response.data.status === 1) { + $scope.installBoxGen = false; + getRequestStatus(); + } else { + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type: 'error' + }); + } + } + + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type: 'error' + }); + } + }; + + function getRequestStatus() { + $scope.cyberPanelLoading = false; + + url = "/serverstatus/switchToOLSStatus"; + + var data = {}; + + var config = { + headers: { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas); + + function ListInitialDatas(response) { + if (response.data.abort === 0) { + $scope.requestData = response.data.requestStatus; + $timeout(getRequestStatus, 1000); + } else { + // Notifications + $scope.cyberPanelLoading = true; + $timeout.cancel(); + $scope.requestData = response.data.requestStatus; + if (response.data.installed === 1) { + $timeout(function () { + $window.location.reload(); + }, 3000); + } + } + } + + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type: 'error' + }); + } + } +}); + app.controller('topProcesses', function ($scope, $http, $timeout) { $scope.cyberPanelLoading = true; diff --git a/serverStatus/templates/serverStatus/litespeedStatus.html b/serverStatus/templates/serverStatus/litespeedStatus.html index d95f80f67..af784c6ea 100644 --- a/serverStatus/templates/serverStatus/litespeedStatus.html +++ b/serverStatus/templates/serverStatus/litespeedStatus.html @@ -829,6 +829,65 @@ + + +
+
+

+
+ +
+ {% trans "Switch Back to OpenLiteSpeed" %} +

+ +
+ +
+
+
+ +
+
{% trans "Switch Back to OpenLiteSpeed" %}
+
+ {% trans "You can switch back to OpenLiteSpeed at any time, even during your trial period or after it expires. This will restore your previous OpenLiteSpeed configuration." %} +
+
+
+ +
+ +
+ +
+
+ +
+
{% trans "Important Notes" %}
+
+ {% trans "• This will restore your previous OpenLiteSpeed configuration from backup" %}
+ {% trans "• All LiteSpeed Enterprise features will be disabled" %}
+ {% trans "• You can switch back to Enterprise anytime with a valid license" %}
+ {% trans "• The process may take a few minutes to complete" %} +
+
+
+
+
+ + +
+

+ + {% trans "Switching Back to OpenLiteSpeed" %} + +

+
+
+
+
{% endif %} {% if OLS %} @@ -889,12 +948,12 @@ -
- +
+
-
{% trans "Important Warning" %}
+
{% trans "Trial Information" %}
- {% trans "You cannot revert back to OpenLiteSpeed if you choose not to purchase a LiteSpeed Enterprise license after the 15 day trial period. We recommend you test the Enterprise trial on a separate server." %} + {% trans "You can switch back to OpenLiteSpeed at any time, even during or after the trial period. The system automatically creates a backup of your OpenLiteSpeed configuration before switching to Enterprise." %}
diff --git a/serverStatus/urls.py b/serverStatus/urls.py index 37766a0cd..37feed56f 100644 --- a/serverStatus/urls.py +++ b/serverStatus/urls.py @@ -13,6 +13,8 @@ urlpatterns = [ path('services', views.services, name='services'), path('switchTOLSWS', views.switchTOLSWS, name='switchTOLSWS'), path('switchTOLSWSStatus', views.switchTOLSWSStatus, name='switchTOLSWSStatus'), + path('switchToOLS', views.switchToOLS, name='switchToOLS'), + path('switchToOLSStatus', views.switchToOLSStatus, name='switchToOLSStatus'), path('licenseStatus', views.licenseStatus, name='licenseStatus'), path('changeLicense', views.changeLicense, name='changeLicense'), path('refreshLicense', views.refreshLicense, name='refreshLicense'), diff --git a/serverStatus/views.py b/serverStatus/views.py index 5773ba0f5..b49a32cc3 100644 --- a/serverStatus/views.py +++ b/serverStatus/views.py @@ -554,6 +554,77 @@ def changeLicense(request): return HttpResponse(final_json) +def switchToOLS(request): + """Switch back to OpenLiteSpeed from LiteSpeed Enterprise""" + try: + userID = request.session['userID'] + + currentACL = ACLManager.loadedACL(userID) + + if currentACL['admin'] == 1: + pass + else: + return ACLManager.loadErrorJson('status', 0) + + # Check if we're currently running LiteSpeed Enterprise + if ProcessUtilities.decideServer() == ProcessUtilities.OLS: + data_ret = {'status': 0, 'error_message': 'Already running OpenLiteSpeed. No need to switch.'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + # Check if backup exists + if not os.path.exists('/usr/local/lswsbak'): + data_ret = {'status': 0, 'error_message': 'No OpenLiteSpeed backup found. Cannot switch back to OpenLiteSpeed.'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + execPath = "sudo /usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/serverStatus/serverStatusUtil.py" + execPath = execPath + " switchToOLS" + + ProcessUtilities.popenExecutioner(execPath) + time.sleep(2) + + data_ret = {'status': 1, 'error_message': "None"} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException as msg: + data_ret = {'status': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + +def switchToOLSStatus(request): + """Check the status of switching back to OpenLiteSpeed""" + try: + command = 'sudo cat ' + serverStatusUtil.ServerStatusUtil.lswsInstallStatusPath + output = ProcessUtilities.outputExecutioner(command) + + if output.find('[404]') > -1: + command = "sudo rm -f " + serverStatusUtil.ServerStatusUtil.lswsInstallStatusPath + ProcessUtilities.popenExecutioner(command) + data_ret = {'status': 1, 'abort': 1, 'requestStatus': output, 'installed': 0} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + elif output.find('[200]') > -1: + command = "sudo rm -f " + serverStatusUtil.ServerStatusUtil.lswsInstallStatusPath + ProcessUtilities.popenExecutioner(command) + data_ret = {'status': 1, 'abort': 1, 'requestStatus': output, 'installed': 1} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + else: + data_ret = {'status': 1, 'abort': 0, 'requestStatus': output, 'installed': 0} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException as msg: + command = "sudo rm -f " + serverStatusUtil.ServerStatusUtil.lswsInstallStatusPath + ProcessUtilities.popenExecutioner(command) + data_ret = {'status': 0, 'abort': 1, 'requestStatus': str(msg), 'installed': 0} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def topProcesses(request): proc = httpProc(request, "serverStatus/topProcesses.html", None, 'admin') return proc.render()