Manage image artifacts and show VM create progress
Stop relying on ad hoc rootfs handling by adding image promotion, managed work-seed fingerprint metadata, and lazy self-healing for older managed images after the first create. Rebuild guest images with baked SSH access, a guest NIC bootstrap, and default opencode services, and add the staged Void kernel/initramfs/modules workflow so void-exp uses a matching Void boot stack. Replace the opaque blocking vm.create RPC with a begin/status flow that prints live stages in the CLI while still waiting for vsock health and opencode on guest port 4096. Validate with GOCACHE=/tmp/banger-gocache go test ./... and live void-exp create/delete smoke runs.
This commit is contained in:
parent
9f09b0d25c
commit
30f0c0b54a
37 changed files with 2334 additions and 99 deletions
|
|
@ -716,7 +716,7 @@ func TestEnsureAuthorizedKeyOnWorkDiskRepairsNestedRootLayout(t *testing.T) {
|
|||
vm := testVM("seed-repair", "image-seed-repair", "172.16.0.61")
|
||||
vm.Runtime.WorkDiskPath = workDiskDir
|
||||
|
||||
if err := d.ensureAuthorizedKeyOnWorkDisk(context.Background(), &vm); err != nil {
|
||||
if err := d.ensureAuthorizedKeyOnWorkDisk(context.Background(), &vm, model.Image{}, workDiskPreparation{}); err != nil {
|
||||
t.Fatalf("ensureAuthorizedKeyOnWorkDisk: %v", err)
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(workDiskDir, "root")); !os.IsNotExist(err) {
|
||||
|
|
@ -748,6 +748,61 @@ func TestCreateVMRejectsNonPositiveCPUAndMemory(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBeginVMCreateCompletesAndReturnsStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx := context.Background()
|
||||
db := openDaemonStore(t)
|
||||
image := testImage("default")
|
||||
image.ID = "default-image-id"
|
||||
image.Name = "default"
|
||||
if err := db.UpsertImage(ctx, image); err != nil {
|
||||
t.Fatalf("UpsertImage: %v", err)
|
||||
}
|
||||
|
||||
d := &Daemon{
|
||||
store: db,
|
||||
layout: paths.Layout{
|
||||
VMsDir: t.TempDir(),
|
||||
},
|
||||
config: model.DaemonConfig{
|
||||
DefaultImageName: image.Name,
|
||||
BridgeIP: model.DefaultBridgeIP,
|
||||
},
|
||||
}
|
||||
|
||||
op, err := d.BeginVMCreate(ctx, api.VMCreateParams{Name: "queued", NoStart: true})
|
||||
if err != nil {
|
||||
t.Fatalf("BeginVMCreate: %v", err)
|
||||
}
|
||||
if op.ID == "" {
|
||||
t.Fatal("operation id should be populated")
|
||||
}
|
||||
|
||||
deadline := time.Now().Add(2 * time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
status, err := d.VMCreateStatus(ctx, op.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("VMCreateStatus: %v", err)
|
||||
}
|
||||
if !status.Done {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
if !status.Success {
|
||||
t.Fatalf("status = %+v, want success", status)
|
||||
}
|
||||
if status.VM == nil || status.VM.Name != "queued" {
|
||||
t.Fatalf("status VM = %+v, want queued vm", status.VM)
|
||||
}
|
||||
if status.VM.State != model.VMStateStopped {
|
||||
t.Fatalf("status VM state = %s, want stopped", status.VM.State)
|
||||
}
|
||||
return
|
||||
}
|
||||
t.Fatal("vm create operation did not finish before timeout")
|
||||
}
|
||||
|
||||
func TestCreateVMUsesDefaultsWhenCPUAndMemoryOmitted(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
db := openDaemonStore(t)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue