diff --git a/hack/ci-e2e.sh b/hack/ci-e2e.sh
index b3100f5ee5..0ce6d494ba 100755
--- a/hack/ci-e2e.sh
+++ b/hack/ci-e2e.sh
@@ -82,7 +82,7 @@ if [[ "${BMO_E2E_EMULATOR}" == "vbmc" ]]; then
readarray -t BMCS < <(yq e -o=j -I=0 '.[]' "${E2E_BMCS_CONF_FILE}")
for bmc in "${BMCS[@]}"; do
address=$(echo "${bmc}" | jq -r '.address')
- hostName=$(echo "${bmc}" | jq -r '.hostName')
+ hostName=$(echo "${bmc}" | jq -r '.name')
vbmc_port="${address##*:}"
"${REPO_ROOT}/tools/bmh_test/vm2vbmc.sh" "${hostName}" "${vbmc_port}" "${IP_ADDRESS}"
done
@@ -113,7 +113,6 @@ mkdir -p "${IMAGE_DIR}"
## Download disk images
wget --quiet -P "${IMAGE_DIR}/" https://artifactory.nordix.org/artifactory/metal3/images/iso/"${IMAGE_FILE}"
wget --quiet -P "${IMAGE_DIR}/" https://fastly-cdn.system-rescue.org/releases/11.00/systemrescue-11.00-amd64.iso
-wget --quiet -P "${IMAGE_DIR}/" https://artifactory.nordix.org/artifactory/metal3/images/iso/minimal_linux_live-v2.iso
## Start the image server
docker run --name image-server-e2e -d \
diff --git a/test/e2e/basic_ops_test.go b/test/e2e/basic_ops_test.go
index b0ddd17660..3d80fa067a 100644
--- a/test/e2e/basic_ops_test.go
+++ b/test/e2e/basic_ops_test.go
@@ -61,7 +61,7 @@ var _ = Describe("basic", Label("required", "basic"), func() {
Address: bmc.Address,
CredentialsName: "bmc-credentials",
},
- BootMode: metal3api.Legacy,
+ BootMode: metal3api.BootMode(e2eConfig.GetVariable("BOOT_MODE")),
BootMACAddress: bmc.BootMacAddress,
},
}
diff --git a/test/e2e/bmc.go b/test/e2e/bmc.go
index 319f06b06b..d3624e1a81 100644
--- a/test/e2e/bmc.go
+++ b/test/e2e/bmc.go
@@ -9,28 +9,32 @@ import (
"gopkg.in/yaml.v2"
)
-// BMC defines a BMH to use in the tests.
+// BMC defines connection details for a baseboard management controller
+// and other details needed for creating a virtual machine related to it.
type BMC struct {
- // BMC initial username
+ // User is the username for accessing the BMC.
User string `yaml:"user,omitempty"`
- // BMC initial password
+ // Password is the password for accessing the BMC.
Password string `yaml:"password,omitempty"`
- // BMC initial address
+ // Address of the BMC, e.g. "redfish-virtualmedia+http://192.168.222.1:8000/redfish/v1/Systems/bmo-e2e-1".
Address string `yaml:"address,omitempty"`
- // BMC Mac address
+ // BootMacAddress is the MAC address of the VMs network interface.
BootMacAddress string `yaml:"bootMacAddress,omitempty"`
- // The Hostname of the node, which will be read into BMH object
- HostName string `yaml:"hostName,omitempty"`
- // The IP address of the node
- // Optional. Only needed if e2eConfig variable
- // SSH_CHECK_PROVISIONED is true
+ // Name of the machine associated with this BMC.
+ Name string `yaml:"name,omitempty"`
+ // NetworkName is the name of the network that the new VM should be attached to
+ NetworkName string `yaml:"networkName,omitempty"`
+ // IPAddress is a reserved IP address for the VM.
+ // This will be paired with the MAC address in the DHCP configuration.
+ // Example: 192.168.222.122
IPAddress string `yaml:"ipAddress,omitempty"`
- // Optional. Only needed if e2eConfig variable
- // SSH_CHECK_PROVISIONED is true
- SSHPort string `yaml:"sshPort,omitempty"`
+ // OSLoader is the field in the VM XML.
+ // This can be used to support UEFI and/or secure boot.
+ // Example: /usr/share/OVMF/OVMF_CODE_4M.secboot.fd
+ OSLoader string `yaml:"osLoader,omitempty"`
}
-func LoadBMCConfig(configPath string) (*[]BMC, error) {
+func LoadBMCConfig(configPath string) ([]BMC, error) {
configData, err := os.ReadFile(configPath) //#nosec
var bmcs []BMC
if err != nil {
@@ -39,5 +43,5 @@ func LoadBMCConfig(configPath string) (*[]BMC, error) {
if err := yaml.Unmarshal(configData, &bmcs); err != nil {
return nil, err
}
- return &bmcs, nil
+ return bmcs, nil
}
diff --git a/test/e2e/common.go b/test/e2e/common.go
index 59ff1850a9..42fd43ac45 100644
--- a/test/e2e/common.go
+++ b/test/e2e/common.go
@@ -292,8 +292,15 @@ echo "%s" >> /root/.ssh/authorized_keys`, sshPubKeyData)
// PerformSSHBootCheck performs an SSH check to verify the node's boot source.
// The `expectedBootMode` parameter should be "disk" or "memory".
// The `auth` parameter is an ssh.AuthMethod for authentication.
-func PerformSSHBootCheck(e2eConfig *Config, expectedBootMode string, auth ssh.AuthMethod, sshAddress string) {
+func PerformSSHBootCheck(e2eConfig *Config, expectedBootMode string, ipAddress string) {
user := e2eConfig.GetVariable("SSH_USERNAME")
+ keyPath := e2eConfig.GetVariable("SSH_PRIV_KEY")
+ key, err := os.ReadFile(keyPath)
+ Expect(err).NotTo(HaveOccurred(), "unable to read private key")
+ signer, err := ssh.ParsePrivateKey(key)
+ Expect(err).NotTo(HaveOccurred(), "unable to parse private key")
+ auth := ssh.PublicKeys(signer)
+ sshAddress := fmt.Sprintf("%s:%s", ipAddress, e2eConfig.GetVariable("SSH_PORT"))
client := EstablishSSHConnection(e2eConfig, auth, user, sshAddress)
defer func() {
diff --git a/test/e2e/config/bmcs-fixture.yaml b/test/e2e/config/bmcs-fixture.yaml
index c16c8a36eb..93762eb260 100644
--- a/test/e2e/config/bmcs-fixture.yaml
+++ b/test/e2e/config/bmcs-fixture.yaml
@@ -1,16 +1,11 @@
-# For fixture config, only the `hostName` field matters. The number of BMCs,
-# however, needs to be equal or larger than `GINKGO_NODES`.
+# For fixture it doesn't matter much what we put here. The number of BMCs,
+# however, needs to be equal or larger than `GINKGO_NODES` or we will
+# run out of BMCs to test on.
- user: admin
password: password
address: "redfish+http://192.168.222.1:8000/redfish/v1/Systems/bmo-e2e-0"
bootMacAddress: "00:60:2f:31:81:01"
- hostName: ""
- ipAddress: "192.168.222.122"
- sshPort: "22"
- user: admin
password: password
address: "redfish+http://192.168.222.1:8000/redfish/v1/Systems/bmo-e2e-1"
bootMacAddress: "00:60:2f:31:81:02"
- hostName: ""
- ipAddress: "192.168.222.123"
- sshPort: "22"
diff --git a/test/e2e/config/bmcs-ipmi.yaml b/test/e2e/config/bmcs-ipmi.yaml
index 758d93459b..f509e6ec5e 100644
--- a/test/e2e/config/bmcs-ipmi.yaml
+++ b/test/e2e/config/bmcs-ipmi.yaml
@@ -2,13 +2,13 @@
password: password
address: "ipmi://192.168.222.1:16230"
bootMacAddress: "00:60:2f:31:81:01"
- hostName: "bmo-e2e-0"
+ name: "bmo-e2e-0"
ipAddress: "192.168.222.122"
- sshPort: "22"
+ osLoader: /usr/share/OVMF/OVMF_CODE_4M.fd
- user: admin
password: password
address: "ipmi://192.168.222.1:16231"
bootMacAddress: "00:60:2f:31:81:02"
- hostName: "bmo-e2e-1"
+ name: "bmo-e2e-1"
ipAddress: "192.168.222.123"
- sshPort: "22"
+ osLoader: /usr/share/OVMF/OVMF_CODE_4M.fd
diff --git a/test/e2e/config/bmcs-redfish-virtualmedia.yaml b/test/e2e/config/bmcs-redfish-virtualmedia.yaml
index f991a792d1..f450407b30 100644
--- a/test/e2e/config/bmcs-redfish-virtualmedia.yaml
+++ b/test/e2e/config/bmcs-redfish-virtualmedia.yaml
@@ -2,13 +2,13 @@
password: password
address: "redfish-virtualmedia+http://192.168.222.1:8000/redfish/v1/Systems/bmo-e2e-0"
bootMacAddress: "00:60:2f:31:81:01"
- hostName: "bmo-e2e-0"
+ name: "bmo-e2e-0"
ipAddress: "192.168.222.122"
- sshPort: "22"
+ osLoader: /usr/share/OVMF/OVMF_CODE_4M.secboot.fd
- user: admin
password: password
address: "redfish-virtualmedia+http://192.168.222.1:8000/redfish/v1/Systems/bmo-e2e-1"
bootMacAddress: "00:60:2f:31:81:02"
- hostName: "bmo-e2e-1"
+ name: "bmo-e2e-1"
ipAddress: "192.168.222.123"
- sshPort: "22"
+ osLoader: /usr/share/OVMF/OVMF_CODE_4M.secboot.fd
diff --git a/test/e2e/config/bmcs-redfish.yaml b/test/e2e/config/bmcs-redfish.yaml
index 8ec2b33a71..17a9269c01 100644
--- a/test/e2e/config/bmcs-redfish.yaml
+++ b/test/e2e/config/bmcs-redfish.yaml
@@ -2,13 +2,13 @@
password: password
address: "redfish+http://192.168.222.1:8000/redfish/v1/Systems/bmo-e2e-0"
bootMacAddress: "00:60:2f:31:81:01"
- hostName: "bmo-e2e-0"
+ name: "bmo-e2e-0"
ipAddress: "192.168.222.122"
- sshPort: "22"
+ osLoader: /usr/share/OVMF/OVMF_CODE_4M.fd
- user: admin
password: password
address: "redfish+http://192.168.222.1:8000/redfish/v1/Systems/bmo-e2e-1"
bootMacAddress: "00:60:2f:31:81:02"
- hostName: "bmo-e2e-1"
+ name: "bmo-e2e-1"
ipAddress: "192.168.222.123"
- sshPort: "22"
+ osLoader: /usr/share/OVMF/OVMF_CODE_4M.fd
diff --git a/test/e2e/config/ironic.yaml b/test/e2e/config/ironic.yaml
index 9d05da1cb7..139ef97c3a 100644
--- a/test/e2e/config/ironic.yaml
+++ b/test/e2e/config/ironic.yaml
@@ -41,6 +41,7 @@ variables:
CERT_MANAGER_VERSION: "v1.13.1"
SSH_CHECK_PROVISIONED: "true"
SSH_USERNAME: "root"
+ SSH_PORT: "22"
SSH_PRIV_KEY: "./images/ssh_testkey"
SSH_PUB_KEY: "./images/ssh_testkey.pub"
FETCH_IRONIC_NODES: "true"
@@ -48,6 +49,8 @@ variables:
IRONIC_PASSWORD: "changeme"
IRONIC_PROVISIONING_IP: "localhost"
IRONIC_PROVISIONING_PORT: "6385"
+ # Boot mode can be legacy, UEFI or UEFISecureBoot
+ BOOT_MODE: "UEFI"
intervals:
inspection/wait-unmanaged: ["1m", "5s"]
diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go
index 26b8d78322..19fe4c5942 100644
--- a/test/e2e/e2e_suite_test.go
+++ b/test/e2e/e2e_suite_test.go
@@ -306,7 +306,7 @@ var _ = SynchronizedBeforeSuite(func() []byte {
e2eConfig = LoadE2EConfig(configPath)
bmcs, err := LoadBMCConfig(bmcConfigPath)
Expect(err).ToNot(HaveOccurred(), "Failed to read the bmcs config file")
- bmc = (*bmcs)[GinkgoParallelProcess()-1]
+ bmc = (bmcs)[GinkgoParallelProcess()-1]
clusterProxy = framework.NewClusterProxy("bmo-e2e", kubeconfigPath, scheme)
})
diff --git a/test/e2e/external_inspection_test.go b/test/e2e/external_inspection_test.go
index d8b582a62c..d4a78be0fd 100644
--- a/test/e2e/external_inspection_test.go
+++ b/test/e2e/external_inspection_test.go
@@ -213,7 +213,7 @@ var _ = Describe("External Inspection", Label("required", "external-inspection")
Address: bmc.Address,
CredentialsName: "bmc-credentials",
},
- BootMode: metal3api.Legacy,
+ BootMode: metal3api.BootMode(e2eConfig.GetVariable("BOOT_MODE")),
BootMACAddress: bmc.BootMacAddress,
},
}
diff --git a/test/e2e/inspection_test.go b/test/e2e/inspection_test.go
index 20dc427c65..6b9ff0b735 100644
--- a/test/e2e/inspection_test.go
+++ b/test/e2e/inspection_test.go
@@ -105,7 +105,7 @@ var _ = Describe("Inspection", Label("required", "inspection"), func() {
Address: bmc.Address,
CredentialsName: "bmc-credentials",
},
- BootMode: metal3api.Legacy,
+ BootMode: metal3api.BootMode(e2eConfig.GetVariable("BOOT_MODE")),
BootMACAddress: bmc.BootMacAddress,
},
}
diff --git a/test/e2e/live_iso_test.go b/test/e2e/live_iso_test.go
index ce9115b8ba..599b05a920 100644
--- a/test/e2e/live_iso_test.go
+++ b/test/e2e/live_iso_test.go
@@ -6,14 +6,12 @@ package e2e
import (
"context"
"fmt"
- "os"
"path"
metal3api "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
metal3bmc "github.com/metal3-io/baremetal-operator/pkg/hardwareutils/bmc"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
- "golang.org/x/crypto/ssh"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"
@@ -80,7 +78,7 @@ var _ = Describe("Live-ISO", Label("required", "live-iso"), func() {
URL: imageURL,
DiskFormat: pointer.String("live-iso"),
},
- BootMode: metal3api.Legacy,
+ BootMode: metal3api.BootMode(e2eConfig.GetVariable("BOOT_MODE")),
BootMACAddress: bmc.BootMacAddress,
AutomatedCleaningMode: metal3api.CleaningModeDisabled,
},
@@ -105,13 +103,7 @@ var _ = Describe("Live-ISO", Label("required", "live-iso"), func() {
// The ssh check is not possible in all situations (e.g. fixture) so it can be skipped
if e2eConfig.GetVariable("SSH_CHECK_PROVISIONED") == "true" {
By("Verifying the node booted from live ISO image")
- keyPath := e2eConfig.GetVariable("SSH_PRIV_KEY")
- key, err := os.ReadFile(keyPath)
- Expect(err).NotTo(HaveOccurred(), "unable to read private key")
- signer, err := ssh.ParsePrivateKey(key)
- Expect(err).NotTo(HaveOccurred(), "unable to parse private key")
- auth := ssh.PublicKeys(signer)
- PerformSSHBootCheck(e2eConfig, "memory", auth, fmt.Sprintf("%s:%s", bmc.IPAddress, bmc.SSHPort))
+ PerformSSHBootCheck(e2eConfig, "memory", bmc.IPAddress)
} else {
Logf("WARNING: Skipping SSH check since SSH_CHECK_PROVISIONED != true")
}
diff --git a/test/e2e/provisioning_and_annotation_test.go b/test/e2e/provisioning_and_annotation_test.go
index 0d9e8c9264..091971931e 100644
--- a/test/e2e/provisioning_and_annotation_test.go
+++ b/test/e2e/provisioning_and_annotation_test.go
@@ -7,14 +7,12 @@ import (
"context"
"encoding/json"
"fmt"
- "os"
"path"
"time"
metal3api "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
- "golang.org/x/crypto/ssh"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -66,7 +64,7 @@ var _ = Describe("Provision, detach, recreate from status and deprovision", Labe
Address: bmc.Address,
CredentialsName: "bmc-credentials",
},
- BootMode: metal3api.Legacy,
+ BootMode: metal3api.BootMode(e2eConfig.GetVariable("BOOT_MODE")),
BootMACAddress: bmc.BootMacAddress,
AutomatedCleaningMode: "disabled",
},
@@ -121,15 +119,7 @@ var _ = Describe("Provision, detach, recreate from status and deprovision", Labe
// The ssh check is not possible in all situations (e.g. fixture) so it can be skipped
if e2eConfig.GetVariable("SSH_CHECK_PROVISIONED") == "true" {
By("Verifying the node booting from disk")
- keyPath := e2eConfig.GetVariable("SSH_PRIV_KEY")
- key, err := os.ReadFile(keyPath)
- Expect(err).NotTo(HaveOccurred(), "unable to read private key")
-
- signer, err := ssh.ParsePrivateKey(key)
- Expect(err).NotTo(HaveOccurred(), "unable to parse private key")
-
- auth := ssh.PublicKeys(signer)
- PerformSSHBootCheck(e2eConfig, "disk", auth, fmt.Sprintf("%s:%s", bmc.IPAddress, bmc.SSHPort))
+ PerformSSHBootCheck(e2eConfig, "disk", bmc.IPAddress)
} else {
Logf("WARNING: Skipping SSH check since SSH_CHECK_PROVISIONED != true")
}
@@ -206,7 +196,7 @@ var _ = Describe("Provision, detach, recreate from status and deprovision", Labe
Address: bmc.Address,
CredentialsName: "bmc-credentials",
},
- BootMode: metal3api.Legacy,
+ BootMode: metal3api.BootMode(e2eConfig.GetVariable("BOOT_MODE")),
BootMACAddress: bmc.BootMacAddress,
AutomatedCleaningMode: "disabled",
Image: &metal3api.Image{
diff --git a/test/e2e/re_inspection_test.go b/test/e2e/re_inspection_test.go
index e72c4c5388..a0b889326a 100644
--- a/test/e2e/re_inspection_test.go
+++ b/test/e2e/re_inspection_test.go
@@ -63,7 +63,7 @@ var _ = Describe("Re-Inspection", Label("required", "re-inspection"), func() {
Address: bmc.Address,
CredentialsName: "bmc-credentials",
},
- BootMode: metal3api.Legacy,
+ BootMode: metal3api.BootMode(e2eConfig.GetVariable("BOOT_MODE")),
BootMACAddress: bmc.BootMacAddress,
},
}
@@ -105,7 +105,8 @@ var _ = Describe("Re-Inspection", Label("required", "re-inspection"), func() {
By("checking that the hardware details are corrected after re-inspection")
key = types.NamespacedName{Namespace: bmh.Namespace, Name: bmh.Name}
Expect(clusterProxy.GetClient().Get(ctx, key, &bmh)).To(Succeed())
- Expect(bmh.Status.HardwareDetails.Hostname).To(Equal(bmc.HostName))
+ // TODO(lentzi90): Hostname should not be determined or configured through BMC
+ Expect(bmh.Status.HardwareDetails.Hostname).To(Equal(bmc.Name))
})
AfterEach(func() {
diff --git a/test/e2e/upgrade_test.go b/test/e2e/upgrade_test.go
index 0848c94dd2..c6bb3bafff 100644
--- a/test/e2e/upgrade_test.go
+++ b/test/e2e/upgrade_test.go
@@ -276,7 +276,7 @@ func RunUpgradeTest(ctx context.Context, input *BMOIronicUpgradeInput, upgradeCl
Address: bmc.Address,
CredentialsName: secretName,
},
- BootMode: metal3api.Legacy,
+ BootMode: metal3api.BootMode(e2eConfig.GetVariable("BOOT_MODE")),
BootMACAddress: bmc.BootMacAddress,
},
}
diff --git a/test/vbmctl/main.go b/test/vbmctl/main.go
index bc8cb1649b..cc63d020ec 100644
--- a/test/vbmctl/main.go
+++ b/test/vbmctl/main.go
@@ -38,15 +38,7 @@ func RenderTemplate(inputFile string, data interface{}) (string, error) {
// CreateVolumePool creates a volume pool with specified name if a pool with
// that name does not exist yet.
-func CreateVolumePool(poolName, poolPath string) (*libvirt.StoragePool, error) {
- // Connect to libvirt daemon
- conn, err := libvirt.NewConnect("qemu:///system")
- if err != nil {
- fmt.Println("Failed to connect to qemu:///system")
- return nil, err
- }
- defer conn.Close()
-
+func CreateVolumePool(conn *libvirt.Connect, poolName, poolPath string) (*libvirt.StoragePool, error) {
pool, err := conn.LookupStoragePoolByName(poolName)
if err == nil {
@@ -100,16 +92,8 @@ func CreateVolumePool(poolName, poolPath string) (*libvirt.StoragePool, error) {
return pool, nil
}
-func CreateVolume(volumeName, poolName, poolPath string, capacityInGB int) error {
- // Connect to libvirt daemon
- conn, err := libvirt.NewConnect("qemu:///system")
- if err != nil {
- fmt.Println("Failed to connect to qemu:///system")
- return err
- }
- defer conn.Close()
-
- pool, err := CreateVolumePool(poolName, poolPath)
+func CreateVolume(conn *libvirt.Connect, volumeName, poolName, poolPath string, capacityInGB int) error {
+ pool, err := CreateVolumePool(conn, poolName, poolPath)
if err != nil {
fmt.Println("Failed to create storage pool")
@@ -146,14 +130,14 @@ func CreateVolume(volumeName, poolName, poolPath string, capacityInGB int) error
return nil
}
-// CreateLibvirtVM creates a new virtual machine with the given hostname,
+// CreateLibvirtVM creates a new virtual machine with the given name,
// network name, and MAC address. It first creates a qcow2 file with a size
// of 3GB and defines it in the default storage pool. The function then connects
// to the libvirt daemon and uses a template to generate the VM's XML configuration.
// If the domain is successfully defined and created, the virtual machine is
// started. Errors during qcow2 file creation, volume creation, libvirt connection,
// template rendering, or domain creation are returned.
-func CreateLibvirtVM(hostName, networkName, macAddress string) error {
+func CreateLibvirtVM(conn *libvirt.Connect, name, networkName, macAddress, osLoader string) error {
poolName := "default"
poolPath := "/tmp/pool_oo"
opts := make(map[string]any)
@@ -161,7 +145,7 @@ func CreateLibvirtVM(hostName, networkName, macAddress string) error {
opts[qcow2.OPT_FMT] = "qcow2" // qcow2 format
opts[qcow2.OPT_SUBCLUSTER] = true // enable sub-cluster
- err := qcow2.Blk_Create("/tmp/"+hostName+".qcow2", opts)
+ err := qcow2.Blk_Create("/tmp/"+name+".qcow2", opts)
if err != nil {
fmt.Println("Failed to create qcow2 file")
@@ -169,27 +153,22 @@ func CreateLibvirtVM(hostName, networkName, macAddress string) error {
return err
}
- if err = CreateVolume(hostName, poolName, poolPath, 20); err != nil {
+ if err = CreateVolume(conn, name, poolName, poolPath, 20); err != nil {
return err
}
- conn, err := libvirt.NewConnect("qemu:///system")
- if err != nil {
- fmt.Println("Failed to connect to qemu:///system")
- return err
- }
- defer conn.Close()
-
data := struct {
- HostName string
+ Name string
Network string
MacAddress string
PoolPath string
+ OSLoader string
}{
- HostName: hostName,
+ Name: name,
Network: networkName,
MacAddress: macAddress,
PoolPath: poolPath,
+ OSLoader: osLoader,
}
vmCfg, err := RenderTemplate("templates/VM.xml.tpl", data)
@@ -216,25 +195,18 @@ func CreateLibvirtVM(hostName, networkName, macAddress string) error {
return nil
}
-// CreateLibvirtBMC creates a VM with the given MAC address, hostname, IP address
+// CreateLibvirtVMWithReservedIPAddress creates a VM with the given MAC address, name, IP address
// and adds a DHCP host entry on the given network.
//
// It will return an error if the network does not exist, or if creating the VM
// or adding the DHCP host entry fails.
-func CreateLibvirtBMC(macAddress, hostName, ipAddress, networkName string) error {
- var err error
- conn, err := libvirt.NewConnect("qemu:///system")
- if err != nil {
- return err
- }
- defer conn.Close()
-
+func CreateLibvirtVMWithReservedIPAddress(conn *libvirt.Connect, macAddress, name, ipAddress, osLoader, networkName string) error {
network, err := conn.LookupNetworkByName(networkName)
if err != nil {
return err
}
- xmlTpl, err := template.New("xml").Parse("")
+ xmlTpl, err := template.New("xml").Parse("")
if err != nil {
return err
@@ -242,12 +214,14 @@ func CreateLibvirtBMC(macAddress, hostName, ipAddress, networkName string) error
data := struct {
MacAddress string
- HostName string
+ Name string
IPAddress string
+ OSLoader string
}{
MacAddress: macAddress,
- HostName: hostName,
+ Name: name,
IPAddress: ipAddress,
+ OSLoader: osLoader,
}
var buf bytes.Buffer
@@ -270,7 +244,7 @@ func CreateLibvirtBMC(macAddress, hostName, ipAddress, networkName string) error
fmt.Printf("Error occurred: %v\n", err)
return err
}
- if err = CreateLibvirtVM(hostName, networkName, macAddress); err != nil {
+ if err = CreateLibvirtVM(conn, name, networkName, macAddress, osLoader); err != nil {
fmt.Printf("Error occurred: %v\n", err)
return err
}
@@ -278,8 +252,8 @@ func CreateLibvirtBMC(macAddress, hostName, ipAddress, networkName string) error
}
func main() {
- var vmName = flag.String(
- "vm-name", "VM-1", "The name of the VM to create")
+ var name = flag.String(
+ "name", "BMH-0", "The name of the VM to create")
var networkName = flag.String(
"network-name", "baremetal-e2e", "The name of the network that the new VM should be attached to")
var macAddress = flag.String(
@@ -290,21 +264,36 @@ func main() {
"yaml-source-file", "", "yaml file where BMCS are defined. If this is set, ignore all other options")
flag.Parse()
var err error
+ bmcs := []bmoe2e.BMC{}
if *configFile == "" {
- if err = CreateLibvirtBMC(*macAddress, *vmName, *ipAddress, *networkName); err != nil {
- fmt.Printf("Error occurred: %v\n", err)
- os.Exit(1)
+ bmc := bmoe2e.BMC{
+ IPAddress: *ipAddress,
+ BootMacAddress: *macAddress,
+ Name: *name,
+ NetworkName: *networkName,
}
+ bmcs = append(bmcs, bmc)
} else {
- bmcs, err := bmoe2e.LoadBMCConfig(*configFile)
+ bmcs, err = bmoe2e.LoadBMCConfig(*configFile)
if err != nil {
+ fmt.Printf("Error occurred: %v\n", err)
os.Exit(1)
}
- for _, bmc := range *bmcs {
- if err = CreateLibvirtBMC(bmc.BootMacAddress, bmc.HostName, bmc.IPAddress, "baremetal-e2e"); err != nil {
- fmt.Printf("Error occurred: %v\n", err)
- os.Exit(1)
- }
+ }
+
+ // Connect to Libvirt
+ conn, err := libvirt.NewConnect("qemu:///system")
+ if err != nil {
+ fmt.Printf("Error occurred: %v\n", err)
+ os.Exit(1)
+ }
+ defer conn.Close()
+
+ for _, bmc := range bmcs {
+ if err = CreateLibvirtVMWithReservedIPAddress(conn, bmc.BootMacAddress, bmc.Name, bmc.IPAddress, bmc.OSLoader, "baremetal-e2e"); err != nil {
+ fmt.Printf("Error occurred: %v\n", err)
+ // Not using os.Exit here so that we still close the connection
+ break
}
}
}
diff --git a/test/vbmctl/templates/VM.xml.tpl b/test/vbmctl/templates/VM.xml.tpl
index bd3de83fb7..2514f54807 100644
--- a/test/vbmctl/templates/VM.xml.tpl
+++ b/test/vbmctl/templates/VM.xml.tpl
@@ -1,10 +1,10 @@
- {{ .HostName }}
+ {{ .Name }}
4194304
- 4194304
2
hvm
+ {{- or .OSLoader "" }}
@@ -29,7 +29,7 @@
-
+
@@ -78,13 +78,13 @@
-
+
-
+
@@ -102,4 +102,3 @@
-