2025-08-01 14:56:30 +05:00
import json
import os
import sys
import paramiko
sys . path . append ( ' /usr/local/CyberCP ' )
import django
os . environ . setdefault ( " DJANGO_SETTINGS_MODULE " , " CyberCP.settings " )
try :
django . setup ( )
from ApachController . ApacheVhosts import ApacheVhost
from plogical . acl import ACLManager
except :
pass
from plogical . randomPassword import generate_pass
import pexpect
from plogical import CyberCPLogFileWriter as logging
import subprocess
import shlex
from shutil import make_archive , rmtree
from plogical import mysqlUtilities
import tarfile
from multiprocessing import Process
import signal
from plogical . installUtilities import installUtilities
import argparse
try :
from plogical . virtualHostUtilities import virtualHostUtilities
from plogical . sslUtilities import sslUtilities
from plogical . mailUtilities import mailUtilities
except :
pass
from xml . etree . ElementTree import Element , SubElement
from xml . etree import ElementTree
from xml . dom import minidom
import time
from shutil import copy
from random import randint
from plogical . processUtilities import ProcessUtilities
try :
from websiteFunctions . models import Websites , ChildDomains , Backups , NormalBackupDests
from databases . models import Databases
from loginSystem . models import Administrator
from plogical . dnsUtilities import DNS
from mailServer . models import Domains as eDomains
from backup . models import DBUsers
except :
pass
VERSION = ' 2.4 '
2025-09-01 13:11:42 +05:00
BUILD = 4
2025-08-01 14:56:30 +05:00
## I am not the monster that you think I am..
class backupUtilities :
Server_root = " /usr/local/lsws "
completeKeyPath = " /home/cyberpanel/.ssh "
destinationsPath = " /home/cyberpanel/destinations "
licenseKey = ' /usr/local/lsws/conf/license.key '
NiceDefault = ' 10 '
CPUDefault = ' 1000 '
CloudBackupConfigPath = ' /home/cyberpanel/CloudBackup.json '
time = 10
def __init__ ( self , extraArgs ) :
self . extraArgs = extraArgs
@staticmethod
def prepareBackupMeta ( backupDomain , backupName , tempStoragePath , backupPath , FromInner = 1 ) :
try :
website = Websites . objects . get ( domain = backupDomain )
connection , cursor = mysqlUtilities . mysqlUtilities . setupConnection ( )
if FromInner :
status = os . path . join ( backupPath , ' status ' )
#logging.CyberCPLogFileWriter.statusWriter(status, 'Setting up meta data..')
command = f " echo ' Setting up meta data.. ' > { status } "
ProcessUtilities . executioner ( command , website . externalApp )
else :
status = ' /home/cyberpanel/dummy '
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile ( f ' Creating meta for { backupDomain } . ' )
######### Generating meta
## XML Generation
metaFileXML = Element ( ' metaFile ' )
child = SubElement ( metaFileXML , ' VERSION ' )
child . text = VERSION
child = SubElement ( metaFileXML , ' BUILD ' )
child . text = str ( BUILD )
### try to take care of - https://github.com/usmannasir/cyberpanel/issues/1196
child = SubElement ( metaFileXML , ' BackupWholeDir ' )
child . text = str ( 1 )
child = SubElement ( metaFileXML , ' masterDomain ' )
child . text = backupDomain
child = SubElement ( metaFileXML , ' phpSelection ' )
child . text = website . phpSelection
child = SubElement ( metaFileXML , ' externalApp ' )
child . text = website . externalApp
### Find user of site
siteUser = website . admin
child = SubElement ( metaFileXML , ' userName ' )
child . text = siteUser . userName
child = SubElement ( metaFileXML , ' userPassword ' )
child . text = siteUser . password
child = SubElement ( metaFileXML , ' firstName ' )
child . text = siteUser . firstName
child = SubElement ( metaFileXML , ' lastName ' )
child . text = siteUser . lastName
child = SubElement ( metaFileXML , ' email ' )
child . text = siteUser . email
child = SubElement ( metaFileXML , ' type ' )
child . text = str ( siteUser . type )
child = SubElement ( metaFileXML , ' owner ' )
child . text = str ( siteUser . owner )
child = SubElement ( metaFileXML , ' token ' )
child . text = siteUser . token
child = SubElement ( metaFileXML , ' api ' )
child . text = str ( siteUser . api )
child = SubElement ( metaFileXML , ' securityLevel ' )
child . text = str ( siteUser . securityLevel )
child = SubElement ( metaFileXML , ' state ' )
child . text = siteUser . state
child = SubElement ( metaFileXML , ' initWebsitesLimit ' )
child . text = str ( siteUser . initWebsitesLimit )
child = SubElement ( metaFileXML , ' aclName ' )
child . text = siteUser . acl . name
#####################
childDomains = website . childdomains_set . all ( )
databases = website . databases_set . all ( )
## Child domains XML
childDomainsXML = Element ( ' ChildDomains ' )
for items in childDomains :
childDomainXML = Element ( ' domain ' )
child = SubElement ( childDomainXML , ' domain ' )
child . text = items . domain
child = SubElement ( childDomainXML , ' phpSelection ' )
child . text = items . phpSelection
child = SubElement ( childDomainXML , ' path ' )
child . text = items . path
childDomainsXML . append ( childDomainXML )
metaFileXML . append ( childDomainsXML )
## Databases XML
databasesXML = Element ( ' Databases ' )
for items in databases :
databaseXML = Element ( ' database ' )
child = SubElement ( databaseXML , ' dbName ' )
child . text = str ( items . dbName )
cursor . execute ( f " select user,host from mysql.db where db= ' { items . dbName } ' " )
databaseUsers = cursor . fetchall ( )
for databaseUser in databaseUsers :
databaseUserXML = Element ( ' databaseUsers ' )
child = SubElement ( databaseUserXML , ' dbUser ' )
child . text = databaseUser [ 0 ]
child = SubElement ( databaseUserXML , ' dbHost ' )
child . text = databaseUser [ 1 ]
## Fetch user password
dbuser = DBUsers . objects . get ( user = databaseUser [ 0 ] , host = databaseUser [ 1 ] )
child = SubElement ( databaseUserXML , ' password ' )
child . text = str ( dbuser . password )
databaseXML . append ( databaseUserXML )
databasesXML . append ( databaseXML )
metaFileXML . append ( databasesXML )
## Get Aliases
try :
aliasesXML = Element ( ' Aliases ' )
aliases = backupUtilities . getAliases ( backupDomain )
for items in aliases :
child = SubElement ( aliasesXML , ' alias ' )
child . text = items
metaFileXML . append ( aliasesXML )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( ' %s . [167:prepMeta] ' % ( str ( msg ) ) )
## Finish Alias
## DNS Records XML
try :
dnsRecordsXML = Element ( " dnsrecords " )
dnsRecords = DNS . getDNSRecords ( backupDomain )
for items in dnsRecords :
dnsRecordXML = Element ( ' dnsrecord ' )
child = SubElement ( dnsRecordXML , ' type ' )
child . text = items . type
child = SubElement ( dnsRecordXML , ' name ' )
child . text = items . name
child = SubElement ( dnsRecordXML , ' content ' )
child . text = items . content
child = SubElement ( dnsRecordXML , ' priority ' )
child . text = str ( items . prio )
dnsRecordsXML . append ( dnsRecordXML )
metaFileXML . append ( dnsRecordsXML )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( ' %s . [158:prepMeta] ' % ( str ( msg ) ) )
## Email accounts XML
try :
emailRecordsXML = Element ( ' emails ' )
eDomain = eDomains . objects . get ( domain = backupDomain )
emailAccounts = eDomain . eusers_set . all ( )
for items in emailAccounts :
emailRecordXML = Element ( ' emailAccount ' )
child = SubElement ( emailRecordXML , ' email ' )
child . text = items . email
child = SubElement ( emailRecordXML , ' password ' )
child . text = items . password
emailRecordsXML . append ( emailRecordXML )
metaFileXML . append ( emailRecordsXML )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( ' %s . [179:prepMeta] ' % ( str ( msg ) ) )
## Email meta generated!
def prettify ( elem ) :
""" Return a pretty-printed XML string for the Element.
"""
rough_string = ElementTree . tostring ( elem , ' utf-8 ' )
reparsed = minidom . parseString ( rough_string )
return reparsed . toprettyxml ( indent = " " )
## /home/example.com/backup/backup-example.com-02.13.2018_10-24-52/meta.xml -- metaPath
metaPath = ' /tmp/ %s ' % ( str ( randint ( 1000 , 9999 ) ) )
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile ( f ' Path to meta file { metaPath } ' )
xmlpretty = prettify ( metaFileXML ) . encode ( ' ascii ' , ' ignore ' )
metaFile = open ( metaPath , ' w ' )
metaFile . write ( xmlpretty . decode ( ) )
metaFile . close ( )
os . chmod ( metaPath , 0o600 )
## meta generated
if FromInner :
newBackup = Backups ( website = website , fileName = backupName , date = time . strftime ( " % m. %d . % Y_ % H- % M- % S " ) ,
size = 0 , status = 1 )
newBackup . save ( )
command = f " echo ' Meta data is ready.. ' > { status } "
ProcessUtilities . executioner ( command , website . externalApp )
return 1 , ' None ' , metaPath
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( f " { str ( msg ) } [207][5009] " )
if FromInner :
#logging.CyberCPLogFileWriter.statusWriter(status, "%s [207][5009]" % (str(msg)), status)
command = f " echo ' { status } [207][5009] ' > { status } "
ProcessUtilities . executioner ( command , website . externalApp )
return 0 , str ( msg ) , ' None '
@staticmethod
def startBackup ( tempStoragePath , backupName , backupPath , metaPath = None ) :
try :
## /home/example.com/backup/backup-example.com-02.13.2018_10-24-52 -- tempStoragePath
## /home/example.com/backup - backupPath
##### Writing the name of backup file.
## /home/example.com/backup/backupFileName
pidFile = f ' { backupPath } startBackup '
writeToFile = open ( pidFile , ' w ' )
writeToFile . writelines ( str ( os . getpid ( ) ) )
writeToFile . close ( )
backupFileNamePath = os . path . join ( backupPath , " backupFileName " )
logging . CyberCPLogFileWriter . statusWriter ( backupFileNamePath , backupName )
#####
status = os . path . join ( backupPath , ' status ' )
logging . CyberCPLogFileWriter . statusWriter ( status , " Making archive of home directory. \n " )
##### Parsing XML Meta file!
## /home/example.com/backup/backup-example.com-02.13.2018_10-24-52 -- tempStoragePath
metaPathInBackup = os . path . join ( tempStoragePath , ' meta.xml ' )
if metaPath != None :
writeToFile = open ( metaPathInBackup , ' w ' )
writeToFile . write ( open ( metaPath , ' r ' ) . read ( ) )
writeToFile . close ( )
backupMetaData = ElementTree . parse ( metaPathInBackup )
##### Making archive of home directory
domainName = backupMetaData . find ( ' masterDomain ' ) . text
## Saving original vhost conf file
#completPathToConf = f'{backupUtilities.Server_root}/conf/vhosts/{domainName}/vhost.conf'
#copy(completPathToConf, tempStoragePath + '/vhost.conf')
## /home/example.com/backup/backup-example.com-02.13.2018_10-24-52 -- tempStoragePath
## shutil.make_archive
## Stop making archive of document_root and copy instead
from shutil import copytree
#copytree('/home/%s/public_html' % domainName, '%s/%s' % (tempStoragePath, 'public_html'))
#command = f'cp -R /home/{domainName}/public_html {tempStoragePath}/public_html'
### doing backup of whole dir and keeping it in public_html folder will restore from here - ref https://github.com/usmannasir/cyberpanel/issues/1196
2025-12-31 22:55:09 +01:00
### Using leading slash for exclude patterns to only exclude top-level directories, not all directories with these names - ref https://github.com/usmannasir/cyberpanel/issues/1615
command = f " rsync -av --ignore-errors --exclude=.wp-cli --exclude=/logs --exclude=/backup --exclude=lscache /home/ { domainName } / { tempStoragePath } /public_html/ "
2025-08-01 14:56:30 +05:00
ProcessUtilities . normalExecutioner ( command )
# if ProcessUtilities.normalExecutioner(command) == 0:
# raise BaseException(f'Failed to run cp command during backup generation.')
# make_archive(os.path.join(tempStoragePath,"public_html"), 'gztar', os.path.join("/home",domainName,"public_html"))
##
logging . CyberCPLogFileWriter . statusWriter ( status , " Backing up databases.. " )
print ( ' 1,None ' )
except BaseException as msg :
# try:
# os.remove(os.path.join(backupPath, backupName + ".tar.gz"))
# except:
# pass
#
# try:
# rmtree(tempStoragePath)
# except:
# pass
status = os . path . join ( backupPath , ' status ' )
logging . CyberCPLogFileWriter . statusWriter ( status , " Aborted, " + str ( msg ) + " .[365] [5009] " )
print ( f " Aborted, { str ( msg ) } .[365] [5009] " )
try :
os . remove ( pidFile )
except :
pass
@staticmethod
def BackupRoot ( tempStoragePath , backupName , backupPath , metaPath = None , externalApp = None , CPHomeStorage = None ) :
## /home/example.com/backup/backup-example.com-02.13.2018_10-24-52 -- tempStoragePath
## /home/example.com/backup - backupPath
## /home/backup/<random_number> - CPHomeStorage
### CPHomeStorage /home/cyberpanel/<random_number>
pidFile = ' %s BackupRoot ' % ( backupPath )
writeToFile = open ( pidFile , ' w ' )
writeToFile . writelines ( str ( os . getpid ( ) ) )
writeToFile . close ( )
status = os . path . join ( backupPath , ' status ' )
metaPathInBackup = os . path . join ( tempStoragePath , ' meta.xml ' )
backupMetaData = ElementTree . parse ( metaPathInBackup )
domainName = backupMetaData . find ( ' masterDomain ' ) . text
##### Saving SSL Certificates if any
sslStoragePath = ' /etc/letsencrypt/live/ ' + domainName
if os . path . exists ( sslStoragePath ) :
try :
copy ( os . path . join ( sslStoragePath , " cert.pem " ) , os . path . join ( CPHomeStorage , domainName + " .cert.pem " ) )
copy ( os . path . join ( sslStoragePath , " fullchain.pem " ) , os . path . join ( CPHomeStorage , domainName + " .fullchain.pem " ) )
copy ( os . path . join ( sslStoragePath , " privkey.pem " ) , os . path . join ( CPHomeStorage , domainName + " .privkey.pem " ) )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( f ' { str ( msg ) } . [283:startBackup] ' )
## Child Domains SSL.
## For master domain copy the conf file to tempStorage path here it was done above, but since it is root operation it should be performed here
completPathToConf = f ' { backupUtilities . Server_root } /conf/vhosts/ { domainName } /vhost.conf '
### If domain is suspended, this path wont exists, so please check for other
if os . path . exists ( completPathToConf ) :
copy ( completPathToConf , f ' { CPHomeStorage } /vhost.conf ' )
else :
completPathToConf = f ' { backupUtilities . Server_root } /conf/vhosts/ { domainName } -suspended/vhost.conf '
if os . path . exists ( completPathToConf ) :
#copy(completPathToConf, tempStoragePath + '/vhost.conf')
copy ( completPathToConf , f ' { CPHomeStorage } /vhost.conf ' )
#### also backup apache conf if available
from ApachController . ApacheVhosts import ApacheVhost
finalConfPathApache = ApacheVhost . configBasePath + domainName + ' .conf '
if os . path . exists ( finalConfPathApache ) :
copy ( finalConfPathApache , f ' { CPHomeStorage } /apache.conf ' )
childDomains = backupMetaData . findall ( ' ChildDomains/domain ' )
try :
for childDomain in childDomains :
actualChildDomain = childDomain . find ( ' domain ' ) . text
childPath = childDomain . find ( ' path ' ) . text
completPathToConf = f ' { backupUtilities . Server_root } /conf/vhosts/ { actualChildDomain } /vhost.conf '
TempConfPath = f ' /home/cyberpanel/ { actualChildDomain } .vhost.conf '
if os . path . exists ( completPathToConf ) :
#copy(completPathToConf, f'{tempStoragePath}/{actualChildDomain}.vhost.conf')
copy ( completPathToConf , f ' { CPHomeStorage } / { actualChildDomain } .vhost.conf ' )
else :
completPathToConf = f ' { backupUtilities . Server_root } /conf/vhosts/ { actualChildDomain } -suspended/vhost.conf '
if os . path . exists ( completPathToConf ) :
#copy(completPathToConf, f'{tempStoragePath}/{actualChildDomain}.vhost.conf')
copy ( completPathToConf , f ' { CPHomeStorage } / { actualChildDomain } .vhost.conf ' )
### also backup apache conf if available
finalConfPathApacheChild = ApacheVhost . configBasePath + actualChildDomain + ' .conf '
if os . path . exists ( finalConfPathApacheChild ) :
copy ( finalConfPathApacheChild , f ' { CPHomeStorage } / { actualChildDomain } .apache.conf ' )
##
### Storing SSL for child domainsa
sslStoragePath = f ' /etc/letsencrypt/live/ { actualChildDomain } '
if os . path . exists ( sslStoragePath ) :
try :
#copy(os.path.join(sslStoragePath, "cert.pem"), os.path.join(tempStoragePath, actualChildDomain + ".cert.pem"))
copy ( os . path . join ( sslStoragePath , " cert.pem " ) , os . path . join ( CPHomeStorage , actualChildDomain + " .cert.pem " ) )
#copy(os.path.join(sslStoragePath, "fullchain.pem"),os.path.join(tempStoragePath, actualChildDomain + ".fullchain.pem"))
copy ( os . path . join ( sslStoragePath , " fullchain.pem " ) , os . path . join ( CPHomeStorage , actualChildDomain + " .fullchain.pem " ) )
#copy(os.path.join(sslStoragePath, "privkey.pem"),os.path.join(tempStoragePath, actualChildDomain + ".privkey.pem"))
copy ( os . path . join ( sslStoragePath , " privkey.pem " ) , os . path . join ( CPHomeStorage , actualChildDomain + " .privkey.pem " ) )
#make_archive(os.path.join(tempStoragePath, "sslData-" + domainName), 'gztar', sslStoragePath)
except :
pass
## no need to do this as on line 380 whole dir will be backuped up
# if childPath.find(f'/home/{domainName}/public_html') == -1:
# # copy_tree(childPath, '%s/%s-docroot' % (tempStoragePath, actualChildDomain))
# command = f'cp -R {childPath} {tempStoragePath}/{actualChildDomain}-docroot'
# ProcessUtilities.executioner(command, externalApp)
except BaseException as msg :
pass
## backup emails
domainName = backupMetaData . find ( ' masterDomain ' ) . text
if os . path . islink ( status ) or os . path . islink ( tempStoragePath or os . path . islink ( backupPath ) ) or os . path . islink (
metaPath ) :
logging . CyberCPLogFileWriter . writeToFile ( ' symlinked. ' )
#logging.CyberCPLogFileWriter.statusWriter(status, 'Symlink attack. [365][5009]')
return 0
## backup email accounts
if externalApp == None :
logging . CyberCPLogFileWriter . statusWriter ( status , " Backing up email accounts.. \n " )
else :
command = f " echo ' Backing up email accounts.. ' > { status } "
ProcessUtilities . executioner ( command , externalApp )
try :
emailPath = f ' /home/vmail/ { domainName } '
if os . path . exists ( emailPath ) :
# copy_tree(emailPath, '%s/vmail' % (tempStoragePath), preserve_symlinks=True)
command = f ' cp -R { emailPath } { CPHomeStorage } /vmail '
ProcessUtilities . executioner ( command )
## shutil.make_archive. Creating final package.
if externalApp == None :
logging . CyberCPLogFileWriter . statusWriter ( status , " Preparing final compressed package.. \n " )
else :
command = f " echo ' Preparing final compressed package.. ' > { status } "
ProcessUtilities . executioner ( command , externalApp , True )
### change own of CPHomeStorage and move data
command = f ' chown -R { externalApp } : { externalApp } { CPHomeStorage } '
ProcessUtilities . executioner ( command )
command = f ' mv { CPHomeStorage } /* { tempStoragePath } / '
ProcessUtilities . executioner ( command , externalApp , True )
#make_archive(os.path.join(backupPath, backupName), 'gztar', tempStoragePath)
#rmtree(tempStoragePath)
command = f ' tar -czf { backupPath } / { backupName } .tar.gz -C { tempStoragePath } . '
ProcessUtilities . executioner ( command , externalApp , True )
### remove leftover storages
command = f ' rm -rf { tempStoragePath } '
ProcessUtilities . executioner ( command , externalApp )
command = f ' rm -rf { CPHomeStorage } '
ProcessUtilities . executioner ( command )
###
backupObs = Backups . objects . filter ( fileName = backupName )
filePath = f ' { backupPath } / { backupName } .tar.gz '
totalSize = ' %s MB ' % ( str ( int ( os . path . getsize ( filePath ) / 1048576 ) ) )
try :
for items in backupObs :
items . status = 1
items . size = totalSize
items . save ( )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( ' %s . [backupRoot:499] ' % str ( msg ) )
for items in backupObs :
items . status = 1
items . size = totalSize
items . save ( )
command = ' chmod 600 %s ' % ( os . path . join ( backupPath , backupName + " .tar.gz " ) )
ProcessUtilities . executioner ( command )
if externalApp == None :
logging . CyberCPLogFileWriter . statusWriter ( status , " Completed \n " )
else :
command = f " echo ' Completed ' > { status } "
ProcessUtilities . executioner ( command , externalApp , True )
os . remove ( pidFile )
except BaseException as msg :
logging . CyberCPLogFileWriter . statusWriter ( status , ' %s . [511:BackupRoot][[5009]] \n ' % str ( msg ) )
if externalApp == None :
logging . CyberCPLogFileWriter . statusWriter ( status , ' %s . [511:BackupRoot][[5009]] \n ' )
else :
command = f " echo ' %s. [511:BackupRoot][[5009]] ' > { status } "
ProcessUtilities . executioner ( command , externalApp )
command = f ' rm -rf { tempStoragePath } '
ProcessUtilities . executioner ( command , externalApp )
command = f ' rm -rf { CPHomeStorage } '
ProcessUtilities . executioner ( command )
@staticmethod
def initiateBackup ( tempStoragePath , backupName , backupPath ) :
try :
p = Process ( target = backupUtilities . startBackup , args = ( tempStoragePath , backupName , backupPath , ) )
p . start ( )
pid = open ( backupPath + ' pid ' , " w " )
pid . write ( str ( p . pid ) )
pid . close ( )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( str ( msg ) + " [initiateBackup] " )
@staticmethod
def createWebsiteFromBackup ( backupFileOrig , dir ) :
try :
backupFile = backupFileOrig . strip ( " .tar.gz " )
originalFile = f " /home/backup/ { backupFileOrig } "
if os . path . exists ( backupFileOrig ) :
path = backupFile
elif not os . path . exists ( originalFile ) :
dir = dir
path = " /home/backup/transfer- " + str ( dir ) + " / " + backupFile
else :
path = f " /home/backup/ { backupFile } "
admin = Administrator . objects . get ( userName = ' admin ' )
## open meta file to read data
## Parsing XML Meta file!
backupMetaData = ElementTree . parse ( os . path . join ( path , ' meta.xml ' ) )
domain = backupMetaData . find ( ' masterDomain ' ) . text
phpSelection = backupMetaData . find ( ' phpSelection ' ) . text
externalApp = backupMetaData . find ( ' externalApp ' ) . text
VERSION = backupMetaData . find ( ' VERSION ' ) . text
BUILD = backupMetaData . find ( ' BUILD ' ) . text
### Fetch user details
try :
userName = backupMetaData . find ( ' userName ' ) . text
try :
siteUser = Administrator . objects . get ( userName = userName )
except :
userPassword = backupMetaData . find ( ' userPassword ' ) . text
firstName = backupMetaData . find ( ' firstName ' ) . text
lastName = backupMetaData . find ( ' lastName ' ) . text
email = backupMetaData . find ( ' email ' ) . text
type = int ( backupMetaData . find ( ' type ' ) . text )
owner = int ( backupMetaData . find ( ' owner ' ) . text )
token = backupMetaData . find ( ' token ' ) . text
api = int ( backupMetaData . find ( ' api ' ) . text )
securityLevel = int ( backupMetaData . find ( ' securityLevel ' ) . text )
state = backupMetaData . find ( ' state ' ) . text
initWebsitesLimit = int ( backupMetaData . find ( ' initWebsitesLimit ' ) . text )
from loginSystem . models import ACL
acl = ACL . objects . get ( name = backupMetaData . find ( ' aclName ' ) . text )
siteUser = Administrator ( userName = userName , password = userPassword , firstName = firstName ,
initWebsitesLimit = initWebsitesLimit , acl = acl ,
lastName = lastName , email = email , type = type , owner = owner , token = token ,
api = api , securityLevel = securityLevel , state = state )
siteUser . save ( )
except :
siteUser = Administrator . objects . get ( userName = ' admin ' )
## Pre-creation checks
if Websites . objects . filter ( domain = domain ) . count ( ) > 0 :
raise BaseException ( ' This website already exists. ' )
if ChildDomains . objects . filter ( domain = domain ) . count ( ) > 0 :
raise BaseException ( " This website already exists as child domain. " )
####### Pre-creation checks ends
## Create Configurations
# result = virtualHostUtilities.createVirtualHost(domain, siteUser.email, phpSelection, externalApp, 0, 1, 0,
# siteUser.userName, 'Default', 0)
result = virtualHostUtilities . createVirtualHost ( domain , siteUser . email , phpSelection , externalApp , 1 , 1 , 0 ,
siteUser . userName , ' Default ' , 0 , None ,
1 )
if result [ 0 ] == 0 :
raise BaseException ( result [ 1 ] )
## Create Configurations ends here
## Create databases
### This code is just to create databases, database users will be created later
databases = backupMetaData . findall ( ' Databases/database ' )
website = Websites . objects . get ( domain = domain )
for database in databases :
dbName = database . find ( ' dbName ' ) . text
if ( ( VERSION == ' 2.1 ' or VERSION == ' 2.3 ' ) and int ( BUILD ) > = 1 ) or ( VERSION == ' 2.4 ' and int ( BUILD ) > = 0 ) :
logging . CyberCPLogFileWriter . writeToFile ( ' Backup version 2.1.1+ detected.. ' )
databaseUsers = database . findall ( ' databaseUsers ' )
for databaseUser in databaseUsers :
dbUser = databaseUser . find ( ' dbUser ' ) . text
res = mysqlUtilities . mysqlUtilities . createDatabase ( dbName , dbUser , ' cyberpanel ' )
if res == 0 :
logging . CyberCPLogFileWriter . writeToFile (
' Failed to restore database %s . But it can be false positive, moving on.. ' % ( dbName ) )
newDB = Databases ( website = website , dbName = dbName , dbUser = dbUser )
newDB . save ( )
break
else :
dbUser = database . find ( ' dbUser ' ) . text
if mysqlUtilities . mysqlUtilities . createDatabase ( dbName , dbUser , " cyberpanel " ) == 0 :
raise BaseException
newDB = Databases ( website = website , dbName = dbName , dbUser = dbUser )
newDB . save ( )
## Create dns zone
dnsrecords = backupMetaData . findall ( ' dnsrecords/dnsrecord ' )
DNS . createDNSZone ( domain , admin )
zone = DNS . getZoneObject ( domain )
for dnsrecord in dnsrecords :
recordType = dnsrecord . find ( ' type ' ) . text
value = dnsrecord . find ( ' name ' ) . text
content = dnsrecord . find ( ' content ' ) . text
prio = int ( dnsrecord . find ( ' priority ' ) . text )
DNS . createDNSRecord ( zone , value , recordType , content , prio , 3600 )
return 1 , ' None '
except BaseException as msg :
return 0 , str ( msg )
@staticmethod
def startRestore ( backupName , dir ) :
try :
if dir == " CyberPanelRestore " :
backupFileName = backupName . strip ( " .tar.gz " )
completPath = os . path . join ( " /home " , " backup " , backupFileName ) ## without extension
originalFile = os . path . join ( " /home " , " backup " , backupName ) ## with extension
elif dir == ' CLI ' :
completPath = backupName . strip ( " .tar.gz " ) ## without extension
originalFile = backupName ## with extension
else :
backupFileName = backupName . strip ( " .tar.gz " )
completPath = " /home/backup/transfer- " + str ( dir ) + " / " + backupFileName ## without extension
originalFile = " /home/backup/transfer- " + str ( dir ) + " / " + backupName ## with extension
pathToCompressedHome = os . path . join ( completPath , " public_html.tar.gz " )
if not os . path . exists ( completPath ) :
os . mkdir ( completPath )
## Writing pid of restore process
pid = os . path . join ( completPath , ' pid ' )
logging . CyberCPLogFileWriter . statusWriter ( pid , str ( os . getpid ( ) ) )
status = os . path . join ( completPath , ' status ' )
logging . CyberCPLogFileWriter . statusWriter ( status , " Extracting Main Archive! " )
## Converting /home/backup/backup-example.com-02.13.2018_10-24-52.tar.gz -> /home/backup/backup-example.com-02.13.2018_10-24-52
tar = tarfile . open ( originalFile )
tar . extractall ( completPath )
tar . close ( )
logging . CyberCPLogFileWriter . statusWriter ( status , " Creating Accounts,Databases and DNS records! " )
########### Creating website and its dabases
## extracting master domain for later use
backupMetaData = ElementTree . parse ( os . path . join ( completPath , " meta.xml " ) )
masterDomain = backupMetaData . find ( ' masterDomain ' ) . text
VERSION = backupMetaData . find ( ' VERSION ' ) . text
BUILD = backupMetaData . find ( ' BUILD ' ) . text
twoPointO = 0
try :
version = backupMetaData . find ( ' VERSION ' ) . text
build = backupMetaData . find ( ' BUILD ' ) . text
phpSelectionGlobalMainSite = backupMetaData . find ( ' phpSelection ' ) . text
twoPointO = 1
except :
twoPointO = 0
try :
BackupWholeDir = int ( backupMetaData . find ( ' BackupWholeDir ' ) . text )
except :
BackupWholeDir = 0
result = backupUtilities . createWebsiteFromBackup ( backupName , dir )
if result [ 0 ] == 1 :
## Let us try to restore SSL.
sslStoragePath = completPath + " / " + masterDomain + " .cert.pem "
if os . path . exists ( sslStoragePath ) :
sslHome = ' /etc/letsencrypt/live/ ' + masterDomain
try :
if not os . path . exists ( sslHome ) :
os . mkdir ( sslHome )
copy ( completPath + " / " + masterDomain + " .cert.pem " , sslHome + " /cert.pem " )
copy ( completPath + " / " + masterDomain + " .privkey.pem " , sslHome + " /privkey.pem " )
copy ( completPath + " / " + masterDomain + " .fullchain.pem " , sslHome + " /fullchain.pem " )
sslUtilities . installSSLForDomain ( masterDomain )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( ' %s . [555:startRestore] ' % ( str ( msg ) ) )
else :
logging . CyberCPLogFileWriter . statusWriter ( status , " Error Message: " + result [
1 ] + " . Not able to create Account, Databases and DNS Records, aborting. [575][5009] " )
return 0
#### Find out web server from backup conf
CurrentServer = ProcessUtilities . OLS
if os . path . exists ( completPath + ' /vhost.conf ' ) :
if open ( f ' { completPath } /vhost.conf ' , ' r ' ) . read ( ) . find ( ' ServerName ' ) > - 1 :
CurrentServer = ProcessUtilities . ent
########### Creating child/sub/addon/parked domains
logging . CyberCPLogFileWriter . statusWriter ( status , " Creating Child Domains! " )
## Reading meta file to create subdomains
externalApp = backupMetaData . find ( ' externalApp ' ) . text
websiteHome = os . path . join ( " /home " , masterDomain , " public_html " )
### Restoring Child Domains if any.
childDomains = backupMetaData . findall ( ' ChildDomains/domain ' )
try :
for childDomain in childDomains :
domain = childDomain . find ( ' domain ' ) . text
## mail domain check
mailDomain = ' mail. %s ' % ( masterDomain )
if domain == mailDomain :
continue
## Mail domain check
phpSelection = childDomain . find ( ' phpSelection ' ) . text
path = childDomain . find ( ' path ' ) . text
retValues = virtualHostUtilities . createDomain ( masterDomain , domain , phpSelection , path , 0 , 0 , 0 ,
' admin ' , 0 )
if retValues [ 0 ] == 1 :
if os . path . exists ( websiteHome ) :
rmtree ( websiteHome )
## Let us try to restore SSL for Child Domains.
from ApachController . ApacheController import ApacheController
try :
if os . path . exists ( completPath + ' / ' + domain + ' .vhost.conf ' ) :
if CurrentServer == ProcessUtilities . decideServer ( ) :
completPathToConf = backupUtilities . Server_root + ' /conf/vhosts/ ' + domain + ' /vhost.conf '
childConfPathinBKUP = completPath + ' / ' + domain + ' .vhost.conf '
copy ( childConfPathinBKUP , completPathToConf )
### take care of apache conf
url = " https://platform.cyberpersons.com/CyberpanelAdOns/Adonpermission "
data = {
" name " : " all " ,
" IP " : ACLManager . GetServerIP ( )
}
import requests
response = requests . post ( url , data = json . dumps ( data ) )
Status = response . json ( ) [ ' status ' ]
if ( Status == 1 ) :
childConfPathinBKUPApache = completPath + ' / ' + domain + ' .apache.conf '
tempStatusPath = ' /home/cyberpanel/fakePath '
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile ( f ' Conf path of apache for child domain { domain } in backup is { childConfPathinBKUPApache } ' )
childData = open ( childConfPathinBKUP , ' r ' ) . read ( )
if childData . find ( ' proxyApacheBackendSSL ' ) > - 1 and os . path . exists ( childConfPathinBKUPApache ) :
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile (
f ' It seems child domain { domain } is using apache conf and { childConfPathinBKUPApache } also exists in backup file ' )
virtualHostUtilities . switchServer ( domain , phpSelection , virtualHostUtilities . apache , tempStatusPath )
finalConfPathApache = ApacheVhost . configBasePath + domain + ' .conf '
if os . path . exists ( finalConfPathApache ) :
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile (
f ' CyberPanel was able to successfully convert { domain } to apache conf as { finalConfPathApache } exists.. ' )
copy ( childConfPathinBKUPApache , finalConfPathApache )
### apache ends
sslStoragePath = completPath + " / " + domain + " .cert.pem "
if os . path . exists ( sslStoragePath ) :
sslHome = ' /etc/letsencrypt/live/ ' + domain
try :
if not os . path . exists ( sslHome ) :
os . mkdir ( sslHome )
copy ( completPath + " / " + domain + " .cert.pem " , sslHome + " /cert.pem " )
copy ( completPath + " / " + domain + " .privkey.pem " , sslHome + " /privkey.pem " )
copy ( completPath + " / " + domain + " .fullchain.pem " ,
sslHome + " /fullchain.pem " )
sslUtilities . installSSLForDomain ( domain )
except :
pass
except :
logging . CyberCPLogFileWriter . writeToFile (
' While restoring backup we had minor issues for rebuilding vhost conf for: ' + domain + ' . However this will be auto healed. ' )
if float ( version ) > 2.0 or float ( build ) > 0 :
if path . find ( ' /home/ %s /public_html ' % masterDomain ) == - 1 :
if BackupWholeDir == 0 :
#copy_tree('%s/%s-docroot' % (completPath, domain), path)
## First remove if already exists
command = ' rm -rf %s ' % ( path )
ProcessUtilities . executioner ( command )
##
command = ' cp -R %s / %s -docroot %s ' % ( completPath , domain , path )
ProcessUtilities . executioner ( command )
continue
else :
logging . CyberCPLogFileWriter . writeToFile ( ' Error domain %s ' % ( domain ) )
logging . CyberCPLogFileWriter . statusWriter ( status , " Error Message: " + retValues [
1 ] + " . Not able to create child domains, aborting. [635][5009] " )
return 0
except BaseException as msg :
status = open ( os . path . join ( completPath , ' status ' ) , " w " )
status . write ( " Error Message: " + str ( msg ) + " . Not able to create child domains, aborting. [638][5009] " )
status . close ( )
logging . CyberCPLogFileWriter . writeToFile ( str ( msg ) + " [startRestore] " )
return 0
## Restore Aliases
logging . CyberCPLogFileWriter . statusWriter ( status , " Restoring Domain Aliases! " )
aliases = backupMetaData . findall ( ' Aliases/alias ' )
for items in aliases :
virtualHostUtilities . createAlias ( masterDomain , items . text , 0 , " " , " " , " admin " )
## Restoring email accounts
logging . CyberCPLogFileWriter . statusWriter ( status , " Restoring email accounts! " )
emailAccounts = backupMetaData . findall ( ' emails/emailAccount ' )
try :
for emailAccount in emailAccounts :
email = emailAccount . find ( ' email ' ) . text
username = email . split ( " @ " ) [ 0 ]
password = emailAccount . find ( ' password ' ) . text
result = mailUtilities . createEmailAccount ( masterDomain , username , password , ' restore ' )
if result [ 0 ] == 0 :
raise BaseException ( result [ 1 ] )
except BaseException as msg :
logging . CyberCPLogFileWriter . statusWriter ( status , " Error Message: " + str (
msg ) + " . Not able to create email accounts, aborting. [671][5009] " )
logging . CyberCPLogFileWriter . writeToFile ( str ( msg ) + " [startRestore] " )
return 0
## Emails restored
## restoring databases
### This will actually restore mysql dump and create mysql users
logging . CyberCPLogFileWriter . statusWriter ( status , " Restoring Databases! " )
databases = backupMetaData . findall ( ' Databases/database ' )
for database in databases :
dbName = database . find ( ' dbName ' ) . text
if ( ( VERSION == ' 2.1 ' or VERSION == ' 2.3 ' ) and int ( BUILD ) > = 1 ) or ( VERSION == ' 2.4 ' and int ( BUILD ) > = 0 ) :
logging . CyberCPLogFileWriter . writeToFile ( ' Backup version 2.1.1+ detected.. ' )
first = 1
databaseUsers = database . findall ( ' databaseUsers ' )
for databaseUser in databaseUsers :
dbUser = databaseUser . find ( ' dbUser ' ) . text
dbHost = databaseUser . find ( ' dbHost ' ) . text
password = databaseUser . find ( ' password ' ) . text
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile ( ' Database user: %s ' % ( dbUser ) )
logging . CyberCPLogFileWriter . writeToFile ( ' Database host: %s ' % ( dbHost ) )
logging . CyberCPLogFileWriter . writeToFile ( ' Database password: %s ' % ( password ) )
## Future ref, this logic can be further refactored to improve restore backup logic
if first :
first = 0
res = mysqlUtilities . mysqlUtilities . restoreDatabaseBackup ( dbName , completPath , password , 1 )
if res == 0 :
logging . CyberCPLogFileWriter . writeToFile (
' Failed to restore database %s . But it can be false positive, moving on.. ' % (
dbName ) )
### This function will not create database, only database user is created as third value is 0 for createDB
mysqlUtilities . mysqlUtilities . createDatabase ( dbName , dbUser , password , 0 , dbHost )
mysqlUtilities . mysqlUtilities . changePassword ( dbUser , password , 1 , dbHost )
# UserInMySQLTable = DBUsers.objects.get(user=dbUser, host=dbHost)
# UserInMySQLTable.password = password
# UserInMySQLTable.save()
else :
password = database . find ( ' password ' ) . text
if mysqlUtilities . mysqlUtilities . restoreDatabaseBackup ( dbName , completPath , password ) == 0 :
raise BaseException
## Databases restored
logging . CyberCPLogFileWriter . statusWriter ( status , " Extracting web home data! " )
# /home/backup/backup-example.com-02.13.2018_10-24-52/public_html.tar.gz
## Moving above v2.0.0 extracting webhome data is not required, thus commenting below lines
if not twoPointO :
tar = tarfile . open ( pathToCompressedHome )
tar . extractall ( websiteHome )
tar . close ( )
else :
if float ( version ) > 2.0 or float ( build ) > 0 :
#copy_tree('%s/public_html' % (completPath), websiteHome)
## First remove if already exists
command = ' rm -rf %s ' % ( websiteHome )
ProcessUtilities . executioner ( command )
##
if BackupWholeDir :
#command = 'cp -R %s/public_html/* %s/*' % (completPath, websiteHome)
command = f ' rsync -av { completPath } /public_html/ /home/ { masterDomain } '
else :
command = ' cp -R %s /public_html %s ' % ( completPath , websiteHome )
ProcessUtilities . executioner ( command )
## extracting email accounts
logging . CyberCPLogFileWriter . statusWriter ( status , " Extracting email accounts! " )
if not twoPointO :
try :
pathToCompressedEmails = os . path . join ( completPath , masterDomain + " .tar.gz " )
emailHome = os . path . join ( " /home " , " vmail " , masterDomain )
tar = tarfile . open ( pathToCompressedEmails )
tar . extractall ( emailHome )
tar . close ( )
## Change permissions
command = " chown -R vmail:vmail " + emailHome
subprocess . call ( shlex . split ( command ) )
except :
pass
else :
emailsPath = ' %s /vmail ' % ( completPath )
if os . path . exists ( emailsPath ) :
#copy_tree(emailsPath, '/home/vmail/%s' % (masterDomain))
## First remove if already exists
command = ' rm -rf /home/vmail/ %s ' % ( masterDomain )
ProcessUtilities . executioner ( command )
##
command = ' cp -R %s /home/vmail/ %s ' % ( emailsPath , masterDomain )
ProcessUtilities . executioner ( command )
command = " chown -R vmail:vmail /home/vmail/ %s " % ( masterDomain )
ProcessUtilities . executioner ( command )
## emails extracted
completPathToConf = backupUtilities . Server_root + ' /conf/vhosts/ ' + masterDomain + ' /vhost.conf '
if os . path . exists ( completPath + ' /vhost.conf ' ) :
if CurrentServer == ProcessUtilities . decideServer ( ) :
confPathMainSite = completPath + ' /vhost.conf '
copy ( confPathMainSite , completPathToConf )
### apache starts here
url = " https://platform.cyberpersons.com/CyberpanelAdOns/Adonpermission "
data = {
" name " : " all " ,
" IP " : ACLManager . GetServerIP ( )
}
import requests
response = requests . post ( url , data = json . dumps ( data ) )
Status = response . json ( ) [ ' status ' ]
if ( Status == 1 ) :
confPathApache = completPath + ' /apache.conf '
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile ( f ' Conf path of apache for main site { masterDomain } in backup is { confPathApache } ' )
tempStatusPath = ' /home/cyberpanel/fakePath '
childData = open ( confPathMainSite , ' r ' ) . read ( )
if childData . find ( ' proxyApacheBackendSSL ' ) > - 1 and os . path . exists ( confPathApache ) :
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile (
f ' It seems main site { masterDomain } is using apache conf. ' )
virtualHostUtilities . switchServer ( masterDomain , phpSelectionGlobalMainSite , virtualHostUtilities . apache ,
tempStatusPath )
finalConfPathApache = ApacheVhost . configBasePath + masterDomain + ' .conf '
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile (
f ' Apache conf path of main domain exists which means CyberPanel successfully converted site to Apache for { masterDomain } ' )
if os . path . exists ( confPathApache ) :
copy ( confPathApache , finalConfPathApache )
### apache ends here
logging . CyberCPLogFileWriter . statusWriter ( status , " Done " )
## Fix permissions
from filemanager . filemanager import FileManager
fm = FileManager ( None , None )
fm . fixPermissions ( masterDomain )
installUtilities . reStartLiteSpeed ( )
except BaseException as msg :
status = os . path . join ( completPath , ' status ' )
logging . CyberCPLogFileWriter . statusWriter ( status , str ( msg ) + " [736][5009] " )
logging . CyberCPLogFileWriter . writeToFile ( str ( msg ) + " [startRestore] " )
@staticmethod
def initiateRestore ( backupName , dir ) :
try :
p = Process ( target = backupUtilities . startRestore , args = ( backupName , dir , ) )
p . start ( )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( str ( msg ) + " [initiateRestore] " )
# @staticmethod
# def sendKey(IPAddress, password, port='22', user='root'):
# try:
#
# expectation = []
# expectation.append("password:")
# expectation.append("Password:")
# expectation.append("Permission denied")
# expectation.append("100%")
#
# ## Temp changes
#
# command = 'chmod 600 %s' % ('/root/.ssh/cyberpanel.pub')
# ProcessUtilities.executioner(command)
#
# command = "scp -o StrictHostKeyChecking=no -P " + port + " /root/.ssh/cyberpanel.pub " + user + "@" + IPAddress + ":~/.ssh/authorized_keys"
# setupKeys = pexpect.spawn(command, timeout=3)
#
# if os.path.exists(ProcessUtilities.debugPath):
# logging.CyberCPLogFileWriter.writeToFile(command)
#
# index = setupKeys.expect(expectation)
#
# ## on first login attempt send password
#
# if index == 0:
# setupKeys.sendline(password)
# setupKeys.expect("100%")
# setupKeys.wait()
# elif index == 1:
# setupKeys.sendline(password)
# setupKeys.expect("100%")
# setupKeys.wait()
# elif index == 2:
# return [0, 'Please enable password authentication on your remote server.']
# elif index == 3:
# pass
# else:
# raise BaseException
#
# ## Temp changes
#
# command = 'chmod 644 %s' % ('/root/.ssh/cyberpanel.pub')
# ProcessUtilities.executioner(command)
#
# return [1, "None"]
#
# except pexpect.TIMEOUT as msg:
#
# command = 'chmod 644 %s' % ('/root/.ssh/cyberpanel.pub')
# ProcessUtilities.executioner(command)
#
# logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [sendKey]")
# return [0, "TIMEOUT [sendKey]"]
# except pexpect.EOF as msg:
#
# command = 'chmod 644 %s' % ('/root/.ssh/cyberpanel.pub')
# ProcessUtilities.executioner(command)
#
# logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [sendKey]")
# return [0, "EOF [sendKey]"]
# except BaseException as msg:
#
# command = 'chmod 644 %s' % ('/root/.ssh/cyberpanel.pub')
# ProcessUtilities.executioner(command)
#
# logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [sendKey]")
# return [0, str(msg) + " [sendKey]"]
# @staticmethod
# def setupSSHKeys(IPAddress, password, port='22', user='root'):
# try:
# ## Checking for host verification
#
# backupUtilities.host_key_verification(IPAddress)
#
# if backupUtilities.checkIfHostIsUp(IPAddress) == 1:
# pass
# else:
# logging.CyberCPLogFileWriter.writeToFile("Host is Down.")
# # return [0,"Host is Down."]
#
# expectation = []
# expectation.append("password:")
# expectation.append("Password:")
# expectation.append("Permission denied")
# expectation.append("File exists")
#
# command = "ssh -o StrictHostKeyChecking=no -p " + port + ' ' + user + "@" + IPAddress + ' "mkdir ~/.ssh || rm -f ~/.ssh/temp && rm -f ~/.ssh/authorized_temp && cp ~/.ssh/authorized_keys ~/.ssh/temp || chmod 700 ~/.ssh || chmod g-w ~"'
# setupKeys = pexpect.spawn(command, timeout=3)
#
# if os.path.exists(ProcessUtilities.debugPath):
# logging.CyberCPLogFileWriter.writeToFile(command)
#
# index = setupKeys.expect(expectation)
#
# ## on first login attempt send password
#
# if index == 0:
# setupKeys.sendline(password)
# elif index == 1:
# setupKeys.sendline(password)
# elif index == 2:
# return [0, 'Please enable password authentication on your remote server.']
# elif index == 3:
# pass
# else:
# raise BaseException
#
# ## if it again give you password, than provided password is wrong
#
# expectation = []
# expectation.append("please try again.")
# expectation.append("Password:")
# expectation.append(pexpect.EOF)
#
# index = setupKeys.expect(expectation)
#
# if index == 0:
# return [0, "Wrong Password!"]
# elif index == 1:
# return [0, "Wrong Password!"]
# elif index == 2:
# setupKeys.wait()
#
# sendKey = backupUtilities.sendKey(IPAddress, password, port, user)
#
# if sendKey[0] == 1:
# return [1, "None"]
# else:
# return [0, sendKey[1]]
#
#
# except pexpect.TIMEOUT as msg:
# return [0, str(msg) + " [TIMEOUT setupSSHKeys]"]
# except BaseException as msg:
# return [0, str(msg) + " [setupSSHKeys]"]
@staticmethod
def sendKey ( IPAddress , password , port = ' 22 ' , user = ' root ' ) :
try :
ssh = paramiko . SSHClient ( )
ssh . set_missing_host_key_policy ( paramiko . AutoAddPolicy ( ) )
ssh . connect ( IPAddress , port = int ( port ) , username = user , password = password )
if os . path . exists ( ' /root/.ssh/cyberpanel.pub ' ) :
pass
else :
2026-02-04 21:33:26 +01:00
# Remove existing key files so ssh-keygen never prompts "Overwrite (y/n)?"
for f in ( ' /root/.ssh/cyberpanel ' , ' /root/.ssh/cyberpanel.pub ' ) :
if os . path . exists ( f ) :
try :
os . remove ( f )
except OSError :
pass
2025-08-01 14:56:30 +05:00
command = " ssh-keygen -f /root/.ssh/cyberpanel -t rsa -N ' ' "
ProcessUtilities . executioner ( command , ' root ' , True )
command = ' chmod 600 %s ' % ( ' /root/.ssh/cyberpanel.pub ' )
ProcessUtilities . executioner ( command )
try :
# Try to use SFTP to create .ssh directory if it doesn't exist
sftp = ssh . open_sftp ( )
try :
sftp . stat ( ' .ssh ' )
except FileNotFoundError :
# Try to create .ssh directory via SFTP
try :
sftp . mkdir ( ' .ssh ' )
except :
# Directory creation via SFTP might fail on some servers
pass
# Try to upload the key
sftp . put ( ' /root/.ssh/cyberpanel.pub ' , ' .ssh/authorized_keys ' )
sftp . close ( )
# Try to set permissions via SSH command (might fail on SFTP-only servers)
try :
stdin , stdout , stderr = ssh . exec_command ( ' chmod 600 .ssh/authorized_keys ' , timeout = 5 )
stdout . channel . recv_exit_status ( )
except :
# If chmod fails, it's likely an SFTP-only server
# The key is uploaded, which is what matters for backups using password auth
logging . CyberCPLogFileWriter . writeToFile (
f ' Could not set permissions on { IPAddress } , likely SFTP-only server ' )
pass
except Exception as e :
# If we can't upload the key, it might be an SFTP-only server
# Return success anyway since password authentication works
logging . CyberCPLogFileWriter . writeToFile (
f ' Could not upload SSH key to { IPAddress } : { str ( e ) } , using password authentication ' )
ssh . close ( )
command = ' chmod 644 %s ' % ( ' /root/.ssh/cyberpanel.pub ' )
ProcessUtilities . executioner ( command )
return [ 1 , " None " ]
ssh . close ( )
command = ' chmod 644 %s ' % ( ' /root/.ssh/cyberpanel.pub ' )
ProcessUtilities . executioner ( command )
return [ 1 , " None " ]
except paramiko . AuthenticationException :
return [ 0 , ' Authentication failed. [sendKey] ' ]
except paramiko . SSHException as e :
return [ 0 , f ' SSH error: { str ( e ) } [sendKey] ' ]
except Exception as e :
return [ 0 , f ' General Error: { str ( e ) } [sendKey] ' ]
@staticmethod
def setupSSHKeys ( IPAddress , password , port = ' 22 ' , user = ' root ' ) :
try :
ssh = paramiko . SSHClient ( )
ssh . set_missing_host_key_policy ( paramiko . AutoAddPolicy ( ) )
if password != ' NOT-NEEDED ' :
ssh . connect ( IPAddress , port = int ( port ) , username = user , password = password )
# Try to execute SSH commands first
ssh_commands_supported = True
commands = [
" mkdir -p .ssh " ,
" rm -f .ssh/temp " ,
" rm -f .ssh/authorized_temp " ,
" cp .ssh/authorized_keys .ssh/temp " ,
" chmod 700 .ssh " ,
" chmod g-w ~ " ,
]
for command in commands :
try :
stdin , stdout , stderr = ssh . exec_command ( command , timeout = 5 )
exit_status = stdout . channel . recv_exit_status ( )
error_output = stderr . read ( ) . decode ( )
# Check if the command was rejected (SFTP-only server)
if exit_status != 0 or " not allowed " in error_output . lower ( ) or " channel closed " in error_output . lower ( ) :
ssh_commands_supported = False
logging . CyberCPLogFileWriter . writeToFile (
f ' SSH commands not supported on { IPAddress } , falling back to pure SFTP mode ' )
break
except BaseException as msg :
ssh_commands_supported = False
logging . CyberCPLogFileWriter . writeToFile (
f ' Error executing remote command { command } . Error { str ( msg ) } , falling back to pure SFTP mode ' )
break
ssh . close ( )
# If SSH commands are not supported, use pure SFTP mode
if not ssh_commands_supported :
# For SFTP-only servers, we'll use password authentication directly
# No need to setup SSH keys, just verify connection works
try :
test_ssh = paramiko . SSHClient ( )
test_ssh . set_missing_host_key_policy ( paramiko . AutoAddPolicy ( ) )
test_ssh . connect ( IPAddress , port = int ( port ) , username = user , password = password )
# Open SFTP connection to verify it works
sftp = test_ssh . open_sftp ( )
sftp . close ( )
test_ssh . close ( )
logging . CyberCPLogFileWriter . writeToFile (
f ' Pure SFTP mode verified for { IPAddress } ' )
return [ 1 , " None " ]
except Exception as e :
return [ 0 , f ' SFTP connection failed: { str ( e ) } ' ]
else :
# SSH commands are supported, proceed with key setup
sendKey = backupUtilities . sendKey ( IPAddress , password , port , user )
if sendKey [ 0 ] == 1 :
command = ' chmod 644 %s ' % ( ' /root/.ssh/cyberpanel.pub ' )
ProcessUtilities . executioner ( command )
return [ 1 , " None " ]
else :
command = ' chmod 644 %s ' % ( ' /root/.ssh/cyberpanel.pub ' )
ProcessUtilities . executioner ( command )
return [ 0 , sendKey [ 1 ] ]
else :
# Load the private key
private_key_path = ' /root/.ssh/cyberpanel '
keyPrivate = paramiko . RSAKey ( filename = private_key_path )
# Connect to the remote server using the private key
ssh = paramiko . SSHClient ( )
ssh . set_missing_host_key_policy ( paramiko . AutoAddPolicy ( ) )
ssh . connect ( IPAddress , username = user , pkey = keyPrivate )
return [ 1 , " None " ]
except paramiko . AuthenticationException :
return [ 0 , ' Authentication failed. [setupSSHKeys] ' ]
except paramiko . SSHException as e :
return [ 0 , f ' SSH error: { str ( e ) } [setupSSHKeys] ' ]
except Exception as e :
return [ 0 , f ' General Error: { str ( e ) } [setupSSHKeys] ' ]
@staticmethod
def checkIfHostIsUp ( IPAddress ) :
try :
if subprocess . check_output ( [ ' ping ' , IPAddress , ' -c 1 ' ] ) . decode ( " utf-8 " ) . find ( " 0 % packet loss " ) > - 1 :
return 1
else :
return 0
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( str ( msg ) + " [checkIfHostIsUp] " )
@staticmethod
def checkConnection ( IPAddress , port = ' 22 ' , user = ' root ' ) :
try :
try :
import json
destinations = backupUtilities . destinationsPath
data = json . loads ( open ( destinations , ' r ' ) . read ( ) )
port = data [ ' port ' ]
user = data [ ' user ' ]
except :
port = " 22 "
expectation = [ ]
expectation . append ( " password: " )
expectation . append ( " Password: " )
expectation . append ( " Last login " )
expectation . append ( pexpect . EOF )
expectation . append ( pexpect . TIMEOUT )
command = " sudo ssh -i /root/.ssh/cyberpanel -o StrictHostKeyChecking=no -p " + port + ' ' + user + " @ " + IPAddress
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile ( command )
checkConn = pexpect . spawn ( command , timeout = 3 )
index = checkConn . expect ( expectation )
if index == 0 :
subprocess . call ( [ ' kill ' , str ( checkConn . pid ) ] )
logging . CyberCPLogFileWriter . writeToFile (
" Remote Server is not able to authenticate for transfer to initiate, IP Address: " + IPAddress )
return [ 0 , " Remote Server is not able to authenticate for transfer to initiate. " ]
elif index == 1 :
subprocess . call ( [ ' kill ' , str ( checkConn . pid ) ] )
logging . CyberCPLogFileWriter . writeToFile (
" Remote Server is not able to authenticate for transfer to initiate, IP Address: " + IPAddress )
return [ 0 , " Remote Server is not able to authenticate for transfer to initiate. " ]
elif index == 2 :
subprocess . call ( [ ' kill ' , str ( checkConn . pid ) ] )
return [ 1 , " None " ]
elif index == 4 :
subprocess . call ( [ ' kill ' , str ( checkConn . pid ) ] )
return [ 1 , " None " ]
else :
subprocess . call ( [ ' kill ' , str ( checkConn . pid ) ] )
return [ 1 , " None " ]
except pexpect . TIMEOUT as msg :
logging . CyberCPLogFileWriter . writeToFile ( " Timeout " + IPAddress + " [checkConnection] " )
return [ 0 , " 371 Timeout while making connection to this server [checkConnection] " ]
except pexpect . EOF as msg :
logging . CyberCPLogFileWriter . writeToFile ( " EOF " + IPAddress + " [checkConnection] " )
return [ 0 , " 374 Remote Server is not able to authenticate for transfer to initiate. [checkConnection] " ]
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( str ( msg ) + " " + IPAddress + " [checkConnection] " )
return [ 0 , " 377 Remote Server is not able to authenticate for transfer to initiate. [checkConnection] " ]
@staticmethod
def verifyHostKey ( IPAddress , port = ' 22 ' , user = ' root ' ) :
try :
backupUtilities . host_key_verification ( IPAddress )
password = " hello " ## dumb password, not used anywhere.
expectation = [ ]
expectation . append ( " continue connecting (yes/no)? " )
expectation . append ( " password: " )
setupSSHKeys = pexpect . spawn ( " ssh -p " + port + user + " @ " + IPAddress , timeout = 3 )
index = setupSSHKeys . expect ( expectation )
if index == 0 :
setupSSHKeys . sendline ( " yes " )
setupSSHKeys . expect ( " password: " )
setupSSHKeys . sendline ( password )
expectation = [ ]
expectation . append ( " password: " )
expectation . append ( pexpect . EOF )
innerIndex = setupSSHKeys . expect ( expectation )
if innerIndex == 0 :
setupSSHKeys . kill ( signal . SIGTERM )
return [ 1 , " None " ]
elif innerIndex == 1 :
setupSSHKeys . kill ( signal . SIGTERM )
return [ 1 , " None " ]
elif index == 1 :
setupSSHKeys . expect ( " password: " )
setupSSHKeys . sendline ( password )
expectation = [ ]
expectation . append ( " password: " )
expectation . append ( pexpect . EOF )
innerIndex = setupSSHKeys . expect ( expectation )
if innerIndex == 0 :
setupSSHKeys . kill ( signal . SIGTERM )
return [ 1 , " None " ]
elif innerIndex == 1 :
setupSSHKeys . kill ( signal . SIGTERM )
return [ 1 , " None " ]
except pexpect . TIMEOUT as msg :
logging . CyberCPLogFileWriter . writeToFile ( " Timeout [verifyHostKey] " )
return [ 0 , " Timeout [verifyHostKey] " ]
except pexpect . EOF as msg :
logging . CyberCPLogFileWriter . writeToFile ( " EOF [verifyHostKey] " )
return [ 0 , " EOF [verifyHostKey] " ]
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( str ( msg ) + " [verifyHostKey] " )
return [ 0 , str ( msg ) + " [verifyHostKey] " ]
@staticmethod
def createBackupDir ( IPAddress , port = ' 22 ' , user = ' root ' ) :
try :
# First try SSH command
command = " sudo ssh -o StrictHostKeyChecking=no -p " + port + " -i /root/.ssh/cyberpanel " + user + " @ " + IPAddress + " mkdir ~/backup "
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile ( command )
result = subprocess . call ( shlex . split ( command ) )
# If SSH command fails, it might be an SFTP-only server
if result != 0 :
logging . CyberCPLogFileWriter . writeToFile (
f " SSH command failed for { IPAddress } , likely SFTP-only server. Skipping directory creation. " )
# Don't fail - SFTP servers may have their own directory structure
return 1
command = " sudo ssh -o StrictHostKeyChecking=no -p " + port + " -i /root/.ssh/cyberpanel " + user + " @ " + IPAddress + ' " cat ~/.ssh/authorized_keys ~/.ssh/temp > ~/.ssh/authorized_temp " '
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile ( command )
subprocess . call ( shlex . split ( command ) )
command = " sudo ssh -o StrictHostKeyChecking=no -p " + port + " -i /root/.ssh/cyberpanel " + user + " @ " + IPAddress + ' " cat ~/.ssh/authorized_temp > ~/.ssh/authorized_keys " '
if os . path . exists ( ProcessUtilities . debugPath ) :
logging . CyberCPLogFileWriter . writeToFile ( command )
subprocess . call ( shlex . split ( command ) )
return 1
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( str ( msg ) + " [createBackupDir] " )
# Don't fail for SFTP-only servers
return 1
@staticmethod
def host_key_verification ( IPAddress ) :
try :
command = ' sudo ssh-keygen -R ' + IPAddress
subprocess . call ( shlex . split ( command ) )
return 1
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( str ( msg ) + " [host_key_verification] " )
return 0
@staticmethod
def getAliases ( masterDomain ) :
try :
aliases = [ ]
master = Websites . objects . get ( domain = masterDomain )
aliasDomains = master . aliasdomains_set . all ( )
for items in aliasDomains :
aliases . append ( items . aliasDomain )
return aliases
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( str ( msg ) + " [getAliases] " )
print ( 0 )
### Cloud Backup functions
def CheckIfSleepNeeded ( self ) :
import psutil
while ( 1 ) :
logging . CyberCPLogFileWriter . writeToFile ( ' Current CPU percent %s . ' % ( int ( psutil . cpu_percent ( interval = None ) ) ) )
if int ( psutil . cpu_percent ( interval = None ) ) > int ( self . cpu ) :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Current CPU usage exceeds %s percent. Backup process will sleep for %s seconds..,0 ' % ( self . cpu , str ( self . time ) ) )
import time
time . sleep ( self . time )
else :
break
def BackupData ( self ) :
try :
### Creating the dir to store backups
self . BackupDataPath = ' %s /data ' % ( self . BackupPath )
command = ' mkdir -p %s ' % ( self . BackupDataPath )
ProcessUtilities . executioner ( command )
self . DataPath = ' /home/ %s ' % ( self . extraArgs [ ' domain ' ] )
## Backing up data
self . CheckIfSleepNeeded ( )
command = ' nice -n %s cp -Rp %s %s ' % ( self . nice , self . DataPath , self . BackupDataPath )
ProcessUtilities . executioner ( command )
## Store child domains if any in json format
DataJson = { }
childs = [ ]
import json
for child in self . website . childdomains_set . all ( ) :
childs . append ( { ' domain ' : child . domain , ' path ' : child . path , ' php ' : child . phpSelection } )
DataJson [ ' ChildDomains ' ] = childs
DataJsonPath = ' %s / %s ' % ( self . BackupPath , ' data.json ' )
writeToFile = open ( DataJsonPath , ' w ' )
writeToFile . write ( json . dumps ( DataJson ) )
writeToFile . close ( )
return 1 , None
except BaseException as msg :
return 0 , str ( msg )
def BackupEmails ( self ) :
try :
from mailServer . models import Domains , EUsers
try :
emailDomain = Domains . objects . get ( domainOwner = self . website )
except :
return 1 , None
### Creating the dir to store backups
self . BackupDataPath = ' %s /emails ' % ( self . BackupPath )
command = ' mkdir -p %s ' % ( self . BackupDataPath )
ProcessUtilities . executioner ( command )
self . DataPath = ' /home/vmail/ %s ' % ( self . extraArgs [ ' domain ' ] )
## Backing up data
self . CheckIfSleepNeeded ( )
command = ' nice -n %s cp -Rp %s %s ' % ( self . nice , self . DataPath , self . BackupDataPath )
ProcessUtilities . executioner ( command )
## Store child domains if any in json format
DataJson = { }
emailsList = [ ]
import json
for emails in emailDomain . eusers_set . all ( ) :
emailsList . append ( { ' email ' : emails . email , ' password ' : emails . password } )
DataJson [ ' emails ' ] = emailsList
DataJsonPath = ' %s / %s ' % ( self . BackupPath , ' emails.json ' )
writeToFile = open ( DataJsonPath , ' w ' )
writeToFile . write ( json . dumps ( DataJson ) )
writeToFile . close ( )
return 1 , None
except BaseException as msg :
return 0 , str ( msg )
def BackupDatabases ( self ) :
try :
### Creating the dir to store backups
self . BackupDataPath = ' %s /databases ' % ( self . BackupPath )
command = ' mkdir -p %s ' % ( self . BackupDataPath )
ProcessUtilities . executioner ( command )
## Backing up data
self . CheckIfSleepNeeded ( )
DataJson = { }
databases = [ ]
import json
for items in self . website . databases_set . all ( ) :
try :
dbuser = DBUsers . objects . get ( user = items . dbUser )
userToTry = items . dbUser
except :
try :
dbusers = DBUsers . objects . all ( ) . filter ( user = items . dbUser )
userToTry = items . dbUser
for it in dbusers :
dbuser = it
break
userToTry = mysqlUtilities . mysqlUtilities . fetchuser ( items . dbName )
if userToTry == 0 or userToTry == 1 :
continue
try :
dbuser = DBUsers . objects . get ( user = userToTry )
except :
try :
dbusers = DBUsers . objects . all ( ) . filter ( user = userToTry )
for it in dbusers :
dbuser = it
break
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile (
' While creating backup for %s , we failed to backup database %s . Error message: %s ' % (
self . website . domain , items . dbName , str ( msg ) ) )
continue
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile (
' While creating backup for %s , we failed to backup database %s . Error message: %s ' % (
self . website . domain , items . dbName , str ( msg ) ) )
continue
databases . append ( { ' databaseName ' : str ( items . dbName ) , ' databaseUser ' : str ( userToTry ) , ' password ' : str ( dbuser . password ) } )
self . CheckIfSleepNeeded ( )
mysqlUtilities . mysqlUtilities . createDatabaseBackup ( items . dbName , self . BackupDataPath )
DataJson [ ' databases ' ] = databases
DataJsonPath = ' %s / %s ' % ( self . BackupPath , ' databases.json ' )
writeToFile = open ( DataJsonPath , ' w ' )
writeToFile . write ( json . dumps ( DataJson ) )
writeToFile . close ( )
return 1 , None
except BaseException as msg :
return 0 , str ( msg )
def CloudBackups ( self ) :
import json
if os . path . exists ( backupUtilities . CloudBackupConfigPath ) :
result = json . loads ( open ( backupUtilities . CloudBackupConfigPath , ' r ' ) . read ( ) )
self . nice = result [ ' nice ' ]
self . cpu = result [ ' cpu ' ]
self . time = int ( result [ ' time ' ] )
else :
self . nice = backupUtilities . NiceDefault
self . cpu = backupUtilities . CPUDefault
self . time = int ( backupUtilities . time )
self . BackupPath = self . extraArgs [ ' path ' ]
self . website = Websites . objects . get ( domain = self . extraArgs [ ' domain ' ] )
command = ' mkdir -p %s ' % ( self . BackupPath )
ProcessUtilities . executioner ( command )
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Starting backup generation..,0 ' )
if self . extraArgs [ ' data ' ] :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Generating backup for your data,5 ' )
result = self . BackupData ( )
if result [ 0 ] == 0 :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Failed to generate backups for data. Error: %s . [404], 0 ' % ( result [ 1 ] ) )
return 0 , self . BackupPath
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Data backup successfully generated,30 ' )
if self . extraArgs [ ' emails ' ] :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Generating backup for your emails,40 ' )
result = self . BackupEmails ( )
if result [ 0 ] == 0 :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Failed to generate backups for emails. Error: %s . [404], 0 ' % ( result [ 1 ] ) )
return 0 , self . BackupPath
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Emails backup successfully generated,60 ' )
if self . extraArgs [ ' databases ' ] :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Generating backup for your databases,60 ' )
result = self . BackupDatabases ( )
if result [ 0 ] == 0 :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Failed to generate backups for databases. Error: %s . [404], 0 ' % ( result [ 1 ] ) )
return 0 , self . BackupPath
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Databases backups successfully generated,30 ' )
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Creating final archive..,80 ' )
command = ' nice -n %s tar czf %s .tar.gz -C %s %s ' % ( self . nice , self . BackupPath , ' /home/cyberpanel/backups/ %s ' % ( self . extraArgs [ ' domain ' ] ) , self . BackupPath . split ( ' / ' ) [ - 1 ] )
ProcessUtilities . executioner ( command )
command = ' rm -rf %s ' % ( self . BackupPath )
ProcessUtilities . executioner ( command )
finalPath = ' %s .tar.gz ' % ( self . BackupPath )
command = ' chown cyberpanel:cyberpanel %s ' % ( finalPath )
ProcessUtilities . executioner ( command )
command = ' chmod 600:600 %s ' % ( finalPath )
ProcessUtilities . executioner ( command )
if self . extraArgs [ ' port ' ] != 0 :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Sending file to destination server..,90 ' )
command = " scp -o StrictHostKeyChecking=no -P %s -i /root/.ssh/cyberpanel %s root@ %s :/home/cyberpanel/backups/ %s / " % ( self . extraArgs [ ' port ' ] , finalPath , self . extraArgs [ ' ip ' ] , self . extraArgs [ ' destinationDomain ' ] )
ProcessUtilities . outputExecutioner ( command )
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] , ' Completed [200]. ' )
return 1 , self . BackupPath + ' .tar.gz '
## Restore functions
def SubmitCloudBackupRestore ( self ) :
try :
import json
if os . path . exists ( backupUtilities . CloudBackupConfigPath ) :
result = json . loads ( open ( backupUtilities . CloudBackupConfigPath , ' r ' ) . read ( ) )
self . nice = result [ ' nice ' ]
self . cpu = result [ ' cpu ' ]
self . time = int ( result [ ' time ' ] )
else :
self . nice = backupUtilities . NiceDefault
self . cpu = backupUtilities . CPUDefault
self . time = int ( backupUtilities . time )
self . BackupPath = ' /home/cyberpanel/backups/ %s / %s ' % ( self . extraArgs [ ' domain ' ] , self . extraArgs [ ' backupFile ' ] )
self . website = Websites . objects . get ( domain = self . extraArgs [ ' domain ' ] )
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Extracting main archive..,0 ' )
command = ' tar -xf %s -C %s ' % ( self . BackupPath , ' /home/cyberpanel/backups/ %s / ' % ( self . extraArgs [ ' domain ' ] ) )
ProcessUtilities . executioner ( command )
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Main Archive extracted,20 ' )
self . extractedPath = ' /home/cyberpanel/backups/ %s / %s ' % ( self . extraArgs [ ' domain ' ] , self . extraArgs [ ' backupFile ' ] . rstrip ( ' .tar.gz ' ) )
self . dataPath = ' %s /data ' % ( self . extractedPath )
self . databasesPath = ' %s /databases ' % ( self . extractedPath )
self . emailsPath = ' %s /emails ' % ( self . extractedPath )
## Data
if os . path . exists ( self . dataPath ) :
try :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Creating child domains if any..,20 ' )
childDomains = json . loads ( open ( ' %s /data.json ' % ( self . extractedPath ) , ' r ' ) . read ( ) ) [ ' ChildDomains ' ]
for child in childDomains :
try :
ch = ChildDomains . objects . get ( domain = child [ ' domain ' ] )
except :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Creating %s ,20 ' % ( child [ ' domain ' ] ) )
virtualHostUtilities . createDomain ( self . website . domain , child [ ' domain ' ] , child [ ' php ' ] , child [ ' path ' ] , 1 , 0 , 0 ,
self . website . admin . userName , 0 , " /home/cyberpanel/ " + str ( randint ( 1000 , 9999 ) ) )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( ' %s [SubmitCloudBackupRestore:1533] ' % str ( msg ) )
homePath = ' /home/ %s ' % ( self . website . domain )
command = ' rm -rf %s ' % ( homePath )
ProcessUtilities . executioner ( command )
if self . extraArgs [ ' sourceDomain ' ] == ' None ' :
command = ' mv %s / %s %s ' % ( self . dataPath , self . website . domain , ' /home ' )
else :
command = ' mv %s / %s %s / %s ' % ( self . dataPath , self . extraArgs [ ' sourceDomain ' ] , ' /home ' , self . extraArgs [ ' domain ' ] )
ProcessUtilities . executioner ( command )
from filemanager . filemanager import FileManager
fm = FileManager ( None , None )
fm . fixPermissions ( self . website . domain )
## Emails
if os . path . exists ( self . emailsPath ) :
try :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Creating emails if any..,40 ' )
emails = json . loads ( open ( ' %s /emails.json ' % ( self . extractedPath ) , ' r ' ) . read ( ) ) [ ' emails ' ]
from mailServer . models import Domains , EUsers
emailDomain = Domains . objects . get ( domain = self . website . domain )
for email in emails :
try :
eu = EUsers . objects . get ( emailOwner = emailDomain , email = email [ ' email ' ] )
except :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Creating %s ,40 ' % ( email [ ' email ' ] ) )
emailAcct = EUsers ( emailOwner = emailDomain , email = email [ ' email ' ] , password = email [ ' password ' ] )
emailAcct . mail = ' maildir:/home/vmail/ %s / %s /Maildir ' % ( self . website . domain , email [ ' email ' ] . split ( ' @ ' ) [ 0 ] )
emailAcct . save ( )
EmailsHome = ' /home/vmail/ %s ' % ( self . website . domain )
command = ' rm -rf %s ' % ( EmailsHome )
ProcessUtilities . executioner ( command )
command = ' mv %s / %s /home/vmail ' % ( self . emailsPath , self . website . domain )
ProcessUtilities . executioner ( command )
command = ' chown -R vmail:vmail %s ' % ( EmailsHome )
ProcessUtilities . executioner ( command )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( ' %s [SubmitCloudBackupRestore:1533] ' % str ( msg ) )
## Databases
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Restoring databases if any..,70 ' )
databases = json . loads ( open ( ' %s /databases.json ' % ( self . extractedPath ) , ' r ' ) . read ( ) ) [ ' databases ' ]
for db in databases :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Restoring database %s ..,70 ' % ( db [ ' databaseName ' ] ) )
mysqlUtilities . mysqlUtilities . submitDBDeletion ( db [ ' databaseName ' ] )
if mysqlUtilities . mysqlUtilities . createDatabase ( db [ ' databaseName ' ] , db [ ' databaseUser ' ] , " cyberpanel " ) == 0 :
raise BaseException ( " Failed to create Databases! " )
newDB = Databases ( website = self . website , dbName = db [ ' databaseName ' ] , dbUser = db [ ' databaseUser ' ] )
newDB . save ( )
mysqlUtilities . mysqlUtilities . restoreDatabaseBackup ( db [ ' databaseName ' ] , self . databasesPath , db [ ' password ' ] )
if self . extraArgs [ ' sourceDomain ' ] != ' None ' :
if self . extraArgs [ ' sourceDomain ' ] != self . extraArgs [ ' domain ' ] :
try :
command = ' wp --info '
outout = ProcessUtilities . outputExecutioner ( command )
if not outout . find ( ' WP-CLI root dir: ' ) > - 1 :
from plogical . applicationInstaller import ApplicationInstaller
ai = ApplicationInstaller ( None , None )
ai . installWPCLI ( )
except subprocess . CalledProcessError :
from plogical . applicationInstaller import ApplicationInstaller
ai = ApplicationInstaller ( None , None )
ai . installWPCLI ( )
path = ' /home/ %s /public_html ' % ( self . extraArgs [ ' domain ' ] )
command = " wp search-replace ' %s ' ' %s ' --path= %s --allow-root " % ( self . extraArgs [ ' sourceDomain ' ] , self . extraArgs [ ' domain ' ] , path )
ProcessUtilities . outputExecutioner ( command )
command = " wp search-replace ' www. %s ' ' %s ' --path= %s --allow-root " % (
self . extraArgs [ ' sourceDomain ' ] , self . extraArgs [ ' domain ' ] , path )
ProcessUtilities . outputExecutioner ( command )
command = " wp search-replace ' www. %s ' ' %s ' --path= %s --allow-root " % (
self . extraArgs [ ' domain ' ] , self . extraArgs [ ' domain ' ] , path )
ProcessUtilities . outputExecutioner ( command )
command = ' rm -rf %s ' % ( self . extractedPath )
ProcessUtilities . executioner ( command )
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] , ' Completed [200]. ' )
except BaseException as msg :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] , ' %s [404]. ' % str ( msg ) )
### Cloud Backup functions ends
def fetchAWSKeys ( self ) :
path = ' /home/cyberpanel/.aws '
credentials = path + ' /credentials '
data = open ( credentials , ' r ' ) . readlines ( )
aws_access_key_id = data [ 1 ] . split ( ' ' ) [ 2 ] . strip ( ' ' ) . strip ( ' \n ' )
aws_secret_access_key = data [ 2 ] . split ( ' ' ) [ 2 ] . strip ( ' ' ) . strip ( ' \n ' )
region = data [ 3 ] . split ( ' ' ) [ 2 ] . strip ( ' ' ) . strip ( ' \n ' )
return aws_access_key_id , aws_secret_access_key , region
def SubmitS3BackupRestore ( self ) :
try :
import json
if os . path . exists ( backupUtilities . CloudBackupConfigPath ) :
result = json . loads ( open ( backupUtilities . CloudBackupConfigPath , ' r ' ) . read ( ) )
self . nice = result [ ' nice ' ]
self . cpu = result [ ' cpu ' ]
self . time = int ( result [ ' time ' ] )
else :
self . nice = backupUtilities . NiceDefault
self . cpu = backupUtilities . CPUDefault
self . time = int ( backupUtilities . time )
### First Download file from S3
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Starting file download from S3..,0 ' )
import boto3
from s3Backups . models import BackupPlan
plan = BackupPlan . objects . get ( name = self . extraArgs [ ' planName ' ] )
aws_access_key_id , aws_secret_access_key , region = self . fetchAWSKeys ( )
if region . find ( ' http ' ) > - 1 :
s3 = boto3 . resource (
' s3 ' ,
aws_access_key_id = aws_access_key_id ,
aws_secret_access_key = aws_secret_access_key ,
endpoint_url = region
)
else :
s3 = boto3 . resource (
' s3 ' ,
aws_access_key_id = aws_access_key_id ,
aws_secret_access_key = aws_secret_access_key ,
)
self . BackupPath = ' /home/cyberpanel/backups/ %s / %s ' % ( self . extraArgs [ ' domain ' ] , self . extraArgs [ ' backupFile ' ] . split ( ' / ' ) [ - 1 ] )
s3 . Bucket ( plan . bucket ) . download_file ( self . extraArgs [ ' backupFile ' ] , self . BackupPath )
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' File download completed..,5 ' )
self . website = Websites . objects . get ( domain = self . extraArgs [ ' domain ' ] )
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Extracting main archive..,0 ' )
command = ' tar -xf %s -C %s ' % ( self . BackupPath , ' /home/cyberpanel/backups/ %s / ' % ( self . extraArgs [ ' domain ' ] ) )
ProcessUtilities . executioner ( command )
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Main Archive extracted,20 ' )
self . extractedPath = ' /home/cyberpanel/backups/ %s / %s ' % ( self . extraArgs [ ' domain ' ] , self . extraArgs [ ' backupFile ' ] . split ( ' / ' ) [ - 1 ] . rstrip ( ' .tar.gz ' ) )
self . dataPath = ' %s /data ' % ( self . extractedPath )
self . databasesPath = ' %s /databases ' % ( self . extractedPath )
self . emailsPath = ' %s /emails ' % ( self . extractedPath )
## Data
if os . path . exists ( self . dataPath ) :
try :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Creating child domains if any..,20 ' )
childDomains = json . loads ( open ( ' %s /data.json ' % ( self . extractedPath ) , ' r ' ) . read ( ) ) [ ' ChildDomains ' ]
for child in childDomains :
try :
ch = ChildDomains . objects . get ( domain = child [ ' domain ' ] )
except :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Creating %s ,20 ' % ( child [ ' domain ' ] ) )
virtualHostUtilities . createDomain ( self . website . domain , child [ ' domain ' ] , child [ ' php ' ] , child [ ' path ' ] , 1 , 0 , 0 ,
self . website . admin . userName , 0 , " /home/cyberpanel/ " + str ( randint ( 1000 , 9999 ) ) )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( ' %s [SubmitCloudBackupRestore:1533] ' % str ( msg ) )
homePath = ' /home/ %s ' % ( self . website . domain )
command = ' rm -rf %s ' % ( homePath )
ProcessUtilities . executioner ( command )
command = ' mv %s / %s %s ' % ( self . dataPath , self . website . domain , ' /home ' )
ProcessUtilities . executioner ( command )
from filemanager . filemanager import FileManager
fm = FileManager ( None , None )
fm . fixPermissions ( self . website . domain )
## Emails
if os . path . exists ( self . emailsPath ) :
try :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Creating emails if any..,40 ' )
emails = json . loads ( open ( ' %s /emails.json ' % ( self . extractedPath ) , ' r ' ) . read ( ) ) [ ' emails ' ]
from mailServer . models import Domains , EUsers
emailDomain = Domains . objects . get ( domain = self . website . domain )
for email in emails :
try :
eu = EUsers . objects . get ( emailOwner = emailDomain , email = email [ ' email ' ] )
except :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Creating %s ,40 ' % ( email [ ' email ' ] ) )
emailAcct = EUsers ( emailOwner = emailDomain , email = email [ ' email ' ] , password = email [ ' password ' ] )
emailAcct . mail = ' maildir:/home/vmail/ %s / %s /Maildir ' % ( self . website . domain , email [ ' email ' ] . split ( ' @ ' ) [ 0 ] )
emailAcct . save ( )
EmailsHome = ' /home/vmail/ %s ' % ( self . website . domain )
command = f ' rm -rf { EmailsHome } '
ProcessUtilities . executioner ( command )
command = ' mv %s / %s /home/vmail ' % ( self . emailsPath , self . website . domain )
ProcessUtilities . executioner ( command )
command = ' chown -R vmail:vmail %s ' % ( EmailsHome )
ProcessUtilities . executioner ( command )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( ' %s [SubmitCloudBackupRestore:1533] ' % str ( msg ) )
## Databases
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Restoring databases if any..,70 ' )
databases = json . loads ( open ( ' %s /databases.json ' % ( self . extractedPath ) , ' r ' ) . read ( ) ) [ ' databases ' ]
for db in databases :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] ,
' Restoring database %s ..,70 ' % ( db [ ' databaseName ' ] ) )
mysqlUtilities . mysqlUtilities . submitDBDeletion ( db [ ' databaseName ' ] )
if mysqlUtilities . mysqlUtilities . createDatabase ( db [ ' databaseName ' ] , db [ ' databaseUser ' ] , " cyberpanel " ) == 0 :
raise BaseException ( " Failed to create Databases! " )
newDB = Databases ( website = self . website , dbName = db [ ' databaseName ' ] , dbUser = db [ ' databaseUser ' ] )
newDB . save ( )
mysqlUtilities . mysqlUtilities . restoreDatabaseBackup ( db [ ' databaseName ' ] , self . databasesPath , db [ ' password ' ] )
command = ' rm -rf %s ' % ( self . extractedPath )
ProcessUtilities . executioner ( command )
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] , ' Completed [200]. ' )
except BaseException as msg :
logging . CyberCPLogFileWriter . statusWriter ( self . extraArgs [ ' tempStatusPath ' ] , ' %s [404]. ' % str ( msg ) )
def submitBackupCreation ( tempStoragePath , backupName , backupPath , backupDomain ) :
try :
## /home/example.com/backup/backup-example.com-02.13.2018_10-24-52 -- tempStoragePath
## backup-example.com-02.13.2018_10-24-52 -- backup name
## /home/example.com/backup - backupPath
## /home/cyberpanel/1047.xml - metaPath
## /home/backup/<random_number> - CPHomeStorage
status = os . path . join ( backupPath , ' status ' )
### Lets first see if enough space for backups is available
from plogical . IncScheduler import IncScheduler
import json
from plogical . getSystemInformation import SystemInformation
#
# IncScheduler.CalculateAndUpdateDiskUsage()
try :
website = Websites . objects . get ( domain = backupDomain )
DiskUsageOfSite = json . loads ( website . config ) [ ' DiskUsage ' ]
used_disk , free_disk , percent_used = SystemInformation . GetRemainingDiskUsageInMBs ( )
if float ( free_disk ) < = float ( DiskUsageOfSite ) :
command = f " echo ' Disk space exceeded the website size. [2065][5009] ' > %s "
ProcessUtilities . executioner ( command , website . externalApp )
return 0
except :
pass
###
website = Websites . objects . get ( domain = backupDomain )
##
CPHomeStorage = f ' /home/backup/ { generate_pass ( 5 ) } '
### Now make this random directory to store data so taht we dont run any root file operations in user home dir
command = f ' mkdir -p { CPHomeStorage } && chown { website . externalApp } : { website . externalApp } { CPHomeStorage } '
ProcessUtilities . executioner ( command , ' root ' , True )
##
schedulerPath = f ' /home/cyberpanel/ { backupDomain } -backup.txt '
##
command = f ' mkdir -p { tempStoragePath } '
ProcessUtilities . executioner ( command , website . externalApp )
##
command = f ' touch { status } '
ProcessUtilities . executioner ( command , website . externalApp )
result = backupUtilities . prepareBackupMeta ( backupDomain , backupName , tempStoragePath , backupPath )
if result [ 0 ] == 0 :
writeToFile = open ( schedulerPath , ' w ' )
writeToFile . writelines ( ' 1325 ' )
writeToFile . close ( )
command = " echo ' %s [1084][5009] ' > %s " % ( str ( result [ 1 ] ) , status )
ProcessUtilities . executioner ( command , website . externalApp )
return 0
command = ' chown %s : %s %s ' % ( website . externalApp , website . externalApp , result [ 2 ] )
ProcessUtilities . executioner ( command )
logging . CyberCPLogFileWriter . writeToFile ( backupPath )
logging . CyberCPLogFileWriter . writeToFile ( tempStoragePath )
execPath = " sudo nice -n 10 /usr/local/CyberCP/bin/python " + virtualHostUtilities . cyberPanel + " /plogical/backupUtilities.py "
execPath = execPath + " startBackup --tempStoragePath " + tempStoragePath + " --backupName " \
+ backupName + " --backupPath " + backupPath + ' --backupDomain ' + backupDomain + ' --metaPath %s ' % (
result [ 2 ] )
output = ProcessUtilities . outputExecutioner ( execPath , website . externalApp )
if output . find ( ' [5009] ' ) > - 1 :
logging . CyberCPLogFileWriter . writeToFile ( output )
writeToFile = open ( schedulerPath , ' w ' )
writeToFile . writelines ( output )
writeToFile . close ( )
return 0
## Backing up databases
command = f ' chown cyberpanel:cyberpanel { result [ 2 ] } '
ProcessUtilities . executioner ( command )
backupMetaData = ElementTree . parse ( result [ 2 ] )
databases = backupMetaData . findall ( ' Databases/database ' )
for database in databases :
dbName = database . find ( ' dbName ' ) . text
res = mysqlUtilities . mysqlUtilities . createDatabaseBackup ( dbName , ' /home/cyberpanel ' )
if res == 0 :
## This login can be further improved later.
logging . CyberCPLogFileWriter . writeToFile ( ' Failed to create database backup for %s . This could be false positive, moving on. ' % ( dbName ) )
command = f ' mv /home/cyberpanel/ { dbName } .sql { CPHomeStorage } / { dbName } .sql '
ProcessUtilities . executioner ( command )
##
#output = ProcessUtilities.outputExecutioner(execPath, website.externalApp)
execPath = " sudo nice -n 10 /usr/local/CyberCP/bin/python " + virtualHostUtilities . cyberPanel + " /plogical/backupUtilities.py "
execPath = execPath + " BackupRoot --tempStoragePath " + tempStoragePath + " --backupName " \
+ backupName + " --backupPath " + backupPath + ' --backupDomain ' + backupDomain + ' --metaPath %s --externalApp %s ' % (
result [ 2 ] , website . externalApp ) + f ' --CPHomeStorage { CPHomeStorage } '
ProcessUtilities . executioner ( execPath , ' root ' )
#command = 'chown -R %s:%s %s' % (website.externalApp, website.externalApp, backupPath)
#ProcessUtilities.executioner(command)
command = f ' rm -f { result [ 2 ] } '
ProcessUtilities . executioner ( command , ' cyberpanel ' )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile (
f " { str ( msg ) } [submitBackupCreation] " )
def cancelBackupCreation ( backupCancellationDomain , fileName ) :
try :
path = f " /home/ { backupCancellationDomain } /backup/pid "
pid = open ( path , " r " ) . readlines ( ) [ 0 ]
try :
os . kill ( int ( pid ) , signal . SIGKILL )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( f " { str ( msg ) } [cancelBackupCreation] " )
backupPath = f " /home/ { backupCancellationDomain } /backup/ "
tempStoragePath = backupPath + fileName
try :
os . remove ( f " { tempStoragePath } .tar.gz " )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( f " { str ( msg ) } [cancelBackupCreation] " )
try :
rmtree ( tempStoragePath )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile ( f " { str ( msg ) } [cancelBackupCreation] " )
status = open ( backupPath + ' status ' , " w " )
status . write ( " Aborted manually. [1165][5009] " )
status . close ( )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile (
f " { str ( msg ) } [cancelBackupCreation] " )
print ( f " 0, { str ( msg ) } " )
def submitRestore ( backupFile , dir ) :
try :
p = Process ( target = backupUtilities . startRestore , args = ( backupFile , dir , ) )
p . start ( )
print ( " 1,None " )
except BaseException as msg :
logging . CyberCPLogFileWriter . writeToFile (
str ( msg ) + " [cancelBackupCreation] " )
print ( f " 0, { str ( msg ) } " )
def submitDestinationCreation ( ipAddress , password , port = ' 22 ' , user = ' root ' ) :
setupKeys = backupUtilities . setupSSHKeys ( ipAddress , password , port , user )
if setupKeys [ 0 ] == 1 :
backupUtilities . createBackupDir ( ipAddress , port , user )
print ( " 1,None " )
else :
print ( setupKeys [ 1 ] )
def getConnectionStatus ( ipAddress ) :
try :
checkCon = backupUtilities . checkConnection ( ipAddress )
if checkCon [ 0 ] == 1 :
print ( " 1,None " )
else :
print ( checkCon [ 1 ] )
except BaseException as msg :
print ( str ( msg ) )
def FetchOCBackupsFolders ( id , owner ) :
# Load the private key
private_key_path = ' /root/.ssh/cyberpanel '
keyPrivate = paramiko . RSAKey ( filename = private_key_path )
from IncBackups . models import OneClickBackups
admin = Administrator . objects . get ( userName = owner )
ocb = OneClickBackups . objects . get ( pk = id , owner = admin )
nbd = NormalBackupDests . objects . get ( name = ocb . sftpUser )
ip = json . loads ( nbd . config ) [ ' ip ' ]
# Connect to the remote server using the private key
ssh = paramiko . SSHClient ( )
ssh . set_missing_host_key_policy ( paramiko . AutoAddPolicy ( ) )
ssh . connect ( ip , username = ocb . sftpUser , pkey = keyPrivate )
# Command to list directories under the specified path
command = f " ls -d cpbackups/*/ "
# Execute the command
stdin , stdout , stderr = ssh . exec_command ( command )
# Read the results
directories = stdout . read ( ) . decode ( ) . splitlines ( )
# Print directories
for directory in directories :
print ( directory )
def main ( ) :
parser = argparse . ArgumentParser ( description = ' CyberPanel Backup Generator ' )
parser . add_argument ( ' function ' , help = ' Specify a function to call! ' )
parser . add_argument ( ' --tempStoragePath ' , help = ' ' )
parser . add_argument ( ' --backupName ' , help = ' ! ' )
parser . add_argument ( ' --backupPath ' , help = ' ' )
parser . add_argument ( ' --backupDomain ' , help = ' ' )
parser . add_argument ( ' --metaPath ' , help = ' ' )
## Destination Creation
parser . add_argument ( ' --ipAddress ' , help = ' ' )
parser . add_argument ( ' --password ' , help = ' ' )
parser . add_argument ( ' --port ' , help = ' ' )
parser . add_argument ( ' --user ' , help = ' ' )
## backup cancellation arguments
parser . add_argument ( ' --backupCancellationDomain ' , help = ' ' )
parser . add_argument ( ' --fileName ' , help = ' ' )
## backup restore arguments
parser . add_argument ( ' --backupFile ' , help = ' ' )
parser . add_argument ( ' --dir ' , help = ' ' )
### For Cloud Backups
parser . add_argument ( ' --data ' , help = ' ' )
parser . add_argument ( ' --emails ' , help = ' ' )
parser . add_argument ( ' --databases ' , help = ' ' )
parser . add_argument ( ' --path ' , help = ' ' )
parser . add_argument ( ' --ip ' , help = ' ' )
parser . add_argument ( ' --sourceDomain ' , help = ' ' )
parser . add_argument ( ' --destinationDomain ' , help = ' ' )
## FOR S3
parser . add_argument ( ' --planName ' , help = ' ' )
parser . add_argument ( ' --externalApp ' , help = ' ' )
### CPHomeStorage
parser . add_argument ( ' --CPHomeStorage ' , help = ' ' )
### id
parser . add_argument ( ' --id ' , help = ' ' )
args = parser . parse_args ( )
if args . function == " submitBackupCreation " :
submitBackupCreation ( args . tempStoragePath , args . backupName , args . backupPath , args . backupDomain )
elif args . function == " cancelBackupCreation " :
cancelBackupCreation ( args . backupCancellationDomain , args . fileName )
elif args . function == " submitRestore " :
submitRestore ( args . backupFile , args . dir )
elif args . function == " submitDestinationCreation " :
submitDestinationCreation ( args . ipAddress , args . password , args . port , args . user )
elif args . function == " getConnectionStatus " :
getConnectionStatus ( args . ipAddress )
elif args . function == " startBackup " :
backupUtilities . startBackup ( args . tempStoragePath , args . backupName , args . backupPath , args . metaPath )
elif args . function == " BackupRoot " :
backupUtilities . BackupRoot ( args . tempStoragePath , args . backupName , args . backupPath , args . metaPath , args . externalApp , args . CPHomeStorage )
elif args . function == ' CloudBackup ' :
extraArgs = { }
extraArgs [ ' domain ' ] = args . backupDomain
extraArgs [ ' tempStatusPath ' ] = args . tempStoragePath
extraArgs [ ' data ' ] = int ( args . data )
extraArgs [ ' emails ' ] = int ( args . emails )
extraArgs [ ' databases ' ] = int ( args . databases )
extraArgs [ ' path ' ] = args . path
extraArgs [ ' port ' ] = args . port
extraArgs [ ' ip ' ] = args . ip
extraArgs [ ' destinationDomain ' ] = args . destinationDomain
bu = backupUtilities ( extraArgs )
bu . CloudBackups ( )
elif args . function == ' SubmitCloudBackupRestore ' :
extraArgs = { }
extraArgs [ ' domain ' ] = args . backupDomain
extraArgs [ ' tempStatusPath ' ] = args . tempStoragePath
extraArgs [ ' backupFile ' ] = args . backupFile
extraArgs [ ' sourceDomain ' ] = args . sourceDomain
bu = backupUtilities ( extraArgs )
bu . SubmitCloudBackupRestore ( )
elif args . function == ' SubmitS3BackupRestore ' :
extraArgs = { }
extraArgs [ ' domain ' ] = args . backupDomain
extraArgs [ ' tempStatusPath ' ] = args . tempStoragePath
extraArgs [ ' backupFile ' ] = args . backupFile
extraArgs [ ' planName ' ] = args . planName
bu = backupUtilities ( extraArgs )
bu . SubmitS3BackupRestore ( )
elif args . function == ' FetchOCBackupsFolders ' :
FetchOCBackupsFolders ( args . id , args . user )
if __name__ == " __main__ " :
main ( )