Skip to content

Commit 5459b8d

Browse files
Huy Maisirpaleet
authored andcommitted
Allow vbmctl to create VM with multiple network interfaces
vbmctl currently creates VM with 1 network interface. This is enough for BMO E2E, but to be able to have VMs that work for other purposes, having the flexibility to have multiple networks is required. Co-authored-by: Huy Mai <[email protected]> Co-authored-by: Siiri Kemppainen <[email protected]> Signed-off-by: Lennart Jern <[email protected]>
1 parent 8fb74b2 commit 5459b8d

File tree

7 files changed

+89
-49
lines changed

7 files changed

+89
-49
lines changed

test/e2e/bmc.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ import (
1010
"gopkg.in/yaml.v2"
1111
)
1212

13+
type Network struct {
14+
// Name of the libvirt network.
15+
Name string `yaml:"name,omitempty"`
16+
// MacAddress of the interface connected to the network.
17+
MacAddress string `yaml:"macAddress,omitempty"`
18+
// IPAddress to reserve for the MAC address in the network.
19+
IPAddress string `yaml:"ipAddress,omitempty"`
20+
}
21+
1322
// BMC defines connection details for a baseboard management controller
1423
// and other details needed for creating a virtual machine related to it.
1524
type BMC struct {
@@ -33,6 +42,8 @@ type BMC struct {
3342
IPAddress string `yaml:"ipAddress,omitempty"`
3443
// RootDeviceHints provides guidance for where to write the disk image.
3544
RootDeviceHints metal3api.RootDeviceHints `yaml:"rootDeviceHints,omitempty"`
45+
// Networks describes the network interfaces that should be added to the VM representing this BMH.
46+
Networks []Network `yaml:"networks,omitempty"`
3647
}
3748

3849
func LoadBMCConfig(configPath string) ([]BMC, error) {

test/e2e/config/bmcs-ipmi.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
ipAddress: "192.168.222.122"
77
rootDeviceHints:
88
deviceName: "/dev/vda"
9+
networks:
10+
- name: baremetal-e2e
11+
macAddress: "00:60:2f:31:81:01"
12+
ipAddress: "192.168.222.122"
913
- user: admin
1014
password: password
1115
address: "ipmi://192.168.222.1:16231"
@@ -14,3 +18,7 @@
1418
ipAddress: "192.168.222.123"
1519
rootDeviceHints:
1620
deviceName: "/dev/vda"
21+
networks:
22+
- name: baremetal-e2e
23+
macAddress: "00:60:2f:31:81:02"
24+
ipAddress: "192.168.222.123"

test/e2e/config/bmcs-redfish-virtualmedia.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
ipAddress: "192.168.222.122"
77
rootDeviceHints:
88
deviceName: "/dev/vda"
9+
networks:
10+
- name: baremetal-e2e
11+
macAddress: "00:60:2f:31:81:01"
12+
ipAddress: "192.168.222.122"
913
- user: admin
1014
password: password
1115
address: "redfish-virtualmedia+http://192.168.222.1:8000/redfish/v1/Systems/bmo-e2e-1"
@@ -14,3 +18,7 @@
1418
ipAddress: "192.168.222.123"
1519
rootDeviceHints:
1620
deviceName: "/dev/vda"
21+
networks:
22+
- name: baremetal-e2e
23+
macAddress: "00:60:2f:31:81:02"
24+
ipAddress: "192.168.222.123"

test/e2e/config/bmcs-redfish.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
ipAddress: "192.168.222.122"
77
rootDeviceHints:
88
deviceName: "/dev/vda"
9+
networks:
10+
- name: baremetal-e2e
11+
macAddress: "00:60:2f:31:81:01"
12+
ipAddress: "192.168.222.122"
913
- user: admin
1014
password: password
1115
address: "redfish+http://192.168.222.1:8000/redfish/v1/Systems/bmo-e2e-1"
@@ -14,3 +18,7 @@
1418
ipAddress: "192.168.222.123"
1519
rootDeviceHints:
1620
deviceName: "/dev/vda"
21+
networks:
22+
- name: baremetal-e2e
23+
macAddress: "00:60:2f:31:81:02"
24+
ipAddress: "192.168.222.123"

test/e2e/re_inspection_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ var _ = Describe("Re-Inspection", Label("required", "re-inspection"), func() {
105105
By("checking that the hardware details are corrected after re-inspection")
106106
key = types.NamespacedName{Namespace: bmh.Namespace, Name: bmh.Name}
107107
Expect(clusterProxy.GetClient().Get(ctx, key, &bmh)).To(Succeed())
108-
// TODO(lentzi90): Hostname should not be determined or configured through BMC
109-
Expect(bmh.Status.HardwareDetails.Hostname).To(Equal(bmc.Name))
108+
// We are just checking that it changed from wrongHostName to something else.
109+
Expect(bmh.Status.HardwareDetails.Hostname).To(Not(Equal(wrongHostName)))
110110

111111
By("Delete BMH")
112112
err = clusterProxy.GetClient().Delete(ctx, &bmh)

test/vbmctl/main.go

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"flag"
1010
"log"
1111
"os"
12+
"strconv"
1213
"text/template"
1314

1415
bmoe2e "github.com/metal3-io/baremetal-operator/test/e2e"
@@ -133,35 +134,31 @@ func CreateVolume(conn *libvirt.Connect, volumeName, poolName, poolPath string,
133134
return nil
134135
}
135136

136-
// CreateLibvirtVM creates a new virtual machine with the given name,
137-
// network name, and MAC address. It first creates a qcow2 file with a size
138-
// of 3GB and defines it in the baremetal-e2e storage pool. The function then connects
139-
// to the libvirt daemon and uses a template to generate the VM's XML configuration.
140-
// If the domain is successfully defined and created, the virtual machine is
141-
// started. Errors during qcow2 file creation, volume creation, libvirt connection,
142-
// template rendering, or domain creation are returned.
143-
func CreateLibvirtVM(conn *libvirt.Connect, name, networkName, macAddress string) error {
137+
// CreateLibvirtVM creates a new virtual machine based on the bmc details.
138+
// The VM is defined only, not started. Two volumes are also created for the VM.
139+
func CreateLibvirtVM(conn *libvirt.Connect, bmc *bmoe2e.BMC) error {
140+
if err := ReserveIPAddresses(conn, bmc.Name, bmc.Networks); err != nil {
141+
log.Printf("Error occurred: %v\n", err)
142+
return err
143+
}
144144
poolName := "baremetal-e2e"
145145
poolPath := "/tmp/pool_oo"
146-
147-
if err := CreateVolume(conn, name+"-1", poolName, poolPath, 20); err != nil { //nolint: mnd
146+
if err := CreateVolume(conn, bmc.Name+"-1", poolName, poolPath, 20); err != nil { //nolint: mnd
148147
return err
149148
}
150149

151-
if err := CreateVolume(conn, name+"-2", poolName, poolPath, 20); err != nil { //nolint: mnd
150+
if err := CreateVolume(conn, bmc.Name+"-2", poolName, poolPath, 20); err != nil { //nolint: mnd
152151
return err
153152
}
154153

155154
data := struct {
156-
Name string
157-
Network string
158-
MacAddress string
159-
PoolPath string
155+
Name string
156+
Networks []bmoe2e.Network
157+
PoolPath string
160158
}{
161-
Name: name,
162-
Network: networkName,
163-
MacAddress: macAddress,
164-
PoolPath: poolPath,
159+
Name: bmc.Name,
160+
Networks: bmc.Networks,
161+
PoolPath: poolPath,
165162
}
166163

167164
vmCfg, err := RenderTemplate("templates/VM.xml.tpl", data)
@@ -182,17 +179,9 @@ func CreateLibvirtVM(conn *libvirt.Connect, name, networkName, macAddress string
182179
return nil
183180
}
184181

185-
// CreateLibvirtVMWithReservedIPAddress creates a VM with the given MAC address, name, IP address
186-
// and adds a DHCP host entry on the given network.
187-
//
188-
// It will return an error if the network does not exist, or if creating the VM
189-
// or adding the DHCP host entry fails.
190-
func CreateLibvirtVMWithReservedIPAddress(conn *libvirt.Connect, macAddress, name, ipAddress, networkName string) error {
191-
network, err := conn.LookupNetworkByName(networkName)
192-
if err != nil {
193-
return err
194-
}
195-
182+
// updateNetwork is a helper function for CreateLibvirtVMWithReservedIPAddress.
183+
// It updates the network with a DHCP host entry.
184+
func updateNetwork(network *libvirt.Network, macAddress, name, ipAddress string) error {
196185
xmlTpl, err := template.New("xml").Parse("<host mac='{{ .MacAddress }}' name='{{ .Name }}' ip='{{ .IPAddress }}' />")
197186

198187
if err != nil {
@@ -229,9 +218,24 @@ func CreateLibvirtVMWithReservedIPAddress(conn *libvirt.Connect, macAddress, nam
229218
log.Printf("Error occurred: %v\n", err)
230219
return err
231220
}
232-
if err = CreateLibvirtVM(conn, name, networkName, macAddress); err != nil {
233-
log.Printf("Error occurred: %v\n", err)
234-
return err
221+
return nil
222+
}
223+
224+
// ReserveIPAddresses adds a DHCP host entry for all networks that
225+
// specify an IP address.
226+
func ReserveIPAddresses(conn *libvirt.Connect, hostName string, networks []bmoe2e.Network) error {
227+
for i, net := range networks {
228+
// Checking if this network has IP specified.
229+
if net.IPAddress != "" {
230+
network, err := conn.LookupNetworkByName(net.Name)
231+
if err != nil {
232+
return err
233+
}
234+
err = updateNetwork(network, net.MacAddress, hostName+"-"+strconv.Itoa(i), net.IPAddress)
235+
if err != nil {
236+
return err
237+
}
238+
}
235239
}
236240
return nil
237241
}
@@ -252,9 +256,15 @@ func main() {
252256
bmcs := []bmoe2e.BMC{}
253257
if *configFile == "" {
254258
bmc := bmoe2e.BMC{
255-
IPAddress: *ipAddress,
256259
BootMacAddress: *macAddress,
257260
Name: *name,
261+
Networks: []bmoe2e.Network{
262+
{
263+
Name: *networkName,
264+
MacAddress: *macAddress,
265+
IPAddress: *ipAddress,
266+
},
267+
},
258268
}
259269
bmcs = append(bmcs, bmc)
260270
} else {
@@ -272,16 +282,9 @@ func main() {
272282
defer conn.Close()
273283

274284
for _, bmc := range bmcs {
275-
if bmc.IPAddress != "" {
276-
if err = CreateLibvirtVMWithReservedIPAddress(conn, bmc.BootMacAddress, bmc.Name, bmc.IPAddress, *networkName); err != nil {
277-
log.Printf("Error occurred: %v\n", err)
278-
break
279-
}
280-
} else {
281-
if err = CreateLibvirtVM(conn, bmc.Name, *networkName, bmc.BootMacAddress); err != nil {
282-
log.Printf("Error occurred: %v\n", err)
283-
break
284-
}
285+
if err = CreateLibvirtVM(conn, &bmc); err != nil {
286+
log.Printf("Error occurred: %v\n", err)
287+
break
285288
}
286289
}
287290
}

test/vbmctl/templates/VM.xml.tpl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,13 @@
7272
<target chassis='6' port='0x15'/>
7373
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
7474
</controller>
75-
<interface type='network'>
75+
{{ range .Networks }}
76+
<interface type='network'>
7677
<mac address='{{ .MacAddress }}'/>
77-
<source network='{{ .Network }}'/>
78+
<source network='{{ .Name }}'/>
7879
<model type='virtio' />
79-
</interface>
80+
</interface>
81+
{{ end }}
8082
<serial type='pty'>
8183
<log file='/var/log/libvirt/qemu/{{ .Name }}-serial0.log' append='on'/>
8284
<target type='isa-serial' port='0'>

0 commit comments

Comments
 (0)