qubes.devices – Devices

API for various types of devices.

Main concept is that some domain main expose (potentially multiple) devices, which can be attached to other domains. Devices can be of different buses (like ‘pci’, ‘usb’, etc). Each device bus is implemented by an extension.

Devices are identified by pair of (backend domain, ident), where ident is str and can contain only characters from [a-zA-Z0-9._-] set.

Such extension should provide:
  • qubes.devices endpoint - a class descendant from

qubes.devices.DeviceInfo, designed to hold device description ( including bus-specific properties) - handle device-attach:bus and device-detach:bus events for performing the attach/detach action; events are fired even when domain isn’t running and extension should be prepared for this; handlers for those events can be coroutines - handle device-list:bus event - list devices exposed by particular domain; it should return list of appropriate DeviceInfo objects - handle device-get:bus event - get one device object exposed by this domain of given identifier - handle device-list-attached:class event - list currently attached devices to this domain - fire device-list-change:class event when device list change is detected (new/removed device)

Note that device-listing event handlers can not be asynchronous. This for example means you can not call qrexec service there. This is intentional to keep device listing operation cheap. You need to design the extension to take this into account (for example by using QubesDB).

Extension may use QubesDB watch API (QubesVM.watch_qdb_path(path), then handle domain-qdb-change:path) to detect changes and fire device-list-change:class event.

exception qubes.devices.DeviceAlreadyAttached[source]

Bases: qubes.exc.QubesException, KeyError

Trying to attach already attached device

exception qubes.devices.DeviceNotAttached[source]

Bases: qubes.exc.QubesException, KeyError

Trying to detach not attached device

class qubes.devices.DeviceAssignment(backend_domain, ident, options=None, persistent=False, bus=None)[source]

Bases: object

Maps a device to a frontend_domain.

clone()[source]

Clone object instance

device

Get DeviceInfo object corresponding to this DeviceAssignment

class qubes.devices.DeviceCollection(vm, bus)[source]

Bases: object

Bag for devices.

Used as default value for DeviceManager.__missing__() factory.

Parameters:
  • vm – VM for which we manage devices
  • bus – device bus

This class emits following events on VM object:

device-attach:<class>(device, options)

Fired when device is attached to a VM.

Handler for this event can be asynchronous (a coroutine).

Parameters:
  • deviceDeviceInfo object to be attached
  • optionsdict of attachment options
device-pre-attach:<class>(device)

Fired before device is attached to a VM

Handler for this event can be asynchronous (a coroutine).

Parameters:deviceDeviceInfo object to be attached
device-detach:<class>(device)

Fired when device is detached from a VM.

Handler for this event can be asynchronous (a coroutine).

Parameters:deviceDeviceInfo object to be attached
device-pre-detach:<class>(device)

Fired before device is detached from a VM

Handler for this event can be asynchronous (a coroutine).

Parameters:deviceDeviceInfo object to be attached
device-list:<class>

Fired to get list of devices exposed by a VM. Handlers of this event should return a list of py:class:DeviceInfo objects (or appropriate class specific descendant)

device-get:<class>(ident)

Fired to get a single device, given by the ident parameter. Handlers of this event should either return appropriate object of DeviceInfo, or None. Especially should not raise exceptions.KeyError.

device-list-attached:<class>(persistent)

Fired to get list of currently attached devices to a VM. Handlers of this event should return list of devices actually attached to a domain, regardless of its settings.

assignments(persistent=None)[source]
List assignments for devices which are (or may be) attached to the
vm.

Devices may be attached persistently (so they are included in qubes.xml) or not. Device can also be in qubes.xml, but be temporarily detached.

Parameters:persistent (bool) – only include devices which are or are not

attached persistently.

attach(device_assignment: qubes.devices.DeviceAssignment)[source]

Attach (add) device to domain.

Parameters:device (DeviceInfo) – device object
attached()[source]

List devices which are (or may be) attached to this vm

available()[source]

List devices exposed by this vm

detach(device_assignment: qubes.devices.DeviceAssignment)[source]

Detach (remove) device from domain.

Parameters:device (DeviceInfo) – device object
load_persistent(device_assignment: qubes.devices.DeviceAssignment)[source]

Load DeviceAssignment retrieved from qubes.xml

This can be used only for loading qubes.xml, when VM events are not enabled yet.

persistent()[source]

Devices persistently attached and safe to access before libvirt bootstrap.

update_persistent(device: qubes.devices.DeviceInfo, persistent: bool)[source]

Update persistent flag of already attached device.

class qubes.devices.DeviceInfo(backend_domain, ident, description=None, frontend_domain=None)[source]

Bases: object

Holds all information about a device

backend_domain = None

domain providing this device

description = None

human readable description/name of the device

frontend_domain = None

(running) domain to which device is currently attached

ident = None

device identifier (unique for given domain and device type)

class qubes.devices.DeviceManager(vm)[source]

Bases: dict

Device manager that hold all devices by their classess.

Parameters:vm – VM for which we manage devices
class qubes.devices.PersistentCollection[source]

Bases: object

Helper object managing persistent `DeviceAssignment`s.

add(assignment: qubes.devices.DeviceAssignment)[source]

Add assignment to collection

discard(assignment)[source]

Discard assignment from collection

get(device: qubes.devices.DeviceInfo) → qubes.devices.DeviceAssignment[source]

Returns the corresponding qubes.devices.DeviceAssignment for the device.

class qubes.devices.UnknownDevice(backend_domain, ident, description=None, frontend_domain=None)[source]

Bases: qubes.devices.DeviceInfo

Unknown device - for example exposed by domain not running currently