diff --git a/IncBackups/static/IncBackups/IncBackups.js b/IncBackups/static/IncBackups/IncBackups.js
index ea8ec296f..a3776ce12 100644
--- a/IncBackups/static/IncBackups/IncBackups.js
+++ b/IncBackups/static/IncBackups/IncBackups.js
@@ -1294,7 +1294,8 @@ app.controller('restorev2backupoage', function ($scope, $http, $timeout, $compil
var data = {
snapshotid: SnapshotId,
path: Path,
- selwebsite: $scope.selwebsite
+ selwebsite: $scope.selwebsite,
+ selectedrepo:$('#reposelectbox').val()
}
var config = {
diff --git a/IncBackups/templates/IncBackups/RestoreV2Backup.html b/IncBackups/templates/IncBackups/RestoreV2Backup.html
index 9e8ed155c..bc75bc74d 100644
--- a/IncBackups/templates/IncBackups/RestoreV2Backup.html
+++ b/IncBackups/templates/IncBackups/RestoreV2Backup.html
@@ -40,6 +40,7 @@
+
diff --git a/IncBackups/views.py b/IncBackups/views.py
index c412e7962..054ea1069 100644
--- a/IncBackups/views.py
+++ b/IncBackups/views.py
@@ -843,6 +843,7 @@ def RestorePathV2(request):
SnapShotId = data['snapshotid']
Path = data['path']
Selectedwebsite = data['selwebsite']
+ Selectedrepo = data['selectedrepo']
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
@@ -852,25 +853,17 @@ def RestorePathV2(request):
else:
return ACLManager.loadError()
- # f'rustic -r testremote snapshots --password "" --json 2>/dev/null'
- # final_json = json.dumps({'status': 0, 'fetchStatus': 1, 'error_message': Selectedrepo })
- # return HttpResponse(final_json)
-
- vm = CPBackupsV2({'domain': Selectedwebsite, 'BackendName': Selectedrepo, "function": ""})
- status, data = vm.FetchSnapShots()
+ vm = CPBackupsV2({'domain': Selectedwebsite, 'BackendName': Selectedrepo, "function": "", 'BasePath': '/home/backup'})
+ status = vm.InitiateRestore(SnapShotId, Path)
if status == 1:
- final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": data})
+ final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None"})
return HttpResponse(final_json)
else:
# final_json = json.dumps({'status': 0, 'fetchStatus': 1, 'error_message': ac,})
final_json = json.dumps({'status': 0, 'fetchStatus': 1, 'error_message': 'Cannot Find!', })
return HttpResponse(final_json)
- final_dic = {'status': 1, 'SnapShotId': SnapShotId, 'Path': Path}
- final_json = json.dumps(final_dic)
- return HttpResponse(final_json)
-
except BaseException as msg:
final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
diff --git a/plogical/Backupsv2.py b/plogical/Backupsv2.py
index ae02f6635..a9c1bdc68 100644
--- a/plogical/Backupsv2.py
+++ b/plogical/Backupsv2.py
@@ -60,6 +60,12 @@ class CPBackupsV2(multi.Thread):
##
self.StatusFile = f'/home/cyberpanel/{self.website.domain}_rustic_backup_log'
+ self.StatusFile_Restore = f'/home/cyberpanel/{self.website.domain}_rustic_backup_log_Restore'
+
+ ## restore or backup?
+
+ self.restore = 0
+
if os.path.exists(self.StatusFile):
os.remove(self.StatusFile)
@@ -629,7 +635,12 @@ token = {token}
#### Resote Functions
- def InitiateRestore(self):
+ def InitiateRestore(self, snapshotid, path):
+
+ ### if restore then status file should be restore status file
+
+ self.restore = 1
+ self.StatusFile = self.StatusFile_Restore
from websiteFunctions.models import Websites, Backupsv2
from django.forms.models import model_to_dict
@@ -663,42 +674,14 @@ token = {token}
self.CurrentFreeSpaceOnDisk = int(ProcessUtilities.outputExecutioner("df -m / | awk 'NR==2 {print $4}'", 'root', True).rstrip('\n'))
if self.WebsiteDiskUsage > self.CurrentFreeSpaceOnDisk:
- self.UpdateStatus(f'Not enough disk space on the server to backup this website.', CPBackupsV2.FAILED)
+ self.UpdateStatus(f'Not enough disk space on the server to restore this website.', CPBackupsV2.FAILED)
return 0
- ### Before doing anything install rustic
-
- statusRes, message = self.InstallRustic()
-
- if statusRes == 0:
- self.UpdateStatus(f'Failed to install Rustic, error: {message}', CPBackupsV2.FAILED)
- return 0
-
-
- # = Backupsv2(website=self.website, fileName='backup-' + self.data['domain'] + "-" + time.strftime("%m.%d.%Y_%H-%M-%S"), status=CPBackupsV2.RUNNING, BasePath=self.data['BasePath'])
- #self.buv2.save()
-
- #self.FinalPath = f"{self.data['BasePath']}/{self.buv2.fileName}"
-
### Rustic backup final path
self.FinalPathRuctic = f"{self.data['BasePath']}/{self.website.domain}"
- #command = f"mkdir -p {self.FinalPath}"
- #ProcessUtilities.executioner(command)
-
-
-
- #command = f"chown {website.externalApp}:{website.externalApp} {self.FinalPath}"
- #ProcessUtilities.executioner(command)
-
- #command = f'chown cyberpanel:cyberpanel {self.FinalPath}'
- #ProcessUtilities.executioner(command)
-
- #command = f"chmod 711 {self.FinalPath}"
- #ProcessUtilities.executioner(command)
-
command = f"mkdir -p {self.FinalPathRuctic}"
ProcessUtilities.executioner(command)
@@ -708,151 +691,29 @@ token = {token}
command = f"chmod 711 {self.FinalPathRuctic}"
ProcessUtilities.executioner(command)
- try:
+ ### Find Restore path first, if path is db, only then restore it to cp
- self.UpdateStatus('Creating backup config,0', CPBackupsV2.RUNNING)
+ if path.find('.sql') > -1:
+ mysqlUtilities.restoreDatabaseBackup(path.rstrip('.sql'), None, None, None, None, 1, self.repo, self.website.externalApp, snapshotid)
+ else:
- Config = {'MainWebsite': model_to_dict(self.website, fields=['domain', 'adminEmail', 'phpSelection', 'state', 'config'])}
- Config['admin'] = model_to_dict(self.website.admin, fields=['userName', 'password', 'firstName', 'lastName',
- 'email', 'type', 'owner', 'token', 'api', 'securityLevel',
- 'state', 'initself.websitesLimit', 'twoFA', 'secretKey', 'config'])
- Config['acl'] = model_to_dict(self.website.admin.acl)
+ if path.find('/home/vmail') > -1:
+ externalApp = None
+ else:
+ externalApp = self.website.externalApp
- ### Child domains to config
+ command = f'rustic -r {self.repo} restore {snapshotid}:{path} {path} --password "" --json 2>/dev/null'
+ result = ProcessUtilities.outputExecutioner(command, externalApp, True)
- ChildsList = []
+ if os.path.exists(ProcessUtilities.debugPath):
+ logging.CyberCPLogFileWriter.writeToFile(result)
- for childDomains in self.website.childdomains_set.all():
- print(childDomains.domain)
- ChildsList.append(model_to_dict(childDomains))
+ self.UpdateStatus('Completed', CPBackupsV2.COMPLETED)
- Config['ChildDomains'] = ChildsList
+ return 1
- #print(str(Config))
- ### Databases
- connection, cursor = mysqlUtilities.setupConnection()
-
- if connection == 0:
- return 0
-
- dataBases = self.website.databases_set.all()
- DBSList = []
-
- for db in dataBases:
-
- query = f"SELECT host,user FROM mysql.db WHERE db='{db.dbName}';"
- cursor.execute(query)
- DBUsers = cursor.fetchall()
-
- UserList = []
-
- for databaseUser in DBUsers:
- query = f"SELECT password FROM `mysql`.`user` WHERE `Host`='{databaseUser[0]}' AND `User`='{databaseUser[1]}';"
- cursor.execute(query)
- resp = cursor.fetchall()
- print(resp)
- UserList.append({'user': databaseUser[1], 'host': databaseUser[0], 'password': resp[0][0]})
-
- DBSList.append({db.dbName: UserList})
-
- Config['databases'] = DBSList
-
- WPSitesList = []
-
- for wpsite in self.website.wpsites_set.all():
- WPSitesList.append(model_to_dict(wpsite,fields=['title', 'path', 'FinalURL', 'AutoUpdates', 'PluginUpdates', 'ThemeUpdates', 'WPLockState']))
-
- Config['WPSites'] = WPSitesList
- self.config = Config
-
- ### DNS Records
-
- from dns.models import Domains
-
- self.dnsDomain = Domains.objects.get(name=self.website.domain)
-
- DNSRecords = []
-
- for record in self.dnsDomain.records_set.all():
- DNSRecords.append(model_to_dict(record))
-
- Config['MainDNSDomain'] = model_to_dict(self.dnsDomain)
- Config['DNSRecords'] = DNSRecords
-
- ### Email accounts
-
- try:
- from mailServer.models import Domains
-
- self.emailDomain = Domains.objects.get(domain=self.website.domain)
-
- EmailAddrList = []
-
- for record in self.emailDomain.eusers_set.all():
- EmailAddrList.append(model_to_dict(record))
-
- Config['MainEmailDomain'] = model_to_dict(self.emailDomain)
- Config['EmailAddresses'] = EmailAddrList
- except:
- pass
-
- #command = f"echo '{json.dumps(Config)}' > {self.FinalPath}/config.json"
- #ProcessUtilities.executioner(command, self.website.externalApp, True)
-
- command = f'chown cyberpanel:cyberpanel {self.FinalPathRuctic}/config.json'
- ProcessUtilities.executioner(command)
-
- WriteToFile = open(f'{self.FinalPathRuctic}/config.json', 'w')
- WriteToFile.write(json.dumps(Config))
- WriteToFile.close()
-
- command = f"chmod 600 {self.FinalPathRuctic}/config.json"
- ProcessUtilities.executioner(command)
-
- if self.BackupConfig() == 0:
- return 0
-
- self.UpdateStatus('Backup config created,5', CPBackupsV2.RUNNING)
- except BaseException as msg:
- self.UpdateStatus(f'Failed during config generation, Error: {str(msg)}', CPBackupsV2.FAILED)
- return 0
-
- try:
- if self.data['BackupDatabase']:
- self.UpdateStatus('Backing up databases..,10', CPBackupsV2.RUNNING)
- if self.BackupDataBasesRustic() == 0:
- self.UpdateStatus(f'Failed to create backup for databases.', CPBackupsV2.FAILED)
- return 0
-
- self.UpdateStatus('Database backups completed successfully..,25', CPBackupsV2.RUNNING)
-
- if self.data['BackupData']:
- self.UpdateStatus('Backing up website data..,30', CPBackupsV2.RUNNING)
- if self.BackupRustic() == 0:
- return 0
- self.UpdateStatus('Website data backup completed successfully..,70', CPBackupsV2.RUNNING)
-
- if self.data['BackupEmails']:
- self.UpdateStatus('Backing up emails..,75', CPBackupsV2.RUNNING)
- if self.BackupEmailsRustic() == 0:
- return 0
- self.UpdateStatus('Emails backup completed successfully..,85', CPBackupsV2.RUNNING)
-
- ### Finally change the backup rustic folder to the website user owner
-
- command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}'
- ProcessUtilities.executioner(command)
-
- self.MergeSnapshots()
-
- self.UpdateStatus('Completed', CPBackupsV2.COMPLETED)
-
- break
- except BaseException as msg:
- self.UpdateStatus(f'Failed, Error: {str(msg)}', CPBackupsV2.FAILED)
- return 0
else:
time.sleep(5)
diff --git a/plogical/mysqlUtilities.py b/plogical/mysqlUtilities.py
index 2be4a3cec..1b22713fc 100755
--- a/plogical/mysqlUtilities.py
+++ b/plogical/mysqlUtilities.py
@@ -339,7 +339,7 @@ password=%s
return 0
@staticmethod
- def restoreDatabaseBackup(databaseName, tempStoragePath, dbPassword, passwordCheck = None, additionalName = None):
+ def restoreDatabaseBackup(databaseName, tempStoragePath, dbPassword, passwordCheck = None, additionalName = None, rustic=0, RusticRepoName = None, externalApp = None, snapshotid = None):
try:
passFile = "/etc/cyberpanel/mysqlPassword"
@@ -379,38 +379,47 @@ password=%s
command = 'chown cyberpanel:cyberpanel %s' % (cnfPath)
subprocess.call(shlex.split(command))
- command = 'mysql --defaults-extra-file=/home/cyberpanel/.my.cnf -u %s --host=%s --port %s %s' % (mysqluser, mysqlhost, mysqlport, databaseName)
- if os.path.exists(ProcessUtilities.debugPath):
- logging.CyberCPLogFileWriter.writeToFile(f'{command} {tempStoragePath}/{databaseName} ' )
- cmd = shlex.split(command)
+ if rustic == 0:
- if additionalName == None:
- with open(tempStoragePath + "/" + databaseName + '.sql', 'r') as f:
- res = subprocess.call(cmd, stdin=f)
- if res != 0:
- logging.CyberCPLogFileWriter.writeToFile("Could not restore MYSQL database: " + databaseName +"! [restoreDatabaseBackup]")
- return 0
+ command = 'mysql --defaults-extra-file=/home/cyberpanel/.my.cnf -u %s --host=%s --port %s %s' % (mysqluser, mysqlhost, mysqlport, databaseName)
+ if os.path.exists(ProcessUtilities.debugPath):
+ logging.CyberCPLogFileWriter.writeToFile(f'{command} {tempStoragePath}/{databaseName} ' )
+ cmd = shlex.split(command)
+
+ if additionalName == None:
+ with open(tempStoragePath + "/" + databaseName + '.sql', 'r') as f:
+ res = subprocess.call(cmd, stdin=f)
+ if res != 0:
+ logging.CyberCPLogFileWriter.writeToFile("Could not restore MYSQL database: " + databaseName +"! [restoreDatabaseBackup]")
+ return 0
+ else:
+ with open(tempStoragePath + "/" + additionalName + '.sql', 'r') as f:
+ res = subprocess.call(cmd, stdin=f)
+
+ if res != 0:
+ logging.CyberCPLogFileWriter.writeToFile("Could not restore MYSQL database: " + additionalName + "! [restoreDatabaseBackup]")
+ return 0
+
+ if passwordCheck == None:
+
+ connection, cursor = mysqlUtilities.setupConnection()
+
+ if connection == 0:
+ return 0
+
+ passwordCMD = "use mysql;SET PASSWORD FOR '" + databaseName + "'@'%s' = '" % (mysqlUtilities.LOCALHOST) + dbPassword + "';FLUSH PRIVILEGES;"
+
+ cursor.execute(passwordCMD)
+ connection.close()
+
+ return 1
else:
- with open(tempStoragePath + "/" + additionalName + '.sql', 'r') as f:
- res = subprocess.call(cmd, stdin=f)
+ command = f'sudo -u {externalApp} rustic -r {RusticRepoName} dump {snapshotid}:{databaseName}.sql --password "" 2>/dev/null | mysql --defaults-extra-file=/home/cyberpanel/.my.cnf -u %s --host=%s --port %s %s' % (
+ mysqluser, mysqlhost, mysqlport, databaseName)
+ if os.path.exists(ProcessUtilities.debugPath):
+ logging.CyberCPLogFileWriter.writeToFile(f'{command} {tempStoragePath}/{databaseName} ')
+ ProcessUtilities.outputExecutioner(command, None, True)
- if res != 0:
- logging.CyberCPLogFileWriter.writeToFile("Could not restore MYSQL database: " + additionalName + "! [restoreDatabaseBackup]")
- return 0
-
- if passwordCheck == None:
-
- connection, cursor = mysqlUtilities.setupConnection()
-
- if connection == 0:
- return 0
-
- passwordCMD = "use mysql;SET PASSWORD FOR '" + databaseName + "'@'%s' = '" % (mysqlUtilities.LOCALHOST) + dbPassword + "';FLUSH PRIVILEGES;"
-
- cursor.execute(passwordCMD)
- connection.close()
-
- return 1
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + "[restoreDatabaseBackup]")
return 0