Skip to content

Commit aca86dc

Browse files
Merge pull request #10349 from elfosardo/q35-efi-metal-support
METAL-1750: baremetal: use q35 machine type with EFI firmware for bootstrap VM
2 parents fe4720d + 2b1d13b commit aca86dc

File tree

2 files changed

+114
-12
lines changed

2 files changed

+114
-12
lines changed

pkg/infrastructure/baremetal/bootstrap.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,22 @@ func getHostCapabilities(virConn *libvirt.Libvirt) (libvirtxml.Caps, error) {
344344
return caps, nil
345345
}
346346

347+
func configureDomainArch(dom *libvirtxml.Domain, arch string) {
348+
dom.OS.Type.Arch = arch
349+
350+
switch arch {
351+
case "x86_64":
352+
dom.OS.Type.Machine = "q35"
353+
dom.OS.Firmware = "efi"
354+
case "aarch64":
355+
// reference: https://libvirt.org/formatdomain.html#bios-bootloader
356+
dom.OS.Firmware = "efi"
357+
fallthrough
358+
case "s390x", "ppc64le":
359+
dom.Devices.Graphics = nil
360+
}
361+
}
362+
347363
func createBootstrapDomain(virConn *libvirt.Libvirt, config baremetalConfig, pool libvirt.StoragePool, liveCDVolume, scratchVolume libvirt.StorageVol) error {
348364
bootstrapDom := newDomain(fmt.Sprintf("%s-bootstrap", config.ClusterID))
349365

@@ -353,18 +369,7 @@ func createBootstrapDomain(virConn *libvirt.Libvirt, config baremetalConfig, poo
353369
}
354370

355371
arch := capabilities.Host.CPU.Arch
356-
bootstrapDom.OS.Type.Arch = arch
357-
358-
if arch == "aarch64" {
359-
// for aarch64 speciffying this will automatically select the firmware and NVRAM file
360-
// reference: https://libvirt.org/formatdomain.html#bios-bootloader
361-
bootstrapDom.OS.Firmware = "efi"
362-
}
363-
364-
// For aarch64, s390x, ppc64 and ppc64le spice is not supported
365-
if arch == "aarch64" || arch == "s390x" || strings.HasPrefix(arch, "ppc64") {
366-
bootstrapDom.Devices.Graphics = nil
367-
}
372+
configureDomainArch(&bootstrapDom, arch)
368373

369374
for _, bridge := range config.Bridges {
370375
netIface := libvirtxml.DomainInterface{
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package baremetal
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"libvirt.org/go/libvirtxml"
8+
)
9+
10+
func TestNewDomain(t *testing.T) {
11+
dom := newDomain("test-bootstrap")
12+
13+
assert.Equal(t, "test-bootstrap", dom.Name)
14+
assert.Equal(t, "kvm", dom.Type)
15+
assert.Equal(t, "hvm", dom.OS.Type.Type)
16+
assert.Empty(t, dom.OS.Type.Arch, "arch should not be set by newDomain")
17+
assert.Empty(t, dom.OS.Type.Machine, "machine should not be set by newDomain")
18+
assert.Equal(t, uint(6), dom.Memory.Value)
19+
assert.Equal(t, "GiB", dom.Memory.Unit)
20+
assert.Equal(t, uint(4), dom.VCPU.Value)
21+
assert.Equal(t, "host-passthrough", dom.CPU.Mode)
22+
assert.NotEmpty(t, dom.Devices.RNGs, "RNG device should be configured")
23+
assert.NotEmpty(t, dom.Devices.Graphics, "graphics should be configured")
24+
assert.NotEmpty(t, dom.Devices.Consoles, "console should be configured")
25+
}
26+
27+
func TestConfigureDomainArch(t *testing.T) {
28+
tests := []struct {
29+
name string
30+
arch string
31+
expectMachine string
32+
expectFirmware string
33+
expectGraphics bool
34+
}{
35+
{
36+
name: "x86_64 sets q35 and efi",
37+
arch: "x86_64",
38+
expectMachine: "q35",
39+
expectFirmware: "efi",
40+
expectGraphics: true,
41+
},
42+
{
43+
name: "aarch64 sets efi and removes graphics",
44+
arch: "aarch64",
45+
expectMachine: "",
46+
expectFirmware: "efi",
47+
expectGraphics: false,
48+
},
49+
{
50+
name: "s390x removes graphics",
51+
arch: "s390x",
52+
expectMachine: "",
53+
expectFirmware: "",
54+
expectGraphics: false,
55+
},
56+
{
57+
name: "ppc64le removes graphics",
58+
arch: "ppc64le",
59+
expectMachine: "",
60+
expectFirmware: "",
61+
expectGraphics: false,
62+
},
63+
}
64+
65+
for _, tc := range tests {
66+
t.Run(tc.name, func(t *testing.T) {
67+
dom := newDomain("test-bootstrap")
68+
configureDomainArch(&dom, tc.arch)
69+
70+
assert.Equal(t, tc.arch, dom.OS.Type.Arch)
71+
assert.Equal(t, tc.expectMachine, dom.OS.Type.Machine)
72+
assert.Equal(t, tc.expectFirmware, dom.OS.Firmware)
73+
74+
if tc.expectGraphics {
75+
assert.NotNil(t, dom.Devices.Graphics, "graphics should be present for %s", tc.arch)
76+
} else {
77+
assert.Nil(t, dom.Devices.Graphics, "graphics should be removed for %s", tc.arch)
78+
}
79+
})
80+
}
81+
}
82+
83+
func TestConfigureDomainArchPreservesOtherFields(t *testing.T) {
84+
dom := newDomain("test-bootstrap")
85+
86+
dom.Devices.Interfaces = []libvirtxml.DomainInterface{
87+
{
88+
Model: &libvirtxml.DomainInterfaceModel{Type: "virtio"},
89+
},
90+
}
91+
92+
configureDomainArch(&dom, "x86_64")
93+
94+
assert.Len(t, dom.Devices.Interfaces, 1, "interfaces should not be modified")
95+
assert.Equal(t, "hvm", dom.OS.Type.Type, "OS type should remain hvm")
96+
assert.Equal(t, "kvm", dom.Type, "domain type should remain kvm")
97+
}

0 commit comments

Comments
 (0)