If domain was just removed, it the qrexec call may result in a
QubesVMNotFoundError exception. If it was removed earlier, and the
caller is in connecting via qrexec, the call will be rejected at the
policy level. Treat both situations uniformely - with
QubesPropertyAccessError. This allows using convenient `getattr()` to
define placeholder value (if appropriate), or try/except with a single
exception instead of two.
QubesOS/qubes-issues#5105
Rename QubesDaemonNoResponseError to more intuitive
QubesDaemonAccessError (keep legacy name still working).
Use QubesPropertyAccessError whenever the access is about @property -
this makes it easy to use `getattr` to use default value instead.
QubesOS/qubes-issues#5811
When caching is enabled, reduce number of calls by getting all the
properties at once. If the call is not available (for example because of
the policy), fallback to getting individual values.
QubesOS/qubes-issues#5415
Reduce Admin API calls by caching returned values. The cache is not
enabled by default, because it could result in stale values being
returned. It can be enabled by setting 'cache_enabled' to True on
Qubes() object. This is safe in two cases:
- the application don't care about changed values - like a short-lived
process that retrieve values once (for example qvm-ls)
- the application listen for events and invalidate cache when property
is changed
For the second case, invalidating the cache on appropriate event
(property-set:*, property-reset:*) is done before calling other event
handlers. This is because the event may try to access the property value
(not necessary from the event arguments), so we need to be sure it will
see the new value.
FixesQubesOS/qubes-issues#5415
When qubesd returns an name of VM or other object, as part of another
call (reading a property, listing devices etc), it's safe to assume that
object exists. Do not try to list it, which could be prevented by qrexec
policy. This means a VM object would be returned (for example in
vm.netvm property), which potentially could not be listed through
app.domains collection. This may lead to some corner cases, but
generally should ease handling of restricted policy.
This does not affect practical information the management VM have access
too, as those names are already returned. It's just client side python
wrapper that didn't allowed to access them.
QubesOS/qubes-issues#5099
In core-admin matching collections are real dicts, so clone this API
behaviour here too. Specific changes:
- iteration yields keys, not values
- implement values and items methods
Additionally fix keys method, it was broken on python2 (list have no
copy method).
This allows to perform actions on objects (VM, storage etc), without
listing them. This is useful when calling VM have minimal permissions
and only selected actions are allowed.
This means that app.domains['some-name'] will not raise KeyError, even
when domain do not exists. But performing actual action (like
vm.start()) will fail in that case.
Add qubesd_call(..., payload_stream=...) argument to allow streaming
payload directly from some file/process stdout. This is mainly (only?)
useful for admin.vm.volume.Import, where disk volume raw data is passed
to the service.