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
|
|
@ -80,6 +80,7 @@ func (s *Store) migrate() error {
|
|||
modules_dir TEXT,
|
||||
packages_path TEXT,
|
||||
build_size TEXT,
|
||||
seeded_ssh_public_key_fingerprint TEXT,
|
||||
docker INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
|
|
@ -107,6 +108,9 @@ func (s *Store) migrate() error {
|
|||
if err := ensureColumnExists(s.db, "images", "work_seed_path", "TEXT"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ensureColumnExists(s.db, "images", "seeded_ssh_public_key_fingerprint", "TEXT"); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -116,8 +120,8 @@ func (s *Store) UpsertImage(ctx context.Context, image model.Image) error {
|
|||
const query = `
|
||||
INSERT INTO images (
|
||||
id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path,
|
||||
modules_dir, packages_path, build_size, docker, created_at, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
modules_dir, packages_path, build_size, seeded_ssh_public_key_fingerprint, docker, created_at, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(id) DO UPDATE SET
|
||||
name=excluded.name,
|
||||
managed=excluded.managed,
|
||||
|
|
@ -129,6 +133,7 @@ func (s *Store) UpsertImage(ctx context.Context, image model.Image) error {
|
|||
modules_dir=excluded.modules_dir,
|
||||
packages_path=excluded.packages_path,
|
||||
build_size=excluded.build_size,
|
||||
seeded_ssh_public_key_fingerprint=excluded.seeded_ssh_public_key_fingerprint,
|
||||
docker=excluded.docker,
|
||||
updated_at=excluded.updated_at`
|
||||
_, err := s.db.ExecContext(ctx, query,
|
||||
|
|
@ -143,6 +148,7 @@ func (s *Store) UpsertImage(ctx context.Context, image model.Image) error {
|
|||
image.ModulesDir,
|
||||
image.PackagesPath,
|
||||
image.BuildSize,
|
||||
image.SeededSSHPublicKeyFingerprint,
|
||||
boolToInt(image.Docker),
|
||||
image.CreatedAt.Format(time.RFC3339),
|
||||
image.UpdatedAt.Format(time.RFC3339),
|
||||
|
|
@ -151,15 +157,15 @@ func (s *Store) UpsertImage(ctx context.Context, image model.Image) error {
|
|||
}
|
||||
|
||||
func (s *Store) GetImageByName(ctx context.Context, name string) (model.Image, error) {
|
||||
return s.getImage(ctx, "SELECT id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, modules_dir, packages_path, build_size, docker, created_at, updated_at FROM images WHERE name = ?", name)
|
||||
return s.getImage(ctx, "SELECT id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, modules_dir, packages_path, build_size, seeded_ssh_public_key_fingerprint, docker, created_at, updated_at FROM images WHERE name = ?", name)
|
||||
}
|
||||
|
||||
func (s *Store) GetImageByID(ctx context.Context, id string) (model.Image, error) {
|
||||
return s.getImage(ctx, "SELECT id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, modules_dir, packages_path, build_size, docker, created_at, updated_at FROM images WHERE id = ?", id)
|
||||
return s.getImage(ctx, "SELECT id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, modules_dir, packages_path, build_size, seeded_ssh_public_key_fingerprint, docker, created_at, updated_at FROM images WHERE id = ?", id)
|
||||
}
|
||||
|
||||
func (s *Store) ListImages(ctx context.Context) ([]model.Image, error) {
|
||||
rows, err := s.db.QueryContext(ctx, "SELECT id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, modules_dir, packages_path, build_size, docker, created_at, updated_at FROM images ORDER BY created_at ASC")
|
||||
rows, err := s.db.QueryContext(ctx, "SELECT id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, modules_dir, packages_path, build_size, seeded_ssh_public_key_fingerprint, docker, created_at, updated_at FROM images ORDER BY created_at ASC")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -337,6 +343,7 @@ func scanImageRow(row scanner) (model.Image, error) {
|
|||
var image model.Image
|
||||
var managed, docker int
|
||||
var workSeedPath sql.NullString
|
||||
var seededSSHPublicKeyFingerprint sql.NullString
|
||||
var createdAt, updatedAt string
|
||||
err := row.Scan(
|
||||
&image.ID,
|
||||
|
|
@ -350,6 +357,7 @@ func scanImageRow(row scanner) (model.Image, error) {
|
|||
&image.ModulesDir,
|
||||
&image.PackagesPath,
|
||||
&image.BuildSize,
|
||||
&seededSSHPublicKeyFingerprint,
|
||||
&docker,
|
||||
&createdAt,
|
||||
&updatedAt,
|
||||
|
|
@ -360,6 +368,7 @@ func scanImageRow(row scanner) (model.Image, error) {
|
|||
image.Managed = managed == 1
|
||||
image.Docker = docker == 1
|
||||
image.WorkSeedPath = workSeedPath.String
|
||||
image.SeededSSHPublicKeyFingerprint = seededSSHPublicKeyFingerprint.String
|
||||
image.CreatedAt, err = time.Parse(time.RFC3339, createdAt)
|
||||
if err != nil {
|
||||
return image, err
|
||||
|
|
|
|||
|
|
@ -335,20 +335,21 @@ func openTestStore(t *testing.T) *Store {
|
|||
func sampleImage(name string) model.Image {
|
||||
now := fixedTime()
|
||||
return model.Image{
|
||||
ID: name + "-id",
|
||||
Name: name,
|
||||
Managed: true,
|
||||
ArtifactDir: "/artifacts/" + name,
|
||||
RootfsPath: "/images/" + name + ".ext4",
|
||||
WorkSeedPath: "/images/" + name + ".work-seed.ext4",
|
||||
KernelPath: "/kernels/" + name,
|
||||
InitrdPath: "/initrd/" + name,
|
||||
ModulesDir: "/modules/" + name,
|
||||
PackagesPath: "/packages/" + name + ".apt",
|
||||
BuildSize: "8G",
|
||||
Docker: true,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
ID: name + "-id",
|
||||
Name: name,
|
||||
Managed: true,
|
||||
ArtifactDir: "/artifacts/" + name,
|
||||
RootfsPath: "/images/" + name + ".ext4",
|
||||
WorkSeedPath: "/images/" + name + ".work-seed.ext4",
|
||||
KernelPath: "/kernels/" + name,
|
||||
InitrdPath: "/initrd/" + name,
|
||||
ModulesDir: "/modules/" + name,
|
||||
PackagesPath: "/packages/" + name + ".apt",
|
||||
BuildSize: "8G",
|
||||
SeededSSHPublicKeyFingerprint: "seeded-fingerprint",
|
||||
Docker: true,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue