diff --git a/ApachController/ApacheVhosts.py b/ApachController/ApacheVhosts.py index 271f0f52a..3ac950ed8 100644 --- a/ApachController/ApacheVhosts.py +++ b/ApachController/ApacheVhosts.py @@ -396,8 +396,9 @@ class ApacheVhost: logging.writeToFile(str(msg)) @staticmethod - def perHostVirtualConfOLS(vhFile, administratorEmail): - # General Configurations tab + def perHostVirtualConfOLS(vhFile, administratorEmail, documentRoot=None): + # General Configurations tab. Child domains use vhRoot=master path in olsChildMainConf, so docRoot + # must be the real document root (not $VH_ROOT/public_html) for content and ACME HTTP-01. try: confFile = open(vhFile, "w+") virtualHostName = vhFile.split('/')[6] @@ -405,6 +406,13 @@ class ApacheVhost: currentConf = vhostConfs.OLSLBConf currentConf = currentConf.replace('{adminEmails}', administratorEmail) currentConf = currentConf.replace('{domain}', virtualHostName) + if documentRoot: + root = documentRoot.rstrip('/') + currentConf = currentConf.replace('{olsDocRoot}', root) + currentConf = currentConf.replace('{olsAcmeChallengeRoot}', root + '/.well-known/acme-challenge') + else: + currentConf = currentConf.replace('{olsDocRoot}', '$VH_ROOT/public_html') + currentConf = currentConf.replace('{olsAcmeChallengeRoot}', '$VH_ROOT/public_html/.well-known/acme-challenge') confFile.write(currentConf) confFile.close() diff --git a/plogical/dnsUtilities.py b/plogical/dnsUtilities.py index de5fe80b6..cae10c88b 100644 --- a/plogical/dnsUtilities.py +++ b/plogical/dnsUtilities.py @@ -889,7 +889,7 @@ class DNS: for zone in sorted(zones, key=lambda v: v['name']): zone = zone['id'] - DNS.createDNSRecordCloudFlare(cf, zone, name, type, value, ttl, priority) + DNS.createDNSRecordCloudFlare(cf, zone, name, type, value, priority, ttl) except CloudFlare.exceptions.CloudFlareAPIError as e: logging.CyberCPLogFileWriter.writeToFile(str(e)) diff --git a/plogical/vhostConfs.py b/plogical/vhostConfs.py index 1c1763597..55f593012 100644 --- a/plogical/vhostConfs.py +++ b/plogical/vhostConfs.py @@ -343,7 +343,7 @@ retryTimeout 0 respBuffer 0 } """ - OLSLBConf = """docRoot $VH_ROOT/public_html + OLSLBConf = """docRoot {olsDocRoot} vhDomain $VH_NAME vhAliases www.$VH_NAME adminEmails {adminEmails} @@ -371,7 +371,7 @@ accesslog $VH_ROOT/logs/$VH_NAME.access_log { } context /.well-known/acme-challenge { - location $VH_ROOT/public_html/.well-known/acme-challenge + location {olsAcmeChallengeRoot} allowBrowse 1 rewrite { diff --git a/plogical/virtualHostUtilities.py b/plogical/virtualHostUtilities.py index 029d827a5..5e2ad5843 100644 --- a/plogical/virtualHostUtilities.py +++ b/plogical/virtualHostUtilities.py @@ -1843,11 +1843,7 @@ local_name %s { raise BaseException(retValues[1]) ## Now restart litespeed after initial configurations are done - - if LimitsCheck: - website = ChildDomains(master=master, domain=virtualHostName, path=path, phpSelection=phpVersion, - ssl=ssl, alais=alias) - website.save() + ## ChildDomains row is saved only after SSL/Apache succeed (avoids orphan DB rows on failure) if ssl == 1: logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, 'Creating SSL..,50') @@ -1883,7 +1879,7 @@ local_name %s { if result[0] == 0: raise BaseException(result[1]) else: - ApacheVhost.perHostVirtualConfOLS(completePathToConfigFile, master.adminEmail) + ApacheVhost.perHostVirtualConfOLS(completePathToConfigFile, master.adminEmail, path) installUtilities.installUtilities.reStartLiteSpeed() php = PHPManager.getPHPString(phpVersion) @@ -1900,10 +1896,20 @@ local_name %s { if dkimCheck == 1: DNS.createDKIMRecords(virtualHostName) + if LimitsCheck: + website = ChildDomains(master=master, domain=virtualHostName, path=path, phpSelection=phpVersion, + ssl=ssl, alais=alias) + website.save() + logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, 'Domain successfully created. [200]') return 1, "None" except BaseException as msg: + try: + if ChildDomains.objects.filter(domain=virtualHostName).exists(): + ChildDomains.objects.filter(domain=virtualHostName).delete() + except BaseException: + pass if ACLManager.FindIfChild() == 0: numberOfWebsites = Websites.objects.count() + ChildDomains.objects.count() vhost.deleteCoreConf(virtualHostName, numberOfWebsites) @@ -1981,11 +1987,11 @@ local_name %s { if child: # Handle None values for child domains admin_email = website.master.adminEmail if website.master.adminEmail else website.master.admin.email - ApacheVhost.perHostVirtualConfOLS(completePathToConfigFile, admin_email) + ApacheVhost.perHostVirtualConfOLS(completePathToConfigFile, admin_email, website.path) else: # Handle None values for main domains admin_email = website.adminEmail if website.adminEmail else website.admin.email - ApacheVhost.perHostVirtualConfOLS(completePathToConfigFile, admin_email) + ApacheVhost.perHostVirtualConfOLS(completePathToConfigFile, admin_email, None) if child: # Handle None values for child domains @@ -2423,9 +2429,14 @@ def main(): except: aliasDomain = 0 - virtualHostUtilities.createDomain(args.masterDomain, args.virtualHostName, args.phpVersion, args.path, - int(args.ssl), dkimCheck, openBasedir, args.websiteOwner, apache, - tempStatusPath, 1, aliasDomain) + ret = virtualHostUtilities.createDomain(args.masterDomain, args.virtualHostName, args.phpVersion, args.path, + int(args.ssl), dkimCheck, openBasedir, args.websiteOwner, apache, + tempStatusPath, 1, aliasDomain) + if ret[0] == 1: + print("1," + str(ret[1])) + sys.exit(0) + print("0," + str(ret[1])) + sys.exit(1) elif args.function == "issueSSL": virtualHostUtilities.issueSSL(args.virtualHostName, args.path, args.administratorEmail) elif args.function == "issueSSLv2": diff --git a/websiteFunctions/website.py b/websiteFunctions/website.py index c976ba90e..419eacb15 100644 --- a/websiteFunctions/website.py +++ b/websiteFunctions/website.py @@ -2487,11 +2487,34 @@ Require valid-user + " --openBasedir " + str(data['openBasedir']) + ' --path ' + path + ' --websiteOwner ' \ + admin.userName + ' --tempStatusPath ' + tempStatusPath + " --apache " + apacheBackend + f' --aliasDomain {str(alias)}' - ProcessUtilities.popenExecutioner(execPath) - time.sleep(2) + create_result = subprocess.run(execPath, shell=True, capture_output=True, text=True, timeout=1800) + st = '' + try: + if os.path.isfile(tempStatusPath): + with open(tempStatusPath, 'r', encoding='utf-8', errors='replace') as sf: + st = sf.read().strip() + except BaseException: + st = '' + out = (create_result.stdout or '').strip() + last_line = out.split('\n')[-1] if out else '' + cli_ok = last_line.startswith('1,') + cli_fail = last_line.startswith('0,') + status_ok = ('Domain successfully created.' in st and '[200]' in st) + status_fail = ('[404]' in st) - data_ret = {'status': 1, 'createWebSiteStatus': 1, 'error_message': "None", - 'tempStatusPath': tempStatusPath} + if create_result.returncode == 0 and (cli_ok or status_ok) and not status_fail: + data_ret = {'status': 1, 'createWebSiteStatus': 1, 'error_message': "None", + 'tempStatusPath': tempStatusPath} + else: + err_msg = 'Child domain creation failed.' + if cli_fail and len(last_line) > 2: + err_msg = last_line.split(',', 1)[1].strip() or err_msg + elif st: + err_msg = st.replace('. [404]', '').strip() or err_msg + elif create_result.stderr and create_result.stderr.strip(): + err_msg = create_result.stderr.strip()[:500] + data_ret = {'status': 0, 'createWebSiteStatus': 0, 'error_message': err_msg[:2000], + 'tempStatusPath': tempStatusPath} json_data = json.dumps(data_ret) return HttpResponse(json_data)