bug fix: backups to rustic

This commit is contained in:
usman@cyberpersons.com 2023-04-01 23:49:04 +05:00
parent 0ae3c01c5c
commit 37972efbcc
3 changed files with 244 additions and 7 deletions

View File

@ -1241,7 +1241,7 @@ app.controller('restorev2backupoage', function ($scope, $http, $timeout, $compil
option.value = 1;
option.text = 'Choose Repooo';
option.text = 'Choose Repo';
selectBox.appendChild(option);
@ -1478,7 +1478,7 @@ app.controller('CreateV2Backup', function ($scope, $http, $timeout, $compile) {
option.value = 1;
option.text = 'Choose Repooo';
option.text = 'Choose Repo';
selectBox.appendChild(option);

View File

@ -1,6 +1,6 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Create V2 Backup" %}{% endblock %}
{% block title %}{% trans "Create v2 Backup" %}{% endblock %}
{% block content %}
{% load static %}
@ -13,14 +13,14 @@
<div class="container">
<div id="page-title">
<h2>{% trans "Create V2 Backup Site" %} - <a target="_blank" href="http://go.cyberpanel.net/backup" style="height: 23px;line-height: 21px;" class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Backup Docs" %}</span></a></h2>
<p>{% trans "This page can be used to create your backup sites" %}</p>
<h2>{% trans "Create V2 Backup" %} - <a target="_blank" href="http://go.cyberpanel.net/backup" style="height: 23px;line-height: 21px;" class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Backup Docs" %}</span></a></h2>
<p>{% trans "This page can be used to create your backup" %}</p>
</div>
<div ng-controller="CreateV2Backup" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Create V2 Backup Site" %} <img ng-hide="backupLoading" src="{% static 'images/loading.gif' %}">
{% trans "Create v2 Backup" %} <img ng-hide="backupLoading" src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
@ -41,7 +41,6 @@
<label class="col-sm-3 control-label">{% trans "Select Repo" %} </label>
<div class="col-sm-6">
<select id="reposelectbox" ng-change="selectrepo()" ng-model="testhabbi" class="form-control">
</select>
</div>
</div>

View File

@ -623,6 +623,242 @@ token = {token}
return 1
#### Resote Functions
def InitiateRestore(self):
from websiteFunctions.models import Websites, Backupsv2
from django.forms.models import model_to_dict
from plogical.mysqlUtilities import mysqlUtilities
self.website = Websites.objects.get(domain=self.data['domain'])
## Base path is basically the path set by user where all the backups will be housed
if not os.path.exists(self.data['BasePath']):
command = f"mkdir -p {self.data['BasePath']}"
ProcessUtilities.executioner(command)
command = f"chmod 711 {self.data['BasePath']}"
ProcessUtilities.executioner(command)
self.StartingTimeStamp = CPBackupsV2.FetchCurrentTimeStamp()
### Init rustic repo in main func so dont need to do again and again
while(1):
self.website = Websites.objects.get(domain=self.data['domain'])
if self.website.BackupLock == 0:
Disk1 = f"du -sm /home/{self.website.domain}/"
Disk2 = "2>/dev/null | awk '{print $1}'"
self.WebsiteDiskUsage = int(ProcessUtilities.outputExecutioner(f"{Disk1} {Disk2}", 'root', True).rstrip('\n'))
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)
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)
command = f'chown cyberpanel:cyberpanel {self.FinalPathRuctic}'
ProcessUtilities.executioner(command)
command = f"chmod 711 {self.FinalPathRuctic}"
ProcessUtilities.executioner(command)
try:
self.UpdateStatus('Creating backup config,0', CPBackupsV2.RUNNING)
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)
### Child domains to config
ChildsList = []
for childDomains in self.website.childdomains_set.all():
print(childDomains.domain)
ChildsList.append(model_to_dict(childDomains))
Config['ChildDomains'] = ChildsList
#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)
### If website lock is there for more then 20 minutes it means old backup is stucked or backup job failed, thus continue backup
if float(CPBackupsV2.FetchCurrentTimeStamp()) > (float(self.StartingTimeStamp) + 1200):
self.website = Websites.objects.get(domain=self.data['domain'])
self.website.BackupLock = 0
self.website.save()
# def BackupEmails(self):
#
# ### This function will backup emails of the website, also need to take care of emails that we need to exclude
@ -744,6 +980,8 @@ token = {token}
print('Error: %s'%msg)
return 0, str(msg)
if __name__ == "__main__":
try:
parser = argparse.ArgumentParser(description='CyberPanel Backup Generator')