Commit c647aab4 authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_cloud: Introduce SlapOSCacheMixin

   This API replaces the usage of SlapTool code for handling data stored in memcached. It introduces an New API for it at the context of the objects to handle volatile data used on SlapOS context.

   Replace Base_getNewsDict by getAccessStatus

   Drop direct access to memcache, use Cache Plugin instead to load and
set information.
parent 307e1012
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2005-2010 Nexedi SA and Contributors. All Rights Reserved.
# Romain Courteaud <romain@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
from DateTime import DateTime
from App.Common import rfc1123_date
from Products.ERP5Type.Cache import DEFAULT_CACHE_SCOPE
import json
class SlapOSCacheMixin:
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
def _getAccessStatusCacheFactory(self):
return self.getPortalObject().portal_caches\
.getRamCacheRoot().get('access_status_data_cache_factory')
def _getAccessStatusPlugin(self):
return self._getAccessStatusCacheFactory().getCachePluginList()[0]
def _getAccessStatusCacheKey(self):
return "%s-ACCESS" % self.getReference()
def _getCachedAccessInfo(self):
if not self.getReference():
return None
try:
entry = self._getAccessStatusPlugin().get(
self._getAccessStatusCacheKey(), DEFAULT_CACHE_SCOPE)
except KeyError:
entry = None
else:
entry = entry.getValue()
return entry
def getAccessStatus(self):
data_json = self._getCachedAccessInfo()
last_modified = rfc1123_date(DateTime())
if data_json is None:
data_dict = {
"user": "SlapOS Master",
'created_at': '%s' % last_modified,
'since': '%s' % last_modified,
'state': "",
"text": "#error no data found for %s" % self.getReference(),
"no_data": 1
}
# Prepare for xml marshalling
#data_dict["text"] = data_dict["text"].decode("UTF-8")
#data_dict["user"] = data_dict["user"].decode("UTF-8")
return data_dict
data_dict = json.loads(data_json)
last_contact = DateTime(data_dict.get('created_at'))
data_dict["no_data_since_15_minutes"] = 0
data_dict["no_data_since_5_minutes"] = 0
if (DateTime() - last_contact) > 0.005:
data_dict["no_data_since_15_minutes"] = 1
data_dict["no_data_since_5_minutes"] = 1
elif (DateTime() - last_contact) > 0.0025:
data_dict["no_data_since_5_minutes"] = 1
return data_dict
def setAccessStatus(self, text, state=""):
user_reference = self.getPortalObject().portal_membership.getAuthenticatedMember()\
.getUserName()
previous = self._getCachedAccessInfo()
created_at = rfc1123_date(DateTime())
since = created_at
status_changed = True
if previous is not None:
previous_json = json.loads(previous)
if text.split(" ")[0] == previous_json.get("text", "").split(" ")[0]:
since = previous_json.get("since",
previous_json.get("created_at", rfc1123_date(DateTime())))
status_changed = False
if state == "":
state = previous_json.get("state", "")
value = json.dumps({
'user': '%s' % user_reference,
'created_at': '%s' % created_at,
'text': '%s' % text,
'since': '%s' % since,
'state': state
})
cache_duration = self._getAccessStatusCacheFactory().cache_duration
self._getAccessStatusPlugin().set(self._getAccessStatusCacheKey(),
DEFAULT_CACHE_SCOPE, value, cache_duration=cache_duration)
return status_changed
def getTextAccessStatus(self):
return self.getAccessStatus()['text']
def getLastAccessDate(self):
data_dict = self.getAccessStatus()
if data_dict.get("no_data") == 1:
return "%s didn't contact the server" % self.getPortalType()
date = DateTime(data_dict['created_at'])
return date.strftime('%Y/%m/%d %H:%M')
#####################
# SlapOS Last Data
#####################
def _getLastDataCacheFactory(self):
return self.getPortalObject().portal_caches\
.getRamCacheRoot().get('last_stored_data_cache_factory')
def _getLastDataPlugin(self):
return self._getLastDataCacheFactory().getCachePluginList()[0]
def setLastData(self, value, key=None):
cache_key = self.getReference()
if key is not None:
cache_key = key
cache_duration = self._getLastDataCacheFactory().cache_duration
self._getLastDataPlugin().set(cache_key, DEFAULT_CACHE_SCOPE,
value, cache_duration=cache_duration)
def getLastData(self, key=None):
cache_key = self.getReference()
if key is not None:
cache_key = key
try:
entry = self._getLastDataPlugin().get(cache_key, DEFAULT_CACHE_SCOPE)
except KeyError:
entry = None
else:
entry = entry.getValue()
return entry
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Mixin Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>SlapOSCacheMixin</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>mixin.erp5.SlapOSCacheMixin</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Mixin Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Cache Factory" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>cache_duration</string> </key>
<value> <int>86400</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Stores last transmitted values in order to avoid multiple writes on repetitive calls to request and set connection dict.</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>access_status_data_cache_factory</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Cache Factory</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Access Status data Cache Factory</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Distributed Ram Cache" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>specialise/portal_memcached/default_memcached_plugin</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>volatile_cache_plugin</string> </value>
</item>
<item>
<key> <string>int_index</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Distributed Ram Cache</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Volatile Distributed Ram Cache</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -107,7 +107,9 @@ ...@@ -107,7 +107,9 @@
<item> <item>
<key> <string>type_mixin</string> </key> <key> <string>type_mixin</string> </key>
<value> <value>
<tuple/> <tuple>
<string>SlapOSCacheMixin</string>
</tuple>
</value> </value>
</item> </item>
</dictionary> </dictionary>
......
...@@ -74,7 +74,9 @@ ...@@ -74,7 +74,9 @@
<item> <item>
<key> <string>type_mixin</string> </key> <key> <string>type_mixin</string> </key>
<value> <value>
<tuple/> <tuple>
<string>SlapOSCacheMixin</string>
</tuple>
</value> </value>
</item> </item>
</dictionary> </dictionary>
......
...@@ -105,7 +105,9 @@ ...@@ -105,7 +105,9 @@
<item> <item>
<key> <string>type_mixin</string> </key> <key> <string>type_mixin</string> </key>
<value> <value>
<tuple/> <tuple>
<string>SlapOSCacheMixin</string>
</tuple>
</value> </value>
</item> </item>
</dictionary> </dictionary>
......
<type_mixin>
<portal_type id="Compute Node">
<item>SlapOSCacheMixin</item>
</portal_type>
<portal_type id="Compute Partition">
<item>SlapOSCacheMixin</item>
</portal_type>
<portal_type id="Person">
<item>SlapOSCacheMixin</item>
</portal_type>
</type_mixin>
\ No newline at end of file
import json
from DateTime import DateTime
memcached_dict = context.Base_getSlapToolMemcachedDict()
try:
d = memcached_dict[document.getReference()]
except (KeyError, TypeError):
d = {
"user": "SlapOS Master",
"text": "#error no data found for %s" % document.getReference(),
"no_data": 1
}
else:
d = json.loads(d)
last_contact = DateTime(d.get('created_at'))
d["no_data_since_15_minutes"] = 0
d["no_data_since_5_minutes"] = 0
if (DateTime() - last_contact) > 0.005:
d["no_data_since_15_minutes"] = 1
d["no_data_since_5_minutes"] = 1
elif (DateTime() - last_contact) > 0.0025:
d["no_data_since_5_minutes"] = 1
return d
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>document</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_getNewsDict</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
return context.getPortalObject().portal_memcached.getMemcachedDict(
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_getSlapToolMemcachedDict</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
import json
compute_node = context compute_node = context
portal = context.getPortalObject() portal = context.getPortalObject()
from zExceptions import Unauthorized from zExceptions import Unauthorized
...@@ -22,14 +21,11 @@ comment = '' ...@@ -22,14 +21,11 @@ comment = ''
if can_allocate: if can_allocate:
# Check if compute_node has error reported # Check if compute_node has error reported
memcached_dict = context.Base_getSlapToolMemcachedDict() log_dict = compute_node.getAccessStatus()
try: if log_dict.get("no_data") == 1:
d = memcached_dict[compute_node.getReference()]
except KeyError:
can_allocate = False can_allocate = False
comment = "Compute Node didn't contact the server" comment = "Compute Node didn't contact the server"
else: else:
log_dict = json.loads(d)
if '#error' in log_dict.get('text', '#error'): if '#error' in log_dict.get('text', '#error'):
can_allocate = False can_allocate = False
comment = 'Compute Node reported an error' comment = 'Compute Node reported an error'
......
from DateTime import DateTime
import json
memcached_dict = context.Base_getSlapToolMemcachedDict()
try:
d = memcached_dict[context.getReference()]
except KeyError:
return "Compute Node didn't contact the server"
else:
log_dict = json.loads(d)
date = DateTime(log_dict['created_at'])
return date.strftime('%Y/%m/%d %H:%M')
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ComputeNode_getLastContactDate</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -125,7 +125,7 @@ ...@@ -125,7 +125,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: context.ComputeNode_getLastContactDate()</string> </value> <value> <string>python: context.getLastAccessDate()</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
from DateTime import DateTime for si in context.getAggregateRelatedValueList(portal_type=["Software Instance"]):
import json
partition = context
memcached_dict = context.Base_getSlapToolMemcachedDict()
result = ""
date = None
for si in partition.getAggregateRelatedValueList(portal_type=["Software Instance", "Slave Instance"]):
obj = si.getObject() obj = si.getObject()
if obj.getValidationState() != "validated": if obj.getValidationState() != "validated":
...@@ -15,13 +6,6 @@ for si in partition.getAggregateRelatedValueList(portal_type=["Software Instance ...@@ -15,13 +6,6 @@ for si in partition.getAggregateRelatedValueList(portal_type=["Software Instance
if obj.getSlapState() == "destroy_requested": if obj.getSlapState() == "destroy_requested":
continue continue
try: return obj.getLastAccessDate()
d = memcached_dict[obj.getReference()]
except KeyError: return ""
result = "#missing no data found for %s" % obj.getReference()
else:
d = json.loads(d)
date = DateTime(d['created_at'])
result = date.strftime('%Y/%m/%d %H:%M')
return result
...@@ -134,7 +134,7 @@ ...@@ -134,7 +134,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>cell/ComputeNode_getLastContactDate</string> </value> <value> <string>cell/getLastAccessDate</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
"""Dirty script to return Software Instance state""" """Dirty script to return Software Instance state"""
import json
state = context.getSlapState() state = context.getSlapState()
has_partition = context.getAggregate(portal_type="Compute Partition") has_partition = context.getAggregate(portal_type="Compute Partition")
result = 'Unable to calculate the status...' result = 'Unable to calculate the status...'
if has_partition: if has_partition:
try: d = context.getAccessStatus()
memcached_dict = context.Base_getSlapToolMemcachedDict() if d.get("no_data") == 1:
try: result = context.getSlapStateTitle()
d = memcached_dict[context.getReference()] else:
except KeyError: result = d['text']
result = context.getSlapStateTitle() if result.startswith('#access '):
else: result = result[len('#access '):]
d = json.loads(d)
result = d['text']
if result.startswith('#access '):
result = result[len('#access '):]
except Exception:
raise
# result = 'There is system issue, please try again later.'
else: else:
if state in ["start_requested", "stop_requested"]: if state in ["start_requested", "stop_requested"]:
......
from DateTime import DateTime from DateTime import DateTime
portal = context.getPortalObject() portal = context.getPortalObject()
import json
error_style = 'background-color: red; display: block; height: 2em; width: 2em; float: left; margin: 5px;' error_style = 'background-color: red; display: block; height: 2em; width: 2em; float: left; margin: 5px;'
access_style = 'background-color: green; display: block; height: 2em; width: 2em; float: left; margin: 5px;' access_style = 'background-color: green; display: block; height: 2em; width: 2em; float: left; margin: 5px;'
...@@ -14,20 +13,17 @@ software_installation = portal.portal_catalog.getResultValue( ...@@ -14,20 +13,17 @@ software_installation = portal.portal_catalog.getResultValue(
if not software_installation or software_installation.getSlapState() == "destroy_requested": if not software_installation or software_installation.getSlapState() == "destroy_requested":
return '<span" style="%s" title="Information not available"></a>' % error_style return '<span" style="%s" title="Information not available"></a>' % error_style
memcached_dict = context.Base_getSlapToolMemcachedDict() d = software_installation.getAccessStatus()
try: if d.get("no_data") == 1:
d = memcached_dict[software_installation.getReference()]
except KeyError:
return "<a href='%s' style='%s'></a>" % (software_installation.getRelativeUrl(), return "<a href='%s' style='%s'></a>" % (software_installation.getRelativeUrl(),
error_style) error_style)
else:
d = json.loads(d) result = d['text']
result = d['text'] date = DateTime(d['created_at'])
date = DateTime(d['created_at']) limit_date = DateTime() - 0.084
limit_date = DateTime() - 0.084 if result.startswith('#error ') or (date - limit_date) < 0:
if result.startswith('#error ') or (date - limit_date) < 0: access_style = error_style
access_style = error_style
return "<a href='%s' style='%s' title='%s at %s'></a>" % ( return "<a href='%s' style='%s' title='%s at %s'></a>" % (
software_installation.getRelativeUrl(), software_installation.getRelativeUrl(),
access_style, result, d['created_at']) access_style, result, d['created_at'])
...@@ -7,12 +7,10 @@ ...@@ -7,12 +7,10 @@
from erp5.component.test.testSlapOSCloudSecurityGroup import TestSlapOSSecurityMixin from erp5.component.test.testSlapOSCloudSecurityGroup import TestSlapOSSecurityMixin
from erp5.component.test.SlapOSTestCaseMixin import changeSkin from erp5.component.test.SlapOSTestCaseMixin import changeSkin
import json
import re import re
import xml_marshaller import xml_marshaller
from AccessControl.SecurityManagement import getSecurityManager, \ from AccessControl.SecurityManagement import getSecurityManager, \
setSecurityManager setSecurityManager
from DateTime import DateTime
class DefaultScenarioMixin(TestSlapOSSecurityMixin): class DefaultScenarioMixin(TestSlapOSSecurityMixin):
...@@ -103,14 +101,7 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin): ...@@ -103,14 +101,7 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
return [] return []
def setAccessToMemcached(self, agent): def setAccessToMemcached(self, agent):
memcached_dict = self.portal.portal_memcached.getMemcachedDict( agent.setAccessStatus("#access ")
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
access_date = DateTime()
memcached_dict[agent.getReference()] = json.dumps(
{"created_at":"%s" % access_date, "text": "#access "}
)
def requestComputeNode(self, title): def requestComputeNode(self, title):
requestXml = self.portal.portal_slap.requestComputer(title) requestXml = self.portal.portal_slap.requestComputer(title)
......
...@@ -2,12 +2,10 @@ ...@@ -2,12 +2,10 @@
import transaction import transaction
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin
from Products.ERP5Type.tests.utils import createZODBPythonScript from Products.ERP5Type.tests.utils import createZODBPythonScript
import json
import time import time
from zExceptions import Unauthorized from zExceptions import Unauthorized
from DateTime import DateTime from DateTime import DateTime
from erp5.component.module.DateUtils import addToDate from erp5.component.module.DateUtils import addToDate
from App.Common import rfc1123_date
class TestSlapOSCoreSlapOSAssertInstanceTreeSuccessorAlarm( class TestSlapOSCoreSlapOSAssertInstanceTreeSuccessorAlarm(
SlapOSTestCaseMixin): SlapOSTestCaseMixin):
...@@ -443,13 +441,7 @@ class TestSlapOSUpdateComputeNodeCapacityScopeAlarm(SlapOSTestCaseMixin): ...@@ -443,13 +441,7 @@ class TestSlapOSUpdateComputeNodeCapacityScopeAlarm(SlapOSTestCaseMixin):
) )
self.compute_node.edit(capacity_scope='open') self.compute_node.edit(capacity_scope='open')
self.compute_node.validate() self.compute_node.validate()
memcached_dict = self.portal.portal_memcached.getMemcachedDict( self.compute_node.setAccessStatus("#access ok")
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
memcached_dict[self.compute_node.getReference()] = json.dumps({
'text': '#access ok',
'created_at': rfc1123_date(DateTime())
})
transaction.commit() transaction.commit()
def test_ComputeNode_checkAndUpdateCapacityScope(self): def test_ComputeNode_checkAndUpdateCapacityScope(self):
...@@ -517,14 +509,12 @@ class TestSlapOSUpdateComputeNodeCapacityScopeAlarm(SlapOSTestCaseMixin): ...@@ -517,14 +509,12 @@ class TestSlapOSUpdateComputeNodeCapacityScopeAlarm(SlapOSTestCaseMixin):
self.compute_node.getCapacityQuantity()) self.compute_node.getCapacityQuantity())
def test_ComputeNode_checkAndUpdateCapacityScope_with_old_access(self): def test_ComputeNode_checkAndUpdateCapacityScope_with_old_access(self):
memcached_dict = self.portal.portal_memcached.getMemcachedDict( try:
key_prefix='slap_tool', self.pinDateTime(addToDate(DateTime(),to_add={'minute': -11}))
plugin_path='portal_memcached/default_memcached_plugin') self.compute_node.setAccessStatus("#access ok")
memcached_dict[self.compute_node.getReference()] = json.dumps({ finally:
'text': '#access ok', self.unpinDateTime()
'created_at': rfc1123_date(addToDate(DateTime(),
to_add={'minute': -11}))
})
self.compute_node.ComputeNode_checkAndUpdateCapacityScope() self.compute_node.ComputeNode_checkAndUpdateCapacityScope()
self.assertEqual('close', self.compute_node.getCapacityScope()) self.assertEqual('close', self.compute_node.getCapacityScope())
self.assertEqual("Compute Node didn't contact for more than 10 minutes", self.assertEqual("Compute Node didn't contact for more than 10 minutes",
...@@ -552,24 +542,14 @@ class TestSlapOSUpdateComputeNodeCapacityScopeAlarm(SlapOSTestCaseMixin): ...@@ -552,24 +542,14 @@ class TestSlapOSUpdateComputeNodeCapacityScopeAlarm(SlapOSTestCaseMixin):
self.assertEqual('open', self.compute_node.getCapacityScope()) self.assertEqual('open', self.compute_node.getCapacityScope())
def test_ComputeNode_checkAndUpdateCapacityScope_with_error(self): def test_ComputeNode_checkAndUpdateCapacityScope_with_error(self):
memcached_dict = self.portal.portal_memcached.getMemcachedDict( self.compute_node.setAccessStatus('#error not ok')
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
memcached_dict[self.compute_node.getReference()] = json.dumps({
'text': '#error not ok'
})
self.compute_node.ComputeNode_checkAndUpdateCapacityScope() self.compute_node.ComputeNode_checkAndUpdateCapacityScope()
self.assertEqual('close', self.compute_node.getCapacityScope()) self.assertEqual('close', self.compute_node.getCapacityScope())
self.assertEqual("Compute Node reported an error", self.assertEqual("Compute Node reported an error",
self.compute_node.workflow_history['edit_workflow'][-1]['comment']) self.compute_node.workflow_history['edit_workflow'][-1]['comment'])
def test_ComputeNode_checkAndUpdateCapacityScope_with_error_non_public(self): def test_ComputeNode_checkAndUpdateCapacityScope_with_error_non_public(self):
memcached_dict = self.portal.portal_memcached.getMemcachedDict( self.compute_node.setAccessStatus('#error not ok')
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
memcached_dict[self.compute_node.getReference()] = json.dumps({
'text': '#error not ok'
})
self.compute_node.edit(allocation_scope='open/personal') self.compute_node.edit(allocation_scope='open/personal')
self.compute_node.ComputeNode_checkAndUpdateCapacityScope() self.compute_node.ComputeNode_checkAndUpdateCapacityScope()
self.assertEqual('open', self.compute_node.getCapacityScope()) self.assertEqual('open', self.compute_node.getCapacityScope())
......
mixin.erp5.SlapOSCacheMixin
\ No newline at end of file
acl_users/slapos_access_token_extraction acl_users/slapos_access_token_extraction
acl_users/slapos_machine acl_users/slapos_machine
acl_users/slapos_shadow acl_users/slapos_shadow
computer_model_module/template_computer_model
computer_model_module/template_computer_model/**
compute_node_module/template_compute_node compute_node_module/template_compute_node
compute_node_module/template_compute_node/** compute_node_module/template_compute_node/**
computer_model_module/template_computer_model
computer_model_module/template_computer_model/**
instance_tree_module/template_instance_tree instance_tree_module/template_instance_tree
person_module/template_member person_module/template_member
person_module/template_member/** person_module/template_member/**
...@@ -17,6 +17,10 @@ portal_alarms/slapos_garbage_collect_destroyed_root_tree ...@@ -17,6 +17,10 @@ portal_alarms/slapos_garbage_collect_destroyed_root_tree
portal_alarms/slapos_garbage_collect_non_allocated_root_tree portal_alarms/slapos_garbage_collect_non_allocated_root_tree
portal_alarms/slapos_stop_collect_instance portal_alarms/slapos_stop_collect_instance
portal_alarms/slapos_update_compute_node_capacity_scope portal_alarms/slapos_update_compute_node_capacity_scope
portal_caches/access_status_data_cache_factory
portal_caches/access_status_data_cache_factory/volatile_cache_plugin
portal_caches/last_stored_data_cache_factory
portal_caches/last_stored_data_cache_factory/volatile_cache_plugin
product_module/compute_node product_module/compute_node
software_installation_module/template_software_installation software_installation_module/template_software_installation
software_instance_module/template_slave_instance software_instance_module/template_slave_instance
......
Compute Node | SlapOSCacheMixin
Compute Partition | SlapOSCacheMixin
Person | SlapOSCacheMixin
\ No newline at end of file
from DateTime import DateTime from DateTime import DateTime
import json
portal = context.getPortalObject() portal = context.getPortalObject()
from Products.ERP5Type.Document import newTempBase from Products.ERP5Type.Document import newTempBase
...@@ -19,26 +18,11 @@ show_all = False ...@@ -19,26 +18,11 @@ show_all = False
if "show_all" in kw: if "show_all" in kw:
show_all = kw.pop("omit_zero_ticket") show_all = kw.pop("omit_zero_ticket")
memcached_dict = context.getPortalObject().portal_memcached.getMemcachedDict(
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
def checkForError(reference): def checkForError(reference):
try: result = context.getAccessStatusText()
d = memcached_dict[reference]
except KeyError:
return 1
d = json.loads(d)
result = d['text']
#last_contact = DateTime(d.get('created_at'))
# Optimise by checking memcache information first.
if result.startswith('#error '): if result.startswith('#error '):
return 1 return 1
for compute_node in portal.portal_catalog( for compute_node in portal.portal_catalog(
default_allocation_scope_uid = [personal_category_uid, public_category_uid, friend_category_uid], default_allocation_scope_uid = [personal_category_uid, public_category_uid, friend_category_uid],
select_list={"reference": None}, select_list={"reference": None},
......
from DateTime import DateTime from DateTime import DateTime
import json
portal = context.getPortalObject() portal = context.getPortalObject()
if portal.ERP5Site_isSupportRequestCreationClosed(): if portal.ERP5Site_isSupportRequestCreationClosed():
...@@ -22,7 +20,6 @@ compute_node_reference = context.getReference() ...@@ -22,7 +20,6 @@ compute_node_reference = context.getReference()
compute_node_title = context.getTitle() compute_node_title = context.getTitle()
should_notify = True should_notify = True
memcached_dict = context.Base_getSlapToolMemcachedDict()
tolerance = DateTime()-0.5 tolerance = DateTime()-0.5
for software_installation in software_installation_list: for software_installation in software_installation_list:
should_notify = False should_notify = False
...@@ -31,9 +28,12 @@ for software_installation in software_installation_list: ...@@ -31,9 +28,12 @@ for software_installation in software_installation_list:
continue continue
reference = software_installation.getReference() reference = software_installation.getReference()
try: d = software_installation.getAccessStatus()
d = memcached_dict[reference] if d.get("no_data", None) == 1:
d = json.loads(d) ticket_title = "[MONITORING] No information for %s on %s" % (reference, compute_node_reference)
description = "The software release %s did not started to build on %s since %s" % \
(software_installation.getUrlString(), compute_node_title, software_installation.getCreationDate())
else:
last_contact = DateTime(d.get('created_at')) last_contact = DateTime(d.get('created_at'))
if d.get("text").startswith("building"): if d.get("text").startswith("building"):
should_notify = True should_notify = True
...@@ -49,13 +49,7 @@ for software_installation in software_installation_list: ...@@ -49,13 +49,7 @@ for software_installation in software_installation_list:
description = "The software release %s is failing to build for too long on %s, started on %s" % \ description = "The software release %s is failing to build for too long on %s, started on %s" % \
(software_installation.getUrlString(), compute_node_title, software_installation.getCreationDate()) (software_installation.getUrlString(), compute_node_title, software_installation.getCreationDate())
except KeyError:
ticket_title = "[MONITORING] No information for %s on %s" % (reference, compute_node_reference)
description = "The software release %s did not started to build on %s since %s" % \
(software_installation.getUrlString(), compute_node_title, software_installation.getCreationDate())
if should_notify: if should_notify:
support_request = context.Base_generateSupportRequestForSlapOS( support_request = context.Base_generateSupportRequestForSlapOS(
ticket_title, ticket_title,
description, description,
......
from DateTime import DateTime from DateTime import DateTime
import json
portal = context.getPortalObject() portal = context.getPortalObject()
if portal.ERP5Site_isSupportRequestCreationClosed(): if portal.ERP5Site_isSupportRequestCreationClosed():
...@@ -18,50 +16,49 @@ reference = context.getReference() ...@@ -18,50 +16,49 @@ reference = context.getReference()
compute_node_title = context.getTitle() compute_node_title = context.getTitle()
ticket_title = "[MONITORING] Lost contact with compute_node %s" % reference ticket_title = "[MONITORING] Lost contact with compute_node %s" % reference
description = "" description = ""
should_notify = True
last_contact = "No Contact Information" last_contact = "No Contact Information"
memcached_dict = context.Base_getSlapToolMemcachedDict()
try: d = context.getAccessStatus()
d = memcached_dict[reference] # Ignore if data isn't present.
d = json.loads(d) if d.get("no_data") == 1:
description = "The Compute Node %s (%s) has not contacted the server (No Contact Information)" % (
compute_node_title, reference)
else:
last_contact = DateTime(d.get('created_at')) last_contact = DateTime(d.get('created_at'))
if (DateTime() - last_contact) > 0.01: if (DateTime() - last_contact) > 0.01:
description = "The Compute Node %s (%s) has not contacted the server for more than 30 minutes" \ description = "The Compute Node %s (%s) has not contacted the server for more than 30 minutes" \
"(last contact date: %s)" % (compute_node_title, reference, last_contact) "(last contact date: %s)" % (compute_node_title, reference, last_contact)
else: else:
should_notify = False # Nothing to notify.
except KeyError: return
description = "The Compute Node %s (%s) has not contacted the server (No Contact Information)" % (
compute_node_title, reference)
if should_notify: support_request = context.Base_generateSupportRequestForSlapOS(
support_request = context.Base_generateSupportRequestForSlapOS( ticket_title,
ticket_title, description,
description, context.getRelativeUrl()
context.getRelativeUrl() )
)
person = context.getSourceAdministrationValue(portal_type="Person") person = context.getSourceAdministrationValue(portal_type="Person")
if not person: if not person:
return support_request return support_request
# Send Notification message # Send Notification message
notification_reference = 'slapos-crm-compute_node_check_state.notification' notification_reference = 'slapos-crm-compute_node_check_state.notification'
notification_message = portal.portal_notifications.getDocumentValue( notification_message = portal.portal_notifications.getDocumentValue(
reference=notification_reference) reference=notification_reference)
if notification_message is None: if notification_message is None:
message = """%s""" % description message = """%s""" % description
else: else:
mapping_dict = {'compute_node_title':context.getTitle(), mapping_dict = {'compute_node_title':context.getTitle(),
'compute_node_id':reference, 'compute_node_id':reference,
'last_contact':last_contact} 'last_contact':last_contact}
message = notification_message.asText( message = notification_message.asText(
substitution_method_parameter_dict={'mapping_dict':mapping_dict}) substitution_method_parameter_dict={'mapping_dict':mapping_dict})
support_request.SupportRequest_trySendNotificationMessage( support_request.SupportRequest_trySendNotificationMessage(
ticket_title, ticket_title,
message, person.getRelativeUrl()) message, person.getRelativeUrl())
return support_request return support_request
import json
portal = context.getPortalObject() portal = context.getPortalObject()
compute_node = context compute_node = context
now_date = DateTime() now_date = DateTime()
...@@ -7,20 +6,16 @@ if (now_date - compute_node.getCreationDate()) < maximum_days: ...@@ -7,20 +6,16 @@ if (now_date - compute_node.getCreationDate()) < maximum_days:
# This compute_node was created recently skip # This compute_node was created recently skip
return True return True
memcached_dict = context.Base_getSlapToolMemcachedDict() message_dict = context.getAccessStatus()
# Check if there is some information in memcached # Ignore if data isn't present.
try: if message_dict.get("no_data", None) == 1:
d = memcached_dict[compute_node.getReference()]
except KeyError:
message_dict = {} message_dict = {}
else:
message_dict = json.loads(d)
if message_dict.has_key('created_at'): if message_dict.has_key('created_at'):
contact_date = DateTime(message_dict.get('created_at').encode('utf-8')) contact_date = DateTime(message_dict.get('created_at').encode('utf-8'))
return (now_date - contact_date) < maximum_days return (now_date - contact_date) < maximum_days
# If no memcached, check in consumption report # If no access status information, check in consumption report
for sale_packing_list in portal.portal_catalog( for sale_packing_list in portal.portal_catalog(
portal_type="Sale Packing List Line", portal_type="Sale Packing List Line",
simulation_state="delivered", simulation_state="delivered",
......
from DateTime import DateTime from DateTime import DateTime
import json
memcached_dict = context.Base_getSlapToolMemcachedDict() d = context.getAccessStatus()
try: # Ignore if data isn't present.
d = memcached_dict[context.getReference()] if d.get("no_data", None) == 1:
except KeyError: return
# Information not available
return None
d = json.loads(d) if d['text'].startswith('#error '):
result = d['text'] return DateTime(d.get('created_at'))
last_contact = DateTime(d.get('created_at'))
# Optimise by checking memcache information first.
if result.startswith('#error '):
return last_contact
return None
from DateTime import DateTime from DateTime import DateTime
import json
if context.getAggregateValue(portal_type="Compute Partition") is not None: if context.getAggregateValue(portal_type="Compute Partition") is not None:
memcached_dict = context.Base_getSlapToolMemcachedDict() d = context.getAccessStatus()
try: # Ignore if data isn't present.
d = memcached_dict[context.getReference()] if d.get("no_data", None) == 1:
except KeyError:
if include_message: if include_message:
return "Not possible to connect" return "Not possible to connect"
return return
d = json.loads(d)
result = d['text'] result = d['text']
last_contact = DateTime(d.get('created_at')) last_contact = DateTime(d.get('created_at'))
since = DateTime(d.get('since')) since = DateTime(d.get('since'))
# Optimise by checking memcache information first.
if result.startswith('#error '): if result.startswith('#error '):
if ((DateTime()-since)*24*60) > tolerance: if ((DateTime()-since)*24*60) > tolerance:
if include_created_at and not include_since: if include_created_at and not include_since:
...@@ -24,7 +20,6 @@ if context.getAggregateValue(portal_type="Compute Partition") is not None: ...@@ -24,7 +20,6 @@ if context.getAggregateValue(portal_type="Compute Partition") is not None:
return result, last_contact, since return result, last_contact, since
return result return result
# XXX time limit of 48 hours for run at least once.
if include_message and include_created_at and not include_since: if include_message and include_created_at and not include_since:
return result, last_contact return result, last_contact
elif include_message and include_created_at and include_since: elif include_message and include_created_at and include_since:
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
# #
from DateTime import DateTime from DateTime import DateTime
import json
if context.getSimulationState() == "invalidated": if context.getSimulationState() == "invalidated":
return "Closed Ticket" return "Closed Ticket"
...@@ -18,22 +17,20 @@ if document is None: ...@@ -18,22 +17,20 @@ if document is None:
aggregate_portal_type = document.getPortalType() aggregate_portal_type = document.getPortalType()
memcached_dict = context.Base_getSlapToolMemcachedDict()
if aggregate_portal_type == "Compute Node": if aggregate_portal_type == "Compute Node":
if document.getMonitorScope() == "disabled": if document.getMonitorScope() == "disabled":
return "Monitor is disabled to the related %s." % document.getPortalType() return "Monitor is disabled to the related %s." % document.getPortalType()
try:
d = memcached_dict[document.getReference()]
d = json.loads(d)
last_contact = DateTime(d.get('created_at'))
if (DateTime() - last_contact) < 0.01:
return "All OK, latest contact: %s " % last_contact
else:
return "Problem, latest contact: %s" % last_contact
except KeyError:
return "No Contact Information"
d = context.getAccessStatus()
if d.get("no_data", None) == 1:
return "No Contact Information"
last_contact = DateTime(d.get('created_at'))
if (DateTime() - last_contact) < 0.01:
return "All OK, latest contact: %s " % last_contact
else:
return "Problem, latest contact: %s" % last_contact
if aggregate_portal_type == "Software Installation": if aggregate_portal_type == "Software Installation":
compute_node_title = document.getAggregateTitle() compute_node_title = document.getAggregateTitle()
if document.getAggregateValue().getMonitorScope() == "disabled": if document.getAggregateValue().getMonitorScope() == "disabled":
...@@ -42,23 +39,20 @@ if aggregate_portal_type == "Software Installation": ...@@ -42,23 +39,20 @@ if aggregate_portal_type == "Software Installation":
if document.getSlapState() not in ["start_requested", "stop_requested"]: if document.getSlapState() not in ["start_requested", "stop_requested"]:
return "Software Installation is Destroyed." return "Software Installation is Destroyed."
try: d = context.getAccessStatus()
d = memcached_dict[document.getReference()] if d.get("no_data", None) == 1:
d = json.loads(d)
last_contact = DateTime(d.get('created_at'))
if d.get("text").startswith("building"):
return "The software release %s is building for mode them 12 hours on %s, started on %s" % \
(document.getUrlString(), compute_node_title, document.getCreationDate())
elif d.get("text").startswith("#access"):
return "All OK, software built."
elif d.get("text").startswith("#error"):
return "The software release %s is failing to build for too long on %s, started on %s" % \
(document.getUrlString(), compute_node_title, document.getCreationDate())
except KeyError:
return "The software release %s did not started to build on %s since %s" % \ return "The software release %s did not started to build on %s since %s" % \
(document.getUrlString(), compute_node_title, document.getCreationDate()) (document.getUrlString(), compute_node_title, document.getCreationDate())
last_contact = DateTime(d.get('created_at'))
if d.get("text").startswith("building"):
return "The software release %s is building for mode them 12 hours on %s, started on %s" % \
(document.getUrlString(), compute_node_title, document.getCreationDate())
elif d.get("text").startswith("#access"):
return "All OK, software built."
elif d.get("text").startswith("#error"):
return "The software release %s is failing to build for too long on %s, started on %s" % \
(document.getUrlString(), compute_node_title, document.getCreationDate())
if aggregate_portal_type == "Instance Tree": if aggregate_portal_type == "Instance Tree":
if document.getMonitorScope() == "disabled": if document.getMonitorScope() == "disabled":
......
...@@ -25,6 +25,9 @@ import transaction ...@@ -25,6 +25,9 @@ import transaction
from erp5.component.test.SlapOSTestCaseMixin import \ from erp5.component.test.SlapOSTestCaseMixin import \
SlapOSTestCaseMixin,SlapOSTestCaseMixinWithAbort, simulate SlapOSTestCaseMixin,SlapOSTestCaseMixinWithAbort, simulate
from DateTime import DateTime from DateTime import DateTime
from App.Common import rfc1123_date
from Products.ERP5Type.Cache import DEFAULT_CACHE_SCOPE
from Products.ERP5Type.tests.utils import createZODBPythonScript from Products.ERP5Type.tests.utils import createZODBPythonScript
import json import json
...@@ -826,13 +829,7 @@ class TestComputeNode_hasContactedRecently(SlapOSTestCaseMixinWithAbort): ...@@ -826,13 +829,7 @@ class TestComputeNode_hasContactedRecently(SlapOSTestCaseMixinWithAbort):
@simulate('ComputeNode_getCreationDate', '*args, **kwargs','return DateTime() - 32') @simulate('ComputeNode_getCreationDate', '*args, **kwargs','return DateTime() - 32')
def test_ComputeNode_hasContactedRecently_memcached(self): def test_ComputeNode_hasContactedRecently_memcached(self):
compute_node = self._makeComputeNode()[0] compute_node = self._makeComputeNode()[0]
memcached_dict = self.portal.portal_memcached.getMemcachedDict( compute_node.setAccessStatus("#access ")
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
memcached_dict[compute_node.getReference()] = json.dumps({
"created_at": DateTime().strftime("%Y/%m/%d %H:%M")
})
self.tic() self.tic()
compute_node.getCreationDate = self.portal.ComputeNode_getCreationDate compute_node.getCreationDate = self.portal.ComputeNode_getCreationDate
...@@ -843,13 +840,12 @@ class TestComputeNode_hasContactedRecently(SlapOSTestCaseMixinWithAbort): ...@@ -843,13 +840,12 @@ class TestComputeNode_hasContactedRecently(SlapOSTestCaseMixinWithAbort):
@simulate('ComputeNode_getCreationDate', '*args, **kwargs','return DateTime() - 32') @simulate('ComputeNode_getCreationDate', '*args, **kwargs','return DateTime() - 32')
def test_ComputeNode_hasContactedRecently_memcached_oudated_no_spl(self): def test_ComputeNode_hasContactedRecently_memcached_oudated_no_spl(self):
compute_node = self._makeComputeNode()[0] compute_node = self._makeComputeNode()[0]
memcached_dict = self.portal.portal_memcached.getMemcachedDict( try:
key_prefix='slap_tool', self.pinDateTime(DateTime()-32)
plugin_path='portal_memcached/default_memcached_plugin') compute_node.setAccessStatus("#access ")
finally:
self.unpinDateTime()
memcached_dict[compute_node.getReference()] = json.dumps({
"created_at": (DateTime() - 32).strftime("%Y/%m/%d %H:%M")
})
self.tic() self.tic()
compute_node.getCreationDate = self.portal.ComputeNode_getCreationDate compute_node.getCreationDate = self.portal.ComputeNode_getCreationDate
...@@ -860,13 +856,12 @@ class TestComputeNode_hasContactedRecently(SlapOSTestCaseMixinWithAbort): ...@@ -860,13 +856,12 @@ class TestComputeNode_hasContactedRecently(SlapOSTestCaseMixinWithAbort):
@simulate('ComputeNode_getCreationDate', '*args, **kwargs','return DateTime() - 32') @simulate('ComputeNode_getCreationDate', '*args, **kwargs','return DateTime() - 32')
def test_ComputeNode_hasContactedRecently_memcached_oudated_with_spl(self): def test_ComputeNode_hasContactedRecently_memcached_oudated_with_spl(self):
compute_node = self._makeComputeNode()[0] compute_node = self._makeComputeNode()[0]
memcached_dict = self.portal.portal_memcached.getMemcachedDict( try:
key_prefix='slap_tool', self.pinDateTime(DateTime()-32)
plugin_path='portal_memcached/default_memcached_plugin') compute_node.setAccessStatus("#access ")
finally:
self.unpinDateTime()
memcached_dict[compute_node.getReference()] = json.dumps({
"created_at": (DateTime() - 32).strftime("%Y/%m/%d %H:%M")
})
self.createSPL(compute_node) self.createSPL(compute_node)
self.tic() self.tic()
...@@ -1224,13 +1219,11 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin): ...@@ -1224,13 +1219,11 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
@simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0') @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
def test_ComputeNode_checkState_call_support_request(self): def test_ComputeNode_checkState_call_support_request(self):
compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0] compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
memcached_dict = self.portal.portal_memcached.getMemcachedDict( try:
key_prefix='slap_tool', self.pinDateTime(DateTime()-1.1)
plugin_path='portal_memcached/default_memcached_plugin') compute_node.setAccessStatus("#access ")
finally:
memcached_dict[compute_node.getReference()] = json.dumps( self.unpinDateTime()
{"created_at":"%s" % (DateTime() - 1.1)}
)
self._simulateBase_generateSupportRequestForSlapOS() self._simulateBase_generateSupportRequestForSlapOS()
support_request = self._makeSupportRequest() support_request = self._makeSupportRequest()
...@@ -1279,14 +1272,11 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin): ...@@ -1279,14 +1272,11 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0] compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
person = compute_node.getSourceAdministrationValue() person = compute_node.getSourceAdministrationValue()
try:
memcached_dict = self.portal.portal_memcached.getMemcachedDict( self.pinDateTime(DateTime()-1.1)
key_prefix='slap_tool', compute_node.setAccessStatus("#access ")
plugin_path='portal_memcached/default_memcached_plugin') finally:
self.unpinDateTime()
memcached_dict[compute_node.getReference()] = json.dumps(
{"created_at":"%s" % (DateTime() - 0.1)}
)
self.portal.REQUEST['test_ComputeNode_checkState_notify'] = \ self.portal.REQUEST['test_ComputeNode_checkState_notify'] = \
self._makeNotificationMessage(compute_node.getReference()) self._makeNotificationMessage(compute_node.getReference())
...@@ -1524,25 +1514,15 @@ class TestSlapOSHasError(SlapOSTestCaseMixin): ...@@ -1524,25 +1514,15 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
self._makeComputeNode() self._makeComputeNode()
self._makeComputePartitionList() self._makeComputePartitionList()
memcached_dict = self.portal.portal_memcached.getMemcachedDict( instance.setAccessStatus("#error ")
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
error_date = DateTime()
memcached_dict[instance.getReference()] = json.dumps(
{"created_at":"%s" % error_date, "text": "#error "}
)
self.assertEqual(instance.SoftwareInstance_hasReportedError(), None) self.assertEqual(instance.SoftwareInstance_hasReportedError(), None)
instance.setAggregateValue(self.compute_node.partition1) instance.setAggregateValue(self.compute_node.partition1)
self.assertEqual(str(instance.SoftwareInstance_hasReportedError()), '#error ') self.assertEqual(str(instance.SoftwareInstance_hasReportedError()), '#error ')
memcached_dict[instance.getReference()] = json.dumps( instance.setAccessStatus("#access ")
{"created_at":"%s" % error_date, "text": "#access "}
)
self.assertEqual(instance.SoftwareInstance_hasReportedError(), None) self.assertEqual(instance.SoftwareInstance_hasReportedError(), None)
def test_SoftwareInstallation_hasReportedError(self): def test_SoftwareInstallation_hasReportedError(self):
...@@ -1552,22 +1532,19 @@ class TestSlapOSHasError(SlapOSTestCaseMixin): ...@@ -1552,22 +1532,19 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
software_release.getUrlString() software_release.getUrlString()
) )
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
self.assertEqual(installation.SoftwareInstallation_hasReportedError(), None) self.assertEqual(installation.SoftwareInstallation_hasReportedError(), None)
error_date = DateTime() error_date = DateTime()
memcached_dict[installation.getReference()] = json.dumps( try:
{"created_at":"%s" % error_date, "text": "#error "} self.pinDateTime(error_date)
) installation.setAccessStatus("#error ")
finally:
self.assertEqual(installation.SoftwareInstallation_hasReportedError(), error_date) self.unpinDateTime()
memcached_dict[installation.getReference()] = json.dumps( self.assertEqual(
{"created_at":"%s" % error_date, "text": "#building "} rfc1123_date(installation.SoftwareInstallation_hasReportedError()),
) rfc1123_date(error_date))
installation.setAccessStatus("#building ")
self.assertEqual(installation.SoftwareInstallation_hasReportedError(), None) self.assertEqual(installation.SoftwareInstallation_hasReportedError(), None)
...@@ -1600,14 +1577,13 @@ class TestSlapOSHasError(SlapOSTestCaseMixin): ...@@ -1600,14 +1577,13 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
self._makeComputePartitionList() self._makeComputePartitionList()
instance.setAggregateValue(self.compute_node.partition1) instance.setAggregateValue(self.compute_node.partition1)
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
error_date = DateTime() error_date = DateTime()
memcached_dict[instance.getReference()] = json.dumps( value = json.dumps(
{"created_at":"%s" % error_date, "text": "#error ", "since": "%s" % (error_date - 2)} {"created_at":"%s" % error_date, "text": "#error ", "since": "%s" % (error_date - 2)}
) )
cache_duration = instance._getAccessStatusCacheFactory().cache_duration
instance._getAccessStatusPlugin().set(instance._getAccessStatusCacheKey(),
DEFAULT_CACHE_SCOPE, value, cache_duration=cache_duration)
self.assertEqual( self.assertEqual(
'Visited by InstanceTree_createSupportRequestEvent %s %s' % \ 'Visited by InstanceTree_createSupportRequestEvent %s %s' % \
...@@ -1615,9 +1591,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin): ...@@ -1615,9 +1591,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
"slapos-crm-instance-tree-instance-state.notification"), "slapos-crm-instance-tree-instance-state.notification"),
instance_tree.InstanceTree_checkSoftwareInstanceState()) instance_tree.InstanceTree_checkSoftwareInstanceState())
memcached_dict[instance.getReference()] = json.dumps( instance.setAccessStatus("#access ")
{"created_at":"%s" % error_date, "text": "#access "}
)
self.assertEqual(None, self.assertEqual(None,
instance_tree.InstanceTree_checkSoftwareInstanceState()) instance_tree.InstanceTree_checkSoftwareInstanceState())
...@@ -1720,13 +1694,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin): ...@@ -1720,13 +1694,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
instance.requestInstance(**kw) instance.requestInstance(**kw)
self.tic() self.tic()
memcached_dict = self.portal.portal_memcached.getMemcachedDict( instance.setAccessStatus("#access ")
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
error_date = DateTime()
memcached_dict[instance.getReference()] = json.dumps(
{"created_at":"%s" % error_date, "text": "#access "}
)
self.assertEqual( self.assertEqual(
'Visited by InstanceTree_createSupportRequestEvent %s %s' % \ 'Visited by InstanceTree_createSupportRequestEvent %s %s' % \
...@@ -1761,15 +1729,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin): ...@@ -1761,15 +1729,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
self._makeComputePartitionList() self._makeComputePartitionList()
instance.setAggregateValue(self.compute_node.partition1) instance.setAggregateValue(self.compute_node.partition1)
memcached_dict = self.portal.portal_memcached.getMemcachedDict( instance.setAccessStatus("#error ")
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
error_date = DateTime()
memcached_dict[instance.getReference()] = json.dumps(
{"created_at":"%s" % error_date, "text": "#error "}
)
self.assertEqual( self.assertEqual(
None, None,
instance_tree.InstanceTree_checkSoftwareInstanceState()) instance_tree.InstanceTree_checkSoftwareInstanceState())
......
...@@ -3,12 +3,12 @@ if REQUEST is not None: ...@@ -3,12 +3,12 @@ if REQUEST is not None:
raise Unauthorized raise Unauthorized
def get_compute_partition_dict(reference): def get_compute_partition_dict(reference):
compute_node_dict = context.Base_getNewsDict(context) compute_node_dict = context.getAccessStatus()
compute_partition_dict = { } compute_partition_dict = { }
for compute_partition in context.objectValues(portal_type="Compute Partition"): for compute_partition in context.objectValues(portal_type="Compute Partition"):
software_instance = compute_partition.getAggregateRelatedValue(portal_type="Software Instance") software_instance = compute_partition.getAggregateRelatedValue(portal_type="Software Instance")
if software_instance is not None: if software_instance is not None:
compute_partition_dict[compute_partition.getTitle()] = context.Base_getNewsDict(software_instance) compute_partition_dict[compute_partition.getTitle()] = software_instance.getAccessStatus()
return {"compute_node": compute_node_dict, return {"compute_node": compute_node_dict,
"partition": compute_partition_dict} "partition": compute_partition_dict}
......
...@@ -2,4 +2,4 @@ from zExceptions import Unauthorized ...@@ -2,4 +2,4 @@ from zExceptions import Unauthorized
if REQUEST is not None: if REQUEST is not None:
raise Unauthorized raise Unauthorized
return context.Base_getNewsDict(context) return context.getAccessStatus()
...@@ -25,4 +25,4 @@ if portal_type == "Software Instance" and slap_state == "destroy_requested": ...@@ -25,4 +25,4 @@ if portal_type == "Software Instance" and slap_state == "destroy_requested":
"is_destroyed": 1 "is_destroyed": 1
} }
return context.Base_getNewsDict(context) return context.getAccessStatus()
...@@ -3,10 +3,7 @@ if REQUEST is not None: ...@@ -3,10 +3,7 @@ if REQUEST is not None:
raise Unauthorized raise Unauthorized
from DateTime import DateTime from DateTime import DateTime
import json
slap_state = context.getSlapState() slap_state = context.getSlapState()
_translate = context.Base_translateString _translate = context.Base_translateString
NOT_ALLOCATED = _translate("Searching for partition") NOT_ALLOCATED = _translate("Searching for partition")
...@@ -26,13 +23,10 @@ if compute_partition is not None: ...@@ -26,13 +23,10 @@ if compute_partition is not None:
if instance.getPortalType() == "Slave Instance": if instance.getPortalType() == "Slave Instance":
instance = compute_partition.getAggregateRelatedValue(portal_type="Software Instance") instance = compute_partition.getAggregateRelatedValue(portal_type="Software Instance")
memcached_dict = instance.Base_getSlapToolMemcachedDict() d = instance.getAccessStatus()
try: if d.get("no_data") == 1:
d = memcached_dict[instance.getReference()]
except KeyError:
return _translate(instance.getSlapStateTitle()) return _translate(instance.getSlapStateTitle())
d = json.loads(d)
result = d['text'] result = d['text']
reported_state = d.get("state", "") reported_state = d.get("state", "")
if reported_state == "": if reported_state == "":
......
...@@ -36,6 +36,6 @@ if len(full_software_installation_list) > 0 and \ ...@@ -36,6 +36,6 @@ if len(full_software_installation_list) > 0 and \
len(full_software_installation_list) == len(set(compute_node_list)): len(full_software_installation_list) == len(set(compute_node_list)):
# Software is available for the root instance # Software is available for the root instance
software_installation = full_software_installation_list[0] software_installation = full_software_installation_list[0]
message = software_installation.Base_getNewsDict(software_installation)['text'] message = software_installation.getAccessStatusText()
if message.startswith("#access"): if message.startswith("#access"):
return True return True
...@@ -297,7 +297,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin): ...@@ -297,7 +297,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
</tuple> </tuple>
<dictionary id='i8'> <dictionary id='i8'>
<string>_access_status</string> <string>_access_status</string>
<string>%(access_status)s</string> <string>#error no data found for %(partition_3_instance_guid)s</string>
<string>_computer_id</string> <string>_computer_id</string>
<string>%(compute_node_id)s</string> <string>%(compute_node_id)s</string>
<string>_connection_dict</string> <string>_connection_dict</string>
...@@ -373,7 +373,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin): ...@@ -373,7 +373,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
</tuple> </tuple>
<dictionary id='i19'> <dictionary id='i19'>
<string>_access_status</string> <string>_access_status</string>
<string>%(access_status)s</string> <string>#error no data found for %(partition_2_instance_guid)s</string>
<string>_computer_id</string> <string>_computer_id</string>
<string>%(compute_node_id)s</string> <string>%(compute_node_id)s</string>
<string>_connection_dict</string> <string>_connection_dict</string>
...@@ -449,7 +449,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin): ...@@ -449,7 +449,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
</tuple> </tuple>
<dictionary id='i30'> <dictionary id='i30'>
<string>_access_status</string> <string>_access_status</string>
<string>%(access_status)s</string> <string>#error no data found for %(partition_1_instance_guid)s</string>
<string>_computer_id</string> <string>_computer_id</string>
<string>%(compute_node_id)s</string> <string>%(compute_node_id)s</string>
<string>_connection_dict</string> <string>_connection_dict</string>
...@@ -642,6 +642,8 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin): ...@@ -642,6 +642,8 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -690,6 +692,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin): ...@@ -690,6 +692,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -743,6 +749,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin): ...@@ -743,6 +749,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -830,6 +840,8 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin): ...@@ -830,6 +840,8 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -898,6 +910,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin): ...@@ -898,6 +910,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -943,6 +959,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin): ...@@ -943,6 +959,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -988,6 +1008,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin): ...@@ -988,6 +1008,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -1290,7 +1314,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin): ...@@ -1290,7 +1314,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
slave_1_software_type=self.start_requested_slave_instance.getSourceReference(), slave_1_software_type=self.start_requested_slave_instance.getSourceReference(),
slave_1_instance_guid=self.start_requested_slave_instance.getReference(), slave_1_instance_guid=self.start_requested_slave_instance.getReference(),
slave_1_title=self.start_requested_slave_instance.getTitle(), slave_1_title=self.start_requested_slave_instance.getTitle(),
access_status="#error no data found!", access_status="#error no data found for %s" % self.start_requested_software_instance.getReference(),
) )
self.assertEqual(expected_xml, got_xml, self.assertEqual(expected_xml, got_xml,
'\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))])) '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
...@@ -1325,6 +1349,8 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin): ...@@ -1325,6 +1349,8 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -1374,6 +1400,8 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin): ...@@ -1374,6 +1400,8 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -1744,6 +1772,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin): ...@@ -1744,6 +1772,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -1788,6 +1820,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin): ...@@ -1788,6 +1820,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -1834,6 +1870,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin): ...@@ -1834,6 +1870,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -1890,6 +1930,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin): ...@@ -1890,6 +1930,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -2206,6 +2250,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin): ...@@ -2206,6 +2250,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -2249,6 +2297,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin): ...@@ -2249,6 +2297,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -2493,6 +2545,8 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin): ...@@ -2493,6 +2545,8 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -2541,6 +2595,10 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin): ...@@ -2541,6 +2595,10 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -2593,6 +2651,10 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin): ...@@ -2593,6 +2651,10 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -2646,6 +2708,8 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin): ...@@ -2646,6 +2708,8 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -2697,6 +2761,8 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin): ...@@ -2697,6 +2761,8 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
...@@ -3004,6 +3070,10 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin): ...@@ -3004,6 +3070,10 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'> <dictionary id='i2'>
<string>created_at</string> <string>created_at</string>
<string>%(created_at)s</string> <string>%(created_at)s</string>
<string>no_data_since_15_minutes</string>
<int>0</int>
<string>no_data_since_5_minutes</string>
<int>0</int>
<string>since</string> <string>since</string>
<string>%(since)s</string> <string>%(since)s</string>
<string>state</string> <string>state</string>
......
portal_caches/last_stored_data_cache_factory
portal_caches/last_stored_data_cache_factory/volatile_cache_plugin
\ No newline at end of file
portal_caches/compute_node_information_cache_factory portal_caches/compute_node_information_cache_factory
portal_caches/compute_node_information_cache_factory/persistent_cache_plugin portal_caches/compute_node_information_cache_factory/persistent_cache_plugin
portal_caches/last_stored_data_cache_factory
portal_caches/last_stored_data_cache_factory/volatile_cache_plugin
portal_caches/slap_cache_factory portal_caches/slap_cache_factory
portal_caches/slap_cache_factory/persistent_cache_plugin portal_caches/slap_cache_factory/persistent_cache_plugin
web_site_module/slapos_hateoas web_site_module/slapos_hateoas
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment