- Persist golden VM tag to clones/{id}/tag at spawn time
- GET /clones now returns [{id, tag}] objects instead of plain IDs
- Web UI renders tag as a dim label next to each clone entry (clone 3 · default)
- Pre-existing fixes included in this commit:
- console: tee all PTY output to clones/{id}/console.log for boot capture
- network: destroy stale tap before recreating to avoid EBUSY errors
- orchestrator: fix ubuntu systemd boot (custom fc-console.service, fstab,
mask serial-getty udev dep, longer settle time, correct package list)
- config: remove quiet/loglevel=0 from default boot args
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
69 lines
2.1 KiB
Go
69 lines
2.1 KiB
Go
package orchestrator
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
)
|
|
|
|
// Config holds all tunables for the orchestrator.
|
|
type Config struct {
|
|
FCBin string // path to firecracker binary
|
|
BaseDir string // working directory for all state
|
|
Kernel string // path to vmlinux
|
|
KernelURL string // URL to download vmlinux if Kernel file is missing
|
|
CustomRootfs string // Custom path to rootfs if FC_ROOTFS is set
|
|
VCPUs int64
|
|
MemMiB int64
|
|
Bridge string // host bridge name, or "none" to skip networking
|
|
BridgeCIDR string // e.g. "172.30.0.1/24"
|
|
GuestPrefix string // e.g. "172.30.0" — clones get .11, .12, ...
|
|
GuestGW string // default gateway for guest VMs
|
|
AutoNetConfig bool // inject guest IP/GW/DNS via MMDS on clone start
|
|
BootArgs string
|
|
}
|
|
|
|
func DefaultConfig() Config {
|
|
c := Config{
|
|
FCBin: envOr("FC_BIN", "firecracker"),
|
|
BaseDir: envOr("FC_BASE_DIR", "/tmp/fc-orch"),
|
|
VCPUs: envOrInt("FC_VCPUS", 1),
|
|
MemMiB: envOrInt("FC_MEM_MIB", 128),
|
|
Bridge: envOr("FC_BRIDGE", "fcbr0"),
|
|
BridgeCIDR: envOr("FC_BRIDGE_CIDR", "172.30.0.1/24"),
|
|
GuestPrefix: envOr("FC_GUEST_PREFIX", "172.30.0"),
|
|
GuestGW: envOr("FC_GUEST_GW", "172.30.0.1"),
|
|
AutoNetConfig: envOr("FC_AUTO_NET_CONFIG", "") == "1",
|
|
BootArgs: "console=ttyS0 reboot=k panic=1 pci=off i8042.noaux",
|
|
}
|
|
c.Kernel = envOr("FC_KERNEL", c.BaseDir+"/vmlinux")
|
|
c.KernelURL = envOr("FC_KERNEL_URL",
|
|
"https://s3.amazonaws.com/spec.ccfc.min/firecracker-ci/20260408-ce2a467895c1-0/x86_64/vmlinux-6.1.166")
|
|
c.CustomRootfs = os.Getenv("FC_ROOTFS")
|
|
return c
|
|
}
|
|
|
|
// RootfsPath returns the path to the root filesystem depending on the requested distribution.
|
|
func (c Config) RootfsPath(distro string) string {
|
|
if c.CustomRootfs != "" {
|
|
return c.CustomRootfs
|
|
}
|
|
return filepath.Join(c.BaseDir, "rootfs-"+distro+".ext4")
|
|
}
|
|
|
|
func envOr(key, fallback string) string {
|
|
if v := os.Getenv(key); v != "" {
|
|
return v
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func envOrInt(key string, fallback int64) int64 {
|
|
if v := os.Getenv(key); v != "" {
|
|
if n, err := strconv.ParseInt(v, 10, 64); err == nil {
|
|
return n
|
|
}
|
|
}
|
|
return fallback
|
|
}
|