From: Ondrej Lichtner <olichtne(a)redhat.com>
RemoteDevice objects that on the Controller act as proxies for the real
Device objects on Slaves can now be switched into a cached read only
mode.
In this mode, the RemoteDevice object stores all the property values of
the Slave Device locally on the Controller. When the tester attempts to
access a property this cached value is returned and no proxy call to the
Slave happens.
Method calls and setting new values to a property is disabled as this is
a read only mode. Unfortunatelly this means that methods that don't
change the device state (e.g. ips_filter) are also unaccessible.
However it also means that the cached RemoteDevice object can be used
even if the Device doesn't exist on the Slave anymore.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Devices/RemoteDevice.py | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/lnst/Devices/RemoteDevice.py b/lnst/Devices/RemoteDevice.py
index ddd47f1..8a3f0cf 100644
--- a/lnst/Devices/RemoteDevice.py
+++ b/lnst/Devices/RemoteDevice.py
@@ -13,7 +13,7 @@ olichtne(a)redhat.com (Ondrej Lichtner)
from copy import deepcopy
from lnst.Devices.Device import Device
-from lnst.Common.DeviceError import DeviceDeleted
+from lnst.Common.DeviceError import DeviceDeleted, DeviceReadOnly
def remotedev_decorator(cls):
def func(*args, **kwargs):
@@ -36,6 +36,10 @@ class RemoteDevice(object):
self._machine = None
self.ifindex = None
self.deleted = False
+
+ self._cache = {}
+ self._cached = False
+
self._inited = True
def __deepcopy__(self, memo):
@@ -49,6 +53,20 @@ class RemoteDevice(object):
newone._inited = deepcopy(self._inited, memo)
return newone
+ def enable_readonly_cache(self):
+ self._cache = {}
+ for name, val in self:
+ self._cache[name] = val
+ self._cached = True
+
+ def disable_readonly_cache(self):
+ self._cache = {}
+ self._cached = False
+
+ def update_readonly_cache(self):
+ self.disable_readonly_cache()
+ self.enable_readonly_cache()
+
@property
def _dev_cls(self):
return self.__dev_cls
@@ -85,16 +103,22 @@ class RemoteDevice(object):
attr = getattr(self._dev_cls, name)
- if self.deleted:
+ if self.deleted and not self._cached:
raise DeviceDeleted("This device was deleted on the slave and does not
exist anymore.")
if callable(attr):
+ if self._cached:
+ raise DeviceReadOnly("Can't call methods when in ReadOnly cache
mode.")
+
def dev_method(*args, **kwargs):
return self._machine.rpc_call("dev_method", self.ifindex,
name, args, kwargs,
netns=self.netns)
return dev_method
else:
+ if self._cached:
+ return self._cache[name]
+
return self._machine.rpc_call("dev_attr", self.ifindex, name,
netns=self.netns)
@@ -104,6 +128,10 @@ class RemoteDevice(object):
try:
getattr(self._dev_cls, name)
+
+ if self._cached:
+ raise DeviceReadOnly("Can't set attributes when in ReadOnly
cache mode.")
+
return self._machine.rpc_call("dev_set_attr", self.ifindex, name,
value,
netns=self.netns)
except AttributeError:
--
2.17.0