Skip to content

Commit

Permalink
Merge pull request metal3-io#1786 from Nordix/fix_deploy_htpass
Browse files Browse the repository at this point in the history
🐛 Fix incorrect htpasswd file generation
  • Loading branch information
metal3-io-bot authored and mquhuy committed Jun 19, 2024
2 parents 536b43c + 73f9e0a commit 9306172
Show file tree
Hide file tree
Showing 14 changed files with 361 additions and 12 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ jobs:
contents: write

steps:
- name: Install libvirt-dev
run: sudo apt-get install -y libvirt-dev
- name: Check out code into the Go module directory
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Calculate go version
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/e2e-fixture-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Install libvirt-dev
run: sudo apt-get install -y libvirt-dev

- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6

- name: Calculate go version
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/e2e-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: Install libvirt
run: |
sudo apt-get update
sudo apt-get install -y libvirt-daemon-system qemu-kvm virt-manager
sudo apt-get install -y libvirt-daemon-system qemu-kvm virt-manager libvirt-dev
- name: Run BMO e2e Tests
env:
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ jobs:
- apis
- pkg/hardwareutils
steps:
- name: Install libvirt-dev
run: sudo apt-get install -y libvirt-dev
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- name: Calculate go version
id: vars
run: echo "go_version=$(make go-version)" >> $GITHUB_OUTPUT
Expand Down
22 changes: 22 additions & 0 deletions clean_bmcs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
#
# This script reads BMC information in a config file and prepare VMs
# whose info match those config
#
set -eux

REPO_ROOT=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
cd "${REPO_ROOT}"

CONFIG_FILE=$1
NETWORK=${2:-"baremetal-e2e"}

readarray -t BMCS < <(yq e -o=j -I=0 '.[]' "${CONFIG_FILE}")

for bmc in "${BMCS[@]}"; do
bootMacAddress=$(echo "${bmc}" | jq -r '.bootMacAddress')
ipAddress=$(echo "${bmc}" | jq -r '.ipAddress')
virsh -c qemu:///system net-update "${NETWORK}" delete ip-dhcp-host "<host mac='${bootMacAddress}' ip='${ipAddress}'/>" --live --config
done
"${REPO_ROOT}/tools/bmh_test/clean_local_bmh_test_setup.sh" "^bmo-e2e-"
rm -rf /tmp/bmo-e2e-*
6 changes: 5 additions & 1 deletion hack/ci-e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ else
exit 1
fi

"${REPO_ROOT}/hack/create_bmcs.sh" "${E2E_BMCS_CONF_FILE}" baremetal-e2e
# "${REPO_ROOT}/hack/create_bmcs.sh" "${E2E_BMCS_CONF_FILE}" baremetal-e2e
pushd "${REPO_ROOT}/test/createVM" || exit 1
go run main.go --yaml-source-file "${E2E_BMCS_CONF_FILE}"
popd

# Image server variables
CIRROS_VERSION="0.6.2"
Expand All @@ -118,6 +121,7 @@ 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 \
Expand Down
4 changes: 4 additions & 0 deletions hack/clean-e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ docker rm -f sushy-tools
rm -rf "${REPO_ROOT}/test/e2e/_artifacts"
rm -rf "${REPO_ROOT}"/artifacts-*
rm -rf "${REPO_ROOT}/test/e2e/images"

# Clear network
virsh -c qemu:///system net-destroy baremetal-e2e
virsh -c qemu:///system net-undefine baremetal-e2e
301 changes: 301 additions & 0 deletions test/createVM/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
package main

import (
"bytes"
"flag"
"fmt"
"os"
"text/template"

"github.com/dypflying/go-qcow2lib/qcow2"
"github.com/libvirt/libvirt-go"
bmoe2e "github.com/metal3-io/baremetal-operator/test/e2e"
)

func CreateLibvirtVM(hostName, networkName, macAddress string) error {
opts := make(map[string]any)
opts[qcow2.OPT_SIZE] = 1 << 30 // qcow2 file's size is 1g
opts[qcow2.OPT_FMT] = "qcow2" // qcow2 format
opts[qcow2.OPT_SUBCLUSTER] = true // enable sub-cluster

err := qcow2.Blk_Create("/tmp/"+hostName+".qcow2", opts)

if err != nil {
fmt.Println("Failed to create qcow2 file")
fmt.Printf("Error occurred: %v\n", err)
return err
}

conn, err := libvirt.NewConnect("qemu:///system")
if err != nil {
fmt.Println("Failed to connect to qemu:///system")
return err
}
defer conn.Close()

domainDef := `
<domain type='kvm'>
<name>{{ .HostName }}</name>
<description>Virtualized BareMetalHost</description>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://ubuntu.com/ubuntu/22.04"/>
</libosinfo:libosinfo>
</metadata>
<memory unit='KiB'>4194304</memory>
<vcpu placement='static'>2</vcpu>
<os>
<type arch='x86_64' machine='pc-q35-6.2'>hvm</type>
<boot dev='hd' />
</os>
<cpu mode='host-passthrough' check='none' migratable='on'/>
<pm>
<suspend-to-mem enabled='no'/>
<suspend-to-disk enabled='no'/>
</pm>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' discard='unmap'/>
<source file='/tmp/{{ .HostName }}.qcow2'/>
<target dev='vda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</disk>
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pcie-root'/>
<controller type='pci' index='1' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='1' port='0x8'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='2' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='2' port='0x9'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<controller type='pci' index='3' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='3' port='0xa'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='pci' index='4' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='4' port='0xb'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x3'/>
</controller>
<controller type='pci' index='5' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='5' port='0xc'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x4'/>
</controller>
<controller type='pci' index='6' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='6' port='0xd'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x5'/>
</controller>
<controller type='pci' index='7' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='7' port='0xe'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x6'/>
</controller>
<controller type='pci' index='8' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='8' port='0xf'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x7'/>
</controller>
<controller type='pci' index='9' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='9' port='0x10'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='10' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='10' port='0x11'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
</controller>
<controller type='pci' index='11' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='11' port='0x12'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
</controller>
<controller type='pci' index='12' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='12' port='0x13'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
</controller>
<controller type='pci' index='13' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='13' port='0x14'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
</controller>
<controller type='pci' index='14' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='14' port='0x15'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
</controller>
<controller type='sata' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
</controller>
<controller type='virtio-serial' index='0'>
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
</controller>
<interface type='network'>
<mac address='{{ .MacAddress }}'/>
<source network='{{ .Network }}'/>
<model type='virtio' />
</interface>
<serial type='pty'>
<log file='/var/log/libvirt/qemu/{{ .HostName }}-serial0.log' append='on'/>
<target type='isa-serial' port='0'>
<model name='isa-serial'/>
</target>
</serial>
<console type='pty'>
<log file='/var/log/libvirt/qemu/{{ .HostName }}-serial0.log' append='on'/>
<target type='serial' port='0'/>
</console>
<channel type='unix'>
<target type='virtio' name='org.qemu.guest_agent.0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
<rng model='virtio'>
<backend model='random'>/dev/urandom</backend>
<address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
</rng>
</devices>
</domain>`

xmlTpl, err := template.New("xml").Parse(domainDef)

if err != nil {
fmt.Println("Failed to init the template")
fmt.Printf("Error occurred: %v\n", err)
return err
}

data := struct {
HostName string
Network string
MacAddress string
}{
HostName: hostName,
Network: networkName,
MacAddress: macAddress,
}

var buf bytes.Buffer

err = xmlTpl.Execute(&buf, data)

if err != nil {
return err
}

fmt.Println(buf.String())

dom, err := conn.DomainDefineXML(buf.String())

if err != nil {
fmt.Println("Failed to define domain")
fmt.Printf("Error occurred: %v\n", err)
return err
}

if err := dom.Create(); err != nil {
fmt.Println("Failed to create domain")
fmt.Printf("Error occurred: %v\n", err)
return err
}

fmt.Println("Domain created successfully")
return nil
}

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()

network, err := conn.LookupNetworkByName(networkName)
if err != nil {
return err
}

xmlTpl, err := template.New("xml").Parse("<host mac='{{ .MacAddress }}' name='{{ .HostName }}' ip='{{ .IPAddress }}' />")

if err != nil {
return err
}

data := struct {
MacAddress string
HostName string
IPAddress string
}{
MacAddress: macAddress,
HostName: hostName,
IPAddress: ipAddress,
}

var buf bytes.Buffer

err = xmlTpl.Execute(&buf, data)

if err != nil {
fmt.Printf("Error occurred: %v\n", err)
return err
}

if err = network.Update(
libvirt.NETWORK_UPDATE_COMMAND_ADD_LAST,
libvirt.NETWORK_SECTION_IP_DHCP_HOST,
-1,
buf.String(),
libvirt.NETWORK_UPDATE_AFFECT_LIVE|libvirt.NETWORK_UPDATE_AFFECT_CONFIG,
); err != nil {
fmt.Printf("Error occurred: %v\n", err)
return err
}
if err = CreateLibvirtVM(hostName, networkName, macAddress); err != nil {
fmt.Printf("Error occurred: %v\n", err)
return err
}
return nil
}

func main() {
var vmName = flag.String(
"vm-name", "VM-1", "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(
"mac-address", "00:60:2f:31:81:01", "Mac address of the VM on the network")
var ipAddress = flag.String(
"ip-address", "192.168.222.122", "IP address of the VM on the network")
var configFile = flag.String(
"yaml-source-file", "", "yaml file where BMCS are defined. If this is set, ignore all other options")
flag.Parse()
var err error
if *configFile == "" {
if err = CreateLibvirtBMC(*macAddress, *vmName, *ipAddress, *networkName); err != nil {
fmt.Printf("Error occurred: %v\n", err)
os.Exit(1)
}
} else {
bmcs, err := bmoe2e.LoadBMCConfig(*configFile)
if err != nil {
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)
}
}
}
}
Loading

0 comments on commit 9306172

Please sign in to comment.