In some cases the @transact decorator on
ModelerService.remote_applyDataMaps would result in the underlying
transaction code attempting to set the _p_estimated_size property on
persistent objects such as a NutanixVM. This would result in a
POSKeyError because at this opint the NutanixVM object would be a
"ghost" in ZODB persistent parlance, and not have the _properties
property that ComponentBase's setattr attempted to use.
It turns out that the ZODB persistent module documentation specifically
covers this problem in what you need to do when overriding the attribute
protocol (setattr among others) on persistent object classes.
You must first call self._p_setattr(name, value) to unghost (or
activate) the object if necessary.
The modeling POSKeyError traceback in this one case follows.
Traceback (most recent call last):
File "../apply-zenmodeler-results", line 259, in <module>
Script().run()
File "../apply-zenmodeler-results", line 120, in run
self.processDevice(device_id, grouped_results[device_id])
File "../apply-zenmodeler-results", line 197, in processDevice
self.apply(device, plugin_name, datamaps)
File "../apply-zenmodeler-results", line 241, in apply
self.service.remote_applyDataMaps(device.id, datamaps)
File "/mnt/src/ZenPacks.zenoss.Layer2/ZenPacks/zenoss/Layer2/patches.py", line 110, in remote_applyDataMaps
changed = original(self, device, maps, *args, **kwargs)
File "/opt/zenoss/lib/python2.7/site-packages/ZODB/transact.py", line 51, in g
_commit(note)
File "/opt/zenoss/lib/python2.7/site-packages/ZODB/transact.py", line 23, in _commit
t.commit()
File "/opt/zenoss/lib/python2.7/site-packages/transaction/_transaction.py", line 329, in commit
self._commitResources()
File "/opt/zenoss/lib/python2.7/site-packages/transaction/_transaction.py", line 443, in _commitResources
rm.commit(self)
File "/opt/zenoss/lib/python2.7/site-packages/ZODB/Connection.py", line 562, in commit
self._commit_savepoint(transaction)
File "/opt/zenoss/lib/python2.7/site-packages/ZODB/Connection.py", line 1172, in _commit_savepoint
obj._p_estimated_size = len(data)
File "/mnt/src/ZenPacks.zenoss.ZenPackLib/ZenPacks/zenoss/ZenPackLib/lib/base/ComponentBase.py", line 67, in __setattr__
property_dict = {p.get('id'): p.get('type') for p in self._properties}
File "/opt/zenoss/lib/python2.7/site-packages/ZODB/Connection.py", line 860, in setstate
self._setstate(obj)
File "/opt/zenoss/lib/python2.7/site-packages/ZODB/Connection.py", line 901, in _setstate
p, serial = self._storage.load(obj._p_oid, '')
File "/opt/zenoss/lib/python2.7/site-packages/relstorage/storage.py", line 476, in load
raise POSKeyError(oid)
ZODB.POSException.POSKeyError: 0x2efb54
In some cases the @transact decorator on ModelerService.remote_applyDataMaps would result in the underlying transaction code attempting to set the _p_estimated_size property on persistent objects such as a NutanixVM. This would result in a POSKeyError because at this opint the NutanixVM object would be a "ghost" in ZODB persistent parlance, and not have the _properties property that ComponentBase's setattr attempted to use.
It turns out that the ZODB persistent module documentation specifically covers this problem in what you need to do when overriding the attribute protocol (setattr among others) on persistent object classes.
http://persistent.readthedocs.io/en/latest/using.html#overriding-the-attribute-protocol
You must first call self._p_setattr(name, value) to unghost (or activate) the object if necessary.
The modeling POSKeyError traceback in this one case follows.
Fixes ZPS-2371.