Clarify local runtime bundle bootstrap
Stop presenting make runtime-bundle as a turnkey fresh-checkout bootstrap\nwhen the checked-in manifest is intentionally empty. The manifest comments,\nruntimebundle error messages, Make help, README, and AGENTS docs now all\ndescribe the same local-first flow: stage an archive, use a separate local\nmanifest copy with url/sha256, then bootstrap ./runtime from that manifest.\n\nKeep the existing package/fetch commands intact, and add a small runtimebundle\nregression test so the local-manifest guidance does not drift again.\n\nValidated with make help and GOCACHE=/tmp/banger-gocache go test\n./internal/runtimebundle.
This commit is contained in:
parent
ccba07ec68
commit
617f677c9b
6 changed files with 66 additions and 17 deletions
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## Build, Test, and Development Commands
|
## Build, Test, and Development Commands
|
||||||
- `make build` builds `./banger` and `./bangerd`.
|
- `make build` builds `./banger` and `./bangerd`.
|
||||||
- `make runtime-bundle` bootstraps `./runtime/` from `runtime-bundle.toml`.
|
- `make runtime-bundle` bootstraps `./runtime/` from the archive referenced by `RUNTIME_MANIFEST`; the checked-in `runtime-bundle.toml` is only a template.
|
||||||
- `banger` validates required host tools per command and reports actionable missing-tool errors; do not assume one workstation's package set.
|
- `banger` validates required host tools per command and reports actionable missing-tool errors; do not assume one workstation's package set.
|
||||||
- `./banger vm create --name testbox` creates and starts a VM.
|
- `./banger vm create --name testbox` creates and starts a VM.
|
||||||
- `./banger vm ssh testbox` connects to a running guest.
|
- `./banger vm ssh testbox` connects to a running guest.
|
||||||
|
|
|
||||||
2
Makefile
2
Makefile
|
|
@ -27,7 +27,7 @@ help:
|
||||||
@printf '%s\n' \
|
@printf '%s\n' \
|
||||||
'Targets:' \
|
'Targets:' \
|
||||||
' make build Build ./banger and ./bangerd' \
|
' make build Build ./banger and ./bangerd' \
|
||||||
' make runtime-bundle Download and unpack ./runtime from runtime-bundle.toml' \
|
' make runtime-bundle Fetch and unpack ./runtime from the archive referenced by $(RUNTIME_MANIFEST)' \
|
||||||
' make runtime-package Package $(RUNTIME_SOURCE_DIR) into $(RUNTIME_ARCHIVE) and print its SHA256' \
|
' make runtime-package Package $(RUNTIME_SOURCE_DIR) into $(RUNTIME_ARCHIVE) and print its SHA256' \
|
||||||
' make install Build and install binaries plus the runtime bundle into $(DESTDIR)$(BINDIR) and $(DESTDIR)$(RUNTIMEDIR)' \
|
' make install Build and install binaries plus the runtime bundle into $(DESTDIR)$(BINDIR) and $(DESTDIR)$(RUNTIMEDIR)' \
|
||||||
' make test Run go test ./...' \
|
' make test Run go test ./...' \
|
||||||
|
|
|
||||||
46
README.md
46
README.md
|
|
@ -30,22 +30,43 @@ The bundle contains:
|
||||||
- `id_ed25519`
|
- `id_ed25519`
|
||||||
- the helper scripts used by image builds and installs
|
- the helper scripts used by image builds and installs
|
||||||
|
|
||||||
Bootstrap a source checkout explicitly:
|
Bootstrap a source checkout from a local or published runtime archive. The
|
||||||
|
checked-in [`runtime-bundle.toml`](/home/thales/projects/personal/banger/runtime-bundle.toml)
|
||||||
|
is a template and intentionally ships with empty `url` and `sha256`.
|
||||||
|
|
||||||
|
If you need to create a local archive first, do that from a checkout or machine
|
||||||
|
that already has a populated `./runtime/` tree:
|
||||||
```bash
|
```bash
|
||||||
make runtime-bundle
|
make runtime-package
|
||||||
|
cp dist/banger-runtime.tar.gz /path/to/fresh-checkout/dist/
|
||||||
```
|
```
|
||||||
|
|
||||||
`make runtime-bundle` reads [`runtime-bundle.toml`](/home/thales/projects/personal/banger/runtime-bundle.toml),
|
In the fresh checkout:
|
||||||
downloads the published bundle, verifies its SHA256, and unpacks it into
|
```bash
|
||||||
`./runtime/`. `make install` will not fetch artifacts for you. The manifest
|
cp runtime-bundle.toml runtime-bundle.local.toml
|
||||||
must point at a published or locally staged bundle before bootstrap can work.
|
```
|
||||||
|
|
||||||
|
Edit `runtime-bundle.local.toml` to point at the staged archive and checksum:
|
||||||
|
```toml
|
||||||
|
url = "./dist/banger-runtime.tar.gz"
|
||||||
|
sha256 = "<sha256 printed by make runtime-package>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Then bootstrap `./runtime/` with the local manifest copy:
|
||||||
|
```bash
|
||||||
|
make runtime-bundle RUNTIME_MANIFEST=runtime-bundle.local.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
`url` may be a relative path, absolute path, `file:///...` URL, or HTTP(S)
|
||||||
|
URL. `make install` will not fetch artifacts for you.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
```bash
|
```bash
|
||||||
make runtime-bundle
|
|
||||||
make build
|
make build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Run `make build` after `./runtime/` has been bootstrapped.
|
||||||
|
|
||||||
Install into `~/.local/bin` by default, with the runtime bundle under
|
Install into `~/.local/bin` by default, with the runtime bundle under
|
||||||
`~/.local/lib/banger`:
|
`~/.local/lib/banger`:
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -206,16 +227,19 @@ make rootfs
|
||||||
is not available, pass an explicit `--base-rootfs` to `./make-rootfs.sh`.
|
is not available, pass an explicit `--base-rootfs` to `./make-rootfs.sh`.
|
||||||
|
|
||||||
## Maintaining The Runtime Bundle
|
## Maintaining The Runtime Bundle
|
||||||
Maintain the checked-in manifest in [`runtime-bundle.toml`](/home/thales/projects/personal/banger/runtime-bundle.toml)
|
The checked-in [`runtime-bundle.toml`](/home/thales/projects/personal/banger/runtime-bundle.toml)
|
||||||
with the published bundle URL, SHA256, and `bundle_metadata` defaults.
|
is a template. Keep `bundle_metadata` accurate there, but use a separate local
|
||||||
|
manifest copy when you need concrete `url` and `sha256` values for bootstrap
|
||||||
|
testing or publication.
|
||||||
|
|
||||||
Package a local `./runtime/` tree for publication:
|
Package a local `./runtime/` tree into an archive:
|
||||||
```bash
|
```bash
|
||||||
make runtime-package
|
make runtime-package
|
||||||
```
|
```
|
||||||
|
|
||||||
That writes `dist/banger-runtime.tar.gz` and prints its SHA256 so you can update
|
That writes `dist/banger-runtime.tar.gz` and prints its SHA256 so you can update
|
||||||
the manifest before publishing or testing bootstrap changes.
|
a local manifest copy before testing bootstrap changes or publishing the
|
||||||
|
archive elsewhere.
|
||||||
|
|
||||||
## Remaining Shell Helpers
|
## Remaining Shell Helpers
|
||||||
The runtime VM lifecycle is managed through `banger`. The remaining shell scripts are not the primary user interface:
|
The runtime VM lifecycle is managed through `banger`. The remaining shell scripts are not the primary user interface:
|
||||||
|
|
|
||||||
|
|
@ -69,10 +69,10 @@ func LoadManifest(path string) (Manifest, error) {
|
||||||
|
|
||||||
func Bootstrap(ctx context.Context, manifest Manifest, manifestPath, outDir string) error {
|
func Bootstrap(ctx context.Context, manifest Manifest, manifestPath, outDir string) error {
|
||||||
if manifest.URL == "" {
|
if manifest.URL == "" {
|
||||||
return fmt.Errorf("runtime bundle manifest %s has no url; publish a runtime bundle and update the manifest", manifestPath)
|
return fmt.Errorf("runtime bundle manifest %s has no url; point a local manifest copy at a staged or published runtime bundle archive", manifestPath)
|
||||||
}
|
}
|
||||||
if manifest.SHA256 == "" {
|
if manifest.SHA256 == "" {
|
||||||
return fmt.Errorf("runtime bundle manifest %s has no sha256", manifestPath)
|
return fmt.Errorf("runtime bundle manifest %s has no sha256; add the checksum for the staged or published runtime bundle archive", manifestPath)
|
||||||
}
|
}
|
||||||
manifestDir := filepath.Dir(manifestPath)
|
manifestDir := filepath.Dir(manifestPath)
|
||||||
parentDir := filepath.Dir(outDir)
|
parentDir := filepath.Dir(outDir)
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,30 @@ func TestBootstrapRejectsChecksumMismatch(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBootstrapRejectsMissingURLWithLocalManifestGuidance(t *testing.T) {
|
||||||
|
manifest := Manifest{
|
||||||
|
SHA256: strings.Repeat("0", 64),
|
||||||
|
BundleRoot: "runtime",
|
||||||
|
RequiredPaths: []string{"firecracker"},
|
||||||
|
}
|
||||||
|
err := Bootstrap(context.Background(), manifest, filepath.Join(t.TempDir(), "runtime-bundle.toml"), filepath.Join(t.TempDir(), "runtime"))
|
||||||
|
if err == nil || !strings.Contains(err.Error(), "local manifest copy") {
|
||||||
|
t.Fatalf("Bootstrap() error = %v, want local manifest guidance", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBootstrapRejectsMissingSHAWithArchiveGuidance(t *testing.T) {
|
||||||
|
manifest := Manifest{
|
||||||
|
URL: "./bundle.tar.gz",
|
||||||
|
BundleRoot: "runtime",
|
||||||
|
RequiredPaths: []string{"firecracker"},
|
||||||
|
}
|
||||||
|
err := Bootstrap(context.Background(), manifest, filepath.Join(t.TempDir(), "runtime-bundle.toml"), filepath.Join(t.TempDir(), "runtime"))
|
||||||
|
if err == nil || !strings.Contains(err.Error(), "staged or published runtime bundle archive") {
|
||||||
|
t.Fatalf("Bootstrap() error = %v, want archive guidance", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPackageWritesArchive(t *testing.T) {
|
func TestPackageWritesArchive(t *testing.T) {
|
||||||
runtimeDir := t.TempDir()
|
runtimeDir := t.TempDir()
|
||||||
for _, rel := range []string{
|
for _, rel := range []string{
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
# Update `url` and `sha256` to the published runtime bundle before using
|
# Template manifest for local or published runtime bundle archives.
|
||||||
# `make runtime-bundle` in a fresh checkout.
|
# Keep this checked-in file empty by default; use a local manifest copy with
|
||||||
|
# concrete `url` and `sha256` values when bootstrapping `./runtime/`.
|
||||||
version = "v0"
|
version = "v0"
|
||||||
url = ""
|
url = ""
|
||||||
sha256 = ""
|
sha256 = ""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue