vm create: auto-pull image and kernel from catalogs if missing

One-command sandbox: `banger vm run` on a fresh host now Just Works.
No prior `banger image pull` or `banger kernel pull` needed.

Changes:

- Default `default_image_name` flips from "default" to "debian-bookworm"
  so the golden image is the implicit target when `--image` is omitted.
- `CreateVM` resolves the image via a new `findOrAutoPullImage`: try
  the local store first, and on miss fall back to the embedded imagecat
  catalog + auto-pull. Emits a vm-create progress stage so the user
  sees "pulling from image catalog" in the create output.
- `resolveKernelInputs` gains context + the same pattern via
  `readOrAutoPullKernel`: try the local kernelcat, and on miss look up
  the embedded kernelcat and auto-pull. Fires whenever a bundle's
  manifest references a kernel the user hasn't pulled yet, not just
  during image pull — any CreateVM with an image that needs a kernel
  not yet local will resolve it.
- `--image` help text updated on both `vm run` and `vm create`.

Six tests cover local-hit-no-pull, auto-pull-on-miss, not-in-catalog
error propagation, and a non-ENOENT kernel read error does NOT trigger
a misleading "not in catalog" claim.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Thales Maciel 2026-04-18 15:10:26 -03:00
parent 81a27d6648
commit e0894376ea
No known key found for this signature in database
GPG key ID: 33112E6833C34679
7 changed files with 202 additions and 15 deletions

View file

@ -46,7 +46,7 @@ func Load(layout paths.Layout) (model.DaemonConfig, error) {
CIDR: model.DefaultCIDR,
TapPoolSize: 4,
DefaultDNS: model.DefaultDNS,
DefaultImageName: "default",
DefaultImageName: "debian-bookworm",
}
var file fileConfig

View file

@ -35,8 +35,8 @@ func TestLoadDefaultsResolveFirecrackerAndGenerateSSHKey(t *testing.T) {
t.Fatalf("stat %s: %v", path, err)
}
}
if cfg.DefaultImageName != "default" {
t.Fatalf("DefaultImageName = %q, want default", cfg.DefaultImageName)
if cfg.DefaultImageName != "debian-bookworm" {
t.Fatalf("DefaultImageName = %q, want debian-bookworm", cfg.DefaultImageName)
}
if cfg.WebListenAddr != "127.0.0.1:7777" {
t.Fatalf("WebListenAddr = %q", cfg.WebListenAddr)