Skip to content

Commit 71c97e0

Browse files
committed
incremental backup: exclude repo folder
1 parent 683ada6 commit 71c97e0

File tree

7 files changed

+763
-221
lines changed

7 files changed

+763
-221
lines changed

.idea/workspace.xml

+240-168
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

IncBackups/IncBackupsControl.py

+109-31
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
import os
33
import os.path
44
import sys
5+
56
sys.path.append('/usr/local/CyberCP')
67
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
78

89
import django
10+
911
try:
1012
django.setup()
1113
except:
@@ -25,12 +27,16 @@
2527
from plogical.dnsUtilities import DNS
2628
from mailServer.models import Domains as eDomains
2729
from random import randint
30+
import json
31+
from django.shortcuts import HttpResponse
32+
2833
try:
2934
from plogical.virtualHostUtilities import virtualHostUtilities
3035
from plogical.mailUtilities import mailUtilities
3136
except:
3237
pass
3338

39+
3440
class IncJobs(multi.Thread):
3541

3642
def __init__(self, function, extraArgs):
@@ -51,29 +57,97 @@ def run(self):
5157
self.createBackup()
5258
elif self.function == 'restorePoint':
5359
self.restorePoint()
60+
elif self.function == 'remoteRestore':
61+
self.restorePoint()
62+
63+
def getRemoteBackups(self):
64+
if self.jobid.destination == 'local':
65+
path = '/home/%s/incbackup' % (self.website)
66+
command = 'export RESTIC_PASSWORD=%s && restic -r %s snapshots' % (self.passwordFile, path)
67+
return ProcessUtilities.outputExecutioner(command).split('\n')
68+
elif self.jobid.destination[:4] == 'sftp':
69+
path = '/home/backup/%s' % (self.website)
70+
command = 'export RESTIC_PASSWORD=%s PATH=${PATH}:/usr/bin && restic -r %s:%s snapshots' % (
71+
self.passwordFile, self.backupDestinations, path)
72+
return ProcessUtilities.outputExecutioner(command).split('\n')
73+
else:
74+
path = '/home/%s/incbackup' % (self.website)
75+
command = 'export RESTIC_PASSWORD=%s && restic -r %s snapshots' % (self.passwordFile, path)
76+
return ProcessUtilities.outputExecutioner(command).split('\n')
77+
78+
def fetchCurrentBackups(self):
79+
try:
80+
self.website = self.extraArgs['website']
81+
self.backupDestinations = self.extraArgs['backupDestinations']
82+
self.passwordFile = self.extraArgs['password']
83+
84+
remotePath = '/home/backup/%s' % (self.website)
85+
86+
command = 'export RESTIC_PASSWORD=%s PATH=${PATH}:/usr/bin && restic -r %s:%s snapshots' % (
87+
self.passwordFile, self.backupDestinations, remotePath)
88+
result = ProcessUtilities.outputExecutioner(command).split('\n')
89+
90+
activator = 0
91+
json_data = "["
92+
checker = 0
93+
94+
for items in result:
95+
if items.find('---------------') > -1:
96+
if activator == 0:
97+
activator = 1
98+
continue
99+
else:
100+
activator = 0
101+
102+
if activator:
103+
entry = items.split(' ')
104+
logging.writeToFile(str(entry))
105+
106+
dic = {'id': entry[0],
107+
'date': "%s %s" % (entry[2], entry[3]),
108+
'host': entry[5],
109+
'path': entry[-1]
110+
}
111+
112+
if checker == 0:
113+
json_data = json_data + json.dumps(dic)
114+
checker = 1
115+
else:
116+
json_data = json_data + ',' + json.dumps(dic)
117+
118+
json_data = json_data + ']'
119+
final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data})
120+
return HttpResponse(final_json)
121+
122+
except BaseException, msg:
123+
logging.writeToFile(str(msg))
124+
125+
####
54126

55127
def getAWSData(self):
56128
key = self.backupDestinations.split('/')[-1]
57129
path = '/home/cyberpanel/aws/%s' % (key)
58130
secret = open(path, 'r').read()
59131
return key, secret
60132

61-
def awsFunction(self, fType, backupPath = None, snapshotID = None, bType = None):
133+
def awsFunction(self, fType, backupPath=None, snapshotID=None, bType=None):
62134
try:
63135
if fType == 'backup':
64136
key, secret = self.getAWSData()
65137
command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s backup %s --password-file %s' % (
66-
key, secret, self.website.domain, backupPath, self.passwordFile)
138+
key, secret, self.website.domain, backupPath, self.passwordFile)
67139
result = ProcessUtilities.outputExecutioner(command)
68140
logging.statusWriter(self.statusPath, result, 1)
69141
snapShotid = result.split(' ')[-2]
70142
if bType == 'database':
71-
newSnapshot = JobSnapshots(job=self.jobid, type='%s:%s' % (bType, backupPath.split('/')[-1].strip('.sql')),
143+
newSnapshot = JobSnapshots(job=self.jobid,
144+
type='%s:%s' % (bType, backupPath.split('/')[-1].strip('.sql')),
72145
snapshotid=snapShotid,
73146
destination=self.backupDestinations)
74147
else:
75-
newSnapshot = JobSnapshots(job=self.jobid, type='%s:%s' % (bType, backupPath), snapshotid=snapShotid,
76-
destination=self.backupDestinations)
148+
newSnapshot = JobSnapshots(job=self.jobid, type='%s:%s' % (bType, backupPath),
149+
snapshotid=snapShotid,
150+
destination=self.backupDestinations)
77151
newSnapshot.save()
78152
else:
79153
self.backupDestinations = self.jobid.destination
@@ -88,9 +162,9 @@ def awsFunction(self, fType, backupPath = None, snapshotID = None, bType = None)
88162
logging.statusWriter(self.statusPath, "%s [88][5009]" % (str(msg)), 1)
89163
return 0
90164

91-
def localFunction(self, backupPath, type, restore = None):
165+
def localFunction(self, backupPath, type, restore=None):
92166
if restore == None:
93-
command = 'restic -r %s backup %s --password-file %s' % (self.repoPath, backupPath, self.passwordFile)
167+
command = 'restic -r %s backup %s --password-file %s --exclude %s' % (self.repoPath, backupPath, self.passwordFile, self.repoPath)
94168
result = ProcessUtilities.outputExecutioner(command)
95169
logging.statusWriter(self.statusPath, result, 1)
96170
snapShotid = result.split(' ')[-2]
@@ -107,11 +181,11 @@ def localFunction(self, backupPath, type, restore = None):
107181
else:
108182
repoLocation = '/home/%s/incbackup' % (self.website)
109183
command = 'restic -r %s restore %s --target / --password-file %s' % (
110-
repoLocation, self.jobid.snapshotid, self.passwordFile)
184+
repoLocation, self.jobid.snapshotid, self.passwordFile)
111185
result = ProcessUtilities.outputExecutioner(command)
112186
logging.statusWriter(self.statusPath, result, 1)
113187

114-
def sftpFunction(self, backupPath, type, restore = None):
188+
def sftpFunction(self, backupPath, type, restore=None):
115189
if restore == None:
116190
remotePath = '/home/backup/%s' % (self.website.domain)
117191
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (
@@ -132,7 +206,7 @@ def sftpFunction(self, backupPath, type, restore = None):
132206
else:
133207
repoLocation = '/home/backup/%s' % (self.website)
134208
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s restore %s --target / --password-file %s' % (
135-
self.jobid.destination, repoLocation, self.jobid.snapshotid, self.passwordFile)
209+
self.jobid.destination, repoLocation, self.jobid.snapshotid, self.passwordFile)
136210
result = ProcessUtilities.outputExecutioner(command)
137211
logging.statusWriter(self.statusPath, result, 1)
138212

@@ -160,7 +234,8 @@ def restoreDatabase(self):
160234
else:
161235
self.awsFunction('restore', '', self.jobid.snapshotid)
162236

163-
if mysqlUtilities.mysqlUtilities.restoreDatabaseBackup(self.jobid.type.split(':')[1].rstrip('.sql'), '/home/cyberpanel', 'dummy', 'dummy') == 0:
237+
if mysqlUtilities.mysqlUtilities.restoreDatabaseBackup(self.jobid.type.split(':')[1].rstrip('.sql'),
238+
'/home/cyberpanel', 'dummy', 'dummy') == 0:
164239
raise BaseException
165240

166241
try:
@@ -189,7 +264,6 @@ def restoreEmail(self):
189264
def reconstructWithMeta(self):
190265
try:
191266

192-
193267
if self.jobid.destination == 'local':
194268
self.localFunction('none', 'none', 1)
195269
elif self.jobid.destination[:4] == 'sftp':
@@ -219,7 +293,6 @@ def restorePoint(self):
219293
logging.statusWriter(self.statusPath, message, 1)
220294
self.passwordFile = '/home/%s/%s' % (self.website, self.website)
221295

222-
223296
##
224297

225298
if self.jobid.type[:8] == 'database':
@@ -433,10 +506,11 @@ def backupData(self):
433506
else:
434507
self.awsFunction('backup', backupPath, '', 'data')
435508

436-
logging.statusWriter(self.statusPath, 'Data for %s backed to %s.' % (self.website.domain, self.backupDestinations), 1)
509+
logging.statusWriter(self.statusPath,
510+
'Data for %s backed to %s.' % (self.website.domain, self.backupDestinations), 1)
437511
return 1
438512
except BaseException, msg:
439-
logging.statusWriter(self.statusPath,'%s. [IncJobs.backupData.223][5009]' % str(msg), 1)
513+
logging.statusWriter(self.statusPath, '%s. [IncJobs.backupData.223][5009]' % str(msg), 1)
440514
return 0
441515

442516
def backupDatabases(self):
@@ -461,10 +535,11 @@ def backupDatabases(self):
461535
try:
462536
os.remove('/home/cyberpanel/%s.sql' % (items.dbName))
463537
except BaseException, msg:
464-
logging.statusWriter(self.statusPath,'Failed to delete database: %s. [IncJobs.backupDatabases.456]' % str(msg), 1)
538+
logging.statusWriter(self.statusPath,
539+
'Failed to delete database: %s. [IncJobs.backupDatabases.456]' % str(msg), 1)
465540
return 1
466541
except BaseException, msg:
467-
logging.statusWriter(self.statusPath,'%s. [IncJobs.backupDatabases.269][5009]' % str(msg), 1)
542+
logging.statusWriter(self.statusPath, '%s. [IncJobs.backupDatabases.269][5009]' % str(msg), 1)
468543
return 0
469544

470545
def emailBackup(self):
@@ -480,11 +555,11 @@ def emailBackup(self):
480555
else:
481556
self.awsFunction('backup', backupPath, '', 'email')
482557

483-
484-
logging.statusWriter(self.statusPath, 'Emails for %s backed to %s.' % (self.website.domain, self.backupDestinations), 1)
558+
logging.statusWriter(self.statusPath,
559+
'Emails for %s backed to %s.' % (self.website.domain, self.backupDestinations), 1)
485560
return 1
486561
except BaseException, msg:
487-
logging.statusWriter(self.statusPath,'%s. [IncJobs.emailBackup.269][5009]' % str(msg), 1)
562+
logging.statusWriter(self.statusPath, '%s. [IncJobs.emailBackup.269][5009]' % str(msg), 1)
488563
return 0
489564

490565
def metaBackup(self):
@@ -500,11 +575,11 @@ def metaBackup(self):
500575
else:
501576
self.awsFunction('backup', backupPath, '', 'meta')
502577

503-
504-
logging.statusWriter(self.statusPath, 'Meta for %s backed to %s.' % (self.website.domain, self.backupDestinations), 1)
578+
logging.statusWriter(self.statusPath,
579+
'Meta for %s backed to %s.' % (self.website.domain, self.backupDestinations), 1)
505580
return 1
506581
except BaseException, msg:
507-
logging.statusWriter(self.statusPath,'%s. [IncJobs.metaBackup.269][5009]' % str(msg), 1)
582+
logging.statusWriter(self.statusPath, '%s. [IncJobs.metaBackup.269][5009]' % str(msg), 1)
508583
return 0
509584

510585
def initiateRepo(self):
@@ -518,20 +593,23 @@ def initiateRepo(self):
518593

519594
elif self.backupDestinations[:4] == 'sftp':
520595
remotePath = '/home/backup/%s' % (self.website.domain)
521-
command = 'export PATH=${PATH}:/usr/bin && restic init --repo %s:%s --password-file %s' % (self.backupDestinations, remotePath, self.passwordFile)
596+
command = 'export PATH=${PATH}:/usr/bin && restic init --repo %s:%s --password-file %s' % (
597+
self.backupDestinations, remotePath, self.passwordFile)
522598
result = ProcessUtilities.outputExecutioner(command)
523599
logging.statusWriter(self.statusPath, result, 1)
524600
else:
525-
key,secret = self.getAWSData()
526-
command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s init --password-file %s' % (key, secret, self.website.domain, self.passwordFile)
601+
key, secret = self.getAWSData()
602+
command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s init --password-file %s' % (
603+
key, secret, self.website.domain, self.passwordFile)
527604
result = ProcessUtilities.outputExecutioner(command)
528605
logging.statusWriter(self.statusPath, result, 1)
529606
return 1
530607

531-
logging.statusWriter(self.statusPath, 'Repo %s initiated for %s.' % (self.backupDestinations, self.website.domain), 1)
608+
logging.statusWriter(self.statusPath,
609+
'Repo %s initiated for %s.' % (self.backupDestinations, self.website.domain), 1)
532610
return 1
533611
except BaseException, msg:
534-
logging.statusWriter(self.statusPath,'%s. [IncJobs.initiateRepo.47][5009]' % str(msg), 1)
612+
logging.statusWriter(self.statusPath, '%s. [IncJobs.initiateRepo.47][5009]' % str(msg), 1)
535613
return 0
536614

537615
def createBackup(self):
@@ -562,7 +640,6 @@ def createBackup(self):
562640
command = 'chmod 600 %s' % (self.passwordFile)
563641
ProcessUtilities.executioner(command)
564642

565-
566643
if self.initiateRepo() == 0:
567644
return
568645

@@ -589,6 +666,7 @@ def createBackup(self):
589666
command = 'rm -f %s' % (metaPathNew)
590667
ProcessUtilities.executioner(command)
591668
except BaseException, msg:
592-
logging.statusWriter(self.statusPath,'Failed to delete meta file: %s. [IncJobs.createBackup.591]' % str(msg), 1)
669+
logging.statusWriter(self.statusPath,
670+
'Failed to delete meta file: %s. [IncJobs.createBackup.591]' % str(msg), 1)
593671

594-
logging.statusWriter(self.statusPath, 'Completed', 1)
672+
logging.statusWriter(self.statusPath, 'Completed', 1)

0 commit comments

Comments
 (0)