Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ type Config struct {
CPUTemplate string `json:"cpu_template"`
LogLevels []string `json:"log_levels"`
SmtEnabled bool `json:"smt_enabled"`
// DefaultVcpuCount is the default number of vCPUs for a microVM.
// If not specified (0), defaults to 1.
DefaultVcpuCount uint32 `json:"default_vcpu_count"`
// DefaultMemSizeMib is the default memory size in MiB for a microVM.
// Must be at least 1 MiB. If not specified (0), defaults to 128 MiB.
DefaultMemSizeMib uint32 `json:"default_mem_size_mib"`
// If a CreateVM call specifies no network interfaces and DefaultNetworkInterfaces is non-empty,
// the VM will default to using the network interfaces as specified here. This is especially
// useful when a CNI-based network interface is provided in DefaultNetworkInterfaces.
Expand Down
4 changes: 3 additions & 1 deletion config/config.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@
"root_drive": "./vsock.img",
"cpu_template": "T2",
"log_levels": ["debug"],
"ht_enabled": false
"smt_enabled": false,
"default_vcpu_count": 1,
"default_mem_size_mib": 128
}
40 changes: 40 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,43 @@ func createTempConfig(t *testing.T, contents string) (string, func()) {
}
return configFile.Name(), func() { os.Remove(configFile.Name()) }
}

func TestLoadConfigDefaultVcpuAndMem(t *testing.T) {
testcases := []struct {
name string
configContent string
expectedVcpu uint32
expectedMem uint32
}{
{
name: "DefaultsWhenNotSpecified",
configContent: `{}`,
expectedVcpu: 0, // 0 means use hardcoded default
expectedMem: 0, // 0 means use hardcoded default
},
{
name: "CustomVcpuAndMem",
configContent: `{"default_vcpu_count": 4, "default_mem_size_mib": 512}`,
expectedVcpu: 4,
expectedMem: 512,
},
{
name: "LargeVcpuCount",
configContent: `{"default_vcpu_count": 32}`,
expectedVcpu: 32,
expectedMem: 0,
},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
configFile, cleanup := createTempConfig(t, tc.configContent)
defer cleanup()

cfg, err := LoadConfig(configFile)
assert.NoError(t, err)
assert.Equal(t, tc.expectedVcpu, cfg.DefaultVcpuCount)
assert.Equal(t, tc.expectedMem, cfg.DefaultMemSizeMib)
})
}
}
15 changes: 13 additions & 2 deletions runtime/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,21 @@ const (
)

func machineConfigurationFromProto(cfg *config.Config, req *proto.FirecrackerMachineConfiguration) models.MachineConfiguration {
// Use config values if provided, otherwise fall back to hardcoded defaults
vcpuCount := int64(defaultCPUCount)
if cfg.DefaultVcpuCount > 0 {
vcpuCount = int64(cfg.DefaultVcpuCount)
}

memSizeMib := int64(defaultMemSizeMb)
if cfg.DefaultMemSizeMib > 0 {
memSizeMib = int64(cfg.DefaultMemSizeMib)
}

config := models.MachineConfiguration{
CPUTemplate: models.CPUTemplate(cfg.CPUTemplate),
VcpuCount: firecracker.Int64(defaultCPUCount),
MemSizeMib: firecracker.Int64(defaultMemSizeMb),
VcpuCount: firecracker.Int64(vcpuCount),
MemSizeMib: firecracker.Int64(memSizeMib),
Smt: firecracker.Bool(cfg.SmtEnabled),
}

Expand Down
63 changes: 63 additions & 0 deletions runtime/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,69 @@ func TestMachineConfigurationFromProto(t *testing.T) {
Smt: firecracker.Bool(true),
},
},
{
name: "ConfigDefaultVcpuAndMem",
config: &config.Config{
CPUTemplate: "T2",
DefaultVcpuCount: 4,
DefaultMemSizeMib: 512,
},
proto: nil,
expectedMachineConfig: models.MachineConfiguration{
CPUTemplate: models.CPUTemplateT2,
VcpuCount: firecracker.Int64(4),
MemSizeMib: firecracker.Int64(512),
Smt: firecracker.Bool(false),
},
},
{
name: "ConfigDefaultsWithEmptyProto",
config: &config.Config{
CPUTemplate: "T2",
DefaultVcpuCount: 8,
DefaultMemSizeMib: 1024,
},
proto: &proto.FirecrackerMachineConfiguration{},
expectedMachineConfig: models.MachineConfiguration{
CPUTemplate: models.CPUTemplateT2,
VcpuCount: firecracker.Int64(8),
MemSizeMib: firecracker.Int64(1024),
Smt: firecracker.Bool(false),
},
},
{
name: "ProtoOverridesConfigDefaults",
config: &config.Config{
CPUTemplate: "T2",
DefaultVcpuCount: 4,
DefaultMemSizeMib: 512,
},
proto: &proto.FirecrackerMachineConfiguration{
VcpuCount: 16,
MemSizeMib: 2048,
},
expectedMachineConfig: models.MachineConfiguration{
CPUTemplate: models.CPUTemplateT2,
VcpuCount: firecracker.Int64(16),
MemSizeMib: firecracker.Int64(2048),
Smt: firecracker.Bool(false),
},
},
{
name: "ZeroConfigDefaultsFallbackToHardcoded",
config: &config.Config{
CPUTemplate: "T2",
DefaultVcpuCount: 0,
DefaultMemSizeMib: 0,
},
proto: nil,
expectedMachineConfig: models.MachineConfiguration{
CPUTemplate: models.CPUTemplateT2,
VcpuCount: firecracker.Int64(defaultCPUCount),
MemSizeMib: firecracker.Int64(defaultMemSizeMb),
Smt: firecracker.Bool(false),
},
},
}

for _, tc := range testcases {
Expand Down