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 @@ -