From f41f07d8f241b6a9086b8d94e1db39fcf8816537 Mon Sep 17 00:00:00 2001 From: usmannasir Date: Sun, 29 Oct 2023 12:17:24 +0500 Subject: [PATCH 1/5] update favicon --- .../baseTemplate/assets/finalBase/favicon.png | Bin 2448 -> 33830 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/baseTemplate/static/baseTemplate/assets/finalBase/favicon.png b/baseTemplate/static/baseTemplate/assets/finalBase/favicon.png index f72790ed54813b032ab58664123609ca4a960999..8834c6716742b65260a8c26041d92302512bd7dd 100644 GIT binary patch literal 33830 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 literal 2448 zcmV;B32*j^P)LIQ@=E2#;1M+7`bP%%q5%FHa6*ngxNY3R;Ox4TP=Sil5n3fgOMldK88^WMa zYzTuwu_27KLUD=QLJGq?3<|}DFenro!q9}WpwTxB6njud@moD2cRwo0l>2>C;P=hS zGK+`jUZ5~C1En3-Qs%2&mz!tT6daT^z%T=)!5#43rFCtdP}NX)O?SaSNh1tBC^a6D z-Lg2~Emi)llP_N0!8_aFXJ5SxUfY;lCC*DI8GxY)#dWN@Ncnq9X!OtyzQhYKWEehK zcJ#Xx5Y!F=0G(>3`@Dh@tJ;R7nlu4ufpJtZPQYlW3U%D5b}e8HGXO$!97Y3z(+3XP zi1I%AA`Igq7mn`p1*MftFglwFOQY4k(;JWn?>~BGxC#t3MRmtu2+oKk481e)x3T~; z9+ZAsZ;>mfErl42uyl$GMc-w@otB#5WZqHIDHLyxTLl`uo&MrE%G||37fWti3LzK~ zE*yEg`j}i~^*W;d(!0Sjf(jUNyHK+Bif~t8e#-0Qkpv8Qf7PCbjvH{U1FT>kz>t(M zz*4H^YRAAnzag?q^E#s^0OJDqi6t`h>{`7BIp7%F;dicAf{2e3QNDCcQZo1(PUD2F zeF^~>?d*}r(>T}ARaZ0-6n{tsMmJc@^yJrHs(rEh@~-wpAkR3%2HWn#xrTOs$rGUX z78MvWSj_8M??VYASV~>qSW32GKw{S)p8iS{J*mRro!{zxM!XTPIp-}U+c1z%0LOhm z0|d%9{*sS53`J?L*83ictsds8rDPihL`)BY(vNGx;GL&C#o}>hJ`8Usl7EG648 zAeUGH3crv7#s#pRN6mh2yqcIR%JB^0&h3{dst%372;6%G zE2+S>j0#!q5BgdMMbJ5U=QBXryuM{P+hMA@m&E;+2dZuZMfV!D3|IZGY0CFkSIYxI zU%w=()V@$;L0%<&pzNKxK>W_HNIrz1=ztZ=NP-~~g<=O7v69H)q6r43tS;ndNC9#2 z+&V%qF0bbVBlB$s!^JbtSghX8)wL4A8IWrn#YBLJtOsM7l8Hj8t(6DCn-5xr!G@$L z84L(i!Z@!3vf-%t2W4+lbPOoE-b!c-KBF>4$he(Ut^mp4Y6BVkek-*tPd)pHn$PeBBU>RN{TU0H{r1Ep0p=@Zybjnsc!b-O1L zvyw|wmu{UadbspjtKR|T;{mpSp#i0pX=s~zm5Gb&M~17TJhzD8wDr9KAgI4b=q! zBO!};-&mD>d8UR(;Fg$xQJw-u8`QX-$MKIj4TGSioJU!)E{r#nqa0-PG8o%kV zs}S%hN8RGiaY<|Gl`1frtY+Q`K^sE>2A8)m2w6%%xxpV`yri-^xV81qkyyR6yTj7M zpwMGjCG=oqsUug!B9w?SFF_kNLHSVyi1TP`GftZ*+DaX7M(8OR7=6>1SaqEVD7`L$ z=?huU)Lt_j{6km)h4W!U=vnRHh6#w9Y+=gKk3al=MmFJNFgq4ZHAdCvNDs8-P z?3>uh4k5|gH-ggkc!Ne4;Uhfq1BRjLOXQYaRl$X$FHomqN-KaPG(b^1GjO0y4@6_- zj(ig>OYsQ4rxez)4ebl;t{Zau73(d$?}6B!@}!VB15ol4Mk*-E#yPc&8(9#%?p*x! zO&Nre-!M`@X-qy`3<=t&2mZyYGROQ>t5Layi!TLGTbiO$jqrLbTm zK}p{6+8!T9a+h>KDNGni(O1BF?Tb5}T#$^1#5*XA+=kKvCHO@SD(QuCDN&>_vIYgB zvRh0-p)k@5g>5zgg~G@t6j1&)3d2TF6rG3^hFzeb6HeizQ~Hlv>;#1hro>O3#yP{P zk>q|9Dsd>#oc*^&AU)6>>7rV+$MgmNfsL6*wPz0~)G}-Yr3czm-BerlfYO6b@}XMF zu#`7&6I2=}y3K5Fph8$;2Ufz4UI4KPqOkX^?8u@*g$flaRH#r%i~J9schw>$ATPoI O0000FkZ From 6a4e63bf93d7ed51a1a062f34f4c931808fb13ba Mon Sep 17 00:00:00 2001 From: usmannasir Date: Sun, 26 Nov 2023 14:32:35 +0400 Subject: [PATCH 2/5] dynamically detect php version in ref to: https://community.cyberpanel.net/t/php-8-2-in-cyberpanel/49703 --- managePHP/phpManager.py | 32 +++++-- plogical/acl.py | 70 ++++++++++++++- plogical/applicationInstaller.py | 150 +++++++++++++++++++++---------- plogical/phpUtilities.py | 14 ++- plogical/sslUtilities.py | 4 +- plogical/sslv2.py | 3 +- plogical/test.py | 13 +++ 7 files changed, 227 insertions(+), 59 deletions(-) diff --git a/managePHP/phpManager.py b/managePHP/phpManager.py index f21d9674c..9f2a118ad 100755 --- a/managePHP/phpManager.py +++ b/managePHP/phpManager.py @@ -12,14 +12,30 @@ class PHPManager: @staticmethod def findPHPVersions(): - distro = ProcessUtilities.decideDistro() - if distro == ProcessUtilities.centos: - return ['PHP 5.3', 'PHP 5.4', 'PHP 5.5', 'PHP 5.6', 'PHP 7.0', 'PHP 7.1', 'PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1'] - elif distro == ProcessUtilities.cent8: - return ['PHP 7.1','PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1'] - elif distro == ProcessUtilities.ubuntu20: - return ['PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1'] - else: + # distro = ProcessUtilities.decideDistro() + # if distro == ProcessUtilities.centos: + # return ['PHP 5.3', 'PHP 5.4', 'PHP 5.5', 'PHP 5.6', 'PHP 7.0', 'PHP 7.1', 'PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1'] + # elif distro == ProcessUtilities.cent8: + # return ['PHP 7.1','PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1'] + # elif distro == ProcessUtilities.ubuntu20: + # return ['PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1'] + # else: + # return ['PHP 7.0', 'PHP 7.1', 'PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1'] + + try: + + # Run the shell command and capture the output + result = ProcessUtilities.outputExecutioner('ls -la /usr/local/lsws') + + # Get the lines containing 'lsphp' in the output + lsphp_lines = [line for line in result.split('\n') if 'lsphp' in line] + + # Extract the version from the lines and format it as 'PHP x.y' + php_versions = ['PHP ' + line.split()[8][5] + '.' + line.split()[8][6:] for line in lsphp_lines] + + # Now php_versions contains the formatted PHP versions + return php_versions + except BaseException as msg: return ['PHP 7.0', 'PHP 7.1', 'PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1'] @staticmethod diff --git a/plogical/acl.py b/plogical/acl.py index ea9f5d68b..46e2688f3 100644 --- a/plogical/acl.py +++ b/plogical/acl.py @@ -1,6 +1,7 @@ #!/usr/local/CyberCP/bin/python import os,sys +from ApachController.ApacheVhosts import ApacheVhost from manageServices.models import PDNSStatus from .processUtilities import ProcessUtilities @@ -674,8 +675,6 @@ def findAllWebsites(currentACL, userID): @staticmethod def checkOwnership(domain, admin, currentACL): - - try: childDomain = ChildDomains.objects.get(domain=domain) @@ -995,3 +994,70 @@ def FetchCloudFlareAPIKeyFromAcme(): except BaseException as msg: return 0, str(msg), None + + @staticmethod + def FindDocRootOfSite(vhostConf,domainName): + try: + if vhostConf == None: + vhostConf = f'/usr/local/lsws/conf/vhosts/{domainName}/vhost.conf' + + if ProcessUtilities.decideServer() == ProcessUtilities.OLS: + command = "awk '/docRoot/ {print $2}' " + vhostConf + docRoot = ProcessUtilities.outputExecutioner(command, 'root', True).rstrip('\n') + #docRoot = docRoot.replace('$VH_ROOT', f'/home/{domainName}') + return docRoot + else: + command = "awk '/DocumentRoot/ {print $2; exit}' " + vhostConf + docRoot = ProcessUtilities.outputExecutioner(command, 'root', True).rstrip('\n') + return docRoot + except: + pass + + @staticmethod + def ReplaceDocRoot(vhostConf, domainName, NewDocRoot): + try: + if vhostConf == None: + vhostConf = f'/usr/local/lsws/conf/vhosts/{domainName}/vhost.conf' + + if ProcessUtilities.decideServer() == ProcessUtilities.OLS: + #command = f"sed -i 's/docRoot\s\s*.*/docRoot {NewDocRoot}/g " + vhostConf + command = f"sed -i 's#docRoot\s\s*.*#docRoot {NewDocRoot}#g' " + vhostConf + ProcessUtilities.executioner(command, 'root', True) + else: + command = f"sed -i 's#DocumentRoot\s\s*[^[:space:]]*#DocumentRoot {NewDocRoot}#g' " + vhostConf + ProcessUtilities.executioner(command, 'root', True) + + except: + pass + + @staticmethod + def FindDocRootOfSiteApache(vhostConf, domainName): + try: + finalConfPath = ApacheVhost.configBasePath + domainName + '.conf' + + if ProcessUtilities.decideServer() == ProcessUtilities.OLS: + + if os.path.exists(finalConfPath): + command = "awk '/DocumentRoot/ {print $2; exit}' " + finalConfPath + docRoot = ProcessUtilities.outputExecutioner(command, 'root', True).rstrip('\n') + return docRoot + else: + return None + else: + return None + + except: + return None + + @staticmethod + def ReplaceDocRootApache(vhostConf, domainName, NewDocRoot): + try: + finalConfPath = ApacheVhost.configBasePath + domainName + '.conf' + + if ProcessUtilities.decideServer() == ProcessUtilities.OLS: + command = f"sed -i 's#DocumentRoot\s\s*[^[:space:]]*#DocumentRoot {NewDocRoot}#g' " + finalConfPath + ProcessUtilities.executioner(command, 'root', True) + except: + pass + + diff --git a/plogical/applicationInstaller.py b/plogical/applicationInstaller.py index 6a2dcb626..862278330 100755 --- a/plogical/applicationInstaller.py +++ b/plogical/applicationInstaller.py @@ -4,6 +4,7 @@ import shutil import time +from ApachController.ApacheVhosts import ApacheVhost from loginSystem.models import Administrator from managePHP.phpManager import PHPManager from plogical.acl import ACLManager @@ -112,7 +113,7 @@ def installMautic(self): vhFile = f'/usr/local/lsws/conf/vhosts/{domainName}/vhost.conf' - phpPath = phpUtilities.GetPHPVersionFromFile(vhFile) + phpPath = phpUtilities.GetPHPVersionFromFile(vhFile, domainName) ### basically for now php 8.0 is being checked @@ -188,6 +189,13 @@ def installMautic(self): command = 'mkdir -p ' + finalPath ProcessUtilities.executioner(command, externalApp) + command = f'rm -rf {finalPath}*' + ProcessUtilities.executioner(command, externalApp) + + command = f'rm -rf {finalPath}.*' + ProcessUtilities.executioner(command, externalApp) + + ## checking for directories/files if self.dataLossCheck(finalPath, tempStatusPath, externalApp) == 0: @@ -199,16 +207,20 @@ def installMautic(self): statusFile.writelines('Downloading Mautic Core,30') statusFile.close() - command = "wget https://github.com/mautic/mautic/releases/download/%s/%s.zip" % ( - ApplicationInstaller.MauticVersion, ApplicationInstaller.MauticVersion) - ProcessUtilities.outputExecutioner(command, externalApp, None, finalPath) + #command = "wget https://github.com/mautic/mautic/releases/download/%s/%s.zip" % ( + #ApplicationInstaller.MauticVersion, ApplicationInstaller.MauticVersion) + + ### replace command with composer install + command = f'{phpPath} /usr/bin/composer create-project mautic/recommended-project:^4 {finalPath}' + ProcessUtilities.outputExecutioner(command, externalApp, None) statusFile = open(tempStatusPath, 'w') statusFile.writelines('Extracting Mautic Core,50') statusFile.close() - command = "unzip %s.zip" % (ApplicationInstaller.MauticVersion) - ProcessUtilities.outputExecutioner(command, externalApp, None, finalPath) + ### replace command with composer install + #command = "unzip %s.zip" % (ApplicationInstaller.MauticVersion) + #ProcessUtilities.outputExecutioner(command, externalApp, None, finalPath) ## @@ -222,53 +234,99 @@ def installMautic(self): else: finalURL = domainName - ACLManager.CreateSecureDir() - localDB = '%s/%s' % ('/usr/local/CyberCP/tmp', str(randint(1000, 9999))) - - localDBContent = """ 'localhost', - 'db_table_prefix' => null, - 'db_port' => 3306, - 'db_name' => '%s', - 'db_user' => '%s', - 'db_password' => '%s', - 'db_backup_tables' => true, - 'db_backup_prefix' => 'bak_', - 'admin_email' => '%s', - 'admin_password' => '%s', - 'mailer_transport' => null, - 'mailer_host' => null, - 'mailer_port' => null, - 'mailer_user' => null, - 'mailer_password' => null, - 'mailer_api_key' => null, - 'mailer_encryption' => null, - 'mailer_auth_mode' => null, -);""" % (dbName, dbUser, dbPassword, email, password) - - writeToFile = open(localDB, 'w') - writeToFile.write(localDBContent) - writeToFile.close() - - command = 'rm -rf %s/app/config/local.php' % (finalPath) - ProcessUtilities.executioner(command, externalApp) - - command = 'chown %s:%s %s' % (externalApp, externalApp, localDB) - ProcessUtilities.executioner(command) - command = 'cp %s %s/app/config/local.php' % (localDB, finalPath) - ProcessUtilities.executioner(command, externalApp) +# ACLManager.CreateSecureDir() +# localDB = '%s/%s' % ('/usr/local/CyberCP/tmp', str(randint(1000, 9999))) +# +# localDBContent = """ 'localhost', +# 'db_table_prefix' => null, +# 'db_port' => 3306, +# 'db_name' => '%s', +# 'db_user' => '%s', +# 'db_password' => '%s', +# 'db_backup_tables' => true, +# 'db_backup_prefix' => 'bak_', +# 'admin_email' => '%s', +# 'admin_password' => '%s', +# 'mailer_transport' => null, +# 'mailer_host' => null, +# 'mailer_port' => null, +# 'mailer_user' => null, +# 'mailer_password' => null, +# 'mailer_api_key' => null, +# 'mailer_encryption' => null, +# 'mailer_auth_mode' => null, +# );""" % (dbName, dbUser, dbPassword, email, password) +# +# writeToFile = open(localDB, 'w') +# writeToFile.write(localDBContent) +# writeToFile.close() + + #command = 'rm -rf %s/app/config/local.php' % (finalPath) + #ProcessUtilities.executioner(command, externalApp) + + #command = 'chown %s:%s %s' % (externalApp, externalApp, localDB) + #ProcessUtilities.executioner(command) + + #command = 'cp %s %s/app/config/local.php' % (localDB, finalPath) + #ProcessUtilities.executioner(command, externalApp) + + ### replace install command with comspoer soo + #command = f"{phpPath} bin/console mautic:install http://%s -f" % (finalURL) + + command = f"{phpPath} bin/console mautic:install --db_host='localhost' --db_name='{dbName}' --db_user='{dbUser}' --db_password='{dbPassword}' --admin_username='{username}' --admin_email='{email}' --admin_password='{password}' --db_port='3306' http://{finalURL} -f" - command = f"{phpPath} bin/console mautic:install http://%s -f" % (finalURL) result = ProcessUtilities.outputExecutioner(command, externalApp, None, finalPath) if result.find('Install complete') == -1: raise BaseException(result) - os.remove(localDB) + + ExistingDocRoot = ACLManager.FindDocRootOfSite(None, domainName) + + if ExistingDocRoot.find('docroot') > -1: + ExistingDocRoot = ExistingDocRoot.replace('docroot', '') + + + NewDocRoot = f'{ExistingDocRoot}/docroot' + ACLManager.ReplaceDocRoot(None, domainName, NewDocRoot) + + if ProcessUtilities.decideServer() == ProcessUtilities.OLS: + + try: + + ExistingDocRootApache = ACLManager.FindDocRootOfSiteApache(None, domainName) + + if ExistingDocRootApache.find('docroot') == -1: + NewDocRootApache = f'{ExistingDocRootApache}docroot' + else: + NewDocRootApache = ExistingDocRootApache + + if ExistingDocRootApache != None: + ACLManager.ReplaceDocRootApache(None, domainName, NewDocRootApache) + except: + pass + + ### fix incorrect rules in .htaccess of mautic + + if ProcessUtilities.decideServer() == ProcessUtilities.ent: + htAccessPath = f'{finalPath}docroot/.htaccess' + + command = f"sed -i '/# Fallback for Apache < 2.4/,/<\/IfModule>/d' {htAccessPath}" + ProcessUtilities.executioner(command, externalApp, True) + + command = f"sed -i '/# Apache 2.4+/,/<\/IfModule>/d' {htAccessPath}" + ProcessUtilities.executioner(command, externalApp, True) + + + #os.remove(localDB) + command = f"systemctl restart {ApacheVhost.serviceName}" + ProcessUtilities.normalExecutioner(command) + installUtilities.reStartLiteSpeedSocket() statusFile = open(tempStatusPath, 'w') diff --git a/plogical/phpUtilities.py b/plogical/phpUtilities.py index 4a0a130d7..c16d09046 100755 --- a/plogical/phpUtilities.py +++ b/plogical/phpUtilities.py @@ -1,4 +1,7 @@ import sys + +from ApachController.ApacheVhosts import ApacheVhost + sys.path.append('/usr/local/CyberCP') from plogical import CyberCPLogFileWriter as logging import subprocess @@ -217,7 +220,16 @@ def GetStagingInJson(stagings): return msg @staticmethod - def GetPHPVersionFromFile(vhFile): + def GetPHPVersionFromFile(vhFile, domainName=None): + finalConfPath = ApacheVhost.configBasePath + domainName + '.conf' + if os.path.exists(finalConfPath): + command = f'grep -Eo -m 1 "php[0-9]+" {finalConfPath} | sed -n "1p"' + result = ProcessUtilities.outputExecutioner(command, None, True).rstrip('\n') + result = f'/usr/local/lsws/ls{result}/bin/lsphp' + result = result.rsplit("lsphp", 1)[0] + "php" + return result + + if ProcessUtilities.decideServer() == ProcessUtilities.OLS: command = f'grep -Eo "/usr/local/lsws/lsphp[0-9]+/bin/lsphp" {vhFile}' result = ProcessUtilities.outputExecutioner(command, None, True).rstrip('\n') diff --git a/plogical/sslUtilities.py b/plogical/sslUtilities.py index 22c9880a5..d81d2ce1b 100755 --- a/plogical/sslUtilities.py +++ b/plogical/sslUtilities.py @@ -10,6 +10,7 @@ from websiteFunctions.models import ChildDomains, Websites except: pass +from plogical.acl import ACLManager class sslUtilities: @@ -320,7 +321,8 @@ def installSSLForDomain(virtualHostName, adminEmail='example@example.org'): except BaseException as msg: website = Websites.objects.get(domain=virtualHostName) externalApp = website.externalApp - DocumentRoot = ' DocumentRoot /home/' + virtualHostName + '/public_html\n' + docRoot = ACLManager.FindDocRootOfSite(None, virtualHostName) + DocumentRoot = f' DocumentRoot {docRoot}\n' data = open(completePathToConfigFile, 'r').readlines() phpHandler = '' diff --git a/plogical/sslv2.py b/plogical/sslv2.py index ee4a4f5e7..97967adb1 100755 --- a/plogical/sslv2.py +++ b/plogical/sslv2.py @@ -270,7 +270,8 @@ def installSSLForDomain(virtualHostName, adminEmail='example@example.org'): except BaseException as msg: website = Websites.objects.get(domain=virtualHostName) externalApp = website.externalApp - DocumentRoot = ' DocumentRoot /home/' + virtualHostName + '/public_html\n' + docRoot = ACLManager.FindDocRootOfSite(None, virtualHostName) + DocumentRoot = f' DocumentRoot {docRoot}\n' data = open(completePathToConfigFile, 'r').readlines() phpHandler = '' diff --git a/plogical/test.py b/plogical/test.py index e69de29bb..e66d26509 100644 --- a/plogical/test.py +++ b/plogical/test.py @@ -0,0 +1,13 @@ +import subprocess + +# Run the shell command and capture the output +result = subprocess.run(['ls', '-la'], capture_output=True, text=True) + +# Get the lines containing 'lsphp' in the output +lsphp_lines = [line for line in result.stdout.split('\n') if 'lsphp' in line] + +# Extract the version from the lines +php_versions = [line.split()[8] for line in lsphp_lines] + +print(php_versions) + From 36c0d62e786508b028f5757c64933412d3cd596b Mon Sep 17 00:00:00 2001 From: usmannasir Date: Sun, 26 Nov 2023 22:18:16 +0400 Subject: [PATCH 3/5] add reqs --- managePHP/phpManager.py | 2 -- plogical/phpUtilities.py | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/managePHP/phpManager.py b/managePHP/phpManager.py index 9f2a118ad..e54d345b8 100755 --- a/managePHP/phpManager.py +++ b/managePHP/phpManager.py @@ -5,8 +5,6 @@ from random import randint from .models import * from xml.etree import ElementTree -from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging - class PHPManager: diff --git a/plogical/phpUtilities.py b/plogical/phpUtilities.py index c16d09046..1cf5185a4 100755 --- a/plogical/phpUtilities.py +++ b/plogical/phpUtilities.py @@ -1,7 +1,4 @@ import sys - -from ApachController.ApacheVhosts import ApacheVhost - sys.path.append('/usr/local/CyberCP') from plogical import CyberCPLogFileWriter as logging import subprocess @@ -12,6 +9,7 @@ import os from plogical.mailUtilities import mailUtilities from plogical.processUtilities import ProcessUtilities +from ApachController.ApacheVhosts import ApacheVhost import json from django.urls import reverse From c8da443334b8815ec250a0fba606e75355f641cd Mon Sep 17 00:00:00 2001 From: usmannasir Date: Tue, 28 Nov 2023 18:47:17 +0400 Subject: [PATCH 4/5] pssobile bug in wp installer --- plogical/applicationInstaller.py | 9 ++++++++- plogical/phpUtilities.py | 2 ++ plogical/test.py | 13 ------------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/plogical/applicationInstaller.py b/plogical/applicationInstaller.py index 862278330..a4a36ced9 100755 --- a/plogical/applicationInstaller.py +++ b/plogical/applicationInstaller.py @@ -618,11 +618,17 @@ def installWordPress(self): ### lets first find php path + from plogical.phpUtilities import phpUtilities vhFile = f'/usr/local/lsws/conf/vhosts/{domainName}/vhost.conf' - phpPath = phpUtilities.GetPHPVersionFromFile(vhFile) + try: + + phpPath = phpUtilities.GetPHPVersionFromFile(vhFile) + except: + phpPath = '/usr/local/lsws/lsphp80/bin/php' + ### basically for now php 8.0 is being checked @@ -632,6 +638,7 @@ def installWordPress(self): statusFile.close() phpUtilities.InstallSaidPHP('80') + finalPath = '' self.permPath = '' diff --git a/plogical/phpUtilities.py b/plogical/phpUtilities.py index 1cf5185a4..60a23797c 100755 --- a/plogical/phpUtilities.py +++ b/plogical/phpUtilities.py @@ -227,6 +227,8 @@ def GetPHPVersionFromFile(vhFile, domainName=None): result = result.rsplit("lsphp", 1)[0] + "php" return result + if os.path.exists('/usr/local/CyberCP/debug'): + logging.CyberCPLogFileWriter.writeToFile(f'VHFile in GetPHPVersion {vhFile}') if ProcessUtilities.decideServer() == ProcessUtilities.OLS: command = f'grep -Eo "/usr/local/lsws/lsphp[0-9]+/bin/lsphp" {vhFile}' diff --git a/plogical/test.py b/plogical/test.py index e66d26509..e69de29bb 100644 --- a/plogical/test.py +++ b/plogical/test.py @@ -1,13 +0,0 @@ -import subprocess - -# Run the shell command and capture the output -result = subprocess.run(['ls', '-la'], capture_output=True, text=True) - -# Get the lines containing 'lsphp' in the output -lsphp_lines = [line for line in result.stdout.split('\n') if 'lsphp' in line] - -# Extract the version from the lines -php_versions = [line.split()[8] for line in lsphp_lines] - -print(php_versions) - From 971289ba2d7a2157412d03b42a5ad8ecc4a19ee5 Mon Sep 17 00:00:00 2001 From: usmannasir Date: Sun, 10 Dec 2023 10:55:39 +0500 Subject: [PATCH 5/5] docker sites --- plogical/DockerSites.py | 155 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 plogical/DockerSites.py diff --git a/plogical/DockerSites.py b/plogical/DockerSites.py new file mode 100644 index 000000000..23fa97040 --- /dev/null +++ b/plogical/DockerSites.py @@ -0,0 +1,155 @@ +from plogical.processUtilities import ProcessUtilities +from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging + + +class DockerSites: + + def __init__(self, data): + self.data = data + self.JobID = self.data['JobID'] ##JOBID will be file path where status is being written + pass + + def InstallDocker(self): + + command = 'apt install docker-compose -y' + ReturnCode = ProcessUtilities.executioner(command) + + if ReturnCode: + return 1, None + else: + return 0, ReturnCode + + # Takes + # ComposePath, MySQLPath, MySQLRootPass, MySQLDBName, MySQLDBNUser, MySQLPassword, CPUsMySQL, MemoryMySQL, + # port, SitePath, CPUsSite, MemorySite, ComposePath, SiteName + # finalURL, blogTitle, adminUser, adminPassword, adminEmail + + def DeployWPContainer(self): + try: + logging.statusWriter(self.JobID, 'Checking if Docker is installed..,0') + + + command = 'docker --help' + ReturnCode = ProcessUtilities.executioner(command) + if ReturnCode == 0: + status, message = self.InstallDocker() + if status == 0: + logging.statusWriter(self.JobID, 'Failed to installed docker. [404]') + return 0, message + + logging.statusWriter(self.JobID, 'Docker is ready to use..,10') + + WPSite = f""" +version: "3.8" + +services: + db: + image: mysql:5.7 + restart: always + volumes: + - "{self.data['MySQLPath']}:/var/lib/mysql" + environment: + MYSQL_ROOT_PASSWORD: {self.data['MySQLRootPass']} + MYSQL_DATABASE: {self.data['MySQLDBName']} + MYSQL_USER: {self.data['MySQLDBNUser']} + MYSQL_PASSWORD: {self.data['MySQLPassword']} + deploy: + resources: + limits: + cpus: '{self.data['CPUsMySQL']}' # Use 50% of one CPU core + memory: {self.data['MemoryMySQL']}M # Limit memory to 512 megabytes + wordpress: + depends_on: + - db + image: wordpress:latest + restart: always + ports: + - "{self.data['port']}:80" + environment: + WORDPRESS_DB_HOST: db:3306 + WORDPRESS_DB_USER: {self.data['MySQLDBNUser']} + WORDPRESS_DB_PASSWORD: {self.data['MySQLPassword']} + WORDPRESS_DB_NAME: {self.data['MySQLDBName']} + volumes: + - "{self.data['SitePath']}:/var/www/html" + deploy: + resources: + limits: + cpus: '{self.data['CPUsSite']}' # Use 50% of one CPU core + memory: {self.data['MemorySite']}M # Limit memory to 512 megabytes + +volumes: + mysql: {{}} +""" + + ### WriteConfig to compose-file + + WriteToFile = open(self.data['ComposePath'], 'w') + WriteToFile.write(WPSite) + WriteToFile.close() + + #### + + command = f"docker-compose -f {self.data['ComposePath']} -p '{self.data['SiteName']}' up -d" + ReturnCode = ProcessUtilities.executioner(command) + + command = f"docker-compose -f {self.data['ComposePath']} ps -q wordpress" + stdout = ProcessUtilities.outputExecutioner(command) + + self.ContainerID = stdout.rstrip('\n') + + + + command = f'docker-compose -f {self.data["ComposePath"]} exec {self.ContainerID} curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar' + ReturnCode = ProcessUtilities.executioner(command) + + command = f"docker-compose -f {self.data['ComposePath']} exec {self.ContainerID} chmod + wp-cli.phar" + ReturnCode = ProcessUtilities.executioner(command) + + command = f"docker-compose -f {self.data['ComposePath']} exec {self.ContainerID} mv wp-cli.phar /bin/wp" + ReturnCode = ProcessUtilities.executioner(command) + + command = f'docker-compose -f {self.data["ComposePath"]} exec {self.ContainerID} wp core install --url="http://{self.data["finalURL"]}" --title="{self.data["blogTitle"]}" --admin_user="{self.data["adminUser"]}" --admin_password="{self.data["adminPassword"]}" --admin_email="{self.data["adminEmail"]}" --path=. --allow-root' + ReturnCode = ProcessUtilities.executioner(command) + + except BaseException as msg: + print(str(msg)) + pass + + +def Main(): + try: + # Takes + # ComposePath, MySQLPath, MySQLRootPass, MySQLDBName, MySQLDBNUser, MySQLPassword, CPUsMySQL, MemoryMySQL, + # port, SitePath, CPUsSite, MemorySite, SiteName + # finalURL, blogTitle, adminUser, adminPassword, adminEmail + data = { + "JobID": 1122344566667778888, + "ComposePath": "/home/dockercloudpagescloud/docker-compose.yml", + "MySQLPath": '/home/dockercloudpagescloud/public_html/sqldocker', + "MySQLRootPass": 'testdbwp12345', + "MySQLDBName": 'testdbwp', + "MySQLDBNUser": 'testdbwp', + "MySQLPassword": 'testdbwp12345', + "CPUsMySQL": '2', + "MemoryMySQL": '512', + "port": '8000', + "SitePath": '/home/dockercloudpagescloud/public_html/wpdocker', + "CPUsSite": '2', + "MemorySite": '512', + "SiteName": 'wp docker test', + "finalURL": '95.217.125.218:8001', + "blogTitle": 'testdbwp', + "adminUser": 'testdbwp', + "adminPassword": 'testdbwp', + "adminEmail": 'testdbwp', + } + ds = DockerSites(data) + + ds.DeployWPContainer() + except BaseException as msg: + print(str(msg)) + pass + +if __name__ == "__main__": + Main() \ No newline at end of file