mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-12-15 12:59:42 +01:00
Add resource limits display on website detail page
- Fetch actual resource limits from lscgctl command in loadDomainHome - Parse JSON output and extract CPU, Memory, I/O, Tasks values - Display resource limits in dedicated section on website detail page - Only show limits if they actually exist on the site - Use modern card design with gradients matching the rest of the UI
This commit is contained in:
@@ -1486,6 +1486,69 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Resource Limits Section -->
|
||||||
|
{% if resource_limits %}
|
||||||
|
<div class="cyber-card" style="margin-top: 25px;">
|
||||||
|
<div class="cyber-section-title" style="margin-bottom:20px;">
|
||||||
|
<span style="display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;border:1.5px solid #dbeafe;border-radius:8px;margin-right:12px;background:#f6faff;">
|
||||||
|
<i class="fas fa-sliders-h" style="color: #222b38; font-size: 18px;"></i>
|
||||||
|
</span>
|
||||||
|
<span>{% trans "Resource Limits" %}</span>
|
||||||
|
</div>
|
||||||
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px;">
|
||||||
|
{% if resource_limits.cpu %}
|
||||||
|
<div class="resource-card" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none;">
|
||||||
|
<div class="resource-icon" style="background: rgba(255, 255, 255, 0.2); color: white;">
|
||||||
|
<i class="fas fa-microchip"></i>
|
||||||
|
</div>
|
||||||
|
<div class="resource-title" style="color: white;">{% trans "CPU" %}</div>
|
||||||
|
<div class="resource-value" style="color: white;">{{ resource_limits.cpu }}%</div>
|
||||||
|
<div class="resource-limit" style="color: rgba(255, 255, 255, 0.9);">{% trans "CPU cores allocated" %}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if resource_limits.memory %}
|
||||||
|
<div class="resource-card" style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; border: none;">
|
||||||
|
<div class="resource-icon" style="background: rgba(255, 255, 255, 0.2); color: white;">
|
||||||
|
<i class="fas fa-memory"></i>
|
||||||
|
</div>
|
||||||
|
<div class="resource-title" style="color: white;">{% trans "Memory" %}</div>
|
||||||
|
<div class="resource-value" style="color: white;">{{ resource_limits.memory }}</div>
|
||||||
|
<div class="resource-limit" style="color: rgba(255, 255, 255, 0.9);">{% trans "RAM limit" %}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if resource_limits.io %}
|
||||||
|
<div class="resource-card" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; border: none;">
|
||||||
|
<div class="resource-icon" style="background: rgba(255, 255, 255, 0.2); color: white;">
|
||||||
|
<i class="fas fa-tachometer-alt"></i>
|
||||||
|
</div>
|
||||||
|
<div class="resource-title" style="color: white;">{% trans "I/O" %}</div>
|
||||||
|
<div class="resource-value" style="color: white;">{{ resource_limits.io }}</div>
|
||||||
|
<div class="resource-limit" style="color: rgba(255, 255, 255, 0.9);">{% trans "Disk I/O limit" %}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if resource_limits.tasks %}
|
||||||
|
<div class="resource-card" style="background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); color: white; border: none;">
|
||||||
|
<div class="resource-icon" style="background: rgba(255, 255, 255, 0.2); color: white;">
|
||||||
|
<i class="fas fa-tasks"></i>
|
||||||
|
</div>
|
||||||
|
<div class="resource-title" style="color: white;">{% trans "Processes" %}</div>
|
||||||
|
<div class="resource-value" style="color: white;">{{ resource_limits.tasks }}</div>
|
||||||
|
<div class="resource-limit" style="color: rgba(255, 255, 255, 0.9);">{% trans "Max processes" %}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 15px; padding: 12px; background: #f8f9ff; border-radius: 8px; border-left: 4px solid #5b5fcf;">
|
||||||
|
<p style="margin: 0; color: #64748b; font-size: 13px;">
|
||||||
|
<i class="fas fa-info-circle" style="color: #5b5fcf; margin-right: 8px;"></i>
|
||||||
|
{% trans "These are the actual resource limits applied to this website. Limits are enforced at the system level using OpenLiteSpeed cgroups." %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<!-- Add Resource Usage Graphs -->
|
<!-- Add Resource Usage Graphs -->
|
||||||
<div class="cyber-card">
|
<div class="cyber-card">
|
||||||
<div class="cyber-section-title" style="margin-bottom:28px;">
|
<div class="cyber-section-title" style="margin-bottom:28px;">
|
||||||
|
|||||||
@@ -3700,6 +3700,44 @@ context /cyberpanel_suspension_page.html {
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
CyberCPLogFileWriter.writeLog(f"Failed to ensure fastapi_ssh_server is running: {e}")
|
CyberCPLogFileWriter.writeLog(f"Failed to ensure fastapi_ssh_server is running: {e}")
|
||||||
|
|
||||||
|
# Fetch actual resource limits from lscgctl command if they exist
|
||||||
|
Data['resource_limits'] = None
|
||||||
|
try:
|
||||||
|
import subprocess
|
||||||
|
lscgctl_path = '/usr/local/lsws/lsns/bin/lscgctl'
|
||||||
|
if os.path.exists(lscgctl_path):
|
||||||
|
# Get the website username
|
||||||
|
username = website.exsysUser
|
||||||
|
|
||||||
|
# Run lscgctl list-user command
|
||||||
|
result = subprocess.run(
|
||||||
|
[lscgctl_path, 'list-user', username],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=5
|
||||||
|
)
|
||||||
|
|
||||||
|
if result.returncode == 0 and result.stdout.strip():
|
||||||
|
# Parse JSON output
|
||||||
|
import json
|
||||||
|
limits_data = json.loads(result.stdout.strip())
|
||||||
|
|
||||||
|
# Find the user's limits (key is UID)
|
||||||
|
for uid, user_limits in limits_data.items():
|
||||||
|
if user_limits.get('name') == username:
|
||||||
|
# Extract and format the limits for display
|
||||||
|
Data['resource_limits'] = {
|
||||||
|
'cpu': user_limits.get('cpu', ''),
|
||||||
|
'memory': user_limits.get('mem', ''),
|
||||||
|
'io': user_limits.get('io', ''),
|
||||||
|
'tasks': user_limits.get('tasks', ''),
|
||||||
|
'iops': user_limits.get('iops', '')
|
||||||
|
}
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
# Silently fail - resource limits are optional
|
||||||
|
CyberCPLogFileWriter.writeToFile(f"Could not fetch resource limits for {self.domain}: {str(e)}")
|
||||||
|
|
||||||
proc = httpProc(request, 'websiteFunctions/website.html', Data)
|
proc = httpProc(request, 'websiteFunctions/website.html', Data)
|
||||||
return proc.render()
|
return proc.render()
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user