final major refactor

This commit is contained in:
usmannasir 2025-07-05 15:46:08 +05:00
parent 3a79bc4db0
commit b66fd7ce0f
3 changed files with 480 additions and 253 deletions

View File

@ -14,112 +14,42 @@ from os.path import *
from stat import *
import stat
import secrets
import install_utils
VERSION = '2.4'
BUILD = 2
char_set = {'small': 'abcdefghijklmnopqrstuvwxyz', 'nums': '0123456789', 'big': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'}
# Using shared char_set from install_utils
char_set = install_utils.char_set
def generate_pass(length=14):
chars = string.ascii_uppercase + string.ascii_lowercase + string.digits
size = length
return ''.join(random.choice(chars) for x in range(size))
# Using shared function from install_utils
generate_pass = install_utils.generate_pass
# There can not be peace without first a great suffering.
# distros
# distros - using from install_utils
centos = install_utils.centos
ubuntu = install_utils.ubuntu
cent8 = install_utils.cent8
openeuler = install_utils.openeuler
cent9 = 4 # Not in install_utils yet
CloudLinux8 = 0 # Not in install_utils yet
centos = 0
ubuntu = 1
cent8 = 2
cent9 = 4
openeuler = 3
CloudLinux8 = 0
def FetchCloudLinuxAlmaVersionVersion():
if os.path.exists('/etc/os-release'):
data = open('/etc/os-release', 'r').read()
if (data.find('CloudLinux') > -1 or data.find('cloudlinux') > -1) and (data.find('8.9') > -1 or data.find('Anatoly Levchenko') > -1 or data.find('VERSION="8.') > -1):
return 'cl-89'
elif (data.find('CloudLinux') > -1 or data.find('cloudlinux') > -1) and (data.find('8.8') > -1 or data.find('Anatoly Filipchenko') > -1):
return 'cl-88'
elif (data.find('CloudLinux') > -1 or data.find('cloudlinux') > -1) and (data.find('9.4') > -1 or data.find('VERSION="9.') > -1):
return 'cl-88'
elif (data.find('AlmaLinux') > -1 or data.find('almalinux') > -1) and (data.find('8.9') > -1 or data.find('Midnight Oncilla') > -1 or data.find('VERSION="8.') > -1):
return 'al-88'
elif (data.find('AlmaLinux') > -1 or data.find('almalinux') > -1) and (data.find('8.7') > -1 or data.find('Stone Smilodon') > -1):
return 'al-87'
elif (data.find('AlmaLinux') > -1 or data.find('almalinux') > -1) and (data.find('9.4') > -1 or data.find('9.3') > -1 or data.find('Shamrock Pampas') > -1 or data.find('Seafoam Ocelot') > -1 or data.find('VERSION="9.') > -1):
return 'al-93'
else:
return -1
# Using shared function from install_utils
FetchCloudLinuxAlmaVersionVersion = install_utils.FetchCloudLinuxAlmaVersionVersion
def get_distro():
distro = -1
distro_file = ""
if exists("/etc/lsb-release"):
distro_file = "/etc/lsb-release"
with open(distro_file) as f:
for line in f:
if line == "DISTRIB_ID=Ubuntu\n":
distro = ubuntu
elif exists("/etc/redhat-release"):
distro_file = "/etc/redhat-release"
distro = centos
data = open('/etc/redhat-release', 'r').read()
if data.find('CentOS Linux release 8') > -1:
return cent8
## if almalinux 9 then pretty much same as cent8
if data.find('AlmaLinux release 8') > -1 or data.find('AlmaLinux release 9') > -1:
return cent8
if data.find('Rocky Linux release 8') > -1 or data.find('Rocky Linux 8') > -1 or data.find('rocky:8') > -1:
return cent8
if data.find('CloudLinux 8') or data.find('cloudlinux 8'):
return cent8
else:
if exists("/etc/openEuler-release"):
distro_file = "/etc/openEuler-release"
distro = openeuler
else:
logging.InstallLog.writeToFile("Can't find linux release file - fatal error")
preFlightsChecks.stdOut("Can't find linux release file - fatal error")
os._exit(os.EX_UNAVAILABLE)
if distro == -1:
logging.InstallLog.writeToFile("Can't find distro name in " + distro_file + " - fatal error")
preFlightsChecks.stdOut("Can't find distro name in " + distro_file + " - fatal error")
os._exit(os.EX_UNAVAILABLE)
return distro
# Using shared function from install_utils
get_distro = install_utils.get_distro
def get_Ubuntu_release():
release = -1
if exists("/etc/lsb-release"):
distro_file = "/etc/lsb-release"
with open(distro_file) as f:
for line in f:
if line[:16] == "DISTRIB_RELEASE=":
release = float(line[16:])
if release == -1:
preFlightsChecks.stdOut("Can't find distro release name in " + distro_file + " - fatal error", 1, 1,
os.EX_UNAVAILABLE)
else:
logging.InstallLog.writeToFile("Can't find linux release file - fatal error")
preFlightsChecks.stdOut("Can't find linux release file - fatal error")
os._exit(os.EX_UNAVAILABLE)
release = install_utils.get_Ubuntu_release(use_print=False, exit_on_error=True)
if release == -1:
preFlightsChecks.stdOut("Can't find distro release name in /etc/lsb-release - fatal error", 1, 1,
os.EX_UNAVAILABLE)
return release
@ -132,15 +62,7 @@ class preFlightsChecks:
def install_package(self, package_name, options="", silent=False):
"""Unified package installation across distributions"""
if self.distro == ubuntu:
command = f"DEBIAN_FRONTEND=noninteractive apt-get -y install {package_name} {options}"
shell = True
elif self.distro == centos:
command = f"yum install -y {package_name} {options}"
shell = False
else: # cent8, openeuler
command = f"dnf install -y {package_name} {options}"
shell = False
command, shell = install_utils.get_package_install_command(self.distro, package_name, options)
if not silent:
return preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, shell)
@ -158,15 +80,7 @@ class preFlightsChecks:
def remove_package(self, package_name, silent=False):
"""Unified package removal across distributions"""
if self.distro == ubuntu:
command = f"DEBIAN_FRONTEND=noninteractive apt-get -y remove {package_name}"
shell = True
elif self.distro == centos:
command = f"yum remove -y {package_name}"
shell = False
else: # cent8, openeuler
command = f"dnf remove -y {package_name}"
shell = False
command, shell = install_utils.get_package_remove_command(self.distro, package_name)
if not silent:
return preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR, shell)
@ -371,18 +285,7 @@ class preFlightsChecks:
@staticmethod
def stdOut(message, log=0, do_exit=0, code=os.EX_OK):
print("\n\n")
print(("[" + time.strftime(
"%m.%d.%Y_%H-%M-%S") + "] #########################################################################\n"))
print(("[" + time.strftime("%m.%d.%Y_%H-%M-%S") + "] " + message + "\n"))
print(("[" + time.strftime(
"%m.%d.%Y_%H-%M-%S") + "] #########################################################################\n"))
if log:
logging.InstallLog.writeToFile(message)
if do_exit:
logging.InstallLog.writeToFile(message)
sys.exit(code)
install_utils.stdOut(message, log, do_exit, code)
def mountTemp(self):
try:
@ -471,42 +374,15 @@ class preFlightsChecks:
return 'pure-ftpd-mysql'
return 'pure-ftpd'
# Using shared function from install_utils
@staticmethod
def resFailed(distro, res):
if distro == ubuntu and res != 0:
return True
elif distro == centos and res != 0:
return True
return False
return install_utils.resFailed(distro, res)
# Using shared function from install_utils
@staticmethod
def call(command, distro, bracket, message, log=0, do_exit=0, code=os.EX_OK, shell=False):
finalMessage = 'Running: %s' % (message)
preFlightsChecks.stdOut(finalMessage, log)
count = 0
while True:
if shell == False:
res = subprocess.call(shlex.split(command))
else:
res = subprocess.call(command, shell=True)
if preFlightsChecks.resFailed(distro, res):
count = count + 1
finalMessage = 'Running %s failed. Running again, try number %s' % (message, str(count))
preFlightsChecks.stdOut(finalMessage)
if count == 3:
fatal_message = ''
if do_exit:
fatal_message = '. Fatal error, see /var/log/installLogs.txt for full details'
preFlightsChecks.stdOut("[ERROR] We are not able to run " + message + ' return code: ' + str(res) +
fatal_message + ".", 1, do_exit, code)
return False
else:
preFlightsChecks.stdOut('Successfully ran: %s.' % (message), log)
break
return True
return install_utils.call(command, distro, bracket, message, log, do_exit, code, shell)
def checkIfSeLinuxDisabled(self):
try:
@ -994,7 +870,7 @@ password="%s"
## Write secret phrase
rString = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
rString = install_utils.generate_random_string(32)
data = open('/usr/local/CyberCP/public/phpmyadmin/config.sample.inc.php', 'r').readlines()
@ -1653,7 +1529,7 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout';
###################################################### Email setup ends!
def reStartLiteSpeed(self):
command = '%sbin/lswsctrl restart' % (self.server_root_path)
command = install_utils.format_restart_litespeed_command(self.server_root_path)
preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
def removeUfw(self):
@ -2793,8 +2669,6 @@ admin_password = "12345"
""")
writeToFile.close()
import randomPassword
content = """<?php
$_ENV['snappymail_INCLUDE_AS_API'] = true;
@ -2804,7 +2678,7 @@ $oConfig = \snappymail\Api::Config();
$oConfig->SetPassword('%s');
echo $oConfig->Save() ? 'Done' : 'Error';
?>""" % (randomPassword.generate_pass())
?>""" % (generate_pass())
writeToFile = open('/usr/local/CyberCP/public/snappymail.php', 'w')
writeToFile.write(content)

View File

@ -3,57 +3,26 @@ import subprocess
import os
from mysqlUtilities import mysqlUtilities
import installLog as logging
import randomPassword
import errno
import MySQLdb as mariadb
import install
from os.path import exists
import time
import install_utils
# distros
centos = 0
ubuntu = 1
cent8 = 2
openeuler = 3
# distros - using from install_utils
centos = install_utils.centos
ubuntu = install_utils.ubuntu
cent8 = install_utils.cent8
openeuler = install_utils.openeuler
def get_Ubuntu_release():
release = -1
if exists("/etc/lsb-release"):
distro_file = "/etc/lsb-release"
with open(distro_file) as f:
for line in f:
if line[:16] == "DISTRIB_RELEASE=":
release = float(line[16:])
if release == -1:
print("Can't find distro release name in " + distro_file + " - fatal error")
else:
logging.InstallLog.writeToFile("Can't find linux release file - fatal error")
print("Can't find linux release file - fatal error")
os._exit(os.EX_UNAVAILABLE)
return release
return install_utils.get_Ubuntu_release(use_print=True, exit_on_error=True)
def FetchCloudLinuxAlmaVersionVersion():
if os.path.exists('/etc/os-release'):
data = open('/etc/os-release', 'r').read()
if (data.find('CloudLinux') > -1 or data.find('cloudlinux') > -1) and (data.find('8.9') > -1 or data.find('Anatoly Levchenko') > -1 or data.find('VERSION="8.') > -1):
return 'cl-89'
elif (data.find('CloudLinux') > -1 or data.find('cloudlinux') > -1) and (data.find('8.8') > -1 or data.find('Anatoly Filipchenko') > -1):
return 'cl-88'
elif (data.find('CloudLinux') > -1 or data.find('cloudlinux') > -1) and (data.find('9.4') > -1 or data.find('VERSION="9.') > -1):
return 'cl-88'
elif (data.find('AlmaLinux') > -1 or data.find('almalinux') > -1) and (data.find('8.9') > -1 or data.find('Midnight Oncilla') > -1 or data.find('VERSION="8.') > -1):
return 'al-88'
elif (data.find('AlmaLinux') > -1 or data.find('almalinux') > -1) and (data.find('8.7') > -1 or data.find('Stone Smilodon') > -1):
return 'al-87'
elif (data.find('AlmaLinux') > -1 or data.find('almalinux') > -1) and (data.find('9.4') > -1 or data.find('9.3') > -1 or data.find('Shamrock Pampas') > -1 or data.find('Seafoam Ocelot') > -1 or data.find('VERSION="9.') > -1):
return 'al-93'
else:
return -1
# Using shared function from install_utils
FetchCloudLinuxAlmaVersionVersion = install_utils.FetchCloudLinuxAlmaVersionVersion
class InstallCyberPanel:
mysql_Root_password = ""
@ -62,14 +31,14 @@ class InstallCyberPanel:
def install_package(self, package_name, options=""):
"""Unified package installation across distributions"""
command, shell = install_utils.get_package_install_command(self.distro, package_name, options)
# InstallCyberPanel always uses verbose mode (no silent option)
if self.distro == ubuntu:
command = f"DEBIAN_FRONTEND=noninteractive apt-get -y install {package_name} {options}"
return install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
elif self.distro == centos:
command = f"yum install -y {package_name} {options}"
else: # cent8, openeuler
command = f"dnf install -y {package_name} {options}"
return install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
return install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, shell)
else:
# For non-Ubuntu, original code didn't pass shell parameter
return install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
def manage_service(self, service_name, action="start"):
"""Unified service management"""
@ -81,7 +50,7 @@ class InstallCyberPanel:
actual_service = service_map.get(service_name, service_name)
command = f'systemctl {action} {actual_service}'
return install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
return install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
def modify_file_content(self, file_path, replacements):
"""Generic file content modification"""
@ -184,7 +153,7 @@ class InstallCyberPanel:
@staticmethod
def stdOut(message, log=0, exit=0, code=os.EX_OK):
install.preFlightsChecks.stdOut(message, log, exit, code)
install_utils.stdOut(message, log, exit, code)
def installLiteSpeed(self):
if self.ent == 0:
@ -194,13 +163,13 @@ class InstallCyberPanel:
try:
try:
command = 'groupadd nobody'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
except:
pass
try:
command = 'usermod -a -G nobody nobody'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
except:
pass
@ -209,20 +178,20 @@ class InstallCyberPanel:
else:
command = 'wget https://www.litespeedtech.com/packages/6.0/lsws-6.2-ent-x86_64-linux.tar.gz'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
if InstallCyberPanel.ISARM():
command = 'tar zxf lsws-6.2-ent-aarch64-linux.tar.gz'
else:
command = 'tar zxf lsws-6.2-ent-x86_64-linux.tar.gz'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
if str.lower(self.serial) == 'trial':
command = 'wget -q --output-document=lsws-6.2/trial.key http://license.litespeedtech.com/reseller/trial.key'
if self.serial == '1111-2222-3333-4444':
command = 'wget -q --output-document=/root/cyberpanel/install/lsws-6.2/trial.key http://license.litespeedtech.com/reseller/trial.key'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
else:
writeSerial = open('lsws-6.2/serial.no', 'w')
writeSerial.writelines(self.serial)
@ -234,13 +203,13 @@ class InstallCyberPanel:
os.chdir('lsws-6.2')
command = 'chmod +x install.sh'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
command = 'chmod +x functions.sh'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
command = './install.sh'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
os.chdir(self.cwd)
confPath = '/usr/local/lsws/conf/'
@ -249,7 +218,7 @@ class InstallCyberPanel:
shutil.copy('litespeed/httpd.conf', confPath)
command = 'chown -R lsadm:lsadm ' + confPath
install.preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
except BaseException as msg:
logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [installLiteSpeed]")
@ -258,8 +227,8 @@ class InstallCyberPanel:
return 1
def reStartLiteSpeed(self):
command = self.server_root_path + "bin/lswsctrl restart"
install.preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
command = install_utils.format_restart_litespeed_command(self.server_root_path)
install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
def fix_ols_configs(self):
try:
@ -321,7 +290,7 @@ class InstallCyberPanel:
elif self.distro == centos:
# First install the group
command = 'yum -y groupinstall lsphp-all'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
InstallCyberPanel.stdOut("LiteSpeed PHPs successfully installed!", 1)
@ -356,13 +325,13 @@ class InstallCyberPanel:
if self.distro == ubuntu:
command = 'DEBIAN_FRONTEND=noninteractive apt-get install software-properties-common apt-transport-https curl -y'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
command = "mkdir -p /etc/apt/keyrings"
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
command = "curl -o /etc/apt/keyrings/mariadb-keyring.pgp 'https://mariadb.org/mariadb_release_signing_key.pgp'"
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
RepoPath = '/etc/apt/sources.list.d/mariadb.sources'
RepoContent = f"""
# MariaDB 10.11 repository list - created 2023-12-11 07:53 UTC
@ -379,7 +348,7 @@ Signed-By: /etc/apt/keyrings/mariadb-keyring.pgp
if get_Ubuntu_release() > 21.00:
command = 'curl -LsS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version=10.11'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
# WriteToFile = open(RepoPath, 'w')
# WriteToFile.write(RepoContent)
# WriteToFile.close()
@ -387,7 +356,7 @@ Signed-By: /etc/apt/keyrings/mariadb-keyring.pgp
command = 'DEBIAN_FRONTEND=noninteractive apt-get update -y'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
command = "DEBIAN_FRONTEND=noninteractive apt-get install mariadb-server -y"
@ -417,34 +386,34 @@ gpgcheck=1
if type == 'cl' and version >= 88:
command = 'yum remove db-governor db-governor-mysql -y'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
command = 'yum install governor-mysql -y'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
command = '/usr/share/lve/dbgovernor/mysqlgovernor.py --mysql-version=mariadb106'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
command = '/usr/share/lve/dbgovernor/mysqlgovernor.py --install --yes'
else:
command = 'curl -LsS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version=10.11'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
command = 'yum remove mariadb* -y'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
command = 'sudo dnf -qy module disable mariadb'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
command = 'sudo dnf module reset mariadb -y'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
command = 'dnf install MariaDB-server MariaDB-client MariaDB-backup -y'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True)
############## Start mariadb ######################
@ -461,7 +430,7 @@ gpgcheck=1
command = 'mariadb -u root -e "' + passwordCMD + '"'
install.preFlightsChecks.call(command, self.distro, command, command, 0, 0, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 0, 0, os.EX_OSERR)
def startMariaDB(self):
@ -519,24 +488,24 @@ gpgcheck=1
]
for filename, wget_cmd in packages:
install.preFlightsChecks.call(wget_cmd, self.distro, wget_cmd, wget_cmd, 1, 1, os.EX_OSERR)
install_utils.call(wget_cmd, self.distro, wget_cmd, wget_cmd, 1, 1, os.EX_OSERR)
command = f'dpkg --install --force-confold {filename}'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
else:
self.install_package('pure-ftpd')
####### Install pureftpd to system startup
command = "systemctl enable " + install.preFlightsChecks.pureFTPDServiceName(self.distro)
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
###### FTP Groups and user settings settings
command = 'groupadd -g 2001 ftpgroup'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
command = 'useradd -u 2001 -s /bin/false -d /bin/null -c "pureftpd user" -g ftpgroup ftpuser'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
def startPureFTPD(self):
############## Start pureftpd ######################
@ -559,7 +528,7 @@ gpgcheck=1
else:
command = 'openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -subj "/C=US/ST=Denial/L=Sprinal-ield/O=Dis/CN=www.example.com" -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
os.chdir(self.cwd)
ftpdPath = "/etc/pure-ftpd"
@ -591,13 +560,13 @@ gpgcheck=1
if self.remotemysql == 'ON':
command = "sed -i 's|localhost|%s|g' %s" % (self.mysqlhost, ftpConfPath)
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
command = "sed -i 's|3306|%s|g' %s" % (self.mysqlport, ftpConfPath)
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
command = "sed -i 's|MYSQLSocket /var/lib/mysql/mysql.sock||g' %s" % (ftpConfPath)
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
if self.distro == ubuntu:
@ -623,13 +592,13 @@ gpgcheck=1
subprocess.call(command, shell=True)
command = 'ln -s /etc/pure-ftpd/conf/MySQLConfigFile /etc/pure-ftpd/auth/30mysql'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
command = 'ln -s /etc/pure-ftpd/conf/UnixAuthentication /etc/pure-ftpd/auth/65unix'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
command = 'systemctl restart pure-ftpd-mysql.service'
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
@ -638,10 +607,10 @@ gpgcheck=1
### change mysql md5 to crypt
command = "sed -i 's/MYSQLCrypt md5/MYSQLCrypt crypt/g' /etc/pure-ftpd/db/mysql.conf"
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
command = "systemctl restart pure-ftpd-mysql.service"
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
else:
try:
@ -651,7 +620,7 @@ gpgcheck=1
if type == 'al' and version >= 90:
command = "sed -i 's/MYSQLCrypt md5/MYSQLCrypt crypt/g' /etc/pure-ftpd/pureftpd-mysql.conf"
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
except:
pass
@ -728,10 +697,10 @@ gpgcheck=1
if self.remotemysql == 'ON':
command = "sed -i 's|gmysql-host=localhost|gmysql-host=%s|g' %s" % (self.mysqlhost, dnsPath)
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
command = "sed -i 's|gmysql-port=3306|gmysql-port=%s|g' %s" % (self.mysqlport, dnsPath)
install.preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
InstallCyberPanel.stdOut("PowerDNS configured!", 1)
@ -750,8 +719,8 @@ gpgcheck=1
def Main(cwd, mysql, distro, ent, serial=None, port="8090", ftp=None, dns=None, publicip=None, remotemysql=None,
mysqlhost=None, mysqldb=None, mysqluser=None, mysqlpassword=None, mysqlport=None):
InstallCyberPanel.mysqlPassword = randomPassword.generate_pass()
InstallCyberPanel.mysql_Root_password = randomPassword.generate_pass()
InstallCyberPanel.mysqlPassword = install_utils.generate_pass()
InstallCyberPanel.mysql_Root_password = install_utils.generate_pass()
file_name = '/etc/cyberpanel/mysqlPassword'
@ -778,18 +747,18 @@ def Main(cwd, mysql, distro, ent, serial=None, port="8090", ftp=None, dns=None,
try:
command = 'chmod 640 %s' % (file_name)
install.preFlightsChecks.call(command, distro, '[chmod]',
install_utils.call(command, distro, '[chmod]',
'',
1, 0, os.EX_OSERR)
command = 'chown root:cyberpanel %s' % (file_name)
install.preFlightsChecks.call(command, distro, '[chmod]',
install_utils.call(command, distro, '[chmod]',
'',
1, 0, os.EX_OSERR)
except:
pass
if distro == centos:
InstallCyberPanel.mysqlPassword = randomPassword.generate_pass()
InstallCyberPanel.mysqlPassword = install_utils.generate_pass()
else:
InstallCyberPanel.mysqlPassword = InstallCyberPanel.mysql_Root_password

384
install/install_utils.py Normal file
View File

@ -0,0 +1,384 @@
#!/usr/bin/env python
"""
Common utility functions for CyberPanel installation scripts.
This module contains shared functions used by both install.py and installCyberPanel.py
"""
import os
import sys
import time
import logging
import subprocess
import shlex
import secrets
import string
from os.path import exists
def FetchCloudLinuxAlmaVersionVersion():
"""
Detect CloudLinux or AlmaLinux version by parsing /etc/os-release
Returns: version string or -1 if not found
"""
if os.path.exists('/etc/os-release'):
data = open('/etc/os-release', 'r').read()
if (data.find('CloudLinux') > -1 or data.find('cloudlinux') > -1) and (data.find('8.9') > -1 or data.find('Anatoly Levchenko') > -1 or data.find('VERSION="8.') > -1):
return 'cl-89'
elif (data.find('CloudLinux') > -1 or data.find('cloudlinux') > -1) and (data.find('8.8') > -1 or data.find('Anatoly Filipchenko') > -1):
return 'cl-88'
elif (data.find('CloudLinux') > -1 or data.find('cloudlinux') > -1) and (data.find('9.4') > -1 or data.find('VERSION="9.') > -1):
return 'cl-88'
elif (data.find('AlmaLinux') > -1 or data.find('almalinux') > -1) and (data.find('8.9') > -1 or data.find('Midnight Oncilla') > -1 or data.find('VERSION="8.') > -1):
return 'al-88'
elif (data.find('AlmaLinux') > -1 or data.find('almalinux') > -1) and (data.find('8.7') > -1 or data.find('Stone Smilodon') > -1):
return 'al-87'
elif (data.find('AlmaLinux') > -1 or data.find('almalinux') > -1) and (data.find('9.4') > -1 or data.find('9.3') > -1 or data.find('Shamrock Pampas') > -1 or data.find('Seafoam Ocelot') > -1 or data.find('VERSION="9.') > -1):
return 'al-93'
else:
return -1
def get_Ubuntu_release(use_print=False, exit_on_error=True):
"""
Get Ubuntu release version from /etc/lsb-release
Args:
use_print: If True, use print() for errors, otherwise use the provided output function
exit_on_error: If True, exit on error
Returns: float release number or -1 if not found
"""
release = -1
if exists("/etc/lsb-release"):
distro_file = "/etc/lsb-release"
with open(distro_file) as f:
for line in f:
if line[:16] == "DISTRIB_RELEASE=":
release = float(line[16:])
if release == -1:
error_msg = "Can't find distro release name in " + distro_file + " - fatal error"
if use_print:
print(error_msg)
else:
# This will be overridden by the calling module
return -1
else:
error_msg = "Can't find linux release file - fatal error"
if hasattr(logging, 'InstallLog'):
logging.InstallLog.writeToFile(error_msg)
if use_print:
print(error_msg)
if exit_on_error:
os._exit(os.EX_UNAVAILABLE)
return release
# ANSI color codes
class Colors:
HEADER = '\033[95m' # Purple
INFO = '\033[94m' # Blue
SUCCESS = '\033[92m' # Green
WARNING = '\033[93m' # Yellow
ERROR = '\033[91m' # Red
ENDC = '\033[0m' # Reset
BOLD = '\033[1m' # Bold
UNDERLINE = '\033[4m' # Underline
def get_message_color(message):
"""
Determine the appropriate color based on message content
Args:
message: The message to analyze
Returns:
str: ANSI color code
"""
message_lower = message.lower()
# Error messages
if any(word in message_lower for word in ['error', 'failed', 'fatal', 'critical', 'unable']):
return Colors.ERROR
# Warning messages
elif any(word in message_lower for word in ['warning', 'warn', 'caution', 'alert']):
return Colors.WARNING
# Success messages
elif any(word in message_lower for word in ['success', 'completed', 'installed', 'finished', 'done', 'enabled']):
return Colors.SUCCESS
# Running/Processing messages
elif any(word in message_lower for word in ['running', 'installing', 'downloading', 'processing', 'starting', 'configuring']):
return Colors.INFO
# Default color
else:
return Colors.HEADER
def stdOut(message, log=0, do_exit=0, code=os.EX_OK):
"""
Standard output function with timestamps, coloring, and logging
Args:
message: Message to output
log: If 1, write to log file
do_exit: If 1, exit after outputting
code: Exit code to use if do_exit is 1
"""
# Get appropriate color for the message
color = get_message_color(message)
# Check if terminal supports color
try:
# Check if output is to a terminal
if not sys.stdout.isatty():
color = ''
color_end = ''
else:
color_end = Colors.ENDC
except:
color = ''
color_end = ''
# Format timestamps
timestamp = time.strftime("%m.%d.%Y_%H-%M-%S")
print("\n\n")
print(f"{color}[{timestamp}] #########################################################################{color_end}\n")
print(f"{color}[{timestamp}] {message}{color_end}\n")
print(f"{color}[{timestamp}] #########################################################################{color_end}\n")
if log and hasattr(logging, 'InstallLog'):
logging.InstallLog.writeToFile(message)
if do_exit:
if hasattr(logging, 'InstallLog'):
logging.InstallLog.writeToFile(message)
sys.exit(code)
def format_restart_litespeed_command(server_root_path):
"""
Format the LiteSpeed restart command
Args:
server_root_path: Root path of the server installation
Returns: Formatted command string
"""
return '%sbin/lswsctrl restart' % (server_root_path)
# Distribution constants
ubuntu = 0
centos = 1
cent8 = 2
openeuler = 3
def get_distro():
"""
Detect Linux distribution
Returns: Distribution constant (ubuntu, centos, cent8, or openeuler)
"""
distro = -1
distro_file = ""
if exists("/etc/lsb-release"):
distro_file = "/etc/lsb-release"
with open(distro_file) as f:
for line in f:
if line == "DISTRIB_ID=Ubuntu\n":
distro = ubuntu
elif exists("/etc/redhat-release"):
distro_file = "/etc/redhat-release"
distro = centos
data = open('/etc/redhat-release', 'r').read()
if data.find('CentOS Linux release 8') > -1:
return cent8
## if almalinux 9 then pretty much same as cent8
if data.find('AlmaLinux release 8') > -1 or data.find('AlmaLinux release 9') > -1:
return cent8
if data.find('Rocky Linux release 8') > -1 or data.find('Rocky Linux 8') > -1 or data.find('rocky:8') > -1:
return cent8
if data.find('CloudLinux 8') or data.find('cloudlinux 8'):
return cent8
else:
if exists("/etc/openEuler-release"):
distro_file = "/etc/openEuler-release"
distro = openeuler
else:
if hasattr(logging, 'InstallLog'):
logging.InstallLog.writeToFile("Can't find linux release file - fatal error")
print("Can't find linux release file - fatal error")
os._exit(os.EX_UNAVAILABLE)
if distro == -1:
error_msg = "Can't find distro name in " + distro_file + " - fatal error"
if hasattr(logging, 'InstallLog'):
logging.InstallLog.writeToFile(error_msg)
print(error_msg)
os._exit(os.EX_UNAVAILABLE)
return distro
def get_package_install_command(distro, package_name, options=""):
"""
Get the package installation command for a specific distribution
Args:
distro: Distribution constant
package_name: Name of the package to install
options: Additional options for the package manager
Returns:
tuple: (command, shell) where shell indicates if shell=True is needed
"""
if distro == ubuntu:
command = f"DEBIAN_FRONTEND=noninteractive apt-get -y install {package_name} {options}"
shell = True
elif distro == centos:
command = f"yum install -y {package_name} {options}"
shell = False
else: # cent8, openeuler
command = f"dnf install -y {package_name} {options}"
shell = False
return command, shell
def get_package_remove_command(distro, package_name):
"""
Get the package removal command for a specific distribution
Args:
distro: Distribution constant
package_name: Name of the package to remove
Returns:
tuple: (command, shell) where shell indicates if shell=True is needed
"""
if distro == ubuntu:
command = f"DEBIAN_FRONTEND=noninteractive apt-get -y remove {package_name}"
shell = True
elif distro == centos:
command = f"yum remove -y {package_name}"
shell = False
else: # cent8, openeuler
command = f"dnf remove -y {package_name}"
shell = False
return command, shell
def resFailed(distro, res):
"""
Check if a command execution result indicates failure
Args:
distro: Distribution constant
res: Return code from subprocess
Returns:
bool: True if failed, False if successful
"""
if distro == ubuntu and res != 0:
return True
elif distro == centos and res != 0:
return True
return False
def call(command, distro, bracket, message, log=0, do_exit=0, code=os.EX_OK, shell=False):
"""
Execute a shell command with retry logic and error handling
Args:
command: Command to execute
distro: Distribution constant
bracket: Not used (kept for compatibility)
message: Description of the command for logging
log: If 1, write to log file
do_exit: If 1, exit on failure
code: Exit code to use if do_exit is 1
shell: If True, execute through shell
Returns:
bool: True if successful, False if failed
"""
finalMessage = 'Running: %s' % (message)
stdOut(finalMessage, log)
count = 0
while True:
if shell == False:
res = subprocess.call(shlex.split(command))
else:
res = subprocess.call(command, shell=True)
if resFailed(distro, res):
count = count + 1
finalMessage = 'Running %s failed. Running again, try number %s' % (message, str(count))
stdOut(finalMessage)
if count == 3:
fatal_message = ''
if do_exit:
fatal_message = '. Fatal error, see /var/log/installLogs.txt for full details'
stdOut("[ERROR] We are not able to run " + message + ' return code: ' + str(res) +
fatal_message + ".", 1, do_exit, code)
return False
else:
stdOut('Successfully ran: %s.' % (message), log)
break
return True
# Character sets for password generation (kept for backward compatibility)
char_set = {
'small': 'abcdefghijklmnopqrstuvwxyz',
'nums': '0123456789',
'big': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
}
def generate_pass(length=14):
"""
Generate a cryptographically secure random password
Args:
length: Length of the password to generate (default 14)
Returns:
str: Random password containing uppercase, lowercase letters and digits
"""
alphabet = string.ascii_letters + string.digits
return ''.join(secrets.choice(alphabet) for _ in range(length))
def generate_random_string(length=32, include_special=False):
"""
Generate a random string with optional special characters
Args:
length: Length of the string to generate
include_special: If True, include special characters
Returns:
str: Random string
"""
alphabet = string.ascii_letters + string.digits
if include_special:
alphabet += string.punctuation
return ''.join(secrets.choice(alphabet) for _ in range(length))