Lifecycle Package Reference¶
pkg/lifecycle/— VM lifecycle management, Firecracker API communication.
Overview¶
The pkg/lifecycle package manages Firecracker VM lifecycle operations: start, stop, pause, resume, and state tracking.
Package Structure:
pkg/lifecycle/
├── vmm.go # VMMManager and VMInstance
├── mocks.go # Test mocks
VMMManager¶
File: vmm.go
The VMMManager manages Firecracker VM processes and API communication.
Type Definition¶
type VMMManager struct {
config *ManagerConfig
vms map[string]*VMInstance
mu sync.RWMutex
socketDir string
}
Configuration¶
type ManagerConfig struct {
KernelPath string // vmlinux path
RootfsDir string // rootfs storage directory
SocketDir string // API socket directory
DefaultVCPUs int // default vCPU count
DefaultMemoryMB int // default memory in MB
EnableJailer bool // enable jailer sandbox
}
Constructor¶
func NewVMMManager(config interface{}) VMMManager
Parameters: - config — *ManagerConfig or any interface (defaults applied)
Defaults Applied:
| Field | Default Value |
|---|---|
SocketDir | "/var/run/firecracker" |
Example:
config := &lifecycle.ManagerConfig{
KernelPath: "/usr/share/firecracker/vmlinux",
RootfsDir: "/var/lib/firecracker/rootfs",
SocketDir: "/var/run/firecracker",
DefaultVCPUs: 2,
DefaultMemoryMB: 1024,
}
vmm := lifecycle.NewVMMManager(config)
VMInstance¶
File: vmm.go
Type Definition¶
type VMInstance struct {
ID string // Task ID
PID int // Firecracker process PID
Config interface{} // VM configuration
state VMState // Current state (private)
CreatedAt time.Time // Creation timestamp
SocketPath string // API socket path
InitSystem string // Init type (tini/dumb-init)
GracePeriodSec int // Shutdown grace period
mu sync.RWMutex // Protects state
}
State Methods¶
func (v *VMInstance) SetState(newState VMState)
func (v *VMInstance) GetState() VMState
Thread-safe state access.
VM States¶
type VMState string
const (
VMStateNew VMState = "new" // Created but not started
VMStateStarting VMState = "starting" // Firecracker booting
VMStateRunning VMState = "running" // VM operational
VMStateStopping VMState = "stopping" // Shutdown initiated
VMStateStopped VMState = "stopped" // VM terminated
VMStateCrashed VMState = "crashed" // Unexpected failure
)
Methods¶
Start¶
func (vm *VMMManager) Start(ctx context.Context, task *types.Task, config interface{}) error
Purpose: Start a Firecracker VM for the task.
Steps:
-
Find Firecracker binary
fcBinary, err := exec.LookPath("firecracker") -
Start process with API socket
cmd := exec.Command(fcBinary, "--api-sock", socketPath) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Start() -
Wait for API ready
waitForAPIServer(socketPath, 10*time.Second) -
Configure VM via API
vm.configureVM(ctx, socketPath, config) -
Send InstanceStart action
client := newUnixClient(socketPath, 5*time.Second) actions := ActionsType{ActionType: "InstanceStart"} client.Put("/actions", actions) -
Track instance
vm.vms[task.ID] = &VMInstance{ ID: task.ID, PID: cmd.Process.Pid, SocketPath: socketPath, state: VMStateRunning, CreatedAt: time.Now(), }
Error Handling: - Deferred cleanup on failure (kill process, remove socket) - Validates config is not nil - Checks for duplicate VM
Stop¶
func (vm *VMMManager) Stop(ctx context.Context, taskID string) error
Purpose: Stop a running VM.
Steps:
- Get VM instance
- Send
InstanceStopaction with timeout - Wait for process exit
- Update state to
VMStateStopped
Pause¶
func (vm *VMMManager) Pause(ctx context.Context, taskID string) error
Purpose: Pause VM for snapshot.
API Call:
client.Put("/vm", VMStatePaused)
Resume¶
func (vm *VMMManager) Resume(ctx context.Context, taskID string) error
Purpose: Resume paused VM.
API Call:
client.Put("/vm", VMStateResumed)
GetInfo¶
func (vm *VMMManager) GetInfo(taskID string) (*VMInstance, error)
Purpose: Get VM instance info.
Returns: - *VMInstance — Instance details (ID, PID, state, socket) - error — Not found error
List¶
func (vm *VMMManager) List() []string
Purpose: List all managed VM IDs.
Cleanup¶
func (vm *VMMManager) Cleanup(ctx context.Context, taskID string) error
Purpose: Cleanup VM resources after termination.
Cleanup Steps: 1. Remove API socket file 2. Remove VM from tracking map 3. Release allocated resources
Firecracker API¶
Client¶
type unixClient struct {
socketPath string
timeout time.Duration
}
func newUnixClient(socketPath string, timeout time.Duration) *unixClient
HTTP Methods¶
func (c *unixClient) Get(path string) ([]byte, error)
func (c *unixClient) Put(path string, body interface{}) error
Uses HTTP over Unix socket:
// Dial Unix socket
conn, err := net.Dial("unix", socketPath)
// HTTP client with Unix transport
client := &http.Client{
Transport: &unixTransport{socketPath: socketPath},
}
API Types¶
type ActionsType struct {
ActionType string `json:"action_type"`
}
type BootSource struct {
KernelImagePath string `json:"kernel_image_path"`
BootArgs string `json:"boot_args,omitempty"`
Drives []Drive `json:"drives,omitempty"`
}
type Drive struct {
DriveID string `json:"drive_id"`
IsRootDevice bool `json:"is_root_device"`
IsReadOnly bool `json:"is_read_only"`
PathOnHost string `json:"path_on_host"`
}
type MachineConfig struct {
VCPUs int `json:"vcpu_count"`
MemSizeMib int `json:"mem_size_mib"`
HtEnabled bool `json:"ht_enabled"`
}
API Endpoints¶
| Endpoint | Method | Purpose |
|---|---|---|
/actions | PUT | Start/stop VM |
/boot-source | PUT | Configure kernel |
/drives/{id} | PUT | Configure disk |
/machine-config | PUT | Configure CPU/memory |
/network-interfaces/{id} | PUT | Configure network |
/vm | GET | Get VM info |
/vm | PUT | Pause/resume |
Configure VM¶
func (vm *VMMManager) configureVM(ctx context.Context, socketPath string, config interface{}) error
Purpose: Apply full VM configuration via API.
Steps:
-
Configure machine
machine := MachineConfig{ VCPUs: vmConfig.VCPUs, MemSizeMib: vmConfig.MemoryMB, HtEnabled: false, } client.Put("/machine-config", machine) -
Configure boot source
boot := BootSource{ KernelImagePath: vmConfig.KernelPath, BootArgs: "console=ttyS0 reboot=k panic=1 pci=off", } client.Put("/boot-source", boot) -
Configure root drive
drive := Drive{ DriveID: "rootfs", PathOnHost: vmConfig.RootfsPath, IsRootDevice: true, IsReadOnly: false, } client.Put("/drives/rootfs", drive) -
Configure network interface
iface := NetworkInterface{ IfaceID: "eth0", GuestMac: generateMac(taskID), HostDevName: tapDevice.Name, } client.Put("/network-interfaces/eth0", iface)
Graceful Shutdown¶
When InitSystem is set (tini/dumb-init):
// 1. Send SIGTERM to init process
syscall.Kill(pid, syscall.SIGTERM)
// 2. Wait grace period
time.Sleep(time.Duration(gracePeriodSec) * time.Second)
// 3. Force kill if still running
if processStillRunning {
syscall.Kill(pid, syscall.SIGKILL)
}
Configuration:
executor:
init_system: "tini"
init_grace_period: 10 # seconds
Process Monitoring¶
// Wait for process exit
func waitForProcess(pid int, timeout time.Duration) error {
for i := 0; i < int(timeout/time.Second); i++ {
if !processExists(pid) {
return nil
}
time.Sleep(time.Second)
}
return fmt.Errorf("process did not exit within timeout")
}
API Server Ready Check¶
func waitForAPIServer(socketPath string, timeout time.Duration) error {
for i := 0; i < int(timeout/time.Millisecond); i += 100 {
if _, err := net.Dial("unix", socketPath); err == nil {
return nil
}
time.Sleep(100 * time.Millisecond)
}
return fmt.Errorf("API server not ready after %v", timeout)
}
Testing¶
Mock VMMManager¶
type MockVMMManager struct {
VMs map[string]*VMInstance
StartErr error
StopErr error
}
func (m *MockVMMManager) Start(ctx context.Context, task *types.Task, config interface{}) error {
if m.StartErr != nil {
return m.StartErr
}
m.VMs[task.ID] = &VMInstance{
ID: task.ID,
PID: 12345,
state: VMStateRunning,
}
return nil
}
Error Handling¶
Common Errors¶
| Error | Cause | Resolution |
|---|---|---|
"task cannot be nil" | Nil task passed | Provide valid task |
"VM already exists" | Duplicate task ID | Remove existing VM first |
"firecracker binary not found" | Not installed | Install Firecracker |
"API server not ready" | Boot timeout | Check Firecracker logs |
"failed to configure VM" | API error | Validate config values |
"process did not exit" | Graceful shutdown timeout | Increase grace period |
Related Documentation¶
| Topic | Document |
|---|---|
| SwarmKit executor | SwarmKit Reference |
| Network setup | Network Reference |
| Init systems | Image Reference |
| Snapshot operations | Operations Guide |