Skip to content

Commit 70fe547

Browse files
bgreenbcaladd
authored andcommitted
INTERNAL: Allow channel attribute to assign default network interface for VM hosts
1 parent 42bb01f commit 70fe547

4 files changed

Lines changed: 167 additions & 10 deletions

File tree

common/src/stack/command/stack/commands/report/vm/__init__.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,10 @@ def gen_interfaces(self, host):
247247

248248
for interface in self.call('list.host.interface', [host]):
249249
interface_name = interface['interface']
250-
250+
host_interface = None
251+
network_pxe = False
251252
network = interface['network']
253+
channel = interface['channel']
252254
out = {}
253255

254256
# Skip any vlan tagged or virtual interfaces
@@ -257,20 +259,28 @@ def gen_interfaces(self, host):
257259
if '.' in interface_name or ':' in interface_name:
258260
continue
259261

260-
# Check if the hypervisor has a interface on the same network
261-
# as the virtual machine
262-
host_interface = self.getInterfaceByNetwork(vm_host, network)
263-
264-
# Skip interfaces that the underlying hypervisor
265-
# has no interface for on that network
266-
if not host_interface:
267-
raise CommandError(self, f'On VM {host} could not find interface for network {network} on hypervisor {vm_host}')
268-
269262
if network:
270263

264+
# Check if the hypervisor has a interface on the same network
265+
# as the virtual machine
266+
host_interface = self.getInterfaceByNetwork(vm_host, network)
267+
271268
# If the network isn't set for pxe, don't use it for the bootorder
272269
network_pxe = self.str2bool(self.call('list.network', args = [network])[0].get('pxe'))
273270

271+
# If no network is set for the source interface
272+
# use the channel setting for a default one
273+
# if it is a valid interface on the hypervisor
274+
elif channel:
275+
for interface in self.call('list.host.interface', [vm_host]):
276+
if interface['interface'] == channel:
277+
host_interface = channel
278+
279+
# Otherwise raise an error as libvirt requires
280+
# a source interface when defining the VM's interfaces
281+
if not host_interface:
282+
raise CommandError(self, f'On VM {host} could not find interface for network {network} on hypervisor {vm_host}')
283+
274284
out['mac'] = interface['mac']
275285
out['name'] = host_interface
276286

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<domain type="kvm">
2+
<name>vm-backend-0-3</name>
3+
<uuid>00000000-0000-0000-0000-0000000000</uuid>
4+
<memory>2097152</memory>
5+
<vcpu>1</vcpu>
6+
<os>
7+
<type arch="x86_64">hvm</type>
8+
</os>
9+
<features>
10+
<acpi/>
11+
<apic/>
12+
</features>
13+
<clock offset="utc">
14+
<timer name="rtc" tickpolicy="catchup"/>
15+
<timer name="pit" tickpolicy="delay"/>
16+
<timer name="hpet" present="no"/>
17+
</clock>
18+
<on_poweroff>destroy</on_poweroff>
19+
<on_reboot>restart</on_reboot>
20+
<on_crash>restart</on_crash>
21+
<pm>
22+
<suspend-to-mem enabled="no"/>
23+
<suspend-to-disk enabled="no"/>
24+
</pm>
25+
<devices>
26+
<emulator>/usr/libexec/qemu-kvm</emulator>
27+
<interface type="bridge">
28+
<mac address="52:54:00:4a:7d:92"/>
29+
<source bridge="eth1"/>
30+
<model type="virtio"/>
31+
</interface>
32+
<disk device="disk" type="file">
33+
<driver cache="none" type="qcow2" name="qemu" io="native"/>
34+
<source file="/export/pools/stacki/vm-backend-0-3/vm-backend-0-3_disk1.qcow2"/>
35+
<target dev="sda" bus="sata"/>
36+
<boot order="1"/>
37+
</disk>
38+
<serial type="pty">
39+
<target port="0"/>
40+
</serial>
41+
<serial type="pty">
42+
<target port="1"/>
43+
</serial>
44+
<input bus="ps2" type="mouse"/>
45+
<graphics autoport="yes" keymap="en-us" type="vnc" port="-1"/>
46+
<video>
47+
<model heads="1" vram="9216" type="cirrus"/>
48+
</video>
49+
<rng model="virtio">
50+
<backend model="random">/dev/random</backend>
51+
<address type="pci" domain="0x0000" bus="0x00" slot="0x0c" function="0x0"/>
52+
</rng>
53+
</devices>
54+
</domain>
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<domain type="kvm">
2+
<name>vm-backend-0-3</name>
3+
<uuid>00000000-0000-0000-0000-0000000000</uuid>
4+
<memory>2097152</memory>
5+
<vcpu>1</vcpu>
6+
<os>
7+
<type arch="x86_64">hvm</type>
8+
</os>
9+
<features>
10+
<acpi/>
11+
<apic/>
12+
<vmport state="off"/>
13+
</features>
14+
<clock offset="utc">
15+
<timer name="rtc" tickpolicy="catchup"/>
16+
<timer name="pit" tickpolicy="delay"/>
17+
<timer name="hpet" present="no"/>
18+
</clock>
19+
<on_poweroff>destroy</on_poweroff>
20+
<on_reboot>restart</on_reboot>
21+
<on_crash>restart</on_crash>
22+
<pm>
23+
<suspend-to-mem enabled="no"/>
24+
<suspend-to-disk enabled="no"/>
25+
</pm>
26+
<devices>
27+
<emulator>/usr/bin/qemu-kvm</emulator>
28+
<interface type="bridge">
29+
<mac address="52:54:00:4a:7d:92"/>
30+
<source bridge="eth1"/>
31+
<model type="virtio"/>
32+
</interface>
33+
<disk device="disk" type="file">
34+
<driver cache="none" type="qcow2" name="qemu" io="native"/>
35+
<source file="/export/pools/stacki/vm-backend-0-3/vm-backend-0-3_disk1.qcow2"/>
36+
<target dev="sda" bus="sata"/>
37+
<boot order="1"/>
38+
</disk>
39+
<serial type="pty">
40+
<target port="0"/>
41+
</serial>
42+
<serial type="pty">
43+
<target port="1"/>
44+
</serial>
45+
<input bus="ps2" type="mouse"/>
46+
<graphics autoport="yes" keymap="en-us" type="vnc" port="-1"/>
47+
<video>
48+
<model heads="1" vram="9216" type="cirrus"/>
49+
</video>
50+
<rng model="virtio">
51+
<backend model="random">/dev/random</backend>
52+
<address type="pci" domain="0x0000" bus="0x00" slot="0x0c" function="0x0"/>
53+
</rng>
54+
</devices>
55+
</domain>

test-framework/test-suites/integration/tests/report/test_report_vm.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,44 @@ def test_report_vm_bad_network(self, add_hypervisor, add_vm_multiple, host):
9191
run_report = host.run('stack report vm vm-backend-0-3')
9292
assert run_report.rc != 0 and error_msg in run_report.stderr
9393

94+
def test_report_vm_no_network(
95+
self,
96+
add_hypervisor,
97+
add_vm_multiple,
98+
host,
99+
host_os,
100+
test_file
101+
):
102+
"""
103+
Test report vm raises a command error
104+
when a virtual machine has an interface
105+
on a network the hypervisor lacks
106+
"""
107+
108+
# Add a new network then assign it to a virtual machine
109+
add_network = host.run('stack add host interface hypervisor-0-1 mac=52:54:00:4a:7d:92 interface=eth1 network=private ip=192.168.0.8')
110+
assert add_network.rc == 0
111+
set_network = host.run('stack set host interface network vm-backend-0-3 interface=eth0 network= ')
112+
assert set_network.rc == 0
113+
set_channel = host.run('stack set host interface channel vm-backend-0-3 interface=eth0 channel=eth1')
114+
assert set_channel.rc == 0
115+
116+
expect_output = Path(test_file(f'report/vm_config_no_network_{host_os}.txt')).read_text()
117+
config_result = host.run('stack report vm vm-backend-0-3 bare=y')
118+
assert config_result.rc == 0
119+
120+
# The uuid of the config will change every time,
121+
# zero it out so the configs will always match
122+
# to what we expect
123+
sub_uuid = re.sub(
124+
r'<uuid>.*</uuid>',
125+
'<uuid>00000000-0000-0000-0000-0000000000</uuid>',
126+
config_result.stdout
127+
)
128+
129+
# Now they can be compared
130+
assert sub_uuid == expect_output
131+
94132
def test_report_vm_virt_interface(self, add_hypervisor, add_vm_multiple, host, host_os, test_file):
95133
"""
96134
Test virtual interfaces for a VM are skipped

0 commit comments

Comments
 (0)