feat: rebuild browser ssh from the ground up

This commit is contained in:
Aarnav Tale
2026-04-09 21:56:06 -04:00
parent d255098128
commit 0f19fdf0da
39 changed files with 1292 additions and 1231 deletions
-53
View File
@@ -1,53 +0,0 @@
import { eq, isNotNull } from "drizzle-orm";
import { nodesResource } from "~/server/headscale/live-store";
import log from "~/utils/log";
import type { Route } from "../../layout/+types/app";
import { ephemeralNodes } from "./schema";
export async function pruneEphemeralNodes({ context, request }: Route.LoaderArgs) {
const principal = await context.auth.require(request);
const ephemerals = await context.db
.select()
.from(ephemeralNodes)
.where(isNotNull(ephemeralNodes.node_key));
if (ephemerals.length === 0) {
log.debug("api", "No ephemeral nodes to prune");
return;
}
const apiKey = context.auth.getHeadscaleApiKey(principal);
const api = context.hsApi.getRuntimeClient(apiKey);
const nodes = await api.getNodes();
const toPrune = nodes.filter((node) => {
if (node.online) {
return false;
}
return ephemerals.some((ephemeral) => node.nodeKey === ephemeral.node_key);
});
if (toPrune.length === 0) {
log.debug("api", "No SSH nodes to prune");
return;
}
// Delete from the Headscale nodes list and then from the database
const promises = toPrune.map((node) => {
return async () => {
log.debug("api", `Pruning node ${node.name}`);
await api.deleteNode(node.id);
await context.db.delete(ephemeralNodes).where(eq(ephemeralNodes.node_key, node.nodeKey));
log.debug("api", `Node ${node.name} pruned successfully`);
};
});
await Promise.all(promises.map((p) => p()));
if (toPrune.length > 0) {
await context.hsLive.refresh(nodesResource, api);
}
}
-8
View File
@@ -2,14 +2,6 @@ import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
import { HostInfo } from "~/types";
export const ephemeralNodes = sqliteTable("ephemeral_nodes", {
auth_key: text("auth_key").primaryKey(),
node_key: text("node_key"),
});
export type EphemeralNode = typeof ephemeralNodes.$inferSelect;
export type EphemeralNodeInsert = typeof ephemeralNodes.$inferInsert;
export const hostInfo = sqliteTable("host_info", {
host_id: text("host_id").primaryKey(),
payload: text("payload", { mode: "json" }).$type<HostInfo>(),