incremental backups: completion

This commit is contained in:
Usman Nasir
2019-10-06 18:41:09 +05:00
parent d81d00d8ca
commit e814bc1331
14 changed files with 908 additions and 59 deletions

View File

@@ -0,0 +1,541 @@
#!/usr/local/CyberCP/bin/python2
import os
import os.path
import sys
sys.path.append('/usr/local/CyberCP')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
import django
try:
django.setup()
except:
pass
import threading as multi
from plogical.processUtilities import ProcessUtilities
from IncBackups.models import IncJob, JobSnapshots
from websiteFunctions.models import Websites
import plogical.randomPassword as randomPassword
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
from xml.etree.ElementTree import Element, SubElement
from xml.etree import ElementTree
from xml.dom import minidom
from backup.models import DBUsers
import plogical.mysqlUtilities as mysqlUtilities
from plogical.backupUtilities import backupUtilities
from plogical.dnsUtilities import DNS
from mailServer.models import Domains as eDomains
from random import randint
try:
from plogical.virtualHostUtilities import virtualHostUtilities
from plogical.mailUtilities import mailUtilities
except:
pass
class IncJobs(multi.Thread):
def __init__(self, function, extraArgs):
multi.Thread.__init__(self)
self.function = function
self.extraArgs = extraArgs
self.repoPath = ''
self.passwordFile = ''
self.statusPath = ''
self.website = ''
self.backupDestinations = ''
self.jobid = 0
self.metaPath = ''
def run(self):
if self.function == 'createBackup':
self.createBackup()
elif self.function == 'restorePoint':
self.restorePoint()
def restoreData(self):
try:
if self.jobid.destination == 'local':
repoLocation = '/home/%s/incbackup' % (self.website)
command = 'restic -r %s restore %s --target / --password-file %s' % (repoLocation, self.jobid.snapshotid, self.passwordFile)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
elif self.jobid.destination[:4] == 'sftp':
repoLocation = '/home/backup/%s' % (self.website)
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s restore %s --target / --password-file %s' % (self.jobid.destination, repoLocation, self.jobid.snapshotid, self.passwordFile)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
except BaseException, msg:
logging.statusWriter(self.statusPath, "%s [46][5009]" % (str(msg)), 1)
return 0
def restoreDatabase(self):
try:
if self.jobid.destination == 'local':
repoLocation = '/home/%s/incbackup' % (self.website)
command = 'restic -r %s restore %s --target / --password-file %s' % (repoLocation, self.jobid.snapshotid, self.passwordFile)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
elif self.jobid.destination[:4] == 'sftp':
repoLocation = '/home/backup/%s' % (self.website)
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s restore %s --target / --password-file %s' % (self.jobid.destination, repoLocation, self.jobid.snapshotid, self.passwordFile)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
if mysqlUtilities.mysqlUtilities.restoreDatabaseBackup(self.jobid.type.split(':')[1], '/home/cyberpanel', 'dummy', 'dummy') == 0:
raise BaseException
try:
os.remove('/home/cyberpanel/%s' % (self.jobid.type.split(':')[1]))
except:
pass
except BaseException, msg:
logging.statusWriter(self.statusPath, "%s [46][5009]" % (str(msg)), 1)
return 0
def restoreEmail(self):
try:
if self.jobid.destination == 'local':
repoLocation = '/home/%s/incbackup' % (self.website)
command = 'restic -r %s restore %s --target / --password-file %s' % (repoLocation, self.jobid.snapshotid, self.passwordFile)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
elif self.jobid.destination[:4] == 'sftp':
repoLocation = '/home/backup/%s' % (self.website)
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s restore %s --target / --password-file %s' % (self.jobid.destination, repoLocation, self.jobid.snapshotid, self.passwordFile)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
except BaseException, msg:
logging.statusWriter(self.statusPath, "%s [46][5009]" % (str(msg)), 1)
return 0
def restorePoint(self):
try:
self.statusPath = self.extraArgs['tempPath']
self.website = self.extraArgs['website']
jobid = self.extraArgs['jobid']
self.jobid = JobSnapshots.objects.get(pk=jobid)
message = 'Starting restore of %s for %s.' % (self.jobid.snapshotid, self.website)
logging.statusWriter(self.statusPath, message, 1)
self.passwordFile = '/home/%s/%s' % (self.website, self.website)
## Restore Meta first
metaPathNew = '/home/%s/meta.xml' % (self.website)
if self.jobid.destination == 'local':
repoLocation = '/home/%s/incbackup' % (self.website)
command = 'restic -r %s restore latest --target / --password-file %s --include %s' % (repoLocation, self.passwordFile, metaPathNew)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
elif self.jobid.destination[:4] == 'sftp':
repoLocation = '/home/backup/%s' % (self.website)
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s restore latest --target / --password-file %s --include %s' % (self.jobid.destination, repoLocation, self.passwordFile, metaPathNew)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
## Reconstruct configs configs
if self.extraArgs['reconstruct']:
execPath = "nice -n 10 /usr/local/CyberCP/bin/python2 " + virtualHostUtilities.cyberPanel + "/IncBackups/restoreMeta.py"
execPath = execPath + " submitRestore --metaPath %s --statusFile %s" % (metaPathNew, self.statusPath)
ProcessUtilities.outputExecutioner(execPath)
##
if self.jobid.type[:8] == 'database':
message = 'Restoring database..'
logging.statusWriter(self.statusPath, message, 1)
self.restoreDatabase()
message = 'Database restored.'
logging.statusWriter(self.statusPath, message, 1)
elif self.jobid.type[:4] == 'data':
self.restoreData()
elif self.jobid.type[:5] == 'email':
message = 'Restoring email..'
logging.statusWriter(self.statusPath, message, 1)
self.restoreEmail()
message = 'Emails restored.'
logging.statusWriter(self.statusPath, message, 1)
logging.statusWriter(self.statusPath, 'Completed', 1)
except BaseException, msg:
logging.statusWriter(self.extraArgs['tempPath'], str(msg), 1)
def prepareBackupMeta(self):
try:
######### Generating meta
## XML Generation
metaFileXML = Element('metaFile')
child = SubElement(metaFileXML, 'masterDomain')
child.text = self.website.domain
child = SubElement(metaFileXML, 'phpSelection')
child.text = self.website.phpSelection
child = SubElement(metaFileXML, 'externalApp')
child.text = self.website.externalApp
childDomains = self.website.childdomains_set.all()
databases = self.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:
try:
dbuser = DBUsers.objects.get(user=items.dbUser)
userToTry = items.dbUser
except:
dbusers = DBUsers.objects.all().filter(user=items.dbUser)
userToTry = items.dbUser
for it in dbusers:
dbuser = it
break
userToTry = mysqlUtilities.mysqlUtilities.fetchuser(items.dbUser)
try:
dbuser = DBUsers.objects.get(user=userToTry)
except:
dbusers = DBUsers.objects.all().filter(user=userToTry)
for it in dbusers:
dbuser = it
break
databaseXML = Element('database')
child = SubElement(databaseXML, 'dbName')
child.text = items.dbName
child = SubElement(databaseXML, 'dbUser')
child.text = userToTry
child = SubElement(databaseXML, 'password')
child.text = dbuser.password
databasesXML.append(databaseXML)
metaFileXML.append(databasesXML)
## Get Aliases
aliasesXML = Element('Aliases')
aliases = backupUtilities.getAliases(self.website.domain)
for items in aliases:
child = SubElement(aliasesXML, 'alias')
child.text = items
metaFileXML.append(aliasesXML)
## Finish Alias
## DNS Records XML
try:
dnsRecordsXML = Element("dnsrecords")
dnsRecords = DNS.getDNSRecords(self.website.domain)
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, msg:
logging.statusWriter(self.statusPath, '%s. [158:prepMeta]' % (str(msg)), 1)
## Email accounts XML
try:
emailRecordsXML = Element('emails')
eDomain = eDomains.objects.get(domain=self.website.domain)
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, msg:
logging.statusWriter(self.statusPath, '%s. [warning:179:prepMeta]' % (str(msg)), 1)
## 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-06-50-03-Thu-Feb-2018/meta.xml -- metaPath
metaPath = '/home/cyberpanel/%s' % (str(randint(1000, 9999)))
xmlpretty = prettify(metaFileXML).encode('ascii', 'ignore')
metaFile = open(metaPath, 'w')
metaFile.write(xmlpretty)
metaFile.close()
os.chmod(metaPath, 0640)
## meta generated
logging.statusWriter(self.statusPath, 'Meta data is ready..', 1)
metaPathNew = '/home/%s/meta.xml' % (self.website.domain)
command = 'mv %s %s' % (metaPath, metaPathNew)
ProcessUtilities.executioner(command)
return 1
except BaseException, msg:
logging.statusWriter(self.statusPath, "%s [207][5009]" % (str(msg)), 1)
return 0
def backupData(self):
try:
logging.statusWriter(self.statusPath, 'Backing up data..', 1)
if self.backupDestinations == 'local':
backupPath = '/home/%s' % (self.website.domain)
command = 'restic -r %s backup %s --password-file %s --exclude %s' % (self.repoPath, backupPath, self.passwordFile, self.repoPath)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
snapShotid = result.split(' ')[-2]
newSnapshot = JobSnapshots(job=self.jobid, type='data:%s' % (backupPath), snapshotid=snapShotid, destination=self.backupDestinations)
newSnapshot.save()
elif self.backupDestinations[:4] == 'sftp':
remotePath = '/home/backup/%s' % (self.website.domain)
backupPath = '/home/%s' % (self.website.domain)
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (self.backupDestinations, remotePath, backupPath, self.passwordFile, self.repoPath)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
snapShotid = result.split(' ')[-2]
newSnapshot = JobSnapshots(job=self.jobid, type='data:%s' % (remotePath), snapshotid=snapShotid,
destination=self.backupDestinations)
newSnapshot.save()
logging.statusWriter(self.statusPath, 'Data for %s backed to %s.' % (self.website.domain, self.backupDestinations), 1)
return 1
except BaseException, msg:
logging.statusWriter(self.statusPath,'%s. [IncJobs.backupData.223][5009]' % str(msg), 1)
return 0
def backupDatabases(self):
try:
logging.statusWriter(self.statusPath, 'Backing up databases..', 1)
databases = self.website.databases_set.all()
for items in databases:
if mysqlUtilities.mysqlUtilities.createDatabaseBackup(items.dbName, '/home/cyberpanel') == 0:
return 0
dbPath = '/home/cyberpanel/%s.sql' % (items.dbName)
if self.backupDestinations == 'local':
command = 'restic -r %s backup %s --password-file %s' % (self.repoPath, dbPath, self.passwordFile)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
snapShotid = result.split(' ')[-2]
newSnapshot = JobSnapshots(job=self.jobid, type='database:%s' % (items.dbName), snapshotid=snapShotid, destination=self.backupDestinations)
newSnapshot.save()
elif self.backupDestinations[:4] == 'sftp':
remotePath = '/home/backup/%s' % (self.website.domain)
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (
self.backupDestinations, remotePath, dbPath, self.passwordFile, self.repoPath)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
snapShotid = result.split(' ')[-2]
newSnapshot = JobSnapshots(job=self.jobid, type='database:%s' % (items.dbName), snapshotid=snapShotid,
destination=self.backupDestinations)
newSnapshot.save()
try:
os.remove('/home/cyberpanel/%s' % (items.dbName))
except:
pass
return 1
except BaseException, msg:
logging.statusWriter(self.statusPath,'%s. [IncJobs.backupDatabases.269][5009]' % str(msg), 1)
return 0
def emailBackup(self):
try:
logging.statusWriter(self.statusPath, 'Backing up emails..', 1)
backupPath = '/home/vmail/%s' % (self.website.domain)
if self.backupDestinations == 'local':
command = 'restic -r %s backup %s --password-file %s' % (
self.repoPath, backupPath, self.passwordFile)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
snapShotid = result.split(' ')[-2]
newSnapshot = JobSnapshots(job=self.jobid, type='email:%s' % (backupPath), snapshotid=snapShotid,
destination=self.backupDestinations)
newSnapshot.save()
elif self.backupDestinations[:4] == 'sftp':
remotePath = '/home/backup/%s' % (self.website.domain)
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (
self.backupDestinations, remotePath, backupPath, self.passwordFile, self.repoPath)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
snapShotid = result.split(' ')[-2]
newSnapshot = JobSnapshots(job=self.jobid, type='email:%s' % (backupPath), snapshotid=snapShotid,
destination=self.backupDestinations)
newSnapshot.save()
logging.statusWriter(self.statusPath, 'Emails for %s backed to %s.' % (self.website.domain, self.backupDestinations), 1)
return 1
except BaseException, msg:
logging.statusWriter(self.statusPath,'%s. [IncJobs.emailBackup.269][5009]' % str(msg), 1)
return 0
def initiateRepo(self):
try:
logging.statusWriter(self.statusPath, 'Will first initiate backup repo..', 1)
if self.backupDestinations == 'local':
command = 'restic init --repo %s --password-file %s' % (self.repoPath, self.passwordFile)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
elif self.backupDestinations[:4] == 'sftp':
remotePath = '/home/backup/%s' % (self.website.domain)
command = 'export PATH=${PATH}:/usr/bin && restic init --repo %s:%s --password-file %s' % (self.backupDestinations, remotePath, self.passwordFile)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
else:
logging.statusWriter(self.statusPath, 'AWS implementation is currently pending. [5009]', 1)
return 0
logging.statusWriter(self.statusPath, 'Repo %s initiated for %s.' % (self.backupDestinations, self.website.domain), 1)
return 1
except BaseException, msg:
logging.statusWriter(self.statusPath,'%s. [IncJobs.initiateRepo.47][5009]' % str(msg), 1)
return 0
def createBackup(self):
self.statusPath = self.extraArgs['tempPath']
website = self.extraArgs['website']
self.backupDestinations = self.extraArgs['backupDestinations']
websiteData = self.extraArgs['websiteData']
websiteEmails = self.extraArgs['websiteEmails']
websiteSSLs = self.extraArgs['websiteSSLs']
websiteDatabases = self.extraArgs['websiteDatabases']
self.website = Websites.objects.get(domain=website)
newJob = IncJob(website=self.website)
newJob.save()
self.jobid = newJob
self.passwordFile = '/home/%s/%s' % (self.website.domain, self.website.domain)
self.repoPath = '/home/%s/incbackup' % (self.website.domain)
if not os.path.exists(self.passwordFile):
password = randomPassword.generate_pass()
command = 'echo "%s" > %s' % (password, self.passwordFile)
ProcessUtilities.executioner(command, self.website.externalApp)
if self.initiateRepo() == 0:
return
if self.prepareBackupMeta() == 0:
return
if websiteData:
if self.backupData() == 0:
return
if websiteDatabases:
if self.backupDatabases() == 0:
return
if websiteEmails:
if self.emailBackup() == 0:
return
## meta generated
logging.statusWriter(self.statusPath, 'Taking backup of meta file, this file can be used to reconstruct at later point..', 1)
metaPathNew = '/home/%s/meta.xml' % (self.website.domain)
if self.backupDestinations == 'local':
command = 'restic -r %s backup %s --password-file %s' % (
self.repoPath, metaPathNew, self.passwordFile)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
elif self.backupDestinations[:4] == 'sftp':
remotePath = '/home/backup/%s' % (self.website.domain)
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (
self.backupDestinations, remotePath, metaPathNew, self.passwordFile, self.repoPath)
result = ProcessUtilities.outputExecutioner(command)
logging.statusWriter(self.statusPath, result, 1)
try:
os.remove(metaPathNew)
except:
pass
logging.statusWriter(self.statusPath, 'Completed', 1)

167
IncBackups/restoreMeta.py Normal file
View File

@@ -0,0 +1,167 @@
#!/usr/local/CyberCP/bin/python2
import os
import os.path
import sys
sys.path.append('/usr/local/CyberCP')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
import django
try:
django.setup()
except:
pass
from websiteFunctions.models import Websites
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
from xml.etree import ElementTree
import plogical.mysqlUtilities as mysqlUtilities
from databases.models import Databases
import argparse
try:
from plogical.virtualHostUtilities import virtualHostUtilities
from plogical.mailUtilities import mailUtilities
except:
pass
class restoreMeta():
@staticmethod
def startRestore(metaPath, statusPath):
try:
## extracting master domain for later use
backupMetaData = ElementTree.parse(metaPath)
masterDomain = backupMetaData.find('masterDomain').text
########### Creating child/sub/addon/parked domains
logging.statusWriter(statusPath, "Creating Child Domains!", 1)
### Restoring Child Domains if any.
childDomains = backupMetaData.findall('ChildDomains/domain')
try:
for childDomain in childDomains:
domain = childDomain.find('domain').text
phpSelection = childDomain.find('phpSelection').text
path = childDomain.find('path').text
virtualHostUtilities.createDomain(masterDomain, domain, phpSelection, path, 0, 0, 0,
'admin', 0)
except BaseException, msg:
logging.writeToFile(str(msg) + " [startRestore]")
return 0
## Restore Aliases
logging.statusWriter(statusPath, "Restoring Domain Aliases!", 1)
aliases = backupMetaData.findall('Aliases/alias')
for items in aliases:
virtualHostUtilities.createAlias(masterDomain, items.text, 0, "", "", "admin")
## Restoring email accounts
logging.statusWriter(statusPath, "Restoring email accounts!", 1)
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)
if result[0] == 0:
logging.statusWriter(statusPath, 'Email existed, updating password according to last snapshot. %s' % (email))
if mailUtilities.changeEmailPassword(email, password, 1)[0] == 0:
logging.statusWriter(statusPath,
'Failed changing password for: %s' % (
email))
else:
logging.statusWriter(statusPath,
'Password changed for: %s' % (
email))
else:
logging.statusWriter(statusPath,
'Email created: %s' % (
email))
except BaseException, msg:
logging.writeToFile(str(msg) + " [startRestore]")
return 0
## Emails restored
## restoring databases
logging.statusWriter(statusPath, "Restoring Databases!", 1)
## Create databases
databases = backupMetaData.findall('Databases/database')
website = Websites.objects.get(domain=masterDomain)
for database in databases:
dbName = database.find('dbName').text
dbUser = database.find('dbUser').text
dbPassword = database.find('password').text
try:
dbExist = Databases.objects.get(dbName=dbName)
logging.statusWriter(statusPath, 'Database exists, changing Database password.. %s' % (dbName))
mysqlUtilities.mysqlUtilities.changePassword(dbUser, dbPassword, 1)
if mysqlUtilities.mysqlUtilities.changePassword(dbUser, dbPassword, 1) == 0:
logging.statusWriter(statusPath, 'Failed changing password for database: %s' % (dbName))
else:
logging.statusWriter(statusPath, 'Password successfully changed for database: %s.' % (dbName))
except:
logging.statusWriter(statusPath, 'Database did not exist, creating new.. %s' % (dbName))
if mysqlUtilities.mysqlUtilities.createDatabase(dbName, dbUser, "cyberpanel") == 0:
logging.statusWriter(statusPath, 'Failed the creation of database: %s' % (dbName))
else:
logging.statusWriter(statusPath, 'Database: %s successfully created.' % (dbName))
try:
newDB = Databases(website=website, dbName=dbName, dbUser=dbUser)
newDB.save()
except:
pass
## Databases restored
try:
os.remove(metaPath)
except:
pass
except BaseException, msg:
logging.writeToFile(str(msg) + " [startRestore]")
def main():
parser = argparse.ArgumentParser(description='CyberPanel Installer')
parser.add_argument('function', help='Specific a function to call!')
parser.add_argument('--metaPath', help='')
parser.add_argument('--statusFile', help='!')
## backup restore arguments
parser.add_argument('--backupFile', help='')
parser.add_argument('--dir', help='')
args = parser.parse_args()
if args.function == "submitRestore":
restoreMeta.startRestore(args.metaPath,args.statusFile)
if __name__ == "__main__":
main()

View File

@@ -6,6 +6,7 @@ app.controller('createIncrementalBackups', function ($scope, $http, $timeout) {
$scope.backupButton = true;
$scope.cyberpanelLoading = true;
$scope.runningBackup = true;
$scope.restoreSt = true;
$scope.fetchDetails = function () {
@@ -123,6 +124,8 @@ app.controller('createIncrementalBackups', function ($scope, $http, $timeout) {
$scope.createBackup = function () {
$scope.status = '';
$scope.cyberpanelLoading = false;
@@ -153,6 +156,12 @@ app.controller('createIncrementalBackups', function ($scope, $http, $timeout) {
if (response.data.status === 1) {
$scope.tempPath = response.data.tempPath;
getBackupStatus();
}else{
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
@@ -169,6 +178,7 @@ app.controller('createIncrementalBackups', function ($scope, $http, $timeout) {
var data = {
backupID: id,
websiteToBeBacked: $scope.websiteToBeBacked
};
var config = {
@@ -188,7 +198,12 @@ app.controller('createIncrementalBackups', function ($scope, $http, $timeout) {
$scope.populateCurrentRecords();
}else{
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
@@ -207,7 +222,8 @@ app.controller('createIncrementalBackups', function ($scope, $http, $timeout) {
url = "/IncrementalBackups/fetchRestorePoints";
var data = {
id: id
id: id,
websiteToBeBacked: $scope.websiteToBeBacked
};
var config = {
@@ -245,6 +261,47 @@ app.controller('createIncrementalBackups', function ($scope, $http, $timeout) {
};
$scope.restorePoint = function (id, reconstruct) {
$scope.status = '';
$scope.cyberpanelLoading = false;
$scope.restoreSt = false;
url = "/IncrementalBackups/restorePoint";
var data = {
websiteToBeBacked: $scope.websiteToBeBacked,
jobid : id,
reconstruct: reconstruct
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.status === 1) {
$scope.tempPath = response.data.tempPath;
getBackupStatus();
}
}
function cantLoadInitialDatas(response) {
}
};
});

View File

@@ -140,7 +140,7 @@
class="btn btn-border btn-alt border-green btn-link font-green"
title=""><span>Restore Points</span></a>
<div id="settings" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-dialog modal-lg">
<!-- Modal content-->
<div class="modal-content">
@@ -149,9 +149,8 @@
&times;
</button>
<h4 class="modal-title">Restore Points
<img id="cyberpanelLoading"
src="/static/images/loading.gif"
style="display: none;">
<img ng-hide="cyberpanelLoading"
src="{% static 'images/loading.gif' %}">
</h4>
</div>
<div class="modal-body">
@@ -173,13 +172,25 @@
<td ng-bind="job.type"></td>
<td ng-bind="job.destination"></td>
<td>
<a class="btn btn-border btn-alt border-green btn-link font-green"
<a ng-click="restorePoint(job.id, 0)" class="btn btn-border btn-alt border-green btn-link font-green"
title=""><span>Restore</span></a>
<a ng-click="restorePoint(job.id, 1)" class="btn btn-border btn-alt border-green btn-link font-green"
title=""><span>Restore and Reconstruct</span></a>
</td>
</tr>
</tbody>
</table>
<div ng-hide="restoreSt" class="form-group">
<div class="col-sm-12">
<div class="col-sm-12">
<textarea ng-model="status"
class="form-control"
rows="7"></textarea>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" ng-disabled="savingSettings"

View File

@@ -12,4 +12,5 @@ urlpatterns = [
url(r'^getBackupStatus$', views.getBackupStatus, name='getBackupStatusInc'),
url(r'^deleteBackup$', views.deleteBackup, name='deleteBackupInc'),
url(r'^fetchRestorePoints$', views.fetchRestorePoints, name='fetchRestorePointsInc'),
url(r'^restorePoint$', views.restorePoint, name='restorePointInc'),
]

View File

@@ -11,7 +11,7 @@ import os
from loginSystem.models import Administrator
from websiteFunctions.models import Websites
from .models import IncJob, JobSnapshots
from .IncBackups import IncJobs
from .IncBackupsControl import IncJobs
from random import randint
import time
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
@@ -68,8 +68,6 @@ def addDestination(request):
data = json.loads(request.body)
if data['type'] == 'SFTP':
ipAddress = data['IPAddress']
@@ -159,9 +157,6 @@ def addDestination(request):
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
@@ -284,12 +279,12 @@ def fetchCurrentBackups(request):
website = Websites.objects.get(domain=backupDomain)
backups = website.incjob_set.all().reverse()
backups = website.incjob_set.all()
json_data = "["
checker = 0
for items in backups:
for items in reversed(backups):
includes = ""
@@ -381,47 +376,50 @@ def submitBackupCreation(request):
def getBackupStatus(request):
try:
userID = request.session['userID']
data = json.loads(request.body)
status = data['tempPath']
backupDomain = data['websiteToBeBacked']
domain = Websites.objects.get(domain=backupDomain)
userID = request.session['userID']
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1:
pass
else:
return ACLManager.loadErrorJson('fetchStatus', 0)
## file name read ends
if os.path.exists(status):
command = "sudo cat " + status
status = ProcessUtilities.outputExecutioner(command, 'cyberpanel')
result = ProcessUtilities.outputExecutioner(command, 'cyberpanel')
if status.find("Completed") > -1:
if result.find("Completed") > -1:
### Removing Files
command = 'sudo rm -f ' + status
ProcessUtilities.executioner(command, 'cyberpanel')
os.remove(status)
final_json = json.dumps(
{'backupStatus': 1, 'error_message': "None", "status": status, "abort": 1})
{'backupStatus': 1, 'error_message': "None", "status": result, "abort": 1})
return HttpResponse(final_json)
elif status.find("[5009]") > -1:
elif result.find("[5009]") > -1:
## removing status file, so that backup can re-run
try:
command = 'sudo rm -f ' + status
ProcessUtilities.executioner(command, 'cyberpanel')
os.remove(status)
except:
pass
final_json = json.dumps(
{'backupStatus': 1, 'error_message': "None", "status": status,
{'backupStatus': 1, 'error_message': "None", "status": result,
"abort": 1})
return HttpResponse(final_json)
else:
final_json = json.dumps(
{'backupStatus': 1, 'error_message': "None", "status": status,
{'backupStatus': 1, 'error_message': "None", "status": result,
"abort": 0})
return HttpResponse(final_json)
else:
@@ -438,11 +436,14 @@ def deleteBackup(request):
try:
userID = request.session['userID']
currentACL = ACLManager.loadedACL(userID)
if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
return ACLManager.loadErrorJson('destStatus', 0)
admin = Administrator.objects.get(pk=userID)
data = json.loads(request.body)
backupDomain = data['websiteToBeBacked']
if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1:
pass
else:
return ACLManager.loadErrorJson('fetchStatus', 0)
id = data['backupID']
@@ -462,6 +463,13 @@ def fetchRestorePoints(request):
userID = request.session['userID']
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
data = json.loads(request.body)
backupDomain = data['websiteToBeBacked']
if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1:
pass
else:
return ACLManager.loadErrorJson('fetchStatus', 0)
data = json.loads(request.body)
id = data['id']
@@ -494,3 +502,42 @@ def fetchRestorePoints(request):
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def restorePoint(request):
try:
userID = request.session['userID']
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
data = json.loads(request.body)
backupDomain = data['websiteToBeBacked']
jobid = data['jobid']
if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1:
pass
else:
return ACLManager.loadErrorJson('metaStatus', 0)
tempPath = "/home/cyberpanel/" + str(randint(1000, 9999))
extraArgs = {}
extraArgs['website'] = backupDomain
extraArgs['jobid'] = jobid
extraArgs['tempPath'] = tempPath
extraArgs['reconstruct'] = data['reconstruct']
startJob = IncJobs('restorePoint', extraArgs)
startJob.start()
time.sleep(2)
final_json = json.dumps({'status': 1, 'error_message': "None", 'tempPath': tempPath})
return HttpResponse(final_json)
except BaseException, msg:
logging.writeToFile(str(msg))
final_dic = {'status': 0, 'metaStatus': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)

View File

@@ -587,6 +587,26 @@
</li>
<li>
<a href="{% url 'loadBackupHome' %}" title="{% trans 'Incremental Back up' %}">
<i class="glyph-icon tooltip-button icon-copy" title=".icon-folder"></i>
<span>{% trans "Incremental Back up" %}</span>
</a>
<div class="sidebar-submenu">
<ul>
<li class="createBackup"><a href="{% url 'createBackupInc' %}"
title="{% trans 'Create Back up' %}"><span>{% trans "Create Back up" %}</span></a>
</li>
<li class="restoreBackup"><a href="{% url 'backupDestinationsInc' %}"
title="{% trans 'Restore Back up' %}"><span>{% trans "Add Destinations" %}</span></a>
</li>
</ul>
</div><!-- .sidebar-submenu -->
</li>
<li>
<a href="{% url 'loadSSLHome' %}" title="{% trans 'Back up' %}">
<i class="glyph-icon tooltip-button icon-lock" title="{% trans 'SSL' %}"></i>

View File

@@ -10,7 +10,7 @@
<div ng-controller="emailDomainPage" class="container">
<div id="page-title">
<h2 ><span id="domainNamePage">{{ domain }}</span> - <a target="_blank" href="http://go.cyberpanel.net/emailLimits" style="height: 23px;line-height: 21px;" class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Emai Limits Docs" %}</span></a></h2>
<h2 ><span id="domainNamePage">{{ domain }}</span> - <a target="_blank" href="http://go.cyberpanel.net/emailLimits" style="height: 23px;line-height: 21px;" class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Email Limits Docs" %}</span></a></h2>
<p>{% trans "View and change email limits for a domain name." %}</p>
</div>

View File

@@ -123,8 +123,8 @@
<div class="form-group">
<div class="input-group">
<select ng-model="languageSelection" class="form-control">
<option selected>English</option>
<select ng-model="languageSelection" ng-init="languageSelection='english'" class="form-control">
<option value="english">English</option>
<option>Chinese</option>
<option>Italian</option>
<option>French</option>

View File

@@ -49,8 +49,7 @@ class CyberCPLogFileWriter:
statusFile.close()
print(mesg + '\n')
except BaseException, msg:
pass
#CyberCPLogFileWriter.writeToFile(str(msg) + ' [statusWriter]')
CyberCPLogFileWriter.writeToFile(str(msg) + ' [statusWriter]')
#print str(msg)

View File

@@ -2,7 +2,6 @@
import os.path
import sys
import django
sys.path.append('/usr/local/CyberCP')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
django.setup()
@@ -713,7 +712,7 @@ class cPanelImporter:
command = "sudo chown -R " + externalApp + ":" + externalApp + " /home/" + self.mainDomain
ProcessUtilities.normalExecutioner(command)
command = "sudo chown -R lscpd:lscpd /home/" + self.mainDomain + "/logs"
command = "sudo chown -R root:nobody /home/" + self.mainDomain + "/logs"
ProcessUtilities.normalExecutioner(command)
command = "sudo find %s -type d -exec chmod 0755 {} \;" % ("/home/" + self.mainDomain + "/public_html")

View File

@@ -180,8 +180,9 @@ class mailUtilities:
return 0
@staticmethod
def changeEmailPassword(email, newPassword):
def changeEmailPassword(email, newPassword, encrypt = None):
try:
if encrypt == None:
CentOSPath = '/etc/redhat-release'
changePass = EUsers.objects.get(email=email)
if os.path.exists(CentOSPath):
@@ -191,6 +192,10 @@ class mailUtilities:
else:
changePass.password = newPassword
changePass.save()
else:
changePass = EUsers.objects.get(email=email)
changePass.password = newPassword
changePass.save()
return 0,'None'
except BaseException, msg:
return 0, str(msg)

View File

@@ -698,7 +698,7 @@ password=%s
return 0
@staticmethod
def changePassword(userName, dbPassword):
def changePassword(userName, dbPassword, encrypt = None):
try:
connection, cursor = mysqlUtilities.setupConnection()
@@ -707,13 +707,15 @@ password=%s
return 0
cursor.execute("use mysql")
if encrypt == None:
try:
dbuser = DBUsers.objects.get(user=userName)
cursor.execute("SET PASSWORD FOR '" + userName + "'@'localhost' = PASSWORD('" + dbPassword + "')")
except:
userName = mysqlUtilities.fetchuser(userName)
cursor.execute("SET PASSWORD FOR '" + userName + "'@'localhost' = PASSWORD('" + dbPassword + "')")
else:
cursor.execute("SET PASSWORD FOR '" + userName + "'@'localhost' = '" + dbPassword + "'")
connection.close()

View File

@@ -191,11 +191,11 @@ class ProcessUtilities(multi.Thread):
if user == None:
logging.writeToFile(ProcessUtilities.token + command)
#logging.writeToFile(ProcessUtilities.token + command)
sock.sendall(ProcessUtilities.token + command)
else:
command = '%s-u %s %s' % (ProcessUtilities.token, user, command)
logging.writeToFile(command)
#logging.writeToFile(command)
command = command.replace('sudo', '')
sock.sendall(command)