qubes.vm – Different Virtual Machine types

Qubes is composed of several virtual machines that are interconnected in several ways. From now on they will be called „domains”, as they may not actually be true virtual machines – we plan to support LXC containers for example. Because of Xen-only legacy of Qubes code, it is custom to refer to them in long/plural as domains and in short/singular as vm.

Domain object

There are couple of programming objects that refer to domain. The main is the instance of qubes.vm.QubesVM. This is the main „porcelain” object, which carries other objects and supplies convenience methods like qubes.vm.qubesvm.QubesVM.start(). This class is actually divided in two, the qubes.vm.qubesvm.QubesVM cares about Qubes-specific actions, that are more or less directly related to security model. It is intended to be easily auditable by non-expert programmers (ie. we don’t use Python’s magic there). The second class is its parent, qubes.vm.BaseVM, which is concerned about technicalities like XML serialising/deserialising. It is of less concern to threat model auditors, but still relevant to overall security of the Qubes OS. It is written for programmers by programmers.

The second object is the XML node that refers to the domain. It can be accessed as Qubes.vm.BaseVM.xml attribute of the domain object. The third one is Qubes.vm.qubesvm.QubesVM.libvirt_domain object for directly interacting with libvirt. Those objects are intended to be used from core and/or plugins, but not directly by user or from qvm-tools. They are however public, so there are no restrictions.

Domain classes

There are several different types of VM, because not every Qubes domain is equal – some of them perform specific functions, like NetVM; others have different life cycle, like DisposableVM. For that, different domains have different Python classes. They are all defined in this package, generally one class per module, but some modules contain private globals that serve this particular class.

Package contents

Main public classes

class qubes.vm.BaseVM(app, xml, features=None, devices=None, tags=None, **kwargs)[source]

Bases: qubes.PropertyHolder

Base class for all VMs

  • app (qubes.Qubes) – Qubes application context
  • xml (lxml.etree._Element or None) – xml node from which to deserialise

This class is responsible for serializing and deserialising machines and provides basic framework. It contains no management logic. For that, see qubes.vm.qubesvm.QubesVM.


Create libvirt’s XML domain config file


Initialise logger for this domain.


Start watching QubesDB

Calling this method in appropriate time is responsibility of child class.


Add a QubesDB path to be watched.

Each change to the path will cause domain-qdb-change:path event to be fired. You can call this method for example in response to domain-init and domain-load events.

app = None

mother qubes.Qubes object

devices = None

DeviceManager object keeping devices that are attached to this domain

features = None

dictionary of features of this qube


Domain class name


Colourful label assigned to VM. This is where the colour of the padlock is set.

log = None

logger instance for logging messages related to this VM


User-specified name of the domain.


Internal, persistent identificator of particular domain. Note this is different from Xen domid.

storage = None

storage manager

tags = None

user-specified tags


UUID from libvirt.

volumes = None

storage volumes

Helper classes and functions

class qubes.vm.Features(vm, other=None, **kwargs)[source]

Bases: dict

Manager of the features.

Features can have three distinct values: no value (not present in mapping, which is closest thing to None), empty string (which is interpreted as False) and non-empty string, which is True. Anything assigned to the mapping is coerced to strings, however if you assign instances of bool, they are converted as described above. Be aware that assigning the number 0 (which is considered false in Python) will result in string ‘0’, which is considered true.

This class inherits from dict, but has most of the methods that manipulate the item disarmed (they raise NotImplementedError). The ones that are left fire appropriate events on the qube that owns an instance of this class.

check_with_netvm(feature, default=<object object>)[source]

Check if the vm’s netvm has the specified feature.

check_with_template(feature, default=<object object>)[source]

Check if the vm’s template has the specified feature.

clear() → None. Remove all items from D.[source]
pop(_key, _default=None)[source]

Not implemented :raises: NotImplementedError


Not implemented :raises: NotImplementedError

setdefault(_key, _default=None)[source]

Not implemented :raises: NotImplementedError

update([E, ]**F) → None. Update D from dict/iterable E and F.[source]

If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]