From 3032dff01dcfbd582515fb89f70f893f07dc69e2 Mon Sep 17 00:00:00 2001 From: Master3395 Date: Sat, 20 Sep 2025 21:31:41 +0200 Subject: [PATCH] Implement remote connection handling and progress tracking for backup operations: Introduce a method for attempting connections to remote CyberPanel servers with port fallback. Enhance the frontend to display detailed progress and logs during backup transfers, including error handling and notifications for port fallback usage. Update HTML and JavaScript to support new progress tracking features and improve user feedback during backup and restore processes. --- backup/backupManager.py | 194 ++++++++--- backup/static/backup/backup.js | 140 +++++++- backup/templates/backup/remoteBackups.html | 372 +++++++++++++++++++-- plogical/remoteBackup.py | 4 +- 4 files changed, 639 insertions(+), 71 deletions(-) diff --git a/backup/backupManager.py b/backup/backupManager.py index c8ca6083a..e91dfbfd2 100644 --- a/backup/backupManager.py +++ b/backup/backupManager.py @@ -38,6 +38,33 @@ from django.http import JsonResponse class BackupManager: localBackupPath = '/home/cyberpanel/localBackupPath' + + @staticmethod + def _try_remote_connection(ipAddress, password, endpoint, cyberPanelPort=8090, timeout=10): + """ + Try to connect to remote CyberPanel server with port fallback. + Returns: (success, data, used_port, error_message) + """ + import requests + import json + + ports_to_try = [cyberPanelPort, 8090] if cyberPanelPort != 8090 else [8090] + finalData = json.dumps({'username': "admin", "password": password}) + + for port in ports_to_try: + try: + url = f"https://{ipAddress}:{port}{endpoint}" + r = requests.post(url, data=finalData, verify=False, timeout=timeout) + data = json.loads(r.text) + return True, data, port, None + + except (requests.exceptions.ConnectionError, requests.exceptions.Timeout, + requests.exceptions.RequestException, json.JSONDecodeError) as e: + if port == ports_to_try[-1]: # Last port failed + return False, None, None, f"Could not connect to remote server on any port. Tried ports: {', '.join(map(str, ports_to_try))}. Last error: {str(e)}" + continue + + return False, None, None, "Connection failed on all ports" def __init__(self, domain=None, childDomain=None): self.domain = domain @@ -1084,33 +1111,35 @@ class BackupManager: ipAddress = data['ipAddress'] password = data['password'] + cyberPanelPort = data.get('cyberPanelPort', 8090) # Default to 8090 if not provided ## Ask for Remote version of CyberPanel try: - finalData = json.dumps({'username': "admin", "password": password}) - - url = "https://" + ipAddress + ":8090/api/cyberPanelVersion" - - r = requests.post(url, data=finalData, verify=False) - - data = json.loads(r.text) - - if data['getVersion'] == 1: - - if float(data['currentVersion']) >= 1.6 and data['build'] >= 0: - pass - else: - data_ret = {'status': 0, - 'error_message': "Your version does not match with version of remote server.", - "dir": "Null"} - data_ret = json.dumps(data_ret) - return HttpResponse(data_ret) - else: + # Try to connect with port fallback + success, data, used_port, error_msg = BackupManager._try_remote_connection( + ipAddress, password, "/api/cyberPanelVersion", cyberPanelPort + ) + + if not success: + data_ret = {'status': 0, 'error_message': error_msg, "dir": "Null"} + data_ret = json.dumps(data_ret) + return HttpResponse(data_ret) + + if data['getVersion'] != 1: data_ret = {'status': 0, 'error_message': "Not able to fetch version of remote server. Error Message: " + - data[ - 'error_message'], "dir": "Null"} + data.get('error_message', 'Unknown error'), "dir": "Null"} + data_ret = json.dumps(data_ret) + return HttpResponse(data_ret) + + # Check version compatibility + if float(data['currentVersion']) >= 1.6 and data['build'] >= 0: + pass + else: + data_ret = {'status': 0, + 'error_message': "Your version does not match with version of remote server.", + "dir": "Null"} data_ret = json.dumps(data_ret) return HttpResponse(data_ret) @@ -1125,11 +1154,13 @@ class BackupManager: ## Fetch public key of remote server! - finalData = json.dumps({'username': "admin", "password": password}) - - url = "https://" + ipAddress + ":8090/api/fetchSSHkey" - r = requests.post(url, data=finalData, verify=False) - data = json.loads(r.text) + success, data, used_port, error_msg = BackupManager._try_remote_connection( + ipAddress, password, "/api/fetchSSHkey", used_port + ) + + if not success: + final_json = json.dumps({'status': 0, 'error_message': error_msg}) + return HttpResponse(final_json) if data['pubKeyStatus'] == 1: pubKey = data["pubKey"].strip("\n") @@ -1167,18 +1198,19 @@ class BackupManager: ## try: - finalData = json.dumps({'username': "admin", "password": password}) - - url = "https://" + ipAddress + ":8090/api/fetchAccountsFromRemoteServer" - - r = requests.post(url, data=finalData, verify=False) - - data = json.loads(r.text) + success, data, used_port, error_msg = BackupManager._try_remote_connection( + ipAddress, password, "/api/fetchAccountsFromRemoteServer", used_port + ) + + if not success: + data_ret = {'status': 0, 'error_message': error_msg, "dir": "Null"} + data_ret = json.dumps(data_ret) + return HttpResponse(data_ret) if data['fetchStatus'] == 1: json_data = data['data'] data_ret = {'status': 1, 'error_message': "None", - "dir": "Null", 'data': json_data} + "dir": "Null", 'data': json_data, 'used_port': used_port} data_ret = json.dumps(data_ret) return HttpResponse(data_ret) else: @@ -1208,6 +1240,7 @@ class BackupManager: ipAddress = data['ipAddress'] password = data['password'] accountsToTransfer = data['accountsToTransfer'] + cyberPanelPort = data.get('cyberPanelPort', 8090) # Default to 8090 if not provided try: @@ -1240,9 +1273,32 @@ class BackupManager: finalData = json.dumps({'username': "admin", "password": password, "ipAddress": ownIP, "accountsToTransfer": accountsToTransfer, 'port': port}) - url = "https://" + ipAddress + ":8090/api/remoteTransfer" - - r = requests.post(url, data=finalData, verify=False) + # Try to connect with port fallback + ports_to_try = [cyberPanelPort, 8090] if cyberPanelPort != 8090 else [8090] + connection_successful = False + used_port = None + + for port in ports_to_try: + try: + url = f"https://{ipAddress}:{port}/api/remoteTransfer" + r = requests.post(url, data=finalData, verify=False, timeout=10) + data = json.loads(r.text) + connection_successful = True + used_port = port + break + except (requests.exceptions.ConnectionError, requests.exceptions.Timeout, + requests.exceptions.RequestException, json.JSONDecodeError) as e: + if port == ports_to_try[-1]: # Last port failed + data_ret = {'remoteTransferStatus': 0, + 'error_message': f"Could not connect to remote server on any port. Tried ports: {', '.join(map(str, ports_to_try))}. Last error: {str(e)}"} + data_ret = json.dumps(data_ret) + return HttpResponse(data_ret) + continue + + if not connection_successful: + data_ret = {'remoteTransferStatus': 0, 'error_message': "Connection failed on all ports"} + data_ret = json.dumps(data_ret) + return HttpResponse(data_ret) if os.path.exists('/usr/local/CyberCP/debug'): message = 'Remote transfer initiation status: %s' % (r.text) @@ -1302,12 +1358,36 @@ class BackupManager: password = data['password'] dir = data['dir'] username = "admin" + cyberPanelPort = data.get('cyberPanelPort', 8090) # Default to 8090 if not provided finalData = json.dumps({'dir': dir, "username": username, "password": password}) - r = requests.post("https://" + ipAddress + ":8090/api/FetchRemoteTransferStatus", data=finalData, - verify=False) - - data = json.loads(r.text) + + # Try to connect with port fallback + ports_to_try = [cyberPanelPort, 8090] if cyberPanelPort != 8090 else [8090] + connection_successful = False + used_port = None + + for port in ports_to_try: + try: + url = f"https://{ipAddress}:{port}/api/FetchRemoteTransferStatus" + r = requests.post(url, data=finalData, verify=False, timeout=10) + data = json.loads(r.text) + connection_successful = True + used_port = port + break + except (requests.exceptions.ConnectionError, requests.exceptions.Timeout, + requests.exceptions.RequestException, json.JSONDecodeError) as e: + if port == ports_to_try[-1]: # Last port failed + data_ret = {'remoteTransferStatus': 0, + 'error_message': f"Could not connect to remote server on any port. Tried ports: {', '.join(map(str, ports_to_try))}. Last error: {str(e)}"} + data_ret = json.dumps(data_ret) + return HttpResponse(data_ret) + continue + + if not connection_successful: + data_ret = {'remoteTransferStatus': 0, 'error_message': "Connection failed on all ports"} + data_ret = json.dumps(data_ret) + return HttpResponse(data_ret) if data['fetchStatus'] == 1: if data['status'].find("Backups are successfully generated and received on") > -1: @@ -1429,12 +1509,36 @@ class BackupManager: password = data['password'] dir = data['dir'] username = "admin" + cyberPanelPort = data.get('cyberPanelPort', 8090) # Default to 8090 if not provided finalData = json.dumps({'dir': dir, "username": username, "password": password}) - r = requests.post("https://" + ipAddress + ":8090/api/cancelRemoteTransfer", data=finalData, - verify=False) - - data = json.loads(r.text) + + # Try to connect with port fallback + ports_to_try = [cyberPanelPort, 8090] if cyberPanelPort != 8090 else [8090] + connection_successful = False + used_port = None + + for port in ports_to_try: + try: + url = f"https://{ipAddress}:{port}/api/cancelRemoteTransfer" + r = requests.post(url, data=finalData, verify=False, timeout=10) + data = json.loads(r.text) + connection_successful = True + used_port = port + break + except (requests.exceptions.ConnectionError, requests.exceptions.Timeout, + requests.exceptions.RequestException, json.JSONDecodeError) as e: + if port == ports_to_try[-1]: # Last port failed + data_ret = {'cancelStatus': 0, + 'error_message': f"Could not connect to remote server on any port. Tried ports: {', '.join(map(str, ports_to_try))}. Last error: {str(e)}"} + data_ret = json.dumps(data_ret) + return HttpResponse(data_ret) + continue + + if not connection_successful: + data_ret = {'cancelStatus': 0, 'error_message': "Connection failed on all ports"} + data_ret = json.dumps(data_ret) + return HttpResponse(data_ret) if data['cancelStatus'] == 1: pass diff --git a/backup/static/backup/backup.js b/backup/static/backup/backup.js index 7323e8e49..a068ba3a6 100644 --- a/backup/static/backup/backup.js +++ b/backup/static/backup/backup.js @@ -742,6 +742,18 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { $scope.transferBoxBtn = true; $scope.stopTransferbtn = true; $scope.fetchAccountsBtn = false; + + // Progress tracking variables + $scope.overallProgress = 0; + $scope.currentStep = 0; + $scope.transferInProgress = false; + $scope.transferCompleted = false; + $scope.transferError = false; + $scope.downloadStatus = "Waiting..."; + $scope.transferStatus = "Waiting..."; + $scope.restoreStatus = "Waiting..."; + $scope.logEntries = []; + $scope.showLog = false; // notifications boxes @@ -765,6 +777,61 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { $scope.passwordEnter = function () { $scope.backupButton = false; }; + + // Progress tracking functions + $scope.addLogEntry = function(message, type = 'info') { + $scope.logEntries.push({ + timestamp: new Date(), + message: message, + type: type + }); + + // Keep only last 100 log entries + if ($scope.logEntries.length > 100) { + $scope.logEntries = $scope.logEntries.slice(-100); + } + + // Auto-scroll to bottom + setTimeout(function() { + var logOutput = document.getElementById('logOutput'); + if (logOutput) { + logOutput.scrollTop = logOutput.scrollHeight; + } + }, 100); + }; + + $scope.updateProgress = function(step, progress, status) { + $scope.currentStep = step; + $scope.overallProgress = progress; + + switch(step) { + case 1: + $scope.downloadStatus = status; + break; + case 2: + $scope.transferStatus = status; + break; + case 3: + $scope.restoreStatus = status; + break; + } + }; + + $scope.toggleLog = function() { + $scope.showLog = !$scope.showLog; + }; + + $scope.resetProgress = function() { + $scope.overallProgress = 0; + $scope.currentStep = 0; + $scope.transferInProgress = false; + $scope.transferCompleted = false; + $scope.transferError = false; + $scope.downloadStatus = "Waiting..."; + $scope.transferStatus = "Waiting..."; + $scope.restoreStatus = "Waiting..."; + $scope.logEntries = []; + }; $scope.addRemoveWebsite = function (website, websiteStatus) { @@ -819,12 +886,14 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { var IPAddress = $scope.IPAddress; var password = $scope.password; + var cyberPanelPort = $scope.cyberPanelPort || 8090; // Default to 8090 if not specified url = "/backup/submitRemoteBackups"; var data = { ipAddress: IPAddress, password: password, + cyberPanelPort: cyberPanelPort, }; var config = { @@ -860,6 +929,16 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { $scope.accountsFetched = false; $scope.backupProcessStarted = true; $scope.backupCancelled = true; + + // Show fallback port notification if used + if (response.data.used_port && response.data.used_port != $scope.cyberPanelPort) { + new PNotify({ + title: 'Port Fallback Used', + text: `Connected using port ${response.data.used_port} (fallback from ${$scope.cyberPanelPort})`, + type: 'info', + delay: 5000 + }); + } } else { @@ -893,6 +972,10 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { }; $scope.startTransfer = function () { + // Reset progress tracking + $scope.resetProgress(); + $scope.transferInProgress = true; + $scope.addLogEntry("Starting remote backup transfer...", "info"); // notifications boxes $scope.notificationsBox = true; @@ -915,12 +998,14 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { var IPAddress = $scope.IPAddress; var password = $scope.password; + var cyberPanelPort = $scope.cyberPanelPort || 8090; // Default to 8090 if not specified url = "/backup/starRemoteTransfer"; var data = { ipAddress: IPAddress, password: password, + cyberPanelPort: cyberPanelPort, accountsToTransfer: websitesToBeBacked, }; @@ -1002,6 +1087,7 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { var data = { password: $scope.password, ipAddress: $scope.IPAddress, + cyberPanelPort: $scope.cyberPanelPort || 8090, dir: tempTransferDir }; @@ -1021,13 +1107,31 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { if (response.data.backupsSent === 0) { $scope.backupStatus = false; $scope.requestData = response.data.status; + + // Update progress based on status content + var status = response.data.status; + if (status) { + $scope.addLogEntry(status, "info"); + + // Parse status for progress updates + if (status.includes("Backup process started") || status.includes("Generating backup")) { + $scope.updateProgress(1, 25, "Generating backups on remote server..."); + } else if (status.includes("Transferring") || status.includes("Sending backup")) { + $scope.updateProgress(2, 50, "Transferring backup files..."); + } else if (status.includes("Backup received") || status.includes("Downloading")) { + $scope.updateProgress(2, 75, "Downloading backup files..."); + } + } + $timeout(getBackupStatus, 2000); } else { $scope.requestData = response.data.status; + $scope.addLogEntry("Backup transfer completed successfully!", "success"); + $scope.updateProgress(2, 100, "Transfer completed"); $timeout.cancel(); // Start the restore of remote backups that are transferred to local server - + $scope.addLogEntry("Starting local restore process...", "info"); remoteBackupRestore(); } } else { @@ -1035,6 +1139,8 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { $scope.error_message = response.data.error_message; $scope.backupLoading = true; $scope.couldNotConnect = true; + $scope.transferError = true; + $scope.addLogEntry("Transfer failed: " + response.data.error_message, "error"); // Notifications box settings @@ -1077,7 +1183,12 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { function ListInitialDatas(response) { if (response.data.remoteRestoreStatus === 1) { + $scope.addLogEntry("Remote restore initiated successfully", "success"); + $scope.updateProgress(3, 85, "Restoring websites..."); localRestoreStatus(); + } else { + $scope.addLogEntry("Remote restore failed: " + (response.data.error_message || "Unknown error"), "error"); + $scope.transferError = true; } } @@ -1121,9 +1232,31 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { if (response.data.complete === 0) { $scope.backupStatus = false; $scope.restoreData = response.data.status; + + // Update restore progress + var status = response.data.status; + if (status) { + $scope.addLogEntry(status, "info"); + + if (status.includes("completed[success]")) { + $scope.updateProgress(3, 100, "Restore completed successfully!"); + $scope.transferCompleted = true; + $scope.transferInProgress = false; + $scope.addLogEntry("All websites restored successfully!", "success"); + } else if (status.includes("Error") || status.includes("error")) { + $scope.addLogEntry("Restore error: " + status, "error"); + } else { + $scope.updateProgress(3, 90, "Finalizing restore..."); + } + } + $timeout(localRestoreStatus, 2000); } else { $scope.restoreData = response.data.status; + $scope.updateProgress(3, 100, "Restore completed!"); + $scope.transferCompleted = true; + $scope.transferInProgress = false; + $scope.addLogEntry("Restore process completed successfully!", "success"); $timeout.cancel(); $scope.backupLoading = true; $scope.startTransferbtn = false; @@ -1133,6 +1266,8 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { $scope.error_message = response.data.error_message; $scope.backupLoading = true; $scope.couldNotConnect = true; + $scope.transferError = true; + $scope.addLogEntry("Restore failed: " + response.data.error_message, "error"); // Notifications box settings @@ -1163,6 +1298,7 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { var data = { password: $scope.password, ipAddress: $scope.IPAddress, + cyberPanelPort: $scope.cyberPanelPort || 8090, dir: tempTransferDir, }; @@ -1215,12 +1351,14 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { var IPAddress = $scope.IPAddress; var password = $scope.password; + var cyberPanelPort = $scope.cyberPanelPort || 8090; url = "/backup/cancelRemoteBackup"; var data = { ipAddress: IPAddress, password: password, + cyberPanelPort: cyberPanelPort, dir: tempTransferDir, }; diff --git a/backup/templates/backup/remoteBackups.html b/backup/templates/backup/remoteBackups.html index 1ed4f5451..8a88352f9 100644 --- a/backup/templates/backup/remoteBackups.html +++ b/backup/templates/backup/remoteBackups.html @@ -381,6 +381,251 @@ background: var(--success-color, #10b981); } + /* Progress Section Styles */ + .progress-section { + background: var(--bg-primary, #fff); + border-radius: 15px; + box-shadow: 0 4px 20px var(--shadow-light, rgba(0, 0, 0, 0.1)); + margin-top: 2rem; + overflow: hidden; + animation: fadeInUp 0.5s ease-out; + } + + .progress-header { + background: linear-gradient(135deg, var(--accent-color, #5b5fcf) 0%, var(--accent-hover, #4547a9) 100%); + color: white; + padding: 1.5rem 2rem; + display: flex; + justify-content: space-between; + align-items: center; + } + + .progress-title { + font-size: 1.5rem; + font-weight: 600; + display: flex; + align-items: center; + gap: 0.75rem; + } + + .status-badge { + padding: 0.5rem 1rem; + border-radius: 20px; + font-size: 0.875rem; + font-weight: 500; + display: flex; + align-items: center; + gap: 0.5rem; + } + + .status-progress { + background: rgba(255, 255, 255, 0.2); + color: white; + } + + .status-completed { + background: #10b981; + color: white; + } + + .status-error { + background: #ef4444; + color: white; + } + + .progress-overview { + padding: 2rem; + background: var(--bg-secondary, #f8fafc); + } + + .progress-bar-container { + position: relative; + background: var(--bg-primary, #fff); + border-radius: 10px; + padding: 1rem; + box-shadow: 0 2px 10px var(--shadow-light, rgba(0, 0, 0, 0.05)); + } + + .progress-bar { + width: 100%; + height: 20px; + background: #e2e8f0; + border-radius: 10px; + overflow: hidden; + position: relative; + } + + .progress-fill { + height: 100%; + background: linear-gradient(90deg, var(--accent-color, #5b5fcf) 0%, var(--accent-hover, #4547a9) 100%); + border-radius: 10px; + transition: width 0.5s ease; + position: relative; + } + + .progress-fill::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.3) 50%, transparent 100%); + animation: shimmer 2s infinite; + } + + @keyframes shimmer { + 0% { transform: translateX(-100%); } + 100% { transform: translateX(100%); } + } + + .progress-text { + text-align: center; + margin-top: 0.75rem; + font-weight: 600; + color: var(--text-primary, #1e293b); + font-size: 1.1rem; + } + + .progress-details { + padding: 2rem; + } + + .progress-step { + display: flex; + align-items: center; + padding: 1.5rem 0; + border-bottom: 1px solid var(--border-light, #e2e8f0); + opacity: 0.5; + transition: all 0.3s ease; + } + + .progress-step:last-child { + border-bottom: none; + } + + .progress-step.active { + opacity: 1; + background: var(--bg-hover, #f8f9ff); + margin: 0 -2rem; + padding: 1.5rem 2rem; + border-radius: 10px; + } + + .progress-step.completed { + opacity: 1; + } + + .step-icon { + width: 50px; + height: 50px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin-right: 1.5rem; + font-size: 1.25rem; + transition: all 0.3s ease; + } + + .progress-step:not(.active):not(.completed) .step-icon { + background: var(--bg-secondary, #f1f5f9); + color: var(--text-secondary, #64748b); + } + + .progress-step.active .step-icon { + background: var(--accent-color, #5b5fcf); + color: white; + animation: pulse 2s infinite; + } + + .progress-step.completed .step-icon { + background: #10b981; + color: white; + } + + @keyframes pulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.1); } + } + + .step-content { + flex: 1; + } + + .step-title { + font-size: 1.1rem; + font-weight: 600; + color: var(--text-primary, #1e293b); + margin-bottom: 0.25rem; + } + + .step-description { + color: var(--text-secondary, #64748b); + font-size: 0.9rem; + } + + .log-section { + border-top: 1px solid var(--border-light, #e2e8f0); + background: var(--bg-dark, #1e293b); + color: var(--text-light, #e2e8f0); + } + + .log-header { + padding: 1rem 2rem; + border-bottom: 1px solid var(--border-dark, #334155); + display: flex; + justify-content: space-between; + align-items: center; + } + + .log-header h4 { + margin: 0; + color: var(--text-light, #e2e8f0); + display: flex; + align-items: center; + gap: 0.5rem; + } + + .log-content { + max-height: 300px; + overflow-y: auto; + } + + .log-output { + padding: 1rem 2rem; + font-family: 'Consolas', 'Monaco', 'Courier New', monospace; + font-size: 0.875rem; + line-height: 1.5; + } + + .log-entry { + margin-bottom: 0.5rem; + display: flex; + gap: 1rem; + } + + .log-time { + color: var(--text-muted, #94a3b8); + min-width: 80px; + } + + .log-message { + flex: 1; + } + + .log-entry.log-error .log-message { + color: #ef4444; + } + + .log-entry.log-success .log-message { + color: #10b981; + } + + .log-entry.log-info .log-message { + color: #3b82f6; + } + .terminal-body { padding: 1.5rem; height: 350px; @@ -525,7 +770,7 @@
-
+
-
+
+
+ + + + {% trans "Port where CyberPanel is running on remote server (default: 8090)" %} + +
+
+
- -
-
-
- + +
+
+
+ + + {% trans "Transfer Progress" %}
-
-
-
-
+
+ + {% trans "In Progress" %} + + + {% trans "Completed" %} + + + {% trans "Error" %} +
-
-
-
-

- {% trans "Backup Progress" %} -

-
+ + +
+
+
+
-
-

- {% trans "Restore Progress" %} -

-
+
+ {{ overallProgress }}% + {% trans "Complete!" %} +
+
+
+ + +
+
+
+ + + +
+
+
{% trans "Downloading Backups" %}
+
{{ downloadStatus }}
+
+
+ +
+
+ + + +
+
+
{% trans "Transferring Data" %}
+
{{ transferStatus }}
+
+
+ +
+
+ + + +
+
+
{% trans "Restoring Websites" %}
+
{{ restoreStatus }}
+
+
+
+ + +
+
+

+ + {% trans "Live Log" %} + +

+
+
+
+
+ {{ logEntry.timestamp | date:'HH:mm:ss' }} + {{ logEntry.message }} +
diff --git a/plogical/remoteBackup.py b/plogical/remoteBackup.py index 5d8f2decc..2e6bc3d9b 100644 --- a/plogical/remoteBackup.py +++ b/plogical/remoteBackup.py @@ -150,10 +150,10 @@ class remoteBackup: return [0, msg] @staticmethod - def postRemoteTransfer(ipAddress, ownIP ,password, sshkey): + def postRemoteTransfer(ipAddress, ownIP ,password, sshkey, cyberPanelPort=8090): try: finalData = json.dumps({'username': "admin", "ipAddress": ownIP, "password": password}) - url = "https://" + ipAddress + ":8090/api/remoteTransfer" + url = "https://" + ipAddress + ":" + str(cyberPanelPort) + "/api/remoteTransfer" r = requests.post(url, data=finalData, verify=False) data = json.loads(r.text)