battery

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2026 License: Apache-2.0

README

battery

CI Go Reference Go Report Card Go Version License

battery is a MicroVM Warm Pool Manager for flintlock. It manages pools of pre-provisioned, pre-booted microVMs so consumers can claim an already-running VM instantly, instead of waiting for flintlock to provision one on demand. It's part of the liquidmetal-dev family of projects, alongside flintlock and guest-agent.

Status: early-stage / pre-alpha. The gRPC API surface is defined, but the pool reconciliation, replenishment, and lease logic is not yet implemented.

Architecture

battery is made up of two binaries:

  • poolmgrd (cmd/poolmgrd) — the central pool manager daemon. It serves the gRPC API defined under api/proto/poolmgr/v1alpha1:

    • PoolAdmin — create, update, delete, and list pool definitions.
    • Lease — claim a VM from a pool, heartbeat it, and release it back.
    • Events — a server-streaming subscription for pool/VM/lease lifecycle events.

    It's designed to reconcile a fleet of flintlock hosts against each pool's desired state, replenishing VMs using a per-pool strategy, and, once implemented, persist state (e.g., in an embedded SQLite database).

  • poolmgr-hostagent (cmd/poolmgr-hostagent) — a sidecar that runs alongside each flintlock host. Flintlock's guest-agent is only reachable over a host-local vsock socket, so this sidecar proxies exec/ping calls to the in-VM guest-agent on poolmgrd's behalf, exposed via the Hostagent gRPC service.

See docs/design/2026-09-05-microvm-warm-pool-manager-design.md for the full design rationale and decisions, and docs/runbooks/e2e-manual-verification.md for the manual end-to-end verification runbook against a real flintlockd + Firecracker VM.

Getting started

Prerequisites
  • Go 1.25+
  • mise (recommended) to install pinned tool versions from mise.tomlbuf, golangci-lint, protoc-gen-go, and protoc-gen-go-grpc.
Build and test
go build ./...
go vet ./...
go test ./...
golangci-lint run
Working with the API protos

The gRPC API is defined in api/proto using buf. After editing a .proto file, regenerate the Go code with:

./hack/generate-proto.sh

Releasing

Releases are cut by pushing a semver tag matching v*.*.* (e.g. v0.1.0) to main. This triggers .github/workflows/release.yml, which:

  • builds poolmgrd for linux/amd64 and linux/arm64 via GoReleaser
  • publishes a multi-arch container image to ghcr.io/liquidmetal-dev/poolmgrd:<version> (and :latest) — note the image tag drops the leading v from the git tag (e.g. tagging v0.1.0 produces ghcr.io/liquidmetal-dev/poolmgrd:0.1.0), unlike the GitHub release itself, which keeps it
  • creates a GitHub release with a changelog grouped by commit type
  • pushes api/proto (PoolAdmin/Lease/Events/types) to the Buf Schema Registry at buf.build/liquidmetal-dev/battery, creating the BSR module on first push if it doesn't exist yet, and labels the push with both the release tag and the moving main label — main is what buf breaking (below) compares PRs against, so every release advances it

One-time setup: a BUF_TOKEN repository secret (a Buf Schema Registry API token with write access to liquidmetal-dev/battery) must exist before the first tag is pushed. Until the first successful buf push, the buf breaking check in CI (.github/workflows/ci.yml) has nothing to compare against — that specific "no baseline yet" failure is treated as a pass with a warning, but any other buf breaking failure (a real incompatible schema change) still fails the job normally, before and after the first release.

If buf push fails after GoReleaser has already published successfully, the proto schema push can be re-run manually without re-cutting the release: buf push --create --create-visibility public --label <tag> --label main from a checkout of that tag.

git tag v0.1.0
git push origin v0.1.0

License

Apache License 2.0 — see LICENSE for details.

Acknowledgements

Thanks to @phoban01 for the original idea of using warm pools with flintlock, based on his work building a GitLab executor that used flintlock warm pools.

Directories

Path Synopsis
api
cmd
poolmgrd command
Command poolmgrd is the MicroVM Warm Pool Manager server entrypoint.
Command poolmgrd is the MicroVM Warm Pool Manager server entrypoint.
internal
api
Package api implements the pool manager's gRPC service handlers.
Package api implements the pool manager's gRPC service handlers.
config
Package config loads the static process configuration for the pool manager's flintlock client pool: the list of flintlock hosts it may talk to, each with its address and TLS materials.
Package config loads the static process configuration for the pool manager's flintlock client pool: the list of flintlock hosts it may talk to, each with its address and TLS materials.
flintlockclient
Package flintlockclient manages one flintlock gRPC client per configured flintlock host.
Package flintlockclient manages one flintlock gRPC client per configured flintlock host.
metrics
Package metrics defines the pool manager's Prometheus instrumentation: metric definitions, small recording helpers used by the reconciler and API packages, a pull-based collector for per-pool gauges, and gRPC server interceptor options.
Package metrics defines the pool manager's Prometheus instrumentation: metric definitions, small recording helpers used by the reconciler and API packages, a pull-based collector for per-pool gauges, and gRPC server interceptor options.
poolmanager
Package poolmanager owns the lifecycle of per-pool reconciler.Reconciler goroutines: starting one for every pool at poolmgrd startup and on PoolAdminServer.CreatePool, stopping it on DeletePool, and routing lease events to the right pool's reconciler as api.ReconcilerNotifier.
Package poolmanager owns the lifecycle of per-pool reconciler.Reconciler goroutines: starting one for every pool at poolmgrd startup and on PoolAdminServer.CreatePool, stopping it on DeletePool, and routing lease events to the right pool's reconciler as api.ReconcilerNotifier.
reconciler
Package reconciler implements the per-pool control loop that keeps a pool's warm VM count at its target: replenishment strategies decide how many new VMs are needed, and the provisioning pipeline turns that into AVAILABLE VMRecords by driving flintlock and the pool's create_commands.
Package reconciler implements the per-pool control loop that keeps a pool's warm VM count at its target: replenishment strategies decide how many new VMs are needed, and the provisioning pipeline turns that into AVAILABLE VMRecords by driving flintlock and the pool's create_commands.
server
Package server constructs the pool manager's gRPC API server: TLS credentials (or an explicit insecure mode) plus an optional basic-auth interceptor, mirroring flintlock's own server auth pattern.
Package server constructs the pool manager's gRPC API server: TLS credentials (or an explicit insecure mode) plus an optional basic-auth interceptor, mirroring flintlock's own server auth pattern.
store
Package store provides the SQLite-backed persistence layer for pool manager data: pools, VMs, leases, and the events outbox.
Package store provides the SQLite-backed persistence layer for pool manager data: pools, VMs, leases, and the events outbox.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL