/*
* SysDeck - Databases Panel (v0.0.33)
* Author: Jeremy Anderson (https://dcos.net)
*
* DB Control module — unified control for SQL / NoSQL / vector /
* time-series / graph / embedded / cloud / AI database engines.
* The bridge helper bridge/db.py surfaces 32+ engines with
* summary / status / start / stop / restart / connections / query
* subcommands.
*
* The cockpit-way pattern (v0.0.31+): the bridge runs systemctl
* directly via subprocess; the JS panel passes { superuser: 'try' }
* to cockpit.spawn so the cockpit bridge prompts the operator via
* polkit for the org.sysdeck.db.modify action.
*
* The panel surfaces:
* - Summary card: total engines, running count, total data size,
* total memory, total connections.
* - Engines table: per-engine id, name, family, status, version,
* port, size, memory, connections, with Start/Stop/Restart
* buttons per row.
* - Query runner: SQL-family engines only — input a SQL string
* and execute against the selected engine.
* - Connections viewer: list active TCP connections to an engine.
*
* Bridge surface (see shared/bridge.js → bridge.db):
* summary() → {engines, totalEngines, runningCount, ...}
* status(id) → single-engine detail dict
* start(id) → {action, engine, rc, success, output, stderr}
* stop(id) → same shape
* restart(id) → same shape
* connections(id) → {connections, count}
* query(id, sql) → {output, engine, query}
*/
export async function mount(panel, { bridge, EventBus }) {
panel.innerHTML = renderSkeleton();
let summary = {};
try {
summary = await bridge.db.summary();
} catch (err) {
panel.innerHTML = renderError(err);
return;
}
const engines = summary.engines || [];
const running = engines.filter((e) => e.status === 'running');
const totalSize = summary.totalSizeMB || 0;
const totalMem = summary.totalMemoryMB || 0;
const totalConn = summary.totalConnections || 0;
// Group engines by family for cleaner rendering.
const byFamily = new Map();
for (const e of engines) {
if (!byFamily.has(e.family)) byFamily.set(e.family, []);
byFamily.get(e.family).push(e);
}
panel.innerHTML = `
${summary.totalEngines || engines.length} engines across ${byFamily.size} families
· ${running.length} running
· ${(totalSize / 1024).toFixed(1)} GB data
· ${(totalMem / 1024).toFixed(1)} GB memory
· ${totalConn} connections
Database Control
SQL-family engines only (postgresql, mysql/mariadb, sqlite, cockroachdb, clickhouse, duckdb).
The query is run via the engine's CLI client (psql -tAc, mysql -e, etc.).
Click ▶/■/↻ on a row above to start / stop / restart an engine. Click 🔍 to view the engine's full status (version, port, data dir, config path, log path, connections, memory).
No database engines detected on this host.
| Engine | Status | Version | Port | Size | Mem | Conns | Actions |
|---|---|---|---|---|---|---|---|
| ${escapeHtml(e.name)} ${escapeHtml(e.id)} |
${statusBadge(e.status)} | ${escapeHtml((e.version || '').slice(0, 30))} | ${e.port || '—'} | ${formatSize(e.sizeMB)} | ${formatSize(e.memoryMB)} | ${e.connections || 0} |
|
${escapeHtml(String(err.message || err))}. Ensure the bridge helper is installed at /usr/lib/sysdeck/bridge/db.py.