storage/callback: make CallbackVolume a Volume

Unfortunately this appears to be necessary due to
various Qubes OS `assert` checks and to get `__str__()` et al
from the super class. It also means that we have to implement
all methods of the super class (in the future as well).
This commit is contained in:
3hhh 2020-07-05 17:23:21 +02:00
parent 178d4dd997
commit 9de54ab242
No known key found for this signature in database
GPG Key ID: EB03A691DB2F0833

View File

@ -101,7 +101,7 @@ class CallbackPool(qubes.storage.Pool):
qvm-prefs test-dvm template_for_dispvms True qvm-prefs test-dvm template_for_dispvms True
qvm-run --dispvm test-dvm xterm qvm-run --dispvm test-dvm xterm
grep -E 'test-dvm|disp' /var/lib/qubes/qubes.xml grep -E 'test-dvm|disp' /var/lib/qubes/qubes.xml
qvm-volume | grep -E 'test-dvm|disp' (unexpected by most users: Qubes OS only places the private volume on the pool, cf. #5933) qvm-volume | grep -E 'test-dvm|disp' (unexpected by most users: Qubes OS places only the private volume on the pool, cf. #5933)
ls /mnt/test02/appvms/ ls /mnt/test02/appvms/
cat /tmp/callback.log cat /tmp/callback.log
#close the disposable VM #close the disposable VM
@ -416,13 +416,10 @@ class CallbackPool(qubes.storage.Pool):
else: else:
delattr(self._cb_impl, name) delattr(self._cb_impl, name)
class CallbackVolume: class CallbackVolume(qubes.storage.Volume):
''' Proxy volume adding callback functionality to other volumes. ''' Proxy volume adding callback functionality to other volumes.
Required to support the `on_sinit` callback for late storage initialization. Required to support the `on_sinit` and other callbacks.
**Important for Developers**: Even though instances of this class behave exactly as `qubes.storage.Volume` instances,
they are no such instances (e.g. `assert isinstance(obj, qubes.storage.Volume)` will fail).
''' '''
def __init__(self, pool, impl): def __init__(self, pool, impl):
@ -435,6 +432,7 @@ class CallbackVolume:
impl.pool = pool #enforce the CallbackPool instance as the parent pool of the volume impl.pool = pool #enforce the CallbackPool instance as the parent pool of the volume
self._cb_pool = pool #: CallbackPool instance the Volume belongs to. self._cb_pool = pool #: CallbackPool instance the Volume belongs to.
self._cb_impl = impl #: Backend volume implementation instance. self._cb_impl = impl #: Backend volume implementation instance.
#NOTE: we must *not* call super().__init()__ as it would prevent attribute delegation
@asyncio.coroutine @asyncio.coroutine
def _assert_initialized(self, **kwargs): def _assert_initialized(self, **kwargs):
@ -510,6 +508,22 @@ class CallbackVolume:
return False return False
return self._cb_impl.is_outdated() return self._cb_impl.is_outdated()
@property
def revisions(self):
return self._cb_impl.revisions
@property
def size(self):
return self._cb_impl.size
@size.setter
def size(self, size):
self._cb_impl.size = size
@property
def config(self):
return self._cb_impl.config
def block_device(self): def block_device(self):
# pylint: disable=protected-access # pylint: disable=protected-access
if self._cb_pool._cb_requires_init: if self._cb_pool._cb_requires_init: