Before mounting, probe each share's remote path with `rclone lsf` (10s timeout, parallel execution). Failed shares are skipped — they never get mounted or exposed to SMB/NFS/WebDAV — preventing the silent hang that occurred when rclone mounted a nonexistent directory. - ShareHealth enum: Pending → Probing → Healthy / Failed(reason) - Supervisor: probe phase between preflight and mount, protocol configs generated after probe with only healthy shares - Web UI: health-aware badges (OK/FAILED/PROBING/PENDING) with error messages on dashboard, status partial, and share detail - JSON API: health + health_message fields on /api/status - CLI: `warpgate status` queries daemon API first for tri-state display (OK/FAILED/DOWN), falls back to direct mount checks Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
77 lines
3.5 KiB
HTML
77 lines
3.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Warpgate — {{ name }}</title>
|
|
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
|
|
<style>
|
|
:root {
|
|
--bg: #0f1117; --surface: #1a1d27; --border: #2a2d3a;
|
|
--text: #e1e4ed; --text-muted: #8b8fa3; --accent: #6c8aff;
|
|
--green: #4ade80; --red: #f87171; --yellow: #fbbf24;
|
|
--font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace;
|
|
}
|
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
body { background: var(--bg); color: var(--text); font-family: var(--font); padding: 24px; max-width: 960px; margin: 0 auto; }
|
|
a { color: var(--accent); text-decoration: none; }
|
|
a:hover { text-decoration: underline; }
|
|
.breadcrumb { font-size: 0.85em; color: var(--text-muted); margin-bottom: 16px; }
|
|
h1 { font-size: 1.4em; margin-bottom: 16px; }
|
|
.badge { font-size: 0.75em; padding: 2px 8px; border-radius: 4px; font-weight: 600; vertical-align: middle; }
|
|
.badge-ok { background: rgba(74,222,128,0.15); color: var(--green); }
|
|
.badge-error { background: rgba(248,113,113,0.15); color: var(--red); }
|
|
.badge-ro { background: rgba(251,191,36,0.15); color: var(--yellow); }
|
|
.badge-warn { background: rgba(251,191,36,0.15); color: var(--yellow); }
|
|
.error-text { color: var(--red); }
|
|
.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 24px; }
|
|
.detail-card { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 16px; }
|
|
.detail-card .label { font-size: 0.8em; color: var(--text-muted); margin-bottom: 4px; }
|
|
.detail-card .value { font-size: 1.2em; font-weight: 600; }
|
|
.info-table { width: 100%; border-collapse: collapse; }
|
|
.info-table td { padding: 8px 12px; border-bottom: 1px solid var(--border); }
|
|
.info-table td:first-child { color: var(--text-muted); width: 140px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="breadcrumb"><a href="/">Dashboard</a> / {{ name }}</div>
|
|
|
|
<h1>
|
|
{{ name }}
|
|
{% if health == "OK" %}<span class="badge badge-ok">OK</span>{% elif health == "FAILED" %}<span class="badge badge-error">FAILED</span>{% elif health == "PROBING" %}<span class="badge badge-warn">PROBING</span>{% else %}<span class="badge badge-warn">PENDING</span>{% endif %}
|
|
{% if read_only %}<span class="badge badge-ro">Read-Only</span>{% endif %}
|
|
</h1>
|
|
|
|
<div class="detail-grid">
|
|
<div class="detail-card">
|
|
<div class="label">Cache Used</div>
|
|
<div class="value">{{ cache_display }}</div>
|
|
</div>
|
|
<div class="detail-card">
|
|
<div class="label">Dirty Files</div>
|
|
<div class="value">{{ dirty_count }}</div>
|
|
</div>
|
|
<div class="detail-card">
|
|
<div class="label">Transfer Speed</div>
|
|
<div class="value">{{ speed_display }}</div>
|
|
</div>
|
|
<div class="detail-card">
|
|
<div class="label">Active Transfers</div>
|
|
<div class="value">{{ transfers }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<table class="info-table">
|
|
<tr><td>Health</td><td>{{ health }}</td></tr>
|
|
{% if health == "FAILED" %}
|
|
<tr><td>Probe Error</td><td class="error-text">{{ health_message }}</td></tr>
|
|
{% endif %}
|
|
<tr><td>Mount Point</td><td>{{ mount_point }}</td></tr>
|
|
<tr><td>Remote Path</td><td>{{ remote_path }}</td></tr>
|
|
<tr><td>RC Port</td><td>{{ rc_port }}</td></tr>
|
|
<tr><td>Errored Files</td><td>{{ errored_files }}</td></tr>
|
|
<tr><td>Total Errors</td><td>{{ errors }}</td></tr>
|
|
</table>
|
|
</body>
|
|
</html>
|