Skip to content

Commit c516575

Browse files
authored
Merge pull request #113 from gardenlinux/feat/ci-test-cloud-hypervisor
ci: add CHV in tandem with QEMU tests
2 parents 41f2957 + f43b90f commit c516575

File tree

8 files changed

+223
-19
lines changed

8 files changed

+223
-19
lines changed

.github/actions/test/integration/build/action.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ runs:
110110
run: |
111111
wget -q "https://cloud-images.ubuntu.com/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64.img" -O /opt/ubuntu.qcow2
112112
113+
- name: Generate raw ubuntu image for CHV
114+
shell: bash
115+
run: |
116+
qemu-img convert -p -f qcow2 -O raw /opt/ubuntu.qcow2 /opt/ubuntu.raw
117+
113118
- name: Generate ubuntu cloud-init
114119
shell: bash
115120
run: |

.github/actions/test/integration/setup/hv.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@
3434
<qemu:arg value='-fw_cfg' />
3535
<qemu:arg value='name=opt/com.coreos/config,file=/var/lib/libvirt/images/hv.ign' />
3636
</qemu:commandline>
37-
</domain>
37+
</domain>

.github/actions/test/integration/setup/virbr-vm.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
<ip address='192.168.222.1' netmask='255.255.255.0'>
1010
<dhcp>
1111
<range start='192.168.222.100' end='192.168.222.254' />
12-
<host mac='52:54:00:00:00:01' ip='192.168.222.2' name='vm' />
12+
<host mac='52:54:00:00:00:01' ip='192.168.222.2' name='vm-qemu' />
13+
<host mac='52:54:00:00:00:11' ip='192.168.222.3' name='vm-chv' />
1314
</dhcp>
1415
</ip>
15-
</network>
16+
</network>
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
name: test-cloudhypervisor
2+
description: Execute Integration Tests for Hypervisor Capabilities (CloudHyperVisor)
3+
runs:
4+
using: "composite"
5+
steps:
6+
- name: Copy VM defintions and artifacts to the HyperVisors
7+
shell: bash
8+
run: |
9+
KEY=/opt/ssh_host_ed25519_key
10+
SSH_OPTS="-i $KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
11+
USER="root"
12+
IP_HV1="192.168.122.2"
13+
IP_HV2="192.168.122.3"
14+
15+
scp $SSH_OPTS ./.github/actions/test/integration/test/cloudhypervisor/vm.xml "$USER@$IP_HV1:/opt/vm-chv.xml"
16+
scp $SSH_OPTS /opt/ubuntu.raw "$USER@$IP_HV1:/var/lib/libvirt/images/ubuntu.raw"
17+
scp $SSH_OPTS /opt/ubuntu-cloud-init-ds.iso "$USER@$IP_HV1:/var/lib/libvirt/images/ubuntu-cloud-init-ds.iso"
18+
19+
# libvirt migration between cloudhypervisor instances does not support storage migration yet
20+
scp $SSH_OPTS /opt/ubuntu.raw "$USER@$IP_HV2:/var/lib/libvirt/images/ubuntu.raw"
21+
# the cloud-init data is not migrated from source to destination, but needed for the VM to run at the destination
22+
scp $SSH_OPTS /opt/ubuntu-cloud-init-ds.iso "$USER@$IP_HV2:/var/lib/libvirt/images/ubuntu-cloud-init-ds.iso"
23+
24+
- name: Start VM on HyperVisor 1
25+
shell: bash
26+
run: |
27+
KEY=/opt/ssh_host_ed25519_key
28+
SSH_OPTS="-i $KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
29+
USER="root"
30+
IP_HV1="192.168.122.2"
31+
32+
ssh $SSH_OPTS "$USER@$IP_HV1" << EOF
33+
virsh -c ch:///session define /opt/vm-chv.xml
34+
virsh -c ch:///session start VM-CHV
35+
EOF
36+
37+
- name: Wait for VM to be ready
38+
shell: bash
39+
run: |
40+
KEY=/opt/ssh_host_ed25519_key
41+
SSH_OPTS="-i $KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
42+
USER="root"
43+
IP_HV1="192.168.122.2"
44+
45+
ssh $SSH_OPTS "$USER@$IP_HV1" << EOF
46+
KEY=/opt/ssh_host_ed25519_key
47+
SSH_OPTS="-i \$KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
48+
USER="root"
49+
50+
MAX_ITER=40
51+
for ((i=1; i<=MAX_ITER; i++)); do
52+
IP=\$(virsh -c ch:///session domifaddr VM-CHV | awk '/ipv4/ {print \$4}' | cut -d'/' -f1)
53+
if [ -z "\$IP" ]; then
54+
echo "No IP address found for VM. Retrying..."
55+
elif ssh \$SSH_OPTS "\$USER@\$IP" 'exit' ; then
56+
echo "VM is up at IP: \$IP"
57+
# create a dummy file for verification later
58+
ssh \$SSH_OPTS "\$USER@\$IP" 'echo "Hello, World!" > /opt/hello.txt'
59+
break
60+
fi
61+
if (( i == MAX_ITER )); then
62+
echo "Timeout waiting for VM to respond to SSH."
63+
cat /var/log/CHV.log
64+
exit 1
65+
fi
66+
echo "Waiting for VM to respond to SSH... (\$i/\$MAX_ITER)"
67+
sleep 10
68+
done
69+
EOF
70+
71+
- name: Mirgrate the VM to HyperVisor 2
72+
shell: bash
73+
run: |
74+
KEY=/opt/ssh_host_ed25519_key
75+
SSH_OPTS="-i $KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
76+
USER="root"
77+
IP_HV1="192.168.122.2"
78+
79+
ssh $SSH_OPTS "$USER@$IP_HV1" << EOF
80+
USER="root"
81+
IP_HV2="192.168.122.3"
82+
83+
virsh -c ch:///session migrate --persistent --undefinesource --live VM-CHV ch+ssh://\$USER@\$IP_HV2/system
84+
if virsh -c ch:///session dominfo VM-CHV &>/dev/null; then
85+
echo "VM is still present on HV1 after migration!"
86+
exit 1
87+
fi
88+
EOF
89+
90+
- name: Verify VM status on HyperVisor 2
91+
shell: bash
92+
run: |
93+
KEY=/opt/ssh_host_ed25519_key
94+
SSH_OPTS="-i $KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
95+
USER="root"
96+
IP_HV2="192.168.122.3"
97+
98+
ssh $SSH_OPTS "$USER@$IP_HV2" << EOF
99+
if virsh -c ch:///session dominfo VM-CHV | awk '/State:/ {print \$2}' | grep -q "running"; then
100+
echo "VM is running on HV2."
101+
else
102+
echo "VM is not running on HV2."
103+
exit 1
104+
fi
105+
106+
KEY=/opt/ssh_host_ed25519_key
107+
SSH_OPTS="-i \$KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
108+
USER="root"
109+
# waiting for the IP to be visible to the new HyperVisor via DHCP takes WAYYYYYYY too long
110+
# the IP is static, so we can just use it directly
111+
IP="192.168.222.3"
112+
113+
MAX_ITER=40
114+
for ((i=1; i<=MAX_ITER; i++)); do
115+
if ssh \$SSH_OPTS "\$USER@\$IP" 'exit' ; then
116+
echo "VM is up at IP: \$IP"
117+
# verify the migration by checking the dummy file
118+
if ssh \$SSH_OPTS "\$USER@\$IP" 'test -f /opt/hello.txt'; then
119+
echo "Dummy file exists on VM, migration successful."
120+
break
121+
else
122+
echo "Dummy file does not exist on VM, migration failed."
123+
exit 1
124+
fi
125+
fi
126+
if (( i == MAX_ITER )); then
127+
echo "Timeout waiting for VM to respond to SSH."
128+
cat /var/log/CHV.log
129+
exit 1
130+
fi
131+
echo "Waiting for VM to respond to SSH... (\$i/\$MAX_ITER)"
132+
sleep 10
133+
done
134+
EOF
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<domain type='kvm'>
2+
<name>VM-CHV</name>
3+
<memory unit='GiB'>2</memory>
4+
<vcpu placement='static'>1</vcpu>
5+
<os>
6+
<type arch='x86_64' machine='pc'>hvm</type>
7+
<!-- see https://github.com/cloud-hypervisor/rust-hypervisor-firmware/issues/382 -->
8+
<kernel>/usr/share/cloud-hypervisor/CLOUDHV_EFI.fd</kernel>
9+
</os>
10+
<cpu mode='host-passthrough' check='none' migratable='on' />
11+
<devices>
12+
<disk type='file' device='disk'>
13+
<source file='/var/lib/libvirt/images/ubuntu.raw' />
14+
<target dev='hda' bus='virtio' />
15+
</disk>
16+
<disk type='file' device='cdrom'>
17+
<source file='/var/lib/libvirt/images/ubuntu-cloud-init-ds.iso' />
18+
<target dev='hdb' bus='virtio' />
19+
<readonly />
20+
</disk>
21+
<interface type='network'>
22+
<mac address='52:54:00:00:00:11' />
23+
<source network='default' />
24+
<model type='virtio' />
25+
</interface>
26+
<!-- currently not supported with libvirt/chv: -->
27+
<!-- error: internal error: Serial only works in UNIX/PTY modes -->
28+
<!-- <console type='pty'> -->
29+
<!-- <target type='serial' port='0' /> -->
30+
<!-- </console> -->
31+
<!-- <serial type='file'> -->
32+
<!-- <source path='/var/log/CHV.log' /> -->
33+
<!-- <target port='0' /> -->
34+
<!-- </serial> -->
35+
</devices>
36+
</domain>
37+

.github/actions/test/integration/test/action.yml renamed to .github/actions/test/integration/test/qemu/action.yml

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
name: test
2-
description: Execute Integration Tests for Hypervisor Capabilities
1+
name: test-qemu
2+
description: Execute Integration Tests for Hypervisor Capabilities (QEMU)
33
runs:
44
using: "composite"
55
steps:
@@ -12,7 +12,7 @@ runs:
1212
IP_HV1="192.168.122.2"
1313
IP_HV2="192.168.122.3"
1414
15-
scp $SSH_OPTS ./.github/actions/test/integration/test/vm.xml "$USER@$IP_HV1:/opt/vm.xml"
15+
scp $SSH_OPTS ./.github/actions/test/integration/test/qemu/vm.xml "$USER@$IP_HV1:/opt/vm-qemu.xml"
1616
scp $SSH_OPTS /opt/ubuntu.qcow2 "$USER@$IP_HV1:/var/lib/libvirt/images/ubuntu.qcow2"
1717
scp $SSH_OPTS /opt/ubuntu-cloud-init-ds.iso "$USER@$IP_HV1:/var/lib/libvirt/images/ubuntu-cloud-init-ds.iso"
1818
@@ -28,8 +28,8 @@ runs:
2828
IP_HV1="192.168.122.2"
2929
3030
ssh $SSH_OPTS "$USER@$IP_HV1" << EOF
31-
virsh define /opt/vm.xml
32-
virsh start VM
31+
virsh define /opt/vm-qemu.xml
32+
virsh start VM-QEMU
3333
EOF
3434
3535
- name: Wait for VM to be ready
@@ -47,7 +47,7 @@ runs:
4747
4848
MAX_ITER=40
4949
for ((i=1; i<=MAX_ITER; i++)); do
50-
IP=\$(virsh domifaddr VM | awk '/ipv4/ {print \$4}' | cut -d'/' -f1)
50+
IP=\$(virsh domifaddr VM-QEMU | awk '/ipv4/ {print \$4}' | cut -d'/' -f1)
5151
if [ -z "\$IP" ]; then
5252
echo "No IP address found for VM. Retrying..."
5353
elif ssh \$SSH_OPTS "\$USER@\$IP" 'exit' 2>/dev/null; then
@@ -58,7 +58,7 @@ runs:
5858
fi
5959
if (( i == MAX_ITER )); then
6060
echo "Timeout waiting for VM to respond to SSH."
61-
cat /var/log/VM.log
61+
cat /var/log/QEMU.log
6262
exit 1
6363
fi
6464
echo "Waiting for VM to respond to SSH... (\$i/\$MAX_ITER)"
@@ -78,8 +78,8 @@ runs:
7878
USER="root"
7979
IP_HV2="192.168.122.3"
8080
81-
virsh migrate --persistent --undefinesource --copy-storage-all --live VM qemu+ssh://\$USER@\$IP_HV2/system
82-
if virsh dominfo VM &>/dev/null; then
81+
virsh migrate --persistent --undefinesource --copy-storage-all --live VM-QEMU qemu+ssh://\$USER@\$IP_HV2/system
82+
if virsh dominfo VM-QEMU &>/dev/null; then
8383
echo "VM is still present on HV1 after migration!"
8484
exit 1
8585
fi
@@ -94,7 +94,7 @@ runs:
9494
IP_HV2="192.168.122.3"
9595
9696
ssh $SSH_OPTS "$USER@$IP_HV2" << EOF
97-
if virsh dominfo VM | awk '/State:/ {print \$2}' | grep -q "running"; then
97+
if virsh dominfo VM-QEMU | awk '/State:/ {print \$2}' | grep -q "running"; then
9898
echo "VM is running on HV2."
9999
else
100100
echo "VM is not running on HV2."
@@ -123,10 +123,32 @@ runs:
123123
fi
124124
if (( i == MAX_ITER )); then
125125
echo "Timeout waiting for VM to respond to SSH."
126-
cat /var/log/VM.log
126+
cat /var/log/QEMU.log
127127
exit 1
128128
fi
129129
echo "Waiting for VM to respond to SSH... (\$i/\$MAX_ITER)"
130130
sleep 10
131131
done
132132
EOF
133+
134+
- name: Clean up HyperVisors
135+
shell: bash
136+
run: |
137+
KEY=/opt/ssh_host_ed25519_key
138+
SSH_OPTS="-i $KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
139+
USER="root"
140+
IP_HV1="192.168.122.2"
141+
IP_HV2="192.168.122.3"
142+
143+
cleanup() {
144+
local IP="$1"
145+
ssh $SSH_OPTS "$USER@$IP" << EOF
146+
virsh destroy VM-QEMU || true
147+
virsh undefine VM-QEMU --nvram --tpm --remove-all-storage
148+
rm -f /var/lib/libvirt/images/ubuntu.qcow2
149+
rm -f /opt/vm-qemu.xml
150+
EOF
151+
}
152+
153+
cleanup "$IP_HV1"
154+
cleanup "$IP_HV2"

.github/actions/test/integration/test/vm.xml renamed to .github/actions/test/integration/test/qemu/vm.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
2-
<name>VM</name>
2+
<name>VM-QEMU</name>
33
<memory unit='GiB'>2</memory>
44
<vcpu>2</vcpu>
55
<os firmware='efi'>
@@ -32,8 +32,8 @@
3232
<target type='serial' port='0' />
3333
</console>
3434
<serial type='file'>
35-
<source path='/var/log/VM.log' />
35+
<source path='/var/log/QEMU.log' />
3636
<target port='0' />
3737
</serial>
3838
</devices>
39-
</domain>
39+
</domain>

.github/workflows/test.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
name: test hypervisor capabilities
22
on:
3+
push:
4+
branches:
5+
- feat/ci-test-cloud-hypervisor
36
workflow_run:
47
workflows:
58
- nightly
@@ -33,5 +36,7 @@ jobs:
3336
image_tag: ${{ env.latest_tag || inputs.image_tag }}
3437
- name: Setup
3538
uses: ./.github/actions/test/integration/setup
36-
- name: Test
37-
uses: ./.github/actions/test/integration/test
39+
- name: Test QEMU
40+
uses: ./.github/actions/test/integration/test/qemu
41+
- name: Test CloudHypervisor
42+
uses: ./.github/actions/test/integration/test/cloudhypervisor

0 commit comments

Comments
 (0)