The `image build` flow spun up a transient Firecracker VM, SSHed in, and ran a large bash provisioning script to derive a new managed image from an existing one. It overlapped heavily with the golden- image Dockerfile flow (same mise/docker/tmux/opencode install logic duplicated in Go as `imagemgr.BuildProvisionScript`) and had far more machinery: async op state, RPC begin/status/cancel, webui form + operation page, preflight checks, API types, tests. For custom images, writing a Dockerfile is simpler and more reproducible. Removed end-to-end: - CLI `image build` subcommand + `absolutizeImageBuildPaths`. - Daemon: BuildImage method, imagebuild.go (transient-VM orchestration), image_build_ops.go (async begin/status/cancel), imagemgr/build.go (the 247-line provisioning script generator and all its append* helpers), validateImageBuildPrereqs + addImageBuildPrereqs. - RPC dispatches for image.build / .begin / .status / .cancel. - opstate registry `imageBuildOps`, daemon seam `imageBuild`, background pruner call. - API types: ImageBuildParams, ImageBuildOperation, ImageBuildBeginResult, ImageBuildStatusParams, ImageBuildStatusResult; model type ImageBuildRequest. - Web UI: Backend interface methods, handlers, form, routes, template branches (images.html build form, operation.html build branch, dashboard.html Build button). - Tests that directly exercised BuildImage. Doctor polish (task C): - Drop the "image build" preflight section entirely (its raison d'être is gone). - Default-image check now accepts "not local but in imagecat" as OK: vm create auto-pulls on first use. Only flag when the image is neither locally registered nor in the catalog. Net: 24 files touched, 1,373 lines deleted, 25 added. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
64 lines
1.7 KiB
HTML
64 lines
1.7 KiB
HTML
{{define "dashboard_content"}}
|
|
<section class="split-grid">
|
|
<div>
|
|
<div class="section-head">
|
|
<h3>Virtual Machines</h3>
|
|
<a class="button" href="/vms/new">Create VM</a>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>State</th>
|
|
<th>IP</th>
|
|
<th>Spec</th>
|
|
<th>Created</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .VMs}}
|
|
<tr>
|
|
<td><a class="table-link" href="/vms/{{.ID}}">{{.Name}}</a></td>
|
|
<td><span class="state-pill {{stateClass .State}}">{{.State}}</span></td>
|
|
<td>{{if .Runtime.GuestIP}}{{.Runtime.GuestIP}}{{else}}-{{end}}</td>
|
|
<td>{{.Spec.VCPUCount}} vCPU / {{.Spec.MemoryMiB}} MiB / {{formatBytes .Spec.WorkDiskSizeBytes}}</td>
|
|
<td>{{relativeTime .CreatedAt}}</td>
|
|
</tr>
|
|
{{else}}
|
|
<tr><td colspan="5" class="muted">No VMs yet.</td></tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div>
|
|
<div class="section-head">
|
|
<h3>Images</h3>
|
|
<div class="stack-inline">
|
|
<a class="button secondary" href="/images/register">Register</a>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Managed</th>
|
|
<th>Rootfs</th>
|
|
<th>Created</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .Images}}
|
|
<tr>
|
|
<td><a class="table-link" href="/images/{{.ID}}">{{.Name}}</a></td>
|
|
<td>{{formatBool .Managed}}</td>
|
|
<td><code>{{.RootfsPath}}</code></td>
|
|
<td>{{relativeTime .CreatedAt}}</td>
|
|
</tr>
|
|
{{else}}
|
|
<tr><td colspan="4" class="muted">No images registered.</td></tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
{{end}}
|