Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new device API #579

Merged
merged 49 commits into from
Jun 15, 2024
Merged

new device API #579

merged 49 commits into from
Jun 15, 2024

Conversation

piotrbartman
Copy link
Member

@piotrbartman piotrbartman commented Feb 6, 2024

need QubesOS/qubes-linux-utils/pull/111

draft of implementation of new device API.
split persistent flag into automatically_attach and required, so usb devices can be auto-attached but in case of lack of device or renumbering usb bus we can still start a domain.
TODO: move Device DeviceInterface, DeviceCategorym DeviceInfo, DeviceAssignment etc. to one place (it is shared between this package and client)
TODO: tests in this repo can be broken

To Do and to Considerate

Currently, we can make one assignment of a selected port to a single machine in two ways:

  1. Using identity='any', which means that anything plugged into the designated port will be automatically attached to the VM, as it has been functioning thus far.
  2. Using the identity of the currently plugged device, in which case automatic attachment will only occur if the device presents itself in the same way. This introduces a level of risk, but I believe it is acceptable because if a device can effectively impersonate another device, we cannot protect the user from it anyway.

An open issue is what to do with a device that attempts to forcibly present itself in various ways. At the moment, I consider such an attack to be unlikely.

Another consideration is the user interface. It would be beneficial to provide options such as:

  • The ability to assign at least two different devices, so that if either of them is plugged into a specific port, automatic attachment occurs.
  • Automatically attach any device that presents itself as for example a mass storage and is plugged into a specific port, but not devices that resemble mass storage but are actually keyboards, for example.

The handling of USB bus number changes is still not implemented. According to @marmarek's suggestion, we could check the parent device (PCI) in this regard. However, in the current configuration, this would require significant refactoring, as the current protocol relies on device identification as backend-vm:bus-port. Thus, we need to find a method to ensure that this number is always correct. This will also address issues with block devices because currently, if we plug in USB sticks in different orders or do not properly eject and reinsert one of them, the ident of mass storage devices changes, and automatic attachment fails. Theoretically, using self_identity resolves this issue, but there are still assumptions in many places that backend-vm:block-name identifies the device, which is not straightforward.

QubesOS/qubes-issues#4626

Copy link
Member

@marmarek marmarek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document the intended behavior and usage of this API. More or less update module docstring in qubes/devices.py. Besides updating what's currently there, I'm interested especially in two more things:

  • differences between "assign" and "attach" and how they interact with starting a qube and connecting a device
  • device identification: which properties are used to identify the device when

As for more specific comments:

  • you use vendor/product as strings from hwdata - are they stored anywhere (or otherwise expected to not change)? in rare cases they may change, for example when somebody fixes a typo in hwdata, or add info about the device that wasn't included there before
  • I see new device-added event, but no device-removed (or similar), at least in the documentation (but block extension actually sends device-removed event)
  • why only PCI devices can be "required"?

@piotrbartman
Copy link
Member Author

Ok, I'm writing the docs

  • you use vendor/product as strings from hwdata - are they stored anywhere (or otherwise expected to not change)? in rare cases they may change, for example when somebody fixes a typo in hwdata, or add info about the device that wasn't included there before

The aim was that the device identification is "human-readable" and even more "non-tech-user-readable", meaning in qubes.xml we have a name under which an user identifies the device. But we can use 'raw' data transmitted by the device here, which will bypass the hwdata file and ensure that once created configuration will not be broken by update.

  • I see new device-added event, but no device-removed (or similar), at least in the documentation (but block extension actually sends device-removed event)

So I need to add this to documentation (there are device-removed:block and device-removed:block).

  • why only PCI devices can be "required"?

I think we've decided that there is no benefit in making USB/block required. Moreover, there is still the issue that the USB bus number can change between restarting sys-usb so the device will not be auto-attached, and the question is what we want to do about that. I considered just ignoring that first number, but I'm not sure if it is safe.

@DemiMarie
Copy link
Contributor

DemiMarie commented Feb 11, 2024

  • why only PCI devices can be "required"?

I think we've decided that there is no benefit in making USB/block required.

What if I want a qube to which my USB Bluetooth controller is permanently attached?

Moreover, there is still the issue that the USB bus number can change between restarting sys-usb so the device will not be auto-attached, and the question is what we want to do about that. I considered just ignoring that first number, but I'm not sure if it is safe.

The USB bus number changing is itself a problem, IMO.

@marmarek
Copy link
Member

Moreover, there is still the issue that the USB bus number can change between restarting sys-usb

I'm not sure if we can ensure static bus numbers, but PCI devices should not be reordered anymore. So, maybe you can replace bus number in the ID with PCI device providing it (see symlink target of /sys/bus/usb/devices/usbN, or related udev property)? There is one caveat - one PCI device can provide multiple buses (specifically: USB 3 controller will have two buses: one for USB 2.0 and older and one for 3.0 and newer). So, some smart renumbering would be needed anyway.

As for "required" - for USB indeed it's a tricky problem, but I'd prefer this limitation to be enforced at the frontend side, or in extensions for specific device classes, not in the generic code in devices.py. And also, even if we disallow it for USB, IMO it still makes sense for (at least some) block devices.

But we can use 'raw' data transmitted by the device here, which will bypass the hwdata file and ensure that once created configuration will not be broken by update.

It's good to show human readable name (translated via hwdata) to humans, but internally IMO it should use numeric vendor/product.

@piotrbartman
Copy link
Member Author

  • why only PCI devices can be "required"?

I think we've decided that there is no benefit in making USB/block required.

What if I want a qube to which my USB Bluetooth controller is permanently attached?

You can have USB Bluetooth controller auto-attached to a qube.

Copy link
Member

@marmarek marmarek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

few comments on the recent push; I'm waiting with the full review for the documentation.

self_id = self._interface_num
else:
# partition number: 'sda1' -> '1'
self_id = self.ident[3:]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That wont always work, there can be other names (xvdi1), or even different schemes (nvme0n1p2). Generally, to get partition number, take last number (not just last digit, there can be sda12). But there is still one corner case - whole device ending with a number, like nvme0n1, or loop0 - in those cases the partition number is separated with the p, but you can't tell it's a partition just because it ends with a number... Does the partition device always has "whole block device" as a parent? If so, you can use that fact and only then take partition number. But if parent device is not a block device, then it isn't a partition, so getting just the final number is not appropriate.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Youre right, I fixed it

Comment on lines 461 to 505
@qubes.ext.handler('domain-start')
async def on_domain_start(self, vm, _event, **_kwargs):
# pylint: disable=unused-argument
for assignment in vm.devices['block'].get_assigned_devices():
asyncio.ensure_future(self._attach_and_notify(
vm, assignment.device, assignment.options))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Block devices attached at domain start can be specified in libvirt xml, in fact you already adjust that part.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Block devices that are assigned when VM is starting are attached already at https://github.com/QubesOS/qubes-core-admin/pull/579/files#diff-bd38d7fc85084f576ddb6d1d4702f72158e0e30d5e1deb15cf3d49c28c0eb82eR152-R156. So, it looks like you attach them again at domain-start event here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still the case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Block devices attached at domain startup should be specified in libvirt xml (linked above), instead of attached after domain startup. This is especially important for "required" devices, as one may need them during system startup (for example some standalone qube may have it listed in /etc/fstab and startup will fail without it).

Copy link
Contributor

@DemiMarie DemiMarie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be a good opportunity to use diskseq to identify block devices? diskseq + partition number is guaranteed to be unique until the backend is rebooted, whereas other identifiers are not guaranteed to be unique. Right now this rule is violated by loop and device-mapper devices, but that’s a kernel bug.

@piotrbartman
Copy link
Member Author

Would this be a good opportunity to use diskseq to identify block devices? diskseq + partition number is guaranteed to be unique until the backend is rebooted, whereas other identifiers are not guaranteed to be unique. Right now this rule is violated by loop and device-mapper devices, but that’s a kernel bug.

Not really, here we extract device info basing on qubes-db data, so it's just string processing.

@piotrbartman
Copy link
Member Author

few comments on the recent push; I'm waiting with the full review for the documentation.

Most parts of docstring in qubes/devices.py are the same since the main concept remains unchanged. To find more docs you can go to qubes-devices.rst. Let me know if anything else need to be documented.

@piotrbartman piotrbartman force-pushed the prb/new_device_api branch 2 times, most recently from 04db171 to 842ed20 Compare February 21, 2024 14:30
@marmarek
Copy link
Member

To find more docs you can go to qubes-devices.rst

Oh, I missed you already updated it.

Copy link
Member

@marmarek marmarek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the API now considers also self_identity when automatically attaching devices (which is good!), I think there need to be support for multiple assignments of the same port but with different device self_identity. For example, I may have 3 different devices I'd like to automatically connect to a qube X (when plugged into specific port). Ofc only one of them can be attached at the same time, but I think it should still be possible to have assignments there.
This is problematic for the API, because some places use backend+ident as unique identifier for the assignment. I made a comment about it in one place, but the problem is in several more places.
Maybe in such cases there can be some suffix to the device ident, like yet another +something (hash of self_identity if not self_identity itself? Or not only in such cases, but always? And then for port assignments that would be +any.
There can be a corner case of multiple assignments of the same port, all with required=True. That of course will always fail to start, I think such configuration should still be allowed (for example when user adds new device just to remove the old one later). Maybe a startup message can include a message when such configuration will be detected.

BTW, one day maybe we will have a bus that has unspoofable device identifiers (based on some cryptography?). When that happens, maybe it will make sense to create assignment that has only backend and self_identity (or some other property then?) but has any in place of the current ident. Or maybe, for such trusted identities use it instead of the device port (not sure if a good idea...)? In any case, it would allow automatically attaching specific device regardless of which port it's plugged in. Such support may require some more changes (for example (potential) assignment would not have a specific port value, but it will need to be resolved when actually attaching the device), so lets leave implementation for another iteration. But it's good to think about such possibility when designing API interface.

doc/qubes-devices.rst Outdated Show resolved Hide resolved
!include-service admin.vm.device.mic.Available * include/admin-local-ro
!include-service admin.vm.device.mic.Detach * include/admin-local-rwx
!include-service admin.vm.device.mic.List * include/admin-local-ro
!include-service admin.vm.device.mic.Set.persistent * include/admin-local-rwx
!include-service admin.vm.device.mic.Set.assignment * include/admin-local-rwx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is supposed to be about specific DeviceAssignment property, so I guess there should be policy about required and attach_automatically.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment below

device_assignments, devclass=devclass)

dev_info = {
f'{assignment.backend_domain}+{assignment.ident}':
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is problematic to use dict with just backend+ident here - there may be multiple assignments for different devices plugged into the same port (they will differ in self_identity, but will have the same ident)

See more about it in the generic comment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

next iteration?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Update assignment of already attached device.

Payload:
`None` -> unassign device from qube
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same as the Unassign method, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

Comment on lines +1379 to +1385
`False` -> device will be auto-attached to qube
`True` -> device is required to start qube
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, those in fact set the required flag, so the method should be called admin.vm.device.{endpoint}.Set.required.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not only, if "required" is None it modify attach_automatically flag, so whole assignment. In fact the assignment has only 3 valid states, and setting attach_automatically and required separably can lead to non-valid state. In other words, DeviceAssignment has one state, but exposed to the user/programmer as 2 flags. I even consider to put DeviceAssignment.__required and DeviceAssignment.__automatically_attach as one variable with 3 possible values.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if "required" is None it modify attach_automatically flag

But this is "Unassign" method listed above, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, now I get it, I will correct that

qubes/devices.py Outdated
Comment on lines 561 to 579
keys = []
values = []
key, _, rest = rest.partition("='")
keys.append(key)
while "='" in rest:
value_key, _, rest = rest.partition("='")
value, _, key = value_key.rpartition("' ")
values.append(deserialize_str(value))
keys.append(key)
value = rest[:-1] # ending '
values.append(deserialize_str(value))

properties = dict()
for key, value in zip(keys, values):
if key.startswith("_"):
# it's handled in cls.__init__
properties[key[1:]] = value
else:
properties[key] = value
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this to a helper function? It's used in at least two places.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 461 to 505
@qubes.ext.handler('domain-start')
async def on_domain_start(self, vm, _event, **_kwargs):
# pylint: disable=unused-argument
for assignment in vm.devices['block'].get_assigned_devices():
asyncio.ensure_future(self._attach_and_notify(
vm, assignment.device, assignment.options))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still the case.

qubes/ext/pci.py Outdated
super().__init__(
backend_domain=backend_domain, ident=ident, devclass="pci")

if hasattr(self, 'regex'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if was necessary when it was in a generic class. Here, the regex attribute is always set.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@property
def product(self) -> str:
"""
Device name from local database `/usr/share/hwdata/usb.ids`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Device name from local database `/usr/share/hwdata/usb.ids`
Device name from local database `/usr/share/hwdata/pci.ids`

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

qubes/ext/pci.py Outdated Show resolved Hide resolved
@piotrbartman
Copy link
Member Author

piotrbartman commented Mar 19, 2024

Since the API now considers also self_identity when automatically attaching devices (which is good!), I think there need to be support for multiple assignments of the same port but with different device self_identity. (...)

Agree, but as I mentioned in the last section 'To Do and to Consider' in the PR description, I believe this change belongs to the next iteration, as it requires modifications in several places, and I think currently there are already quite a few changes done.

Comment on lines +193 to +211
@property
def attachment(self) -> Optional['qubes.vm.BaseVM']:
"""
Warning: this property is time-consuming, do not run in loop!
"""
if not self.backend_domain.is_running():
return None
for vm in self.backend_domain.app.domains:
if not vm.is_running():
continue
if self._is_attached_to(vm):
return vm

return None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be an index to make looking this up fast?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, but we need to remember that it should always be up to date (not cached), if you have an idea how to do it, I'm in.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating it whenever a device is attached or detached is the first idea that comes to mind. Caches are fine so long as they are invalidated synchronously when needed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BlockDeviceExtension already has a devices_cache, but attachment is intended to return the actual state (including, in particular, situations where something went wrong and the potential cache is outdated). For API compatibility, this is a property, and the warning is there because when we want to get information about attachment for a bunch of devices, we should use some form of bulk data loading (just like we do for updating devices_cache) rather than in a loop.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any situations where the cache could be outdated, or is that always a bug?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, but if it is predictable it's already update a cache. Maybe if you directly use libvirt to attach device it will bypass mechanism, but attachment still will work.

@piotrbartman
Copy link
Member Author

@marmarek Can you elaborate?
#579 (comment)

@qubesos-bot
Copy link

qubesos-bot commented Mar 29, 2024

OpenQA test summary

Complete test suite and dependencies: https://openqa.qubes-os.org/tests/overview?distri=qubesos&version=4.3&build=2024061301-4.3&flavor=pull-requests

Test run included the following:

New failures, excluding unstable

Compared to: https://openqa.qubes-os.org/tests/overview?distri=qubesos&version=4.3&build=2024052808-4.3&flavor=update

  • system_tests_extra

    • TC_00_QVCTest_whonix-gateway-17: test_010_screenshare (failure)
      self.assertNotEqual(vm.run('test -e /dev/vid... AssertionError: 0 == 0
  • system_tests_network_updates

    • TC_10_QvmTemplate_fedora-40-xfce: test_000_template_list (failure)
      AssertionError: libvirt event impl drain timeout
  • system_tests_basic_vm_qrexec_gui_zfs

    • TC_06_AppVM_whonix-gateway-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

    • TC_06_AppVM_whonix-workstation-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

  • system_tests_guivm_vnc_gui_interactive

    • guivm_startup: Failed (test died)
      # Test died: command 'qvm-run --nogui -pu root sys-gui-vnc env XAUT...
  • system_tests_basic_vm_qrexec_gui_btrfs

    • TC_06_AppVM_whonix-gateway-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

    • TC_06_AppVM_whonix-workstation-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

  • system_tests_basic_vm_qrexec_gui_ext4

    • TC_06_AppVM_whonix-gateway-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

    • TC_06_AppVM_whonix-workstation-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

  • system_tests_basic_vm_qrexec_gui_xfs

    • TC_06_AppVM_whonix-gateway-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

    • TC_06_AppVM_whonix-workstation-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

  • system_tests_basic_vm_qrexec_gui

    • TC_06_AppVM_whonix-gateway-17: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

    • TC_06_AppVM_whonix-workstation-17: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

    • TC_20_AudioVM_PipeWire_fedora-40-xfce: test_226_audio_playback_pipewire (failure)
      AssertionError: Command 'timeout 20s pw-play --format=f32 --rate=44...

  • system_tests_kde_gui_interactive

    • gui_filecopy: unnamed test (unknown)
    • gui_filecopy: Failed (test died)
      # Test died: no candidate needle with tag(s) 'files-test-file' matc...

Failed tests

23 failures
  • system_tests_pvgrub_salt_storage

    • TC_41_HVMGrub_fedora-40-xfce: test_000_standalone_vm (error)
      qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...

    • TC_41_HVMGrub_fedora-40-xfce: test_010_template_based_vm (error)
      qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...

  • system_tests_extra

    • [unstable] TC_00_QVCTest_debian-12-xfce: test_020_webcam (failure + cleanup)
      AssertionError: 'qubes-video-companion webcam' exited early (0): b'...

    • [unstable] TC_00_QVCTest_fedora-40-xfce: test_020_webcam (failure + cleanup)
      AssertionError: 'qubes-video-companion webcam' exited early (0): b'...

    • TC_00_QVCTest_whonix-gateway-17: test_010_screenshare (failure)
      self.assertNotEqual(vm.run('test -e /dev/vid... AssertionError: 0 == 0

    • [unstable] TC_00_QVCTest_whonix-workstation-17: test_010_screenshare (failure)
      self.assertNotEqual(vm.run('test -e /dev/vid... AssertionError: 0 == 0

    • [unstable] TC_00_QVCTest_whonix-workstation-17: test_020_webcam (failure + cleanup)
      AssertionError: 'qubes-video-companion webcam' exited early (0): b'...

  • system_tests_network_updates

    • TC_10_QvmTemplate_fedora-40-xfce: test_000_template_list (failure)
      AssertionError: libvirt event impl drain timeout
  • system_tests_basic_vm_qrexec_gui_zfs

    • TC_06_AppVM_whonix-gateway-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

    • TC_06_AppVM_whonix-workstation-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

  • system_tests_guivm_vnc_gui_interactive

    • guivm_startup: Failed (test died)
      # Test died: command 'qvm-run --nogui -pu root sys-gui-vnc env XAUT...
  • system_tests_basic_vm_qrexec_gui_btrfs

    • TC_06_AppVM_whonix-gateway-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

    • TC_06_AppVM_whonix-workstation-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

  • system_tests_basic_vm_qrexec_gui_ext4

    • TC_06_AppVM_whonix-gateway-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

    • TC_06_AppVM_whonix-workstation-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

  • system_tests_basic_vm_qrexec_gui_xfs

    • TC_06_AppVM_whonix-gateway-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

    • TC_06_AppVM_whonix-workstation-17-pool: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

  • system_tests_splitgpg

  • system_tests_basic_vm_qrexec_gui

    • TC_06_AppVM_whonix-gateway-17: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

    • TC_06_AppVM_whonix-workstation-17: test_010_os_metadata (failure)
      self.assertEqual(tpl.features.get(... AssertionError: None != 'debian'

    • TC_20_AudioVM_PipeWire_fedora-40-xfce: test_226_audio_playback_pipewire (failure)
      AssertionError: Command 'timeout 20s pw-play --format=f32 --rate=44...

  • system_tests_kde_gui_interactive

    • gui_filecopy: unnamed test (unknown)
    • gui_filecopy: Failed (test died)
      # Test died: no candidate needle with tag(s) 'files-test-file' matc...

Fixed failures

Compared to: https://openqa.qubes-os.org/tests/101100#dependencies

38 fixed
  • system_tests_pvgrub_salt_storage

    • StorageFile: test_001_non_volatile (error)
      subprocess.CalledProcessError: Command '/usr/lib/qubes/destroy-snap...
  • system_tests_network_updates

    • TC_00_Dom0Upgrade_whonix-gateway-17: test_006_update_flag_clear (failure)
      Error: Failed to download metadata for repo 'test': Cannot download...

    • TC_10_QvmTemplate_debian-12-xfce: test_010_template_install (failure)
      AssertionError: qvm-template failed: Downloading 'qubes-template-de...

    • TC_10_QvmTemplate_fedora-40-xfce: test_010_template_install (failure)
      AssertionError: qvm-template failed: Downloading 'qubes-template-de...

    • TC_10_QvmTemplate_whonix-gateway-17: test_010_template_install (failure)
      AssertionError: qvm-template failed: Downloading 'qubes-template-de...

    • TC_11_QvmTemplateMgmtVM_debian-12-xfce: test_010_template_install (failure)
      AssertionError: qvm-template failed: Downloading 'qubes-template-de...

    • TC_11_QvmTemplateMgmtVM_fedora-40-xfce: test_010_template_install (failure)
      AssertionError: qvm-template failed: Downloading 'qubes-template-de...

    • TC_11_QvmTemplateMgmtVM_whonix-gateway-17: test_010_template_install (failure)
      AssertionError: qvm-template failed: Downloading 'qubes-template-de...

  • system_tests_basic_vm_qrexec_gui_zfs

  • system_tests_basic_vm_qrexec_gui_btrfs

  • system_tests_basic_vm_qrexec_gui_ext4

  • system_tests_basic_vm_qrexec_gui_xfs

  • system_tests_basic_vm_qrexec_gui@hw1

  • system_tests_usbproxy

  • system_tests_basic_vm_qrexec_gui

  • system_tests_guivm_gui_interactive

    • update_guivm: Failed (test died)
      # Test died: command '(set -o pipefail; qubesctl --all --show-outpu...

Unstable tests

  • system_tests_suspend

    suspend/ (2/4 times with errors)
    suspend/Failed (2/4 times with errors)
    • job 102431 # Test died: no candidate needle with tag(s) 'xscreensaver-prompt' ...
    • job 102443 # Test died: no candidate needle with tag(s) 'xscreensaver-prompt' ...
    suspend/wait_serial (2/4 times with errors)
    • job 102431 # wait_serial expected: qr/2E8vz-\d+-/...
    • job 102443 # wait_serial expected: qr/2E8vz-\d+-/...
  • system_tests_pvgrub_salt_storage

    TC_41_HVMGrub_debian-12-xfce/test_000_standalone_vm (1/2 times with errors)
    • job 101773 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    StorageFile/test_001_non_volatile (1/2 times with errors)
    • job 101124 subprocess.CalledProcessError: Command '/usr/lib/qubes/destroy-snap...
    TC_41_HVMGrub_debian-12-xfce/test_010_template_based_vm (1/2 times with errors)
    • job 101773 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
  • system_tests_extra

    TC_00_QVCTest_whonix-workstation-17/test_010_screenshare (1/2 times with errors)
    • job 101116 self.assertNotEqual(vm.run('test -e /dev/vid... AssertionError: 0 == 0
    TC_00_QVCTest_debian-12-xfce/test_020_webcam (1/2 times with errors)
    • job 101116 AssertionError: 'qubes-video-companion webcam' exited early (0): b'...
    TC_00_QVCTest_fedora-40-xfce/test_020_webcam (1/2 times with errors)
    • job 101765 AssertionError: 'qubes-video-companion webcam' exited early (0): b'...
    TC_00_QVCTest_whonix-workstation-17/test_020_webcam (1/2 times with errors)
    • job 101116 AssertionError: 'qubes-video-companion webcam' exited early (0): b'...
  • system_tests_network_updates

    TC_00_Dom0Upgrade_whonix-gateway-17/test_006_update_flag_clear (1/2 times with errors)
    • job 101123 Error: Failed to download metadata for repo 'test': Cannot download...
    TC_10_QvmTemplate_debian-12-xfce/test_010_template_install (1/2 times with errors)
    • job 101123 AssertionError: qvm-template failed: Downloading 'qubes-template-de...
    TC_10_QvmTemplate_fedora-40-xfce/test_010_template_install (1/2 times with errors)
    • job 101123 AssertionError: qvm-template failed: Downloading 'qubes-template-de...
    TC_10_QvmTemplate_whonix-gateway-17/test_010_template_install (1/2 times with errors)
    • job 101123 AssertionError: qvm-template failed: Downloading 'qubes-template-de...
    TC_11_QvmTemplateMgmtVM_debian-12-xfce/test_010_template_install (1/2 times with errors)
    • job 101123 AssertionError: qvm-template failed: Downloading 'qubes-template-de...
    TC_11_QvmTemplateMgmtVM_fedora-40-xfce/test_010_template_install (1/2 times with errors)
    • job 101123 AssertionError: qvm-template failed: Downloading 'qubes-template-de...
    TC_11_QvmTemplateMgmtVM_whonix-gateway-17/test_010_template_install (1/2 times with errors)
    • job 101123 AssertionError: qvm-template failed: Downloading 'qubes-template-de...
  • system_tests_dispvm

    TC_20_DispVM_fedora-40-xfce/test_100_open_in_dispvm (1/2 times with errors)
    • job 101764 AssertionError: './open-file test.txt' failed with ./open-file test...
  • system_tests_basic_vm_qrexec_gui_btrfs

    TC_20_AudioVM_Pulse_whonix-workstation-17-pool/test_220_audio_play_pulseaudio (1/2 times with errors)
    • job 101110 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
    TC_20_AudioVM_Pulse_whonix-workstation-17-pool/test_222_audio_rec_unmuted_pulseaudio (1/2 times with errors)
    • job 101110 AssertionError: only silence detected, no useful audio data
    TC_20_AudioVM_Pulse_whonix-workstation-17-pool/test_223_audio_play_hvm (1/2 times with errors)
    • job 101110 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
    TC_20_AudioVM_Pulse_fedora-40-xfce-pool/test_225_audio_rec_unmuted_hvm (1/2 times with errors)
    • job 101782 AssertionError: too short audio, expected 10s, got 6.28875283446712...
    TC_20_AudioVM_Pulse_whonix-workstation-17-pool/test_252_audio_playback_audiovm_switch_hvm (2/2 times with errors)
    • job 101110 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
    • job 101782 AssertionError: pacat for test-inst-vm1 (xid 90) running(False) in ...
  • system_tests_basic_vm_qrexec_gui_ext4

    TC_00_Basic/test_141_libvirt_objects_reconnect (1/2 times with errors)
    • job 101111 AssertionError: libvirt event impl drain timeout
    TC_20_AudioVM_Pulse_whonix-workstation-17-pool/test_220_audio_play_pulseaudio (1/2 times with errors)
    • job 101111 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
    TC_20_AudioVM_Pulse_whonix-workstation-17-pool/test_222_audio_rec_unmuted_pulseaudio (1/2 times with errors)
    • job 101111 AssertionError: only silence detected, no useful audio data
    TC_20_AudioVM_Pulse_whonix-workstation-17-pool/test_223_audio_play_hvm (1/2 times with errors)
    • job 101111 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
    TC_20_AudioVM_Pulse_whonix-workstation-17-pool/test_252_audio_playback_audiovm_switch_hvm (1/2 times with errors)
    • job 101111 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
  • system_tests_basic_vm_qrexec_gui_xfs

    TC_20_AudioVM_Pulse_whonix-workstation-17-pool/test_220_audio_play_pulseaudio (2/2 times with errors)
    • job 101112 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
    • job 101781 AssertionError: too short audio, expected 10s, got 8.33947845804988...
    TC_20_AudioVM_Pulse_whonix-workstation-17-pool/test_222_audio_rec_unmuted_pulseaudio (2/2 times with errors)
    • job 101112 AssertionError: only silence detected, no useful audio data
    • job 101781 AssertionError: too short audio, expected 10s, got 8.17784580498866...
    TC_20_AudioVM_Pulse_whonix-workstation-17-pool/test_223_audio_play_hvm (2/2 times with errors)
    • job 101112 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
    • job 101781 AssertionError: too short audio, expected 10s, got 7.71551020408163...
    TC_20_AudioVM_Pulse_whonix-workstation-17-pool/test_252_audio_playback_audiovm_switch_hvm (1/2 times with errors)
    • job 101112 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
  • system_tests_basic_vm_qrexec_gui@hw1

    TC_20_AudioVM_Pulse_whonix-workstation-17/test_220_audio_play_pulseaudio (2/2 times with errors)
    • job 101109 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
    • job 101758 AssertionError: too short audio, expected 10s, got 8.73532879818594...
    TC_20_AudioVM_Pulse_whonix-workstation-17/test_222_audio_rec_unmuted_pulseaudio (2/2 times with errors)
    • job 101109 AssertionError: only silence detected, no useful audio data
    • job 101758 AssertionError: too short audio, expected 10s, got 9.36446712018140...
    TC_20_AudioVM_Pulse_whonix-workstation-17/test_223_audio_play_hvm (1/2 times with errors)
    • job 101109 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
    TC_20_AudioVM_Pulse_whonix-workstation-17/test_252_audio_playback_audiovm_switch_hvm (1/2 times with errors)
    • job 101109 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
  • system_tests_suspend@hw1

    suspend/ (2/4 times with errors)
    suspend/Failed (2/4 times with errors)
    • job 102431 # Test died: no candidate needle with tag(s) 'xscreensaver-prompt' ...
    • job 102443 # Test died: no candidate needle with tag(s) 'xscreensaver-prompt' ...
    suspend/wait_serial (2/4 times with errors)
    • job 102431 # wait_serial expected: qr/2E8vz-\d+-/...
    • job 102443 # wait_serial expected: qr/2E8vz-\d+-/...
  • system_tests_usbproxy

    TC_20_USBProxy_core3_whonix-gateway-17/test_070_attach_not_installed_front (1/2 times with errors)
    • job 101101 qubesusbproxy.core3ext.QubesUSBException: Device attach failed: 202...
  • system_tests_basic_vm_qrexec_gui

    TC_20_AudioVM_Pulse_whonix-workstation-17/test_220_audio_play_pulseaudio (2/2 times with errors)
    • job 101109 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
    • job 101758 AssertionError: too short audio, expected 10s, got 8.73532879818594...
    TC_20_AudioVM_Pulse_whonix-workstation-17/test_222_audio_rec_unmuted_pulseaudio (2/2 times with errors)
    • job 101109 AssertionError: only silence detected, no useful audio data
    • job 101758 AssertionError: too short audio, expected 10s, got 9.36446712018140...
    TC_20_AudioVM_Pulse_whonix-workstation-17/test_223_audio_play_hvm (1/2 times with errors)
    • job 101109 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...
    TC_20_AudioVM_Pulse_whonix-workstation-17/test_252_audio_playback_audiovm_switch_hvm (1/2 times with errors)
    • job 101109 AssertionError: Command 'timeout 20s paplay --format=float32le --ra...

@piotrbartman piotrbartman marked this pull request as ready for review April 10, 2024 03:51
@marmarek
Copy link
Member

Integration tests need an update: https://openqa.qubes-os.org/tests/96815

And unit tests detected I believe a real issue - meminfo-writer service (as well as enabling/disabling dynamic memory management) is toggled based on PCI devices presence - this part likely misbehave now.

@marmarek marmarek merged commit 58b7872 into QubesOS:main Jun 15, 2024
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants