Skip to content

Commit

Permalink
Support for providing audiovm on start for HVM
Browse files Browse the repository at this point in the history
  • Loading branch information
fepitre committed May 10, 2024
1 parent 04deb9e commit 913dcb8
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 5 deletions.
7 changes: 5 additions & 2 deletions qubes/ext/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,13 @@ def on_property_reset(self, subject, event, name, oldvalue=None):

@staticmethod
async def set_stubdom_audiovm_domid(qube, audiovm):
if audiovm:
audiovm_xid = audiovm.xid
else:
audiovm_xid = -1
try:
await qube.run_service_for_stdio(
f"qubes.SetAudioVM+{audiovm.xid}",
f"qubes.SetAudioVM+{audiovm_xid}",
user="root",
stubdom=True,
stdout=subprocess.DEVNULL,
Expand All @@ -120,7 +124,6 @@ def on_property_set(self, subject, event, name, newvalue, oldvalue=None):
subject.log.warning("Cannot change dynamically audiovm: qrexec"
" is not available (stubdom-qrexec feature)")
if has_audio_model and has_stubdom_qrexec:
subject.log.warning(f"setting {newvalue.xid}")
asyncio.ensure_future(
self.set_stubdom_audiovm_domid(subject, newvalue)
)
Expand Down
78 changes: 77 additions & 1 deletion qubes/tests/vm/qubesvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1633,7 +1633,7 @@ def test_610_libvirt_xml_network(self):
<script path="vif-route-qubes" />
</interface>
<!-- server_ip is the address of stubdomain. It hosts it's own DNS server. -->
<emulator type="stubdom-linux" cmdline="-qubes-net:client_ip=10.137.0.1,dns_0=10.139.1.1,dns_1=10.139.1.2,gw=10.137.0.2,netmask=255.255.255.255" />
<emulator type="stubdom-linux" cmdline="-qubes-audio:audiovm_xid=0 -qubes-net:client_ip=10.137.0.1,dns_0=10.139.1.1,dns_1=10.139.1.2,gw=10.137.0.2,netmask=255.255.255.255" />
<input type="tablet" bus="usb"/>
<video>
<model type="vga"/>
Expand All @@ -1647,10 +1647,16 @@ def test_610_libvirt_xml_network(self):
'''
my_uuid = '7db78950-c467-4863-94d1-af59806384ea'
netvm = self.get_vm(qid=2, name='netvm', provides_network=True)

dom0 = self.get_vm(name='dom0', qid=0)
dom0._qubesprop_xid = 0

vm = self.get_vm(uuid=my_uuid)
vm.netvm = netvm
vm.virt_mode = 'hvm'
vm.features['qrexec'] = True
vm.audiovm = dom0

with self.subTest('ipv4_only'):
libvirt_xml = vm.create_config_file()
self.assertXMLEqual(lxml.etree.XML(libvirt_xml),
Expand All @@ -1663,6 +1669,76 @@ def test_610_libvirt_xml_network(self):
extra_ip='<ip address="{}::a89:1" family=\'ipv6\'/>'.format(
qubes.config.qubes_ipv6_prefix.replace(':0000', '')))))

def test_611_libvirt_xml_audiovm(self):
expected = '''<domain type="xen">
<name>test-inst-test</name>
<uuid>7db78950-c467-4863-94d1-af59806384ea</uuid>
<memory unit="MiB">500</memory>
<currentMemory unit="MiB">400</currentMemory>
<vcpu placement="static">2</vcpu>
<cpu mode='host-passthrough'>
<!-- disable nested HVM -->
<feature name='vmx' policy='disable'/>
<feature name='svm' policy='disable'/>
<!-- let the guest know the TSC is safe to use (no migration) -->
<feature name='invtsc' policy='require'/>
</cpu>
<os>
<type arch="x86_64" machine="xenfv">hvm</type>
<!--
For the libxl backend libvirt switches between OVMF (UEFI)
and SeaBIOS based on the loader type. This has nothing to
do with the hvmloader binary.
-->
<loader type="rom">hvmloader</loader>
<boot dev="cdrom" />
<boot dev="hd" />
</os>
<features>
<pae/>
<acpi/>
<apic/>
<viridian/>
</features>
<clock offset="variable" adjustment="0" basis="utc" />
<on_poweroff>destroy</on_poweroff>
<on_reboot>destroy</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<interface type="ethernet">
<mac address="00:16:3e:5e:6c:00" />
<ip address="10.137.0.1" />
<backenddomain name="test-inst-netvm" />
<script path="vif-route-qubes" />
</interface>
<!-- server_ip is the address of stubdomain. It hosts it's own DNS server. -->
<emulator type="stubdom-linux" cmdline="-qubes-audio:audiovm_xid={audiovm_xid} -qubes-net:client_ip=10.137.0.1,dns_0=10.139.1.1,dns_1=10.139.1.2,gw=10.137.0.2,netmask=255.255.255.255" />
<input type="tablet" bus="usb"/>
<video>
<model type="vga"/>
</video>
<graphics type="qubes"/>
<console type="pty">
<target type="xen" port="0"/>
</console>
</devices>
</domain>
'''
my_uuid = '7db78950-c467-4863-94d1-af59806384ea'
netvm = self.get_vm(qid=2, name='netvm', provides_network=True)
audiovm = self.get_vm(qid=3, name='sys-audio', provides_network=False)
audiovm._qubesprop_xid = audiovm.qid

vm = self.get_vm(uuid=my_uuid)
vm.netvm = netvm
vm.audiovm = audiovm
vm.virt_mode = 'hvm'
vm.features['qrexec'] = True

libvirt_xml = vm.create_config_file()
self.assertXMLEqual(lxml.etree.XML(libvirt_xml),
lxml.etree.XML(expected.format(audiovm_xid=audiovm.xid)))

def test_615_libvirt_xml_block_devices(self):
expected = '''<domain type="xen">
<name>test-inst-test</name>
Expand Down
9 changes: 7 additions & 2 deletions templates/libvirt/xen.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
{% if vm.audiovm is defined and vm.audiovm %}
{% set audiovm_xid = vm.audiovm.xid %}
{% else %}
{% set audiovm_xid = -1 %}
{% endif %}
<domain type="xen">
{% block basic %}
<name>{{ vm.name }}</name>
Expand Down Expand Up @@ -179,13 +184,13 @@
{% endif %}
{% if vm.netvm %}
{% if vm.features.check_with_template('linux-stubdom', True) %}
cmdline="-qubes-net:client_ip={{ vm.ip -}}
cmdline="-qubes-audio:audiovm_xid={{ audiovm_xid }} -qubes-net:client_ip={{ vm.ip -}}
,dns_0={{ vm.dns[0] -}}
,dns_1={{ vm.dns[1] -}}
,gw={{ vm.netvm.gateway -}}
,netmask={{ vm.netmask }}"
{% else %}
cmdline="-net lwip,client_ip={{ vm.ip -}}
cmdline="-qubes-audio:audiovm_xid={{ audiovm_xid }} -net lwip,client_ip={{ vm.ip -}}
,server_ip={{ vm.dns[1] -}}
,dns={{ vm.dns[0] -}}
,gw={{ vm.netvm.gateway -}}
Expand Down

0 comments on commit 913dcb8

Please sign in to comment.