-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.go
More file actions
98 lines (92 loc) · 2.98 KB
/
config.go
File metadata and controls
98 lines (92 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package knaller
import (
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
"os"
)
// PortMapping maps a host port to a guest port for TCP forwarding.
type PortMapping struct {
Host int
Guest int
}
// Config describes a microVM to start. At minimum, Kernel and RootFS must be
// set. Knaller starts a Firecracker process, connects to its API socket,
// configures the VM, and boots it. Interact with the running VM via SSH
// (the SSH port is returned in VM.Port).
type Config struct {
Name string // VM name (random 8-char hex if empty)
Kernel string // path to vmlinux kernel image
RootFS string // path to base rootfs ext4 image (copied per-VM)
CPUs float64 // vCPUs (default: 1, e.g. 0.5 = 1 vCPU at 50% quota)
Memory int // memory in MiB (default: 1024, minimum: 128)
NetworkMbps float64 // network bandwidth limit in Mbps per direction (0 = unlimited)
DiskMBps int // disk bandwidth limit in MB/s (0 = unlimited)
DiskIOPS int // disk I/O operations per second limit (0 = unlimited)
Ports []PortMapping // additional TCP port forwarding (host:guest)
SnapshotID string // restore from this snapshot instead of booting fresh
Detach bool // start VM in background (survives terminal close)
FirecrackerBin string // path to firecracker binary (default: "firecracker")
PastaBin string // path to pasta binary (default: "pasta")
Stdout io.Writer // serial console log output (default: io.Discard)
Stderr io.Writer // firecracker process stderr (default: io.Discard)
}
// setDefaults fills in zero-value fields with sensible defaults.
func (c *Config) setDefaults() {
if c.Name == "" {
c.Name = randomName()
}
if c.CPUs == 0 {
c.CPUs = 1.0
}
if c.Memory == 0 {
c.Memory = 1024
}
if c.FirecrackerBin == "" {
c.FirecrackerBin = "firecracker"
}
if c.PastaBin == "" {
c.PastaBin = "pasta"
}
if c.Stdout == nil {
c.Stdout = io.Discard
}
if c.Stderr == nil {
c.Stderr = io.Discard
}
}
// validate checks that all required fields are set and valid. When restoring
// from a snapshot (SnapshotID is set), kernel/rootfs/cpus/memory come from the
// snapshot and are not validated here.
func (c *Config) validate() error {
if c.SnapshotID != "" {
return nil
}
if c.Kernel == "" {
return errors.New("kernel path is required")
}
if _, err := os.Stat(c.Kernel); err != nil {
return fmt.Errorf("kernel: %w", err)
}
if c.RootFS == "" {
return errors.New("rootfs path is required")
}
if _, err := os.Stat(c.RootFS); err != nil {
return fmt.Errorf("rootfs: %w", err)
}
if c.CPUs <= 0 {
return errors.New("cpus must be > 0")
}
if c.Memory < 128 {
return errors.New("memory must be >= 128 MiB")
}
return nil
}
// randomName generates an 8-character random hex string for use as a VM name.
func randomName() string {
b := make([]byte, 4)
rand.Read(b)
return hex.EncodeToString(b)
}