mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-07 13:56:01 +01:00
additional n8n functions
This commit is contained in:
@@ -1151,37 +1151,6 @@ class ContainerManager(multi.Thread):
|
||||
'cpu_usage': container.stats(stream=False)['cpu_stats']['cpu_usage'].get('total_usage', 0)
|
||||
}
|
||||
|
||||
# Add N8N specific health metrics if this is an N8N container
|
||||
if 'n8n' in container.name.lower():
|
||||
try:
|
||||
# Get N8N port from environment variables or port bindings
|
||||
n8n_port = None
|
||||
for port_config in container_info.get('NetworkSettings', {}).get('Ports', {}).values():
|
||||
if port_config:
|
||||
n8n_port = port_config[0].get('HostPort')
|
||||
break
|
||||
|
||||
if n8n_port:
|
||||
# Try to get N8N health metrics from the API
|
||||
health_url = f"http://localhost:{n8n_port}/api/v1/health"
|
||||
response = requests.get(health_url, timeout=5)
|
||||
if response.status_code == 200:
|
||||
health_data = response.json()
|
||||
details['n8nStats'] = {
|
||||
'dbConnected': health_data.get('db', {}).get('status') == 'ok',
|
||||
'activeWorkflows': len(health_data.get('activeWorkflows', [])),
|
||||
'queuedExecutions': health_data.get('executionQueue', {}).get('waiting', 0),
|
||||
'lastExecution': health_data.get('lastExecution')
|
||||
}
|
||||
except:
|
||||
# If we can't get N8N stats, provide default values
|
||||
details['n8nStats'] = {
|
||||
'dbConnected': None,
|
||||
'activeWorkflows': 0,
|
||||
'queuedExecutions': 0,
|
||||
'lastExecution': None
|
||||
}
|
||||
|
||||
data_ret = {'status': 1, 'error_message': 'None', 'data': [1, details]}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
@@ -1332,182 +1301,4 @@ class ContainerManager(multi.Thread):
|
||||
except BaseException as msg:
|
||||
data_ret = {'removeImageStatus': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def _get_backup_dir(self, container_id):
|
||||
"""Helper method to get the backup directory for a container"""
|
||||
return f"/home/docker/backups/{container_id}"
|
||||
|
||||
def createBackup(self, userID=None, data=None):
|
||||
try:
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
if admin.acl.adminStatus != 1:
|
||||
return ACLManager.loadError()
|
||||
|
||||
container_id = data['id']
|
||||
client = docker.from_env()
|
||||
container = client.containers.get(container_id)
|
||||
|
||||
# Create backup directory if it doesn't exist
|
||||
backup_dir = self._get_backup_dir(container_id)
|
||||
os.makedirs(backup_dir, exist_ok=True)
|
||||
|
||||
# Create timestamp for backup
|
||||
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
||||
backup_file = f"{backup_dir}/backup_{timestamp}.tar.gz"
|
||||
|
||||
# Get N8N data directory from container mounts
|
||||
n8n_data_dir = None
|
||||
for mount in container.attrs.get('Mounts', []):
|
||||
if mount.get('Destination', '').endswith('/.n8n'):
|
||||
n8n_data_dir = mount.get('Source')
|
||||
break
|
||||
|
||||
if not n8n_data_dir:
|
||||
raise Exception("N8N data directory not found in container mounts")
|
||||
|
||||
# Create backup using tar
|
||||
backup_cmd = f"tar -czf {backup_file} -C {n8n_data_dir} ."
|
||||
result = subprocess.run(backup_cmd, shell=True, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception(f"Backup failed: {result.stderr}")
|
||||
|
||||
data_ret = {'status': 1, 'error_message': 'None', 'backup_file': backup_file}
|
||||
return HttpResponse(json.dumps(data_ret))
|
||||
|
||||
except Exception as e:
|
||||
data_ret = {'status': 0, 'error_message': str(e)}
|
||||
return HttpResponse(json.dumps(data_ret))
|
||||
|
||||
def listBackups(self, userID=None, data=None):
|
||||
try:
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
if admin.acl.adminStatus != 1:
|
||||
return ACLManager.loadError()
|
||||
|
||||
container_id = data['id']
|
||||
backup_dir = self._get_backup_dir(container_id)
|
||||
|
||||
if not os.path.exists(backup_dir):
|
||||
backups = []
|
||||
else:
|
||||
backups = []
|
||||
for file in os.listdir(backup_dir):
|
||||
if file.startswith('backup_') and file.endswith('.tar.gz'):
|
||||
file_path = os.path.join(backup_dir, file)
|
||||
file_stat = os.stat(file_path)
|
||||
backups.append({
|
||||
'id': file,
|
||||
'date': datetime.fromtimestamp(file_stat.st_mtime).isoformat(),
|
||||
'size': file_stat.st_size
|
||||
})
|
||||
|
||||
data_ret = {'status': 1, 'error_message': 'None', 'backups': backups}
|
||||
return HttpResponse(json.dumps(data_ret))
|
||||
|
||||
except Exception as e:
|
||||
data_ret = {'status': 0, 'error_message': str(e)}
|
||||
return HttpResponse(json.dumps(data_ret))
|
||||
|
||||
def restoreBackup(self, userID=None, data=None):
|
||||
try:
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
if admin.acl.adminStatus != 1:
|
||||
return ACLManager.loadError()
|
||||
|
||||
container_id = data['id']
|
||||
backup_id = data['backup_id']
|
||||
client = docker.from_env()
|
||||
container = client.containers.get(container_id)
|
||||
|
||||
backup_dir = self._get_backup_dir(container_id)
|
||||
backup_file = os.path.join(backup_dir, backup_id)
|
||||
|
||||
if not os.path.exists(backup_file):
|
||||
raise Exception("Backup file not found")
|
||||
|
||||
# Get N8N data directory from container mounts
|
||||
n8n_data_dir = None
|
||||
for mount in container.attrs.get('Mounts', []):
|
||||
if mount.get('Destination', '').endswith('/.n8n'):
|
||||
n8n_data_dir = mount.get('Source')
|
||||
break
|
||||
|
||||
if not n8n_data_dir:
|
||||
raise Exception("N8N data directory not found in container mounts")
|
||||
|
||||
# Stop the container
|
||||
container.stop()
|
||||
|
||||
try:
|
||||
# Clear existing data
|
||||
shutil.rmtree(n8n_data_dir)
|
||||
os.makedirs(n8n_data_dir)
|
||||
|
||||
# Restore from backup
|
||||
restore_cmd = f"tar -xzf {backup_file} -C {n8n_data_dir}"
|
||||
result = subprocess.run(restore_cmd, shell=True, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception(f"Restore failed: {result.stderr}")
|
||||
|
||||
# Start the container
|
||||
container.start()
|
||||
|
||||
data_ret = {'status': 1, 'error_message': 'None'}
|
||||
return HttpResponse(json.dumps(data_ret))
|
||||
|
||||
except Exception as e:
|
||||
# Try to start the container even if restore failed
|
||||
try:
|
||||
container.start()
|
||||
except:
|
||||
pass
|
||||
raise e
|
||||
|
||||
except Exception as e:
|
||||
data_ret = {'status': 0, 'error_message': str(e)}
|
||||
return HttpResponse(json.dumps(data_ret))
|
||||
|
||||
def deleteBackup(self, userID=None, data=None):
|
||||
try:
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
if admin.acl.adminStatus != 1:
|
||||
return ACLManager.loadError()
|
||||
|
||||
container_id = data['id']
|
||||
backup_id = data['backup_id']
|
||||
backup_dir = self._get_backup_dir(container_id)
|
||||
backup_file = os.path.join(backup_dir, backup_id)
|
||||
|
||||
if os.path.exists(backup_file):
|
||||
os.remove(backup_file)
|
||||
|
||||
data_ret = {'status': 1, 'error_message': 'None'}
|
||||
return HttpResponse(json.dumps(data_ret))
|
||||
|
||||
except Exception as e:
|
||||
data_ret = {'status': 0, 'error_message': str(e)}
|
||||
return HttpResponse(json.dumps(data_ret))
|
||||
|
||||
def downloadBackup(self, userID=None, data=None):
|
||||
try:
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
if admin.acl.adminStatus != 1:
|
||||
return ACLManager.loadError()
|
||||
|
||||
container_id = data['id']
|
||||
backup_id = data['backup_id']
|
||||
backup_dir = self._get_backup_dir(container_id)
|
||||
backup_file = os.path.join(backup_dir, backup_id)
|
||||
|
||||
if not os.path.exists(backup_file):
|
||||
raise Exception("Backup file not found")
|
||||
|
||||
with open(backup_file, 'rb') as f:
|
||||
response = HttpResponse(f.read(), content_type='application/gzip')
|
||||
response['Content-Disposition'] = f'attachment; filename="{backup_id}"'
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
data_ret = {'status': 0, 'error_message': str(e)}
|
||||
return HttpResponse(json.dumps(data_ret))
|
||||
return HttpResponse(json_data)
|
||||
Reference in New Issue
Block a user