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.

This commit is contained in:
Master3395
2025-09-21 00:27:49 +02:00
parent 53aea56136
commit 5d445b0e23
5 changed files with 338 additions and 4 deletions

View File

@@ -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__":

View File

@@ -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;

View File

@@ -829,6 +829,65 @@
</form>
</div>
</div>
<!-- Switch Back to OpenLiteSpeed for Enterprise Users -->
<div class="license-panel" ng-controller="switchToOLS">
<div class="card-header">
<h3 class="card-title">
<div class="card-icon">
<i class="fas fa-undo"></i>
</div>
{% trans "Switch Back to OpenLiteSpeed" %}
</h3>
<span ng-hide="cyberPanelLoading" class="loading-spinner"></span>
</div>
<div class="card-content">
<div ng-show="installBoxGen">
<div class="alert alert-info">
<i class="fas fa-info-circle alert-icon"></i>
<div class="alert-content">
<div class="alert-title">{% trans "Switch Back to OpenLiteSpeed" %}</div>
<div class="alert-message">
{% 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." %}
</div>
</div>
</div>
<div class="action-buttons">
<button type="button" ng-click="switchToOLS()" class="btn btn-primary">
<i class="fas fa-undo"></i>
{% trans "Switch Back to OpenLiteSpeed" %}
</button>
</div>
<div style="margin-top: 2rem;">
<div class="alert alert-warning">
<i class="fas fa-exclamation-triangle alert-icon"></i>
<div class="alert-content">
<div class="alert-title">{% trans "Important Notes" %}</div>
<div class="alert-message">
{% trans "• This will restore your previous OpenLiteSpeed configuration from backup" %}<br>
{% trans "• All LiteSpeed Enterprise features will be disabled" %}<br>
{% trans "• You can switch back to Enterprise anytime with a valid license" %}<br>
{% trans "• The process may take a few minutes to complete" %}
</div>
</div>
</div>
</div>
</div>
<!-- Switch Back Progress -->
<div ng-hide="installBoxGen">
<h3 style="text-align: center; margin-bottom: 1.5rem; display: flex; align-items: center; justify-content: center; gap: 1rem;">
<i class="fas fa-undo" style="font-size: 2rem; color: var(--accent-color);"></i>
{% trans "Switching Back to OpenLiteSpeed" %}
<span ng-hide="cyberPanelLoading" class="loading-spinner"></span>
</h3>
<div class="console-output" ng-bind="requestData"></div>
</div>
</div>
</div>
{% endif %}
{% if OLS %}
@@ -889,12 +948,12 @@
</div>
</div>
<div class="alert alert-warning">
<i class="fas fa-exclamation-triangle alert-icon"></i>
<div class="alert alert-info">
<i class="fas fa-info-circle alert-icon"></i>
<div class="alert-content">
<div class="alert-title" style="color: var(--danger-accent);">{% trans "Important Warning" %}</div>
<div class="alert-title">{% trans "Trial Information" %}</div>
<div class="alert-message">
{% 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." %}
</div>
</div>
</div>

View File

@@ -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'),

View File

@@ -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()