mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-10 23:36:11 +01:00
finish adding schedules from ui
This commit is contained in:
@@ -1299,6 +1299,7 @@ app.controller('restorev2backupoage', function ($scope, $http, $timeout, $compil
|
||||
|
||||
|
||||
}
|
||||
|
||||
function getCreationStatus() {
|
||||
|
||||
url = "/IncrementalBackups/CreateV2BackupStatus";
|
||||
@@ -1377,6 +1378,7 @@ app.controller('restorev2backupoage', function ($scope, $http, $timeout, $compil
|
||||
|
||||
|
||||
}
|
||||
|
||||
$scope.RestorePathV2 = function (SnapshotId, Path) {
|
||||
|
||||
SnapshotId = document.getElementById('Snapshot_id').innerText
|
||||
@@ -1859,3 +1861,376 @@ function listpaths(pathid, button) {
|
||||
}
|
||||
}
|
||||
|
||||
app.controller('ScheduleV2Backup', function ($scope, $http, $timeout, $compile) {
|
||||
|
||||
|
||||
$scope.backupLoading = true;
|
||||
$scope.installationProgress = true;
|
||||
$scope.errorMessageBox = true;
|
||||
$scope.success = true;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.goBackDisable = true;
|
||||
|
||||
var repoG, frequencyG, websiteDataG, websiteDatabasesG, websiteEmailsG;
|
||||
|
||||
$scope.deleteBackupInitialv2 = function (repo, frequency, websiteData, websiteDatabases, websiteEmails) {
|
||||
repoG = repo;
|
||||
frequencyG = frequency;
|
||||
websiteDataG = websiteData;
|
||||
websiteDatabasesG = websiteDatabases;
|
||||
websiteEmailsG = websiteEmails;
|
||||
}
|
||||
|
||||
$scope.DeleteScheduleV2 = function () {
|
||||
$scope.backupLoading = false;
|
||||
// document.getElementById('CreateV2BackupButton').style.display = "block";
|
||||
var url = "/IncrementalBackups/DeleteScheduleV2";
|
||||
|
||||
var data = {
|
||||
Selectedwebsite: $scope.selwebsite,
|
||||
repo: repoG,
|
||||
frequency: frequencyG,
|
||||
websiteData: websiteDataG,
|
||||
websiteDatabases: websiteDatabasesG,
|
||||
websiteEmails: websiteEmailsG
|
||||
};
|
||||
//alert( $scope.selwebsite);
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.backupLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
$scope.selectwebsite();
|
||||
new PNotify({
|
||||
title: 'Success!',
|
||||
text: 'Successfully deleted.',
|
||||
type: 'success'
|
||||
});
|
||||
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.backupLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$scope.selectwebsite = function () {
|
||||
document.getElementById('reposelectbox').innerHTML = "";
|
||||
$scope.backupLoading = false;
|
||||
// document.getElementById('CreateV2BackupButton').style.display = "block";
|
||||
var url = "/IncrementalBackups/selectwebsiteCreatev2";
|
||||
|
||||
var data = {
|
||||
Selectedwebsite: $scope.selwebsite,
|
||||
Selectedrepo: $('#reposelectbox').val(),
|
||||
};
|
||||
//alert( $scope.selwebsite);
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.backupLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
|
||||
const selectBox = document.getElementById('reposelectbox');
|
||||
|
||||
|
||||
const options = response.data.data;
|
||||
const option = document.createElement('option');
|
||||
$scope.records = response.data.currentSchedules;
|
||||
|
||||
|
||||
option.value = 1;
|
||||
option.text = 'Choose Repo';
|
||||
|
||||
selectBox.appendChild(option);
|
||||
|
||||
if (options.length >= 1) {
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
|
||||
const option = document.createElement('option');
|
||||
|
||||
|
||||
option.value = options[i];
|
||||
option.text = options[i];
|
||||
|
||||
selectBox.appendChild(option);
|
||||
}
|
||||
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: 'file empty',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.backupLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$scope.CreateScheduleV2 = function () {
|
||||
$scope.backupLoading = false;
|
||||
// document.getElementById('CreateV2BackupButton').style.display = "block";
|
||||
var url = "/IncrementalBackups/CreateScheduleV2";
|
||||
|
||||
var data = {
|
||||
Selectedwebsite: $scope.selwebsite,
|
||||
repo: $('#reposelectbox').val(),
|
||||
frequency: $scope.frequency,
|
||||
websiteData: $scope.websiteData,
|
||||
websiteDatabases: $scope.websiteDatabases,
|
||||
websiteEmails: $scope.websiteEmails
|
||||
};
|
||||
//alert( $scope.selwebsite);
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.backupLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
$scope.selectwebsite();
|
||||
new PNotify({
|
||||
title: 'Success!',
|
||||
text: 'Successfully created.',
|
||||
type: 'success'
|
||||
});
|
||||
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.backupLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var Domain;
|
||||
|
||||
$scope.CreateV2BackupButton = function () {
|
||||
$scope.backupLoading = false;
|
||||
$scope.installationDetailsForm = true;
|
||||
$scope.installationProgress = false;
|
||||
$scope.errorMessageBox = true;
|
||||
$scope.success = true;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.goBackDisable = true;
|
||||
|
||||
var url = "/IncrementalBackups/CreateV2BackupButton";
|
||||
var websiteData = $scope.websiteData;
|
||||
var websiteEmails = $scope.websiteEmails;
|
||||
var websiteDatabases = $scope.websiteDatabases;
|
||||
var chk = 0;
|
||||
if (websiteData === true || websiteDatabases === true || websiteEmails === true) {
|
||||
chk = 1;
|
||||
}
|
||||
var data = {};
|
||||
|
||||
|
||||
data = {
|
||||
Selectedwebsite: $scope.selwebsite,
|
||||
Selectedrepo: $('#reposelectbox').val(),
|
||||
websiteDatabases: websiteDatabases,
|
||||
websiteEmails: websiteEmails,
|
||||
websiteData: websiteData,
|
||||
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
//alert('Done..........')
|
||||
if (chk === 1) {
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
} else {
|
||||
$scope.backupLoading = true;
|
||||
new PNotify({
|
||||
title: 'Choose Backup Content!',
|
||||
text: 'Please Choose Backup content Data, Database, Email',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.backupLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
|
||||
Domain = $scope.selwebsite;
|
||||
getCreationStatus();
|
||||
|
||||
} else {
|
||||
$scope.backupLoading = true;
|
||||
$scope.installationDetailsForm = true;
|
||||
$scope.installationProgress = false;
|
||||
$scope.errorMessageBox = false;
|
||||
$scope.success = true;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.goBackDisable = false;
|
||||
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.backupLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getCreationStatus() {
|
||||
|
||||
url = "/IncrementalBackups/CreateV2BackupStatus";
|
||||
|
||||
var data = {
|
||||
domain: Domain
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
|
||||
if (response.data.abort === 1) {
|
||||
|
||||
if (response.data.installStatus === 1) {
|
||||
|
||||
$scope.webSiteCreationLoading = true;
|
||||
$scope.installationDetailsForm = true;
|
||||
$scope.installationProgress = false;
|
||||
$scope.errorMessageBox = true;
|
||||
$scope.success = false;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.goBackDisable = false;
|
||||
|
||||
$("#installProgress").css("width", "100%");
|
||||
$scope.installPercentage = "100";
|
||||
$scope.currentStatus = response.data.currentStatus;
|
||||
$timeout.cancel();
|
||||
|
||||
} else {
|
||||
$scope.webSiteCreationLoading = true;
|
||||
$scope.installationDetailsForm = true;
|
||||
$scope.installationProgress = false;
|
||||
$scope.errorMessageBox = false;
|
||||
$scope.success = true;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.goBackDisable = false;
|
||||
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
|
||||
$("#installProgress").css("width", "0%");
|
||||
$scope.installPercentage = "0";
|
||||
$scope.goBackDisable = false;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
$scope.webSiteCreationLoading = false;
|
||||
$("#installProgress").css("width", response.data.installationProgress + "%");
|
||||
$scope.installPercentage = response.data.installationProgress;
|
||||
$scope.currentStatus = response.data.currentStatus;
|
||||
$timeout(getCreationStatus, 1000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
|
||||
$scope.webSiteCreationLoading = true;
|
||||
$scope.installationDetailsForm = true;
|
||||
$scope.installationProgress = false;
|
||||
$scope.errorMessageBox = true;
|
||||
$scope.success = true;
|
||||
$scope.couldNotConnect = false;
|
||||
$scope.goBackDisable = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
203
IncBackups/templates/IncBackups/ScheduleV2Backup.html
Normal file
203
IncBackups/templates/IncBackups/ScheduleV2Backup.html
Normal file
@@ -0,0 +1,203 @@
|
||||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Schedule v2 Backup" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Schedule 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 schedule your backups." %}</p>
|
||||
</div>
|
||||
|
||||
<div ng-controller="ScheduleV2Backup" class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Schedule v2 Backup" %} <img ng-hide="backupLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
<form class="form-horizontal bordered-row">
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Website" %} </label>
|
||||
<div class="col-sm-6">
|
||||
<select id="create-backup-select" ng-change="selectwebsite()" ng-model="selwebsite"
|
||||
class="form-control">
|
||||
{% for items in websiteList %}
|
||||
<option value="{{ items }}">{{ items }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Website" %} </label>
|
||||
<div class="col-sm-6">
|
||||
<select id="create-backup-select" ng-model="frequency"
|
||||
class="form-control">
|
||||
<option>30 Minutes</option>
|
||||
<option>1 Hour</option>
|
||||
<option>6 Hours</option>
|
||||
<option>12 Hours</option>
|
||||
<option>1 Day</option>
|
||||
<option>3 Days</option>
|
||||
<option>1 Week</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<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>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Backup Content" %}</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input ng-model="websiteData" type="checkbox" value="">
|
||||
Data
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-9">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input ng-model="websiteDatabases" type="checkbox" value="">
|
||||
Databases
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-9">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input ng-model="websiteEmails" type="checkbox" value="">
|
||||
Emails
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!---
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-9">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input ng-model="websiteSSLs" type="checkbox" value="">
|
||||
SSL Certificates
|
||||
</label>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans " " %} </label>
|
||||
<div class="col-sm-6">
|
||||
<button class="btn" id="CreateV2BackupButton" ng-click="CreateScheduleV2()"
|
||||
style="border-radius: 6px;background-color: #3447b7;color: white !important;">
|
||||
Create Schedule
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!------ List of records --------------->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<div class="col-sm-12">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Repo" %}</th>
|
||||
<th>{% trans "Frequency" %}</th>
|
||||
<th>{% trans "Backup Websites?" %}</th>
|
||||
<th>{% trans "Backup Databases?" %}</th>
|
||||
<th>{% trans "Backup Emails?" %}</th>
|
||||
<th>{% trans "Last Run" %}</th>
|
||||
<th>{% trans "Delete" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="record in records track by $index">
|
||||
<td ng-bind="record.repo"></td>
|
||||
<td ng-bind="record.frequency"></td>
|
||||
<td ng-bind="record.websiteData"></td>
|
||||
<td ng-bind="record.websiteDatabases"></td>
|
||||
<td ng-bind="record.websiteEmails"></td>
|
||||
<td ng-bind="record.lastRun"></td>
|
||||
<a data-toggle="modal" href="" data-target="#DeleteScheduleV2">
|
||||
<td data-toggle="modal" data-target="#DeleteScheduleV2"
|
||||
ng-click="deleteBackupInitialv2(record.repo, record.frequency, record.websiteData, record.websiteDatabases, record.websiteEmails)">
|
||||
<img
|
||||
src="{% static 'images/delete.png' %}"></td>
|
||||
</a>
|
||||
<div id="DeleteScheduleV2" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<!-- Modal content-->
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×
|
||||
</button>
|
||||
<h4 class="modal-title">{% trans "Set up account" %}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<form name="containerSettingsForm" action="/"
|
||||
class="form-horizontal">
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Are you sure?" %}</label>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary"
|
||||
ng-click="DeleteScheduleV2()">Delete <img
|
||||
ng-hide="backupLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn btn-default" data-dismiss="modal">
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!------ List of records --------------->
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -36,4 +36,8 @@ urlpatterns = [
|
||||
url(r'^CreateV2BackupStatus$', views.CreateV2BackupStatus, name='CreateV2BackupStatus'),
|
||||
url(r'^ConfigureSftpV2Backup$', views.ConfigureSftpV2Backup, name='ConfigureSftpV2Backup'),
|
||||
|
||||
url(r'^schedulev2Backups$', views.schedulev2Backups, name='schedulev2Backups'),
|
||||
url(r'^DeleteScheduleV2$', views.DeleteScheduleV2, name='DeleteScheduleV2'),
|
||||
url(r'^CreateScheduleV2$', views.CreateScheduleV2, name='CreateScheduleV2'),
|
||||
|
||||
]
|
||||
@@ -982,6 +982,8 @@ def selectwebsiteCreatev2(request):
|
||||
command = 'cat %s'%(path)
|
||||
CurrentContent = pu.outputExecutioner(command)
|
||||
|
||||
status, currentSchedules = CPBackupsV2.FetchCurrentSchedules(str(Selectedwebsite))
|
||||
|
||||
|
||||
if CurrentContent.find('No such file or directory') > -1:
|
||||
LocalRclonePath = f'/home/{obj.domain}/.config/rclone'
|
||||
@@ -1001,7 +1003,7 @@ def selectwebsiteCreatev2(request):
|
||||
if result.find('type') > -1:
|
||||
pattern = r'\[(.*?)\]'
|
||||
matches = re.findall(pattern, result)
|
||||
final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": matches})
|
||||
final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": matches, 'currentSchedules': currentSchedules})
|
||||
return HttpResponse(final_json)
|
||||
else:
|
||||
final_json = json.dumps({'status': 0, 'fetchStatus': 0, 'error_message': 'Could not Find repo'})
|
||||
@@ -1013,10 +1015,10 @@ def selectwebsiteCreatev2(request):
|
||||
if result.find('type') > -1:
|
||||
pattern = r'\[(.*?)\]'
|
||||
matches = re.findall(pattern, result)
|
||||
final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": matches})
|
||||
final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": matches, 'currentSchedules': currentSchedules})
|
||||
return HttpResponse(final_json)
|
||||
else:
|
||||
final_json = json.dumps({'status': 0, 'fetchStatus': 0, 'error_message': 'Could not Find repo'})
|
||||
final_json = json.dumps({'status': 0, 'fetchStatus': 0, 'error_message': 'Could not Find repo', 'currentSchedules': currentSchedules})
|
||||
return HttpResponse(final_json)
|
||||
|
||||
|
||||
@@ -1065,6 +1067,89 @@ def selectreporestorev2(request):
|
||||
return HttpResponse(final_json)
|
||||
|
||||
|
||||
except BaseException as msg:
|
||||
final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
def schedulev2Backups(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
bm = BackupManager()
|
||||
return bm.schedulev2Backups(request, userID)
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def DeleteScheduleV2(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
data = json.loads(request.body)
|
||||
Selectedwebsite = data['Selectedwebsite']
|
||||
repo = data['repo']
|
||||
frequency = data['frequency']
|
||||
websiteData = data['websiteData']
|
||||
websiteDatabases = data['websiteDatabases']
|
||||
websiteEmails = data['websiteEmails']
|
||||
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
|
||||
if ACLManager.checkOwnership(str(Selectedwebsite), admin, currentACL) == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadError()
|
||||
|
||||
|
||||
status, message = CPBackupsV2.DeleteSchedule(Selectedwebsite, repo, frequency, websiteData, websiteDatabases, websiteEmails)
|
||||
|
||||
final_dic = {'status': 1, 'error_message': message}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
# final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": None})
|
||||
# return HttpResponse(final_json)
|
||||
|
||||
|
||||
except BaseException as msg:
|
||||
final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
def CreateScheduleV2(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
data = json.loads(request.body)
|
||||
Selectedwebsite = data['Selectedwebsite']
|
||||
repo = data['repo']
|
||||
frequency = data['frequency']
|
||||
websiteData = data['websiteData']
|
||||
websiteDatabases = data['websiteDatabases']
|
||||
websiteEmails = data['websiteEmails']
|
||||
|
||||
#
|
||||
# extra_args['BackupData'] = data['websiteData'] if 'websiteData' in data else False
|
||||
# extra_args['BackupEmails'] = data['websiteEmails'] if 'websiteEmails' in data else False
|
||||
# extra_args['BackupDatabase'] = data['websiteDatabases'] if 'websiteDatabases' in data else False
|
||||
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
|
||||
if ACLManager.checkOwnership(str(Selectedwebsite), admin, currentACL) == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadError()
|
||||
|
||||
|
||||
status, message = CPBackupsV2.CreateScheduleV2(Selectedwebsite, repo, frequency, websiteData, websiteDatabases, websiteEmails)
|
||||
|
||||
final_dic = {'status': 1, 'error_message': message}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
# final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": None})
|
||||
# return HttpResponse(final_json)
|
||||
|
||||
|
||||
except BaseException as msg:
|
||||
final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(final_dic)
|
||||
|
||||
@@ -57,12 +57,19 @@ class BackupManager:
|
||||
websitesName = ACLManager.findAllSites(currentACL, userID)
|
||||
proc = httpProc(request, 'IncBackups/RestoreV2Backup.html', {'websiteList': websitesName}, 'createBackup')
|
||||
return proc.render()
|
||||
|
||||
def CreateV2backupSite(self, request=None, userID=None, data=None):
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
websitesName = ACLManager.findAllSites(currentACL, userID)
|
||||
proc = httpProc(request, 'IncBackups/CreateV2Backup.html', {'websiteList': websitesName}, 'createBackup')
|
||||
return proc.render()
|
||||
|
||||
def schedulev2Backups(self, request=None, userID=None, data=None):
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
websitesName = ACLManager.findAllSites(currentACL, userID)
|
||||
proc = httpProc(request, 'IncBackups/ScheduleV2Backup.html', {'websiteList': websitesName}, 'createBackup')
|
||||
return proc.render()
|
||||
|
||||
def gDrive(self, request=None, userID=None, data=None):
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
data-target="#setupGdrive"><span>{% trans "Setup new Account" %}</span></a>
|
||||
<div id="setupGdrive" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
|
||||
<!-- Modal content-->
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
|
||||
@@ -689,6 +689,9 @@
|
||||
<li><a href="{% url 'RestoreV2backupSite' %}"
|
||||
title="{% trans "Restore V2 Backup" %}"><span>{% trans "Restore V2 Backup" %}</span></a>
|
||||
</li>
|
||||
<li><a href="{% url 'schedulev2Backups' %}"
|
||||
title="{% trans "Schedule V2 Backup" %}"><span>{% trans "Schedule V2 Backup" %}</span></a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ except:
|
||||
from plogical.processUtilities import ProcessUtilities
|
||||
import threading as multi
|
||||
|
||||
|
||||
class CPBackupsV2(multi.Thread):
|
||||
PENDING_START = 0
|
||||
RUNNING = 1
|
||||
@@ -106,7 +107,6 @@ class CPBackupsV2(multi.Thread):
|
||||
except:
|
||||
CurrentContent = ''
|
||||
|
||||
|
||||
if type == CPBackupsV2.SFTP:
|
||||
## config = {"name":, "host":, "user":, "port":, "path":, "password":,}
|
||||
command = f'rclone obscure {config["password"]}'
|
||||
@@ -130,7 +130,8 @@ pass = {ObsecurePassword}
|
||||
return HttpResponse(final_json)
|
||||
elif type == CPBackupsV2.GDrive:
|
||||
|
||||
token = """{"access_token":"%s","token_type":"Bearer","refresh_token":"%s"}""" %(config["token"], config["refresh_token"])
|
||||
token = """{"access_token":"%s","token_type":"Bearer","refresh_token":"%s"}""" % (
|
||||
config["token"], config["refresh_token"])
|
||||
|
||||
content = f'''{CurrentContent}
|
||||
[{config["name"]}]
|
||||
@@ -166,14 +167,14 @@ token = {token}
|
||||
|
||||
file = open(self.StatusFile, 'a')
|
||||
file.writelines("[" + time.strftime(
|
||||
"%m.%d.%Y_%H-%M-%S") + ":FAILED] " + message + "[404]" +"\n")
|
||||
"%m.%d.%Y_%H-%M-%S") + ":FAILED] " + message + "[404]" + "\n")
|
||||
file.close()
|
||||
elif status == CPBackupsV2.COMPLETED:
|
||||
self.website.BackupLock = 0
|
||||
self.website.save()
|
||||
file = open(self.StatusFile, 'a')
|
||||
file.writelines("[" + time.strftime(
|
||||
"%m.%d.%Y_%H-%M-%S") + ":COMPLETED] " + message + "[200]" +"\n")
|
||||
"%m.%d.%Y_%H-%M-%S") + ":COMPLETED] " + message + "[200]" + "\n")
|
||||
file.close()
|
||||
else:
|
||||
file = open(self.StatusFile, 'a')
|
||||
@@ -191,8 +192,8 @@ token = {token}
|
||||
command = f'rustic init -r {self.repo} --password ""'
|
||||
ProcessUtilities.executioner(command, self.website.externalApp)
|
||||
|
||||
#command = f'chown cyberpanel:cyberpanel {self.FinalPathRuctic}'
|
||||
#ProcessUtilities.executioner(command)
|
||||
# command = f'chown cyberpanel:cyberpanel {self.FinalPathRuctic}'
|
||||
# ProcessUtilities.executioner(command)
|
||||
|
||||
command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}/config.json'
|
||||
ProcessUtilities.executioner(command)
|
||||
@@ -219,8 +220,7 @@ token = {token}
|
||||
def MergeSnapshots(self):
|
||||
snapshots = ''
|
||||
for snapshot in self.snapshots:
|
||||
snapshots= f'{snapshots} {snapshot}'
|
||||
|
||||
snapshots = f'{snapshots} {snapshot}'
|
||||
|
||||
command = f'rustic -r {self.repo} merge {snapshots} --password "" --json'
|
||||
result = ProcessUtilities.outputExecutioner(command, self.website.externalApp, True)
|
||||
@@ -254,7 +254,7 @@ token = {token}
|
||||
|
||||
### Init rustic repo in main func so dont need to do again and again
|
||||
|
||||
while(1):
|
||||
while (1):
|
||||
|
||||
self.website = Websites.objects.get(domain=self.data['domain'])
|
||||
|
||||
@@ -263,12 +263,15 @@ token = {token}
|
||||
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.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'))
|
||||
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 backup this website.',
|
||||
CPBackupsV2.FAILED)
|
||||
return 0
|
||||
|
||||
### Before doing anything install rustic
|
||||
@@ -279,30 +282,26 @@ token = {token}
|
||||
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.buv2.save()
|
||||
|
||||
#self.FinalPath = f"{self.data['BasePath']}/{self.buv2.fileName}"
|
||||
# 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"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"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"chmod 711 {self.FinalPath}"
|
||||
# ProcessUtilities.executioner(command)
|
||||
|
||||
command = f"mkdir -p {self.FinalPathRuctic}"
|
||||
ProcessUtilities.executioner(command)
|
||||
@@ -317,10 +316,14 @@ token = {token}
|
||||
|
||||
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',
|
||||
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'])
|
||||
'state', 'initself.websitesLimit', 'twoFA', 'secretKey',
|
||||
'config'])
|
||||
Config['acl'] = model_to_dict(self.website.admin.acl)
|
||||
|
||||
### Child domains to config
|
||||
@@ -333,7 +336,7 @@ token = {token}
|
||||
|
||||
Config['ChildDomains'] = ChildsList
|
||||
|
||||
#print(str(Config))
|
||||
# print(str(Config))
|
||||
|
||||
### Databases
|
||||
|
||||
@@ -367,7 +370,9 @@ token = {token}
|
||||
WPSitesList = []
|
||||
|
||||
for wpsite in self.website.wpsites_set.all():
|
||||
WPSitesList.append(model_to_dict(wpsite,fields=['title', 'path', 'FinalURL', 'AutoUpdates', 'PluginUpdates', 'ThemeUpdates', 'WPLockState']))
|
||||
WPSitesList.append(model_to_dict(wpsite, fields=['title', 'path', 'FinalURL', 'AutoUpdates',
|
||||
'PluginUpdates', 'ThemeUpdates',
|
||||
'WPLockState']))
|
||||
|
||||
Config['WPSites'] = WPSitesList
|
||||
self.config = Config
|
||||
@@ -403,8 +408,8 @@ token = {token}
|
||||
except:
|
||||
pass
|
||||
|
||||
#command = f"echo '{json.dumps(Config)}' > {self.FinalPath}/config.json"
|
||||
#ProcessUtilities.executioner(command, self.website.externalApp, True)
|
||||
# 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)
|
||||
@@ -476,8 +481,8 @@ token = {token}
|
||||
### excluded databases are in a list self.data['ExcludedDatabases'] only backup databases if backupdatabase check is on
|
||||
## For example if self.data['BackupDatabase'] is one then only run this function otherwise not
|
||||
|
||||
#command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}'
|
||||
#ProcessUtilities.executioner(command)
|
||||
# command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}'
|
||||
# ProcessUtilities.executioner(command)
|
||||
|
||||
command = f'rustic init -r {self.repo} --password ""'
|
||||
ProcessUtilities.executioner(command, self.website.externalApp)
|
||||
@@ -496,19 +501,19 @@ token = {token}
|
||||
|
||||
CurrentDBPath = f"{self.FinalPathRuctic}/{key}.sql"
|
||||
|
||||
DBResult, SnapID = mysqlUtilities.createDatabaseBackup(key, self.FinalPathRuctic, 1, self.repo, self.website.externalApp)
|
||||
|
||||
DBResult, SnapID = mysqlUtilities.createDatabaseBackup(key, self.FinalPathRuctic, 1, self.repo,
|
||||
self.website.externalApp)
|
||||
|
||||
if DBResult == 1:
|
||||
self.snapshots.append(SnapID)
|
||||
|
||||
#command = f'chown {self.website.externalApp}:{self.website.externalApp} {CurrentDBPath}'
|
||||
#ProcessUtilities.executioner(command)
|
||||
# command = f'chown {self.website.externalApp}:{self.website.externalApp} {CurrentDBPath}'
|
||||
# ProcessUtilities.executioner(command)
|
||||
|
||||
## Now pack config into same thing
|
||||
|
||||
#command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}/config.json'
|
||||
#ProcessUtilities.executioner(command)
|
||||
# command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}/config.json'
|
||||
# ProcessUtilities.executioner(command)
|
||||
|
||||
# command = f'rustic -r {self.repo} backup {CurrentDBPath} --password "" --json 2>/dev/null'
|
||||
# print(f'db command rustic: {command}')
|
||||
@@ -555,16 +560,16 @@ token = {token}
|
||||
### excluded directories are in a list self.data['ExcludedDirectories'] only backup data if backupdata check is on
|
||||
## For example if self.data['BackupData'] is one then only run this function otherwise not
|
||||
|
||||
#command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}'
|
||||
#ProcessUtilities.executioner(command)
|
||||
# command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}'
|
||||
# ProcessUtilities.executioner(command)
|
||||
|
||||
command = f'rustic init -r {self.repo} --password ""'
|
||||
ProcessUtilities.executioner(command, self.website.externalApp)
|
||||
|
||||
source = f'/home/{self.website.domain}'
|
||||
|
||||
#command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}/config.json'
|
||||
#ProcessUtilities.executioner(command)
|
||||
# command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}/config.json'
|
||||
# ProcessUtilities.executioner(command)
|
||||
|
||||
## Pending add user provided folders in the exclude list
|
||||
|
||||
@@ -573,7 +578,6 @@ token = {token}
|
||||
command = f'rustic -r {self.repo} backup {source} --password "" {exclude} --json 2>/dev/null'
|
||||
result = json.loads(ProcessUtilities.outputExecutioner(command, self.website.externalApp, True).rstrip('\n'))
|
||||
|
||||
|
||||
try:
|
||||
SnapShotID = result['id'] ## snapshot id that we need to store in db
|
||||
files_new = result['summary']['files_new'] ## basically new files in backup
|
||||
@@ -583,13 +587,13 @@ token = {token}
|
||||
|
||||
### Config is saved with each backup, snapshot of config is attached to data snapshot with parent
|
||||
|
||||
#self.BackupConfig(SnapShotID)
|
||||
# self.BackupConfig(SnapShotID)
|
||||
|
||||
except BaseException as msg:
|
||||
self.UpdateStatus(f'Backup failed as no snapshot id found, error: {str(msg)}', CPBackupsV2.FAILED)
|
||||
return 0
|
||||
|
||||
#self.UpdateStatus(f'Rustic command result id: {SnapShotID}, files new {files_new}, total_duration {total_duration}', CPBackupsV2.RUNNING)
|
||||
# self.UpdateStatus(f'Rustic command result id: {SnapShotID}, files new {files_new}, total_duration {total_duration}', CPBackupsV2.RUNNING)
|
||||
|
||||
return 1
|
||||
|
||||
@@ -599,15 +603,14 @@ token = {token}
|
||||
### excluded emails are in a list self.data['ExcludedEmails'] only backup data if backupemail check is on
|
||||
## For example if self.data['BackupEmails'] is one then only run this function otherwise not
|
||||
|
||||
#command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}'
|
||||
#ProcessUtilities.executioner(command)
|
||||
# command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}'
|
||||
# ProcessUtilities.executioner(command)
|
||||
|
||||
command = f'rustic init -r {self.repo} --password ""'
|
||||
ProcessUtilities.executioner(command, self.website.externalApp)
|
||||
|
||||
#command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}/config.json'
|
||||
#ProcessUtilities.executioner(command)
|
||||
|
||||
# command = f'chown {self.website.externalApp}:{self.website.externalApp} {self.FinalPathRuctic}/config.json'
|
||||
# ProcessUtilities.executioner(command)
|
||||
|
||||
source = f'/home/vmail/{self.website.domain}'
|
||||
|
||||
@@ -628,7 +631,7 @@ token = {token}
|
||||
|
||||
### Config is saved with each email backup, snapshot of config is attached to email snapshot with parent
|
||||
|
||||
#self.BackupConfig(SnapShotID)
|
||||
# self.BackupConfig(SnapShotID)
|
||||
|
||||
except BaseException as msg:
|
||||
self.UpdateStatus(f'Backup failed as no snapshot id found, error: {str(msg)}', CPBackupsV2.FAILED)
|
||||
@@ -643,7 +646,7 @@ token = {token}
|
||||
### if restore then status file should be restore status file
|
||||
|
||||
self.restore = 1
|
||||
#self.StatusFile = self.StatusFile_Restore
|
||||
# self.StatusFile = self.StatusFile_Restore
|
||||
|
||||
from websiteFunctions.models import Websites
|
||||
from plogical.mysqlUtilities import mysqlUtilities
|
||||
@@ -664,7 +667,7 @@ token = {token}
|
||||
|
||||
### Init rustic repo in main func so dont need to do again and again
|
||||
|
||||
while(1):
|
||||
while (1):
|
||||
|
||||
self.website = Websites.objects.get(domain=self.data['domain'])
|
||||
|
||||
@@ -673,19 +676,21 @@ token = {token}
|
||||
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.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'))
|
||||
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 restore this website.', CPBackupsV2.FAILED)
|
||||
self.UpdateStatus(f'Not enough disk space on the server to restore this website.',
|
||||
CPBackupsV2.FAILED)
|
||||
return 0
|
||||
|
||||
### Rustic backup final path
|
||||
|
||||
self.FinalPathRuctic = f"{self.data['BasePath']}/{self.website.domain}"
|
||||
|
||||
|
||||
command = f"mkdir -p {self.FinalPathRuctic}"
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
@@ -698,7 +703,8 @@ token = {token}
|
||||
### Find Restore path first, if path is db, only then restore it to cp
|
||||
|
||||
if self.data["path"].find('.sql') > -1:
|
||||
mysqlUtilities.restoreDatabaseBackup(self.data["path"].rstrip('.sql'), None, None, None, None, 1, self.repo, self.website.externalApp, self.data["snapshotid"])
|
||||
mysqlUtilities.restoreDatabaseBackup(self.data["path"].rstrip('.sql'), None, None, None, None, 1,
|
||||
self.repo, self.website.externalApp, self.data["snapshotid"])
|
||||
else:
|
||||
|
||||
if self.data["path"].find('/home/vmail') > -1:
|
||||
@@ -736,10 +742,118 @@ token = {token}
|
||||
from websiteFunctions.models import Websites
|
||||
self.website = Websites.objects.get(domain=self.data['domain'])
|
||||
|
||||
|
||||
command = f'rustic -r {self.repo} forget {deleteString} --prune --password "" 2>/dev/null'
|
||||
result = ProcessUtilities.outputExecutioner(command, None, True)
|
||||
|
||||
@staticmethod
|
||||
def FetchCurrentSchedules(website):
|
||||
try:
|
||||
finalConfigPath = f'/home/cyberpanel/v2backups/{website}'
|
||||
|
||||
if os.path.exists(finalConfigPath):
|
||||
command = f'cat {finalConfigPath}'
|
||||
RetResult = ProcessUtilities.outputExecutioner(command)
|
||||
print(repr(RetResult))
|
||||
BackupConfig = json.loads(ProcessUtilities.outputExecutioner(command).rstrip('\n'))
|
||||
|
||||
schedules = []
|
||||
for value in BackupConfig['schedules']:
|
||||
|
||||
schedules.append({'repo': value['repo'], 'frequency': value['frequency'], 'websiteData': value['websiteData'],
|
||||
'websiteEmails': value['websiteEmails'],
|
||||
'websiteDatabases': value['websiteDatabases'], 'lastRun': value['lastRun'],
|
||||
'domain': website})
|
||||
|
||||
return 1, schedules
|
||||
else:
|
||||
return 1, []
|
||||
|
||||
except BaseException as msg:
|
||||
return 0, str(msg)
|
||||
|
||||
@staticmethod
|
||||
def DeleteSchedule(website, repo, frequency, websiteData, websiteDatabases, websiteEmails):
|
||||
try:
|
||||
finalConfigPath = f'/home/cyberpanel/v2backups/{website}'
|
||||
|
||||
if os.path.exists(finalConfigPath):
|
||||
command = f'cat {finalConfigPath}'
|
||||
RetResult = ProcessUtilities.outputExecutioner(command)
|
||||
print(repr(RetResult))
|
||||
BackupConfig = json.loads(ProcessUtilities.outputExecutioner(command).rstrip('\n'))
|
||||
counter = 0
|
||||
|
||||
for value in BackupConfig['schedules']:
|
||||
|
||||
if value['repo'] == repo and value['frequency'] == frequency and value['websiteData'] == websiteData and \
|
||||
value['websiteEmails'] == websiteEmails and value['websiteDatabases'] == websiteDatabases:
|
||||
del BackupConfig['schedules'][counter]
|
||||
break
|
||||
else:
|
||||
counter = counter + 1
|
||||
|
||||
FinalContent = json.dumps(BackupConfig)
|
||||
WriteToFile = open(finalConfigPath, 'w')
|
||||
WriteToFile.write(FinalContent)
|
||||
WriteToFile.close()
|
||||
|
||||
return 1, BackupConfig
|
||||
else:
|
||||
return 1, []
|
||||
|
||||
except BaseException as msg:
|
||||
return 0, str(msg)
|
||||
|
||||
@staticmethod
|
||||
def CreateScheduleV2(website, repo, frequency, websiteData, websiteDatabases, websiteEmails):
|
||||
try:
|
||||
|
||||
finalConfigPath = f'/home/cyberpanel/v2backups/{website}'
|
||||
|
||||
if os.path.exists(finalConfigPath):
|
||||
logging.CyberCPLogFileWriter.writeToFile('22222')
|
||||
|
||||
command = f'cat {finalConfigPath}'
|
||||
RetResult = ProcessUtilities.outputExecutioner(command)
|
||||
print(repr(RetResult))
|
||||
BackupConfig = json.loads(ProcessUtilities.outputExecutioner(command).rstrip('\n'))
|
||||
|
||||
try:
|
||||
BackupConfig['schedules'].append({"repo": repo, "retention": "7", "frequency": frequency, "websiteData": websiteData,
|
||||
"websiteEmails": websiteEmails, "websiteDatabases": websiteDatabases,
|
||||
"lastRun": ""})
|
||||
except:
|
||||
BackupConfig['schedules'] = [{"repo": repo, "retention": "7", "frequency": frequency, "websiteData": websiteData,
|
||||
"websiteEmails": websiteEmails, "websiteDatabases": websiteDatabases,
|
||||
"lastRun": ""}]
|
||||
|
||||
# BackupConfig['schedules'] = {"retention": "7", "frequency": frequency, "websiteData": websiteData,
|
||||
# "websiteEmails": websiteEmails, "websiteDatabases": websiteDatabases,
|
||||
# "lastRun": ""}
|
||||
|
||||
FinalContent = json.dumps(BackupConfig)
|
||||
WriteToFile = open(finalConfigPath, 'w')
|
||||
WriteToFile.write(FinalContent)
|
||||
WriteToFile.close()
|
||||
return 1, BackupConfig
|
||||
else:
|
||||
BackupConfig = {'site': website,
|
||||
'schedules':
|
||||
[{"repo": repo, "retention": "7", "frequency": frequency,
|
||||
"websiteData": websiteData,
|
||||
"websiteEmails": websiteEmails, "websiteDatabases": websiteDatabases,
|
||||
"lastRun": ""}]}
|
||||
|
||||
FinalContent = json.dumps(BackupConfig)
|
||||
WriteToFile = open(finalConfigPath, 'w')
|
||||
WriteToFile.write(FinalContent)
|
||||
WriteToFile.close()
|
||||
|
||||
return 1, BackupConfig
|
||||
|
||||
except BaseException as msg:
|
||||
return 0, str(msg)
|
||||
|
||||
# def BackupEmails(self):
|
||||
#
|
||||
# ### This function will backup emails of the website, also need to take care of emails that we need to exclude
|
||||
@@ -840,11 +954,13 @@ token = {token}
|
||||
else:
|
||||
return 0, str(response.content)
|
||||
|
||||
#sudo mv filename /usr/bin/
|
||||
command = 'wget -P /home/rustic https://github.com/rustic-rs/rustic/releases/download/%s/rustic-%s-x86_64-unknown-linux-musl.tar.gz' %(version, version)
|
||||
# sudo mv filename /usr/bin/
|
||||
command = 'wget -P /home/rustic https://github.com/rustic-rs/rustic/releases/download/%s/rustic-%s-x86_64-unknown-linux-musl.tar.gz' % (
|
||||
version, version)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
command = 'tar xzf /home/rustic/rustic-%s-x86_64-unknown-linux-musl.tar.gz -C /home/rustic//'%(version)
|
||||
command = 'tar xzf /home/rustic/rustic-%s-x86_64-unknown-linux-musl.tar.gz -C /home/rustic//' % (
|
||||
version)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
command = 'sudo mv /home/rustic/rustic /usr/bin/'
|
||||
@@ -858,11 +974,10 @@ token = {token}
|
||||
|
||||
|
||||
except BaseException as msg:
|
||||
print('Error: %s'%msg)
|
||||
print('Error: %s' % msg)
|
||||
return 0, str(msg)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description='CyberPanel Backup Generator')
|
||||
@@ -873,8 +988,10 @@ if __name__ == "__main__":
|
||||
|
||||
if args.function == "BackupDataBases":
|
||||
cpbuv2 = CPBackupsV2({'finalPath': args.path})
|
||||
#cpbuv2.BackupDataBases()
|
||||
# cpbuv2.BackupDataBases()
|
||||
|
||||
except:
|
||||
cpbuv2 = CPBackupsV2({'function':'InitiateRestore', 'domain': 'cyberpanel.net', 'BasePath': '/home/backup', 'SnapShotID': 1, 'BackendName': 'usman'} )
|
||||
cpbuv2 = CPBackupsV2(
|
||||
{'function': 'InitiateRestore', 'domain': 'cyberpanel.net', 'BasePath': '/home/backup', 'SnapShotID': 1,
|
||||
'BackendName': 'usman'})
|
||||
cpbuv2.InitiateRestore()
|
||||
@@ -1411,18 +1411,16 @@ Automatic backup failed for %s on %s.
|
||||
print(repr(RetResult))
|
||||
BackupConfig = json.loads(ProcessUtilities.outputExecutioner(command).rstrip('\n'))
|
||||
|
||||
for key, value in BackupConfig.items():
|
||||
for value in BackupConfig['schedules']:
|
||||
try:
|
||||
print(key, '->', value)
|
||||
if key == 'site':
|
||||
continue
|
||||
|
||||
if value['frequency'] == function:
|
||||
extra_args = {}
|
||||
extra_args['function'] = 'InitiateBackup'
|
||||
extra_args['website'] = website.domain
|
||||
extra_args['domain'] = website.domain
|
||||
extra_args['BasePath'] = '/home/backup'
|
||||
extra_args['BackendName'] = key
|
||||
extra_args['BackendName'] = value['repo']
|
||||
extra_args['BackupData'] = value['websiteData'] if 'websiteData' in value else False
|
||||
extra_args['BackupEmails'] = value['websiteEmails'] if 'websiteEmails' in value else False
|
||||
extra_args['BackupDatabase'] = value['websiteDatabases'] if 'websiteDatabases' in value else False
|
||||
@@ -1450,7 +1448,7 @@ Automatic Backupv2 failed for %s on %s.
|
||||
|
||||
logging.SendEmail(sender, TO, message)
|
||||
else:
|
||||
BackupConfig[key]['lastRun'] = time.strftime("%m.%d.%Y_%H-%M-%S")
|
||||
value['lastRun'] = time.strftime("%m.%d.%Y_%H-%M-%S")
|
||||
except BaseException as msg:
|
||||
print("Error: [v2Backups]: %s" % str(msg))
|
||||
logging.writeToFile('%s. [v2Backups]' % (str(msg)))
|
||||
|
||||
Reference in New Issue
Block a user