Extra features

This commit is contained in:
Aodhan Collins
2025-07-27 01:58:39 +01:00
parent ab949897f5
commit cf761decd8
2 changed files with 185 additions and 11 deletions

155
api.py
View File

@@ -8,6 +8,8 @@ import json
import subprocess
import time
import logging
import platform
import glob
from datetime import datetime
from flask import Flask, jsonify, render_template, request, send_from_directory
from flask_cors import CORS
@@ -136,28 +138,109 @@ class DockerService:
def get_system_info(self):
"""Get system information"""
try:
# CPU usage
cpu_percent = psutil.cpu_percent(interval=1)
# Memory usage
memory = psutil.virtual_memory()
disk = psutil.disk_usage('/')
# Disk usage - try multiple paths for different systems
disk_info = None
disk_paths = ['/']
# Add common mount points for different Linux distributions
if os.path.exists('/home'):
disk_paths.append('/home')
if os.path.exists('/var'):
disk_paths.append('/var')
if os.path.exists('/opt'):
disk_paths.append('/opt')
# Try each path until we find one that works
for path in disk_paths:
try:
disk_info = psutil.disk_usage(path)
break
except (OSError, IOError, PermissionError):
continue
# Fallback to root directory
if disk_info is None:
try:
disk_info = psutil.disk_usage('/')
except (OSError, IOError) as e:
logging.error(f"Cannot get disk usage: {e}")
# Return zero values as fallback
disk_info = type('DiskInfo', (), {
'total': 0,
'used': 0,
'free': 0
})()
# Get load average (works on both Debian and Fedora)
try:
import os
load_avg = os.getloadavg()
except (AttributeError, OSError):
load_avg = (0.0, 0.0, 0.0)
# Get swap memory
swap = psutil.swap_memory()
# Format disk usage for display
def format_bytes(bytes_value):
"""Format bytes to human readable format"""
for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
if bytes_value < 1024.0:
return f"{bytes_value:.1f} {unit}"
bytes_value /= 1024.0
return f"{bytes_value:.1f} PB"
return {
'cpu_percent': psutil.cpu_percent(),
'cpu': {
'percent': cpu_percent,
'cores': psutil.cpu_count(),
'load_avg': load_avg
},
'memory': {
'total': memory.total,
'available': memory.available,
'used': memory.used,
'percent': memory.percent,
'used': memory.used
'formatted_total': format_bytes(memory.total),
'formatted_used': format_bytes(memory.used),
'formatted_available': format_bytes(memory.available)
},
'swap': {
'total': swap.total,
'used': swap.used,
'percent': swap.percent
},
'disk': {
'total': disk.total,
'used': disk.used,
'free': disk.free,
'percent': (disk.used / disk.total) * 100
'total': disk_info.total,
'used': disk_info.used,
'free': disk_info.free,
'percent': (disk_info.used / disk_info.total) * 100 if disk_info.total > 0 else 0,
'formatted_total': format_bytes(disk_info.total),
'formatted_used': format_bytes(disk_info.used),
'formatted_free': format_bytes(disk_info.free)
},
'uptime': self._get_system_uptime()
'uptime': self._get_system_uptime(),
'platform': {
'system': platform.system(),
'release': platform.release(),
'machine': platform.machine()
}
}
except Exception as e:
logging.error(f"Error getting system info: {e}")
return {}
return {
'error': str(e),
'cpu': {'percent': 0, 'cores': 1},
'memory': {'total': 0, 'available': 0, 'used': 0, 'percent': 0},
'disk': {'total': 0, 'used': 0, 'free': 0, 'percent': 0},
'uptime': 'Unknown'
}
def _get_system_uptime(self):
"""Get system uptime"""
@@ -388,5 +471,59 @@ def sync_applications():
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/api/containers/<container_id>/start', methods=['POST'])
def start_container(container_id):
"""Start a specific container"""
try:
if docker_service.client is None:
return jsonify({'success': False, 'error': 'Docker client not available'}), 500
container = docker_service.client.containers.get(container_id)
container.start()
# Update database with new status
db.update_application(container_id, {'status': 'running'})
return jsonify({'success': True, 'message': 'Container started successfully'})
except Exception as e:
logging.error(f"Error starting container {container_id}: {e}")
return jsonify({'success': False, 'error': str(e)}), 500
@app.route('/api/containers/<container_id>/stop', methods=['POST'])
def stop_container(container_id):
"""Stop a specific container"""
try:
if docker_service.client is None:
return jsonify({'success': False, 'error': 'Docker client not available'}), 500
container = docker_service.client.containers.get(container_id)
container.stop()
# Update database with new status
db.update_application(container_id, {'status': 'exited'})
return jsonify({'success': True, 'message': 'Container stopped successfully'})
except Exception as e:
logging.error(f"Error stopping container {container_id}: {e}")
return jsonify({'success': False, 'error': str(e)}), 500
@app.route('/api/containers/<container_id>/restart', methods=['POST'])
def restart_container(container_id):
"""Restart a specific container"""
try:
if docker_service.client is None:
return jsonify({'success': False, 'error': 'Docker client not available'}), 500
container = docker_service.client.containers.get(container_id)
container.restart()
# Update database with new status
db.update_application(container_id, {'status': 'running'})
return jsonify({'success': True, 'message': 'Container restarted successfully'})
except Exception as e:
logging.error(f"Error restarting container {container_id}: {e}")
return jsonify({'success': False, 'error': str(e)}), 500
if __name__ == '__main__':
app.run(host=HOST, port=PORT, debug=DEBUG)