Fleet: node hostname/IP on register + node terminal in the infra computer
Hostname/IP: - Daemon reports the machine's hostname (sysinfo) + primary outbound IPv4 on each heartbeat. migrations/0021 adds nodes.hostname/local_ip; cm-db heartbeat stores them; node JSON exposes them. Cards now title on the real hostname (falling back to name) + show the IP, instead of the "New node" placeholder. `name` stays user-overridable (rename). Terminal moved into the pull-out computer (no more per-card modal): - New infra computer app NodeTerminalApp (computer/apps/infra) — xterm bridged to a node's host shell over the node control channel, filling the app window (mirrors the agent Terminal's layout + ResizeObserver). Added "terminal" to the INFRA_CATALOG grid; a ?node= panel param targets a specific node (picker when unset). Clicking Terminal on a node card now opens the infra computer to that node's shell instead of a separate full-screen window. Deleted NodeTerminal.tsx. Rebuilt + re-hosted both daemon binaries (hostname change). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
cfa16751c5
commit
cf6c331b02
@@ -29,6 +29,8 @@ pub struct NodeHealth {
|
||||
pub struct NodeRow {
|
||||
pub id: NodeId,
|
||||
pub name: String,
|
||||
pub hostname: Option<String>,
|
||||
pub local_ip: Option<String>,
|
||||
pub status: String,
|
||||
pub agent_version: Option<String>,
|
||||
pub tailscale_ip: Option<String>,
|
||||
@@ -69,7 +71,7 @@ pub async fn auth(pool: &PgPool, token: &str) -> Result<Option<(NodeId, Workspac
|
||||
}))
|
||||
}
|
||||
|
||||
const SELECT_WITH_HEALTH: &str = "SELECT n.id, n.name, n.status, n.agent_version, n.tailscale_ip, n.last_seen, n.created_at,
|
||||
const SELECT_WITH_HEALTH: &str = "SELECT n.id, n.name, n.hostname, n.local_ip, n.status, n.agent_version, n.tailscale_ip, n.last_seen, n.created_at,
|
||||
h.node_id AS health_node, h.cpu_pct, h.mem_total, h.mem_used, h.mem_pressure, h.swap_used,
|
||||
h.disk_total, h.disk_free, h.load1, h.load5, h.load15, h.container_count
|
||||
FROM nodes n LEFT JOIN node_health h ON h.node_id = n.id";
|
||||
@@ -103,22 +105,29 @@ pub async fn get(
|
||||
|
||||
/// Record a heartbeat: mark the node online + refresh its version/tailscale IP,
|
||||
/// and upsert its latest host-health snapshot.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn heartbeat(
|
||||
pool: &PgPool,
|
||||
id: NodeId,
|
||||
agent_version: Option<&str>,
|
||||
tailscale_ip: Option<&str>,
|
||||
hostname: Option<&str>,
|
||||
local_ip: Option<&str>,
|
||||
h: &NodeHealth,
|
||||
) -> Result<(), DbError> {
|
||||
sqlx::query(
|
||||
"UPDATE nodes SET status = 'online', last_seen = now(),
|
||||
agent_version = COALESCE($2, agent_version),
|
||||
tailscale_ip = COALESCE($3, tailscale_ip)
|
||||
tailscale_ip = COALESCE($3, tailscale_ip),
|
||||
hostname = COALESCE($4, hostname),
|
||||
local_ip = COALESCE($5, local_ip)
|
||||
WHERE id = $1",
|
||||
)
|
||||
.bind(id.as_uuid())
|
||||
.bind(agent_version)
|
||||
.bind(tailscale_ip)
|
||||
.bind(hostname)
|
||||
.bind(local_ip)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
sqlx::query(
|
||||
@@ -203,6 +212,8 @@ fn map_node(r: sqlx::postgres::PgRow) -> NodeRow {
|
||||
NodeRow {
|
||||
id: NodeId::from(r.get::<uuid::Uuid, _>("id")),
|
||||
name: r.get("name"),
|
||||
hostname: r.get("hostname"),
|
||||
local_ip: r.get("local_ip"),
|
||||
status: r.get("status"),
|
||||
agent_version: r.get("agent_version"),
|
||||
tailscale_ip: r.get("tailscale_ip"),
|
||||
|
||||
Reference in New Issue
Block a user