forked from wrenn/wrenn
Add template build system with admin panel, async workers, and FlattenRootfs RPC
Introduces an end-to-end template building pipeline: admins submit a recipe
(list of shell commands) via the dashboard, a Redis-backed worker pool spins
up a sandbox, executes each command, and produces either a full snapshot
(with healthcheck) or an image-only template (rootfs flattened via a new
FlattenRootfs host-agent RPC). Build progress and per-step logs are persisted
to a new template_builds table and polled by the frontend.
Backend:
- New FlattenRootfs RPC (proto + host agent + sandbox manager)
- BuildService with Redis queue (BLPOP) and configurable worker pool (default 2)
- Admin-only REST endpoints: POST/GET /v1/admin/builds, GET /v1/admin/builds/{id}
- Migration for template_builds table with JSONB logs and recipe columns
- sqlc queries for build CRUD and progress updates
Frontend:
- /admin/templates page with Templates + Builds tabs
- Create Template dialog with recipe textarea, healthcheck, specs
- Build history with expandable per-step logs, status badges, progress bars
- Auto-polling every 3s for active builds
- AdminSidebar updated with Templates nav item
This commit is contained in:
52
frontend/src/lib/api/builds.ts
Normal file
52
frontend/src/lib/api/builds.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { apiFetch, type ApiResult } from '$lib/api/client';
|
||||
|
||||
export type BuildLogEntry = {
|
||||
step: number;
|
||||
cmd: string;
|
||||
stdout: string;
|
||||
stderr: string;
|
||||
exit: number;
|
||||
ok: boolean;
|
||||
elapsed_ms: number;
|
||||
};
|
||||
|
||||
export type Build = {
|
||||
id: string;
|
||||
name: string;
|
||||
base_template: string;
|
||||
recipe: string[];
|
||||
healthcheck?: string;
|
||||
vcpus: number;
|
||||
memory_mb: number;
|
||||
status: string;
|
||||
current_step: number;
|
||||
total_steps: number;
|
||||
logs: BuildLogEntry[];
|
||||
error?: string;
|
||||
sandbox_id?: string;
|
||||
host_id?: string;
|
||||
created_at: string;
|
||||
started_at?: string;
|
||||
completed_at?: string;
|
||||
};
|
||||
|
||||
export type CreateBuildParams = {
|
||||
name: string;
|
||||
base_template?: string;
|
||||
recipe: string[];
|
||||
healthcheck?: string;
|
||||
vcpus?: number;
|
||||
memory_mb?: number;
|
||||
};
|
||||
|
||||
export async function createBuild(params: CreateBuildParams): Promise<ApiResult<Build>> {
|
||||
return apiFetch('POST', '/api/v1/admin/builds', params);
|
||||
}
|
||||
|
||||
export async function listBuilds(): Promise<ApiResult<Build[]>> {
|
||||
return apiFetch('GET', '/api/v1/admin/builds');
|
||||
}
|
||||
|
||||
export async function getBuild(id: string): Promise<ApiResult<Build>> {
|
||||
return apiFetch('GET', `/api/v1/admin/builds/${id}`);
|
||||
}
|
||||
Reference in New Issue
Block a user