Files
CyberPanel/serverStatus/serverStatusUtil.py

598 lines
25 KiB
Python
Raw Normal View History

2025-08-01 14:56:30 +05:00
#!/usr/local/CyberCP/bin/python
import os,sys
import time
sys.path.append('/usr/local/CyberCP')
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
django.setup()
import subprocess
import shlex
import argparse
import shutil
import plogical.CyberCPLogFileWriter as logging
from plogical.processUtilities import ProcessUtilities
from websiteFunctions.models import Websites
from plogical.virtualHostUtilities import virtualHostUtilities
from plogical.sslUtilities import sslUtilities
from plogical.vhost import vhost
from shutil import ignore_patterns
import threading as multi
import urllib.request
import re
2025-08-01 14:56:30 +05:00
class ServerStatusUtil(multi.Thread):
lswsInstallStatusPath = '/home/cyberpanel/switchLSWSStatus'
serverRootPath = '/usr/local/lsws/'
def __init__(self, key):
multi.Thread.__init__(self)
self.key = key
def run(self):
self.switchTOLSWS(self.key)
@staticmethod
def executioner(command, statusFile):
try:
if os.path.exists(ProcessUtilities.debugPath):
logging.CyberCPLogFileWriter.writeToFile(command)
res = subprocess.call(command, stdout=statusFile, stderr=statusFile, shell=True)
if res == 1:
return 0
else:
return 1
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
return 0
@staticmethod
def getLatestLSWSVersion():
"""Fetch the latest LSWS Enterprise version from LiteSpeed's website"""
try:
# Try to fetch from the download page
url = "https://www.litespeedtech.com/products/litespeed-web-server/download"
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req, timeout=10) as response:
html = response.read().decode('utf-8')
# Look for the latest version pattern: lsws-X.Y.Z-ent
version_pattern = r'lsws-(\d+\.\d+\.\d+)-ent'
versions = re.findall(version_pattern, html)
if versions:
# Get the latest version
latest_version = sorted(versions, key=lambda v: [int(x) for x in v.split('.')])[-1]
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
f"Found latest LSWS Enterprise version: {latest_version}\n", 1)
return latest_version
else:
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"Could not find version pattern in HTML, using fallback\n", 1)
except Exception as e:
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
f"Failed to fetch latest LSWS version: {str(e)}, using fallback\n", 1)
# Fallback to known latest version
return "6.3.4"
2025-08-01 14:56:30 +05:00
@staticmethod
def installLiteSpeed(licenseKey, statusFile):
try:
cwd = os.getcwd()
try:
command = 'groupadd nobody'
ServerStatusUtil.executioner(command, statusFile)
except:
pass
try:
command = 'usermod -a -G nobody nobody'
ServerStatusUtil.executioner(command, statusFile)
except:
pass
try:
command = 'systemctl stop lsws'
ServerStatusUtil.executioner(command, statusFile)
except:
pass
from plogical.acl import ACLManager
# Get the latest LSWS Enterprise version dynamically
lsws_version = ServerStatusUtil.getLatestLSWSVersion()
2025-08-01 14:56:30 +05:00
if ACLManager.ISARM():
command = f'wget https://www.litespeedtech.com/packages/6.0/lsws-{lsws_version}-ent-aarch64-linux.tar.gz'
2025-08-01 14:56:30 +05:00
else:
command = f'wget https://www.litespeedtech.com/packages/6.0/lsws-{lsws_version}-ent-x86_64-linux.tar.gz'
2025-08-01 14:56:30 +05:00
if ServerStatusUtil.executioner(command, statusFile) == 0:
return 0
if os.path.exists('/usr/local/CyberCP/lsws-6.0/'):
shutil.rmtree('/usr/local/CyberCP/lsws-6.0')
if os.path.exists(f'/usr/local/CyberCP/lsws-{lsws_version}/'):
shutil.rmtree(f'/usr/local/CyberCP/lsws-{lsws_version}/')
2025-08-01 14:56:30 +05:00
if ACLManager.ISARM():
command = f'tar zxf lsws-{lsws_version}-ent-aarch64-linux.tar.gz -C /usr/local/CyberCP'
2025-08-01 14:56:30 +05:00
else:
command = f'tar zxf lsws-{lsws_version}-ent-x86_64-linux.tar.gz -C /usr/local/CyberCP'
2025-08-01 14:56:30 +05:00
if ServerStatusUtil.executioner(command, statusFile) == 0:
return 0
if licenseKey == 'trial':
command = f'wget -q --output-document=/usr/local/CyberCP/lsws-{lsws_version}/trial.key http://license.litespeedtech.com/reseller/trial.key'
2025-08-01 14:56:30 +05:00
if ServerStatusUtil.executioner(command, statusFile) == 0:
return 0
else:
writeSerial = open(f'/usr/local/CyberCP/lsws-{lsws_version}/serial.no', 'w')
2025-08-01 14:56:30 +05:00
writeSerial.writelines(licenseKey)
writeSerial.close()
shutil.copy('/usr/local/CyberCP/serverStatus/litespeed/install.sh', f'/usr/local/CyberCP/lsws-{lsws_version}/')
shutil.copy('/usr/local/CyberCP/serverStatus/litespeed/functions.sh', f'/usr/local/CyberCP/lsws-{lsws_version}/')
2025-08-01 14:56:30 +05:00
os.chdir(f'/usr/local/CyberCP/lsws-{lsws_version}/')
2025-08-01 14:56:30 +05:00
command = 'chmod +x install.sh'
if ServerStatusUtil.executioner(command, statusFile) == 0:
return 0
command = 'chmod +x functions.sh'
if ServerStatusUtil.executioner(command, statusFile) == 0:
return 0
command = './install.sh'
if ServerStatusUtil.executioner(command, statusFile) == 0:
return 0
os.chdir(cwd)
confPath = '/usr/local/lsws/conf/'
shutil.copy('/usr/local/CyberCP/serverStatus/litespeed/httpd_config.xml', confPath)
shutil.copy('/usr/local/CyberCP/serverStatus/litespeed/modsec.conf', confPath)
shutil.copy('/usr/local/CyberCP/serverStatus/litespeed/httpd.conf', confPath)
try:
command = 'chown -R lsadm:lsadm ' + confPath
subprocess.call(shlex.split(command))
except:
pass
try:
os.rmdir(f"/usr/local/CyberCP/lsws-{lsws_version}")
2025-08-01 14:56:30 +05:00
except:
pass
files = ['/usr/local/lsws/conf/httpd_config.xml', '/usr/local/lsws/conf/modsec.conf', '/usr/local/lsws/conf/httpd.conf']
for items in files:
command = 'chmod 644 %s' % (items)
ServerStatusUtil.executioner(command, statusFile)
return 1
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
return 0
@staticmethod
def setupFileManager(statusFile):
try:
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Setting up Filemanager files..\n")
fileManagerPath = ServerStatusUtil.serverRootPath+"FileManager"
if os.path.exists(fileManagerPath):
shutil.rmtree(fileManagerPath)
shutil.copytree("/usr/local/CyberCP/serverStatus/litespeed/FileManager",fileManagerPath)
## remove unnecessary files
command = 'chmod -R 777 ' + fileManagerPath
if ServerStatusUtil.executioner(command, statusFile) == 0:
return 0
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,"Filemanager files are set!\n")
return 1
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
return 0
@staticmethod
def recover():
FNULL = open(os.devnull, 'w')
if os.path.exists('/usr/local/lsws'):
shutil.rmtree('/usr/local/lsws')
command = 'mv /usr/local/lswsbak /usr/local/lsws'
ServerStatusUtil.executioner(command, FNULL)
command = '/usr/local/lsws/bin/openlitespeed'
ServerStatusUtil.executioner(command, FNULL)
@staticmethod
def createWebsite(website):
try:
virtualHostName = website.domain
confPath = vhost.Server_root + "/conf/vhosts/" + virtualHostName
FNULL = open(os.devnull, 'w')
if not os.path.exists(confPath):
command = 'mkdir -p ' + confPath
ServerStatusUtil.executioner(command, FNULL)
completePathToConfigFile = confPath + "/vhost.conf"
if vhost.perHostVirtualConf(completePathToConfigFile, website.adminEmail , website.externalApp, website.phpSelection,
virtualHostName, 1) == 1:
pass
else:
return 0
retValues = vhost.createConfigInMainVirtualHostFile(virtualHostName)
if retValues[0] == 0:
return 0
if os.path.exists('/etc/letsencrypt/live/' + virtualHostName):
sslUtilities.installSSLForDomain(virtualHostName, website.adminEmail)
vhostPath = vhost.Server_root + "/conf/vhosts"
FNULL = open(os.devnull, 'w')
command = "chown -R " + "lsadm" + ":" + "lsadm" + " " + vhostPath
cmd = shlex.split(command)
subprocess.call(cmd, stdout=FNULL, stderr=subprocess.STDOUT)
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
return 0
@staticmethod
def createDomain(website):
try:
virtualHostName = website.domain
confPath = vhost.Server_root + "/conf/vhosts/" + virtualHostName
completePathToConfigFile = confPath + "/vhost.conf"
confPath = vhost.Server_root + "/conf/vhosts/" + virtualHostName
FNULL = open(os.devnull, 'w')
if not os.path.exists(confPath):
command = 'mkdir -p ' + confPath
ServerStatusUtil.executioner(command, FNULL)
if vhost.perHostDomainConf(website.path, website.master.domain, virtualHostName, completePathToConfigFile, website.master.adminEmail, website.phpSelection, website.master.externalApp, 1) == 1:
pass
else:
return 0
retValues = vhost.createConfigInMainDomainHostFile(virtualHostName, website.master.domain)
if retValues[0] == 0:
return 0
if os.path.exists('/etc/letsencrypt/live/' + virtualHostName):
sslUtilities.installSSLForDomain(virtualHostName, website.master.adminEmail)
vhostPath = vhost.Server_root + "/conf/vhosts"
FNULL = open(os.devnull, 'w')
command = "chown -R " + "lsadm" + ":" + "lsadm" + " " + vhostPath
cmd = shlex.split(command)
subprocess.call(cmd, stdout=FNULL, stderr=subprocess.STDOUT)
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
return 0
@staticmethod
def rebuildvConf():
try:
allWebsites = Websites.objects.all()
for website in allWebsites:
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"Building vhost conf for: " + website.domain + ".\n", 1)
if ServerStatusUtil.createWebsite(website) == 0:
return 0
childs = website.childdomains_set.all()
for child in childs:
try:
if ServerStatusUtil.createDomain(child) == 0:
logging.CyberCPLogFileWriter.writeToFile(
'Error while creating child domain: ' + child.domain)
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(
'Error while creating child domain: ' + child.domain + ' . Exact message: ' + str(
msg))
aliases = website.aliasdomains_set.all()
for alias in aliases:
try:
aliasDomain = alias.aliasDomain
alias.delete()
virtualHostUtilities.createAlias(website.domain, aliasDomain, 0, '/home', website.adminEmail, website.admin)
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(
'Error while creating alais domain: ' + aliasDomain + ' . Exact message: ' + str(
msg))
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"vhost conf successfully built for: " + website.domain + ".\n", 1)
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
return 0
@staticmethod
def switchTOLSWS(licenseKey):
try:
os.environ['TERM'] = "xterm-256color"
statusFile = open(ServerStatusUtil.lswsInstallStatusPath, 'w')
FNULL = open(os.devnull, 'w')
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,"Starting conversion process..\n")
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"Removing OpenLiteSpeed..\n", 1)
## Try to stop current LiteSpeed Process
ProcessUtilities.killLiteSpeed()
if os.path.exists('/usr/local/lsws'):
if not os.path.exists('/usr/local/lswsbak'):
shutil.copytree('/usr/local/lsws', '/usr/local/lswsbak', symlinks=True, ignore=ignore_patterns('*.sock*'))
dirs = os.listdir('/usr/local/lsws')
for dir in dirs:
if dir.find('lsphp') > -1:
continue
finalDir = '/usr/local/lsws/' + dir
try:
shutil.rmtree(finalDir)
except:
pass
if os.path.exists('/etc/redhat-release'):
command = 'yum -y erase openlitespeed'
else:
command = "apt-get -y remove openlitespeed"
ServerStatusUtil.executioner(command, statusFile)
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"OpenLiteSpeed removed.\n", 1)
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"Installing LiteSpeed Enterprise Web Server ..\n", 1)
if ServerStatusUtil.installLiteSpeed(licenseKey, statusFile) == 0:
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Failed to install LiteSpeed. [404]", 1)
ServerStatusUtil.recover()
return 0
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"LiteSpeed Enterprise Web Server installed.\n", 1)
# if ServerStatusUtil.setupFileManager(statusFile) == 0:
# logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, "Failed to set up File Manager. [404]", 1)
# ServerStatusUtil.recover()
# return 0
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"Rebuilding vhost conf..\n", 1)
ServerStatusUtil.rebuildvConf()
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"vhost conf successfully built.\n", 1)
ProcessUtilities.stopLitespeed()
ProcessUtilities.restartLitespeed()
### Check and remove OLS restart if lsws ent detected
CentOSPath = '/etc/redhat-release'
if os.path.exists(CentOSPath):
cronPath = '/var/spool/cron/root'
else:
cronPath = '/var/spool/cron/crontabs/root'
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 to LITESPEED ENTERPRISE WEB SERVER. [200]\n", 1)
except BaseException as msg:
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"%s. [404]" % (str(msg)), 1)
logging.CyberCPLogFileWriter.writeToFile(str(msg))
ServerStatusUtil.recover()
@staticmethod
def switchTOLSWSCLI(licenseKey):
try:
ssu = ServerStatusUtil(licenseKey)
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 converted.', 'installed': 1}
print(str(data_ret))
return 1
else:
data_ret = {'status': 1, 'abort': 0, 'requestStatus': output, 'installed': 0}
#print(output)
time.sleep(2)
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))
2025-08-01 14:56:30 +05:00
def main():
parser = argparse.ArgumentParser(description='Server Status Util.')
parser.add_argument('function', help='Specific a function to call!')
parser.add_argument('--licenseKey', help='LITESPEED ENTERPRISE WEB SERVER License Key')
args = parser.parse_args()
if args.function == "switchTOLSWS":
ServerStatusUtil.switchTOLSWS(args.licenseKey)
elif args.function == "switchToOLS":
ServerStatusUtil.switchToOLS()
2025-08-01 14:56:30 +05:00
if __name__ == "__main__":
main()