Commit a2f0cf6b authored by Rafael Monnerat's avatar Rafael Monnerat

Create API for Memcache usage on SlapOS master

See merge request !359
parents 307e1012 c647aab4
# -*- 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 @@
<item>
<key> <string>type_mixin</string> </key>
<value>
<tuple/>
<tuple>
<string>SlapOSCacheMixin</string>
</tuple>
</value>
</item>
</dictionary>
......
......@@ -74,7 +74,9 @@
<item>
<key> <string>type_mixin</string> </key>
<value>
<tuple/>
<tuple>
<string>SlapOSCacheMixin</string>
</tuple>
</value>
</item>
</dictionary>
......
......@@ -105,7 +105,9 @@
<item>
<key> <string>type_mixin</string> </key>
<value>
<tuple/>
<tuple>
<string>SlapOSCacheMixin</string>
</tuple>
</value>
</item>
</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
portal = context.getPortalObject()
from zExceptions import Unauthorized
......@@ -22,14 +21,11 @@ comment = ''
if can_allocate:
# Check if compute_node has error reported
memcached_dict = context.Base_getSlapToolMemcachedDict()
try:
d = memcached_dict[compute_node.getReference()]
except KeyError:
log_dict = compute_node.getAccessStatus()
if log_dict.get("no_data") == 1:
can_allocate = False
comment = "Compute Node didn't contact the server"
else:
log_dict = json.loads(d)
if '#error' in log_dict.get('text', '#error'):
can_allocate = False
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 @@
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: context.ComputeNode_getLastContactDate()</string> </value>
<value> <string>python: context.getLastAccessDate()</string> </value>
</item>
</dictionary>
</pickle>
......
from DateTime import DateTime
import json
partition = context
memcached_dict = context.Base_getSlapToolMemcachedDict()
result = ""
date = None
for si in partition.getAggregateRelatedValueList(portal_type=["Software Instance", "Slave Instance"]):
for si in context.getAggregateRelatedValueList(portal_type=["Software Instance"]):
obj = si.getObject()
if obj.getValidationState() != "validated":
......@@ -15,13 +6,6 @@ for si in partition.getAggregateRelatedValueList(portal_type=["Software Instance
if obj.getSlapState() == "destroy_requested":
continue
try:
d = memcached_dict[obj.getReference()]
except KeyError:
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 obj.getLastAccessDate()
return result
return ""
......@@ -134,7 +134,7 @@
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>cell/ComputeNode_getLastContactDate</string> </value>
<value> <string>cell/getLastAccessDate</string> </value>
</item>
</dictionary>
</pickle>
......
"""Dirty script to return Software Instance state"""
import json
state = context.getSlapState()
has_partition = context.getAggregate(portal_type="Compute Partition")
result = 'Unable to calculate the status...'
if has_partition:
try:
memcached_dict = context.Base_getSlapToolMemcachedDict()
try:
d = memcached_dict[context.getReference()]
except KeyError:
d = context.getAccessStatus()
if d.get("no_data") == 1:
result = context.getSlapStateTitle()
else:
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:
if state in ["start_requested", "stop_requested"]:
result = 'Looking for a free partition'
......
from DateTime import DateTime
portal = context.getPortalObject()
import json
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;'
......@@ -14,20 +13,17 @@ software_installation = portal.portal_catalog.getResultValue(
if not software_installation or software_installation.getSlapState() == "destroy_requested":
return '<span" style="%s" title="Information not available"></a>' % error_style
memcached_dict = context.Base_getSlapToolMemcachedDict()
try:
d = memcached_dict[software_installation.getReference()]
except KeyError:
d = software_installation.getAccessStatus()
if d.get("no_data") == 1:
return "<a href='%s' style='%s'></a>" % (software_installation.getRelativeUrl(),
error_style)
else:
d = json.loads(d)
result = d['text']
date = DateTime(d['created_at'])
limit_date = DateTime() - 0.084
if result.startswith('#error ') or (date - limit_date) < 0:
result = d['text']
date = DateTime(d['created_at'])
limit_date = DateTime() - 0.084
if result.startswith('#error ') or (date - limit_date) < 0:
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(),
access_style, result, d['created_at'])
......@@ -7,12 +7,10 @@
from erp5.component.test.testSlapOSCloudSecurityGroup import TestSlapOSSecurityMixin
from erp5.component.test.SlapOSTestCaseMixin import changeSkin
import json
import re
import xml_marshaller
from AccessControl.SecurityManagement import getSecurityManager, \
setSecurityManager
from DateTime import DateTime
class DefaultScenarioMixin(TestSlapOSSecurityMixin):
......@@ -103,14 +101,7 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
return []
def setAccessToMemcached(self, agent):
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
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 "}
)
agent.setAccessStatus("#access ")
def requestComputeNode(self, title):
requestXml = self.portal.portal_slap.requestComputer(title)
......
......@@ -2,12 +2,10 @@
import transaction
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin
from Products.ERP5Type.tests.utils import createZODBPythonScript
import json
import time
from zExceptions import Unauthorized
from DateTime import DateTime
from erp5.component.module.DateUtils import addToDate
from App.Common import rfc1123_date
class TestSlapOSCoreSlapOSAssertInstanceTreeSuccessorAlarm(
SlapOSTestCaseMixin):
......@@ -443,13 +441,7 @@ class TestSlapOSUpdateComputeNodeCapacityScopeAlarm(SlapOSTestCaseMixin):
)
self.compute_node.edit(capacity_scope='open')
self.compute_node.validate()
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
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())
})
self.compute_node.setAccessStatus("#access ok")
transaction.commit()
def test_ComputeNode_checkAndUpdateCapacityScope(self):
......@@ -517,14 +509,12 @@ class TestSlapOSUpdateComputeNodeCapacityScopeAlarm(SlapOSTestCaseMixin):
self.compute_node.getCapacityQuantity())
def test_ComputeNode_checkAndUpdateCapacityScope_with_old_access(self):
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
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(addToDate(DateTime(),
to_add={'minute': -11}))
})
try:
self.pinDateTime(addToDate(DateTime(),to_add={'minute': -11}))
self.compute_node.setAccessStatus("#access ok")
finally:
self.unpinDateTime()
self.compute_node.ComputeNode_checkAndUpdateCapacityScope()
self.assertEqual('close', self.compute_node.getCapacityScope())
self.assertEqual("Compute Node didn't contact for more than 10 minutes",
......@@ -552,24 +542,14 @@ class TestSlapOSUpdateComputeNodeCapacityScopeAlarm(SlapOSTestCaseMixin):
self.assertEqual('open', self.compute_node.getCapacityScope())
def test_ComputeNode_checkAndUpdateCapacityScope_with_error(self):
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
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.setAccessStatus('#error not ok')
self.compute_node.ComputeNode_checkAndUpdateCapacityScope()
self.assertEqual('close', self.compute_node.getCapacityScope())
self.assertEqual("Compute Node reported an error",
self.compute_node.workflow_history['edit_workflow'][-1]['comment'])
def test_ComputeNode_checkAndUpdateCapacityScope_with_error_non_public(self):
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
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.setAccessStatus('#error not ok')
self.compute_node.edit(allocation_scope='open/personal')
self.compute_node.ComputeNode_checkAndUpdateCapacityScope()
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_machine
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/**
computer_model_module/template_computer_model
computer_model_module/template_computer_model/**
instance_tree_module/template_instance_tree
person_module/template_member
person_module/template_member/**
......@@ -17,6 +17,10 @@ portal_alarms/slapos_garbage_collect_destroyed_root_tree
portal_alarms/slapos_garbage_collect_non_allocated_root_tree
portal_alarms/slapos_stop_collect_instance
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
software_installation_module/template_software_installation
software_instance_module/template_slave_instance
......
Compute Node | SlapOSCacheMixin
Compute Partition | SlapOSCacheMixin
Person | SlapOSCacheMixin
\ No newline at end of file
from DateTime import DateTime
import json
portal = context.getPortalObject()
from Products.ERP5Type.Document import newTempBase
......@@ -19,26 +18,11 @@ show_all = False
if "show_all" in kw:
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):
try:
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.
result = context.getAccessStatusText()
if result.startswith('#error '):
return 1
for compute_node in portal.portal_catalog(
default_allocation_scope_uid = [personal_category_uid, public_category_uid, friend_category_uid],
select_list={"reference": None},
......
from DateTime import DateTime
import json
portal = context.getPortalObject()
if portal.ERP5Site_isSupportRequestCreationClosed():
......@@ -22,7 +20,6 @@ compute_node_reference = context.getReference()
compute_node_title = context.getTitle()
should_notify = True
memcached_dict = context.Base_getSlapToolMemcachedDict()
tolerance = DateTime()-0.5
for software_installation in software_installation_list:
should_notify = False
......@@ -31,9 +28,12 @@ for software_installation in software_installation_list:
continue
reference = software_installation.getReference()
try:
d = memcached_dict[reference]
d = json.loads(d)
d = software_installation.getAccessStatus()
if d.get("no_data", None) == 1:
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'))
if d.get("text").startswith("building"):
should_notify = True
......@@ -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" % \
(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:
support_request = context.Base_generateSupportRequestForSlapOS(
ticket_title,
description,
......
from DateTime import DateTime
import json
portal = context.getPortalObject()
if portal.ERP5Site_isSupportRequestCreationClosed():
......@@ -18,50 +16,49 @@ reference = context.getReference()
compute_node_title = context.getTitle()
ticket_title = "[MONITORING] Lost contact with compute_node %s" % reference
description = ""
should_notify = True
last_contact = "No Contact Information"
memcached_dict = context.Base_getSlapToolMemcachedDict()
try:
d = memcached_dict[reference]
d = json.loads(d)
d = context.getAccessStatus()
# Ignore if data isn't present.
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'))
if (DateTime() - last_contact) > 0.01:
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)
else:
should_notify = False
except KeyError:
description = "The Compute Node %s (%s) has not contacted the server (No Contact Information)" % (
compute_node_title, reference)
# Nothing to notify.
return
if should_notify:
support_request = context.Base_generateSupportRequestForSlapOS(
support_request = context.Base_generateSupportRequestForSlapOS(
ticket_title,
description,
context.getRelativeUrl()
)
)
person = context.getSourceAdministrationValue(portal_type="Person")
if not person:
person = context.getSourceAdministrationValue(portal_type="Person")
if not person:
return support_request
# Send Notification message
notification_reference = 'slapos-crm-compute_node_check_state.notification'
notification_message = portal.portal_notifications.getDocumentValue(
# Send Notification message
notification_reference = 'slapos-crm-compute_node_check_state.notification'
notification_message = portal.portal_notifications.getDocumentValue(
reference=notification_reference)
if notification_message is None:
if notification_message is None:
message = """%s""" % description
else:
else:
mapping_dict = {'compute_node_title':context.getTitle(),
'compute_node_id':reference,
'last_contact':last_contact}
message = notification_message.asText(
substitution_method_parameter_dict={'mapping_dict':mapping_dict})
support_request.SupportRequest_trySendNotificationMessage(
support_request.SupportRequest_trySendNotificationMessage(
ticket_title,
message, person.getRelativeUrl())
return support_request
return support_request
import json
portal = context.getPortalObject()
compute_node = context
now_date = DateTime()
......@@ -7,20 +6,16 @@ if (now_date - compute_node.getCreationDate()) < maximum_days:
# This compute_node was created recently skip
return True
memcached_dict = context.Base_getSlapToolMemcachedDict()
# Check if there is some information in memcached
try:
d = memcached_dict[compute_node.getReference()]
except KeyError:
message_dict = context.getAccessStatus()
# Ignore if data isn't present.
if message_dict.get("no_data", None) == 1:
message_dict = {}
else:
message_dict = json.loads(d)
if message_dict.has_key('created_at'):
contact_date = DateTime(message_dict.get('created_at').encode('utf-8'))
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(
portal_type="Sale Packing List Line",
simulation_state="delivered",
......
from DateTime import DateTime
import json
memcached_dict = context.Base_getSlapToolMemcachedDict()
try:
d = memcached_dict[context.getReference()]
except KeyError:
# Information not available
return None
d = context.getAccessStatus()
# Ignore if data isn't present.
if d.get("no_data", None) == 1:
return
d = json.loads(d)
result = d['text']
last_contact = DateTime(d.get('created_at'))
# Optimise by checking memcache information first.
if result.startswith('#error '):
return last_contact
return None
if d['text'].startswith('#error '):
return DateTime(d.get('created_at'))
from DateTime import DateTime
import json
if context.getAggregateValue(portal_type="Compute Partition") is not None:
memcached_dict = context.Base_getSlapToolMemcachedDict()
try:
d = memcached_dict[context.getReference()]
except KeyError:
d = context.getAccessStatus()
# Ignore if data isn't present.
if d.get("no_data", None) == 1:
if include_message:
return "Not possible to connect"
return
d = json.loads(d)
result = d['text']
last_contact = DateTime(d.get('created_at'))
since = DateTime(d.get('since'))
# Optimise by checking memcache information first.
if result.startswith('#error '):
if ((DateTime()-since)*24*60) > tolerance:
if include_created_at and not include_since:
......@@ -24,7 +20,6 @@ if context.getAggregateValue(portal_type="Compute Partition") is not None:
return result, last_contact, since
return result
# XXX time limit of 48 hours for run at least once.
if include_message and include_created_at and not include_since:
return result, last_contact
elif include_message and include_created_at and include_since:
......
......@@ -6,7 +6,6 @@
#
from DateTime import DateTime
import json
if context.getSimulationState() == "invalidated":
return "Closed Ticket"
......@@ -18,21 +17,19 @@ if document is None:
aggregate_portal_type = document.getPortalType()
memcached_dict = context.Base_getSlapToolMemcachedDict()
if aggregate_portal_type == "Compute Node":
if document.getMonitorScope() == "disabled":
return "Monitor is disabled to the related %s." % document.getPortalType()
try:
d = memcached_dict[document.getReference()]
d = json.loads(d)
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
except KeyError:
return "No Contact Information"
if aggregate_portal_type == "Software Installation":
compute_node_title = document.getAggregateTitle()
......@@ -42,9 +39,11 @@ if aggregate_portal_type == "Software Installation":
if document.getSlapState() not in ["start_requested", "stop_requested"]:
return "Software Installation is Destroyed."
try:
d = memcached_dict[document.getReference()]
d = json.loads(d)
d = context.getAccessStatus()
if d.get("no_data", None) == 1:
return "The software release %s did not started to build on %s since %s" % \
(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" % \
......@@ -55,11 +54,6 @@ if aggregate_portal_type == "Software Installation":
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" % \
(document.getUrlString(), compute_node_title, document.getCreationDate())
if aggregate_portal_type == "Instance Tree":
if document.getMonitorScope() == "disabled":
return "Monitor is disabled to the related %s." % document.getPortalType()
......
......@@ -25,6 +25,9 @@ import transaction
from erp5.component.test.SlapOSTestCaseMixin import \
SlapOSTestCaseMixin,SlapOSTestCaseMixinWithAbort, simulate
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
import json
......@@ -826,13 +829,7 @@ class TestComputeNode_hasContactedRecently(SlapOSTestCaseMixinWithAbort):
@simulate('ComputeNode_getCreationDate', '*args, **kwargs','return DateTime() - 32')
def test_ComputeNode_hasContactedRecently_memcached(self):
compute_node = self._makeComputeNode()[0]
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
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")
})
compute_node.setAccessStatus("#access ")
self.tic()
compute_node.getCreationDate = self.portal.ComputeNode_getCreationDate
......@@ -843,13 +840,12 @@ class TestComputeNode_hasContactedRecently(SlapOSTestCaseMixinWithAbort):
@simulate('ComputeNode_getCreationDate', '*args, **kwargs','return DateTime() - 32')
def test_ComputeNode_hasContactedRecently_memcached_oudated_no_spl(self):
compute_node = self._makeComputeNode()[0]
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
try:
self.pinDateTime(DateTime()-32)
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()
compute_node.getCreationDate = self.portal.ComputeNode_getCreationDate
......@@ -860,13 +856,12 @@ class TestComputeNode_hasContactedRecently(SlapOSTestCaseMixinWithAbort):
@simulate('ComputeNode_getCreationDate', '*args, **kwargs','return DateTime() - 32')
def test_ComputeNode_hasContactedRecently_memcached_oudated_with_spl(self):
compute_node = self._makeComputeNode()[0]
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
try:
self.pinDateTime(DateTime()-32)
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.tic()
......@@ -1224,13 +1219,11 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
@simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
def test_ComputeNode_checkState_call_support_request(self):
compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
memcached_dict[compute_node.getReference()] = json.dumps(
{"created_at":"%s" % (DateTime() - 1.1)}
)
try:
self.pinDateTime(DateTime()-1.1)
compute_node.setAccessStatus("#access ")
finally:
self.unpinDateTime()
self._simulateBase_generateSupportRequestForSlapOS()
support_request = self._makeSupportRequest()
......@@ -1279,14 +1272,11 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
person = compute_node.getSourceAdministrationValue()
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
key_prefix='slap_tool',
plugin_path='portal_memcached/default_memcached_plugin')
memcached_dict[compute_node.getReference()] = json.dumps(
{"created_at":"%s" % (DateTime() - 0.1)}
)
try:
self.pinDateTime(DateTime()-1.1)
compute_node.setAccessStatus("#access ")
finally:
self.unpinDateTime()
self.portal.REQUEST['test_ComputeNode_checkState_notify'] = \
self._makeNotificationMessage(compute_node.getReference())
......@@ -1524,14 +1514,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
self._makeComputeNode()
self._makeComputePartitionList()
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
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 "}
)
instance.setAccessStatus("#error ")
self.assertEqual(instance.SoftwareInstance_hasReportedError(), None)
......@@ -1539,10 +1522,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
self.assertEqual(str(instance.SoftwareInstance_hasReportedError()), '#error ')
memcached_dict[instance.getReference()] = json.dumps(
{"created_at":"%s" % error_date, "text": "#access "}
)
instance.setAccessStatus("#access ")
self.assertEqual(instance.SoftwareInstance_hasReportedError(), None)
def test_SoftwareInstallation_hasReportedError(self):
......@@ -1552,22 +1532,19 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
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)
error_date = DateTime()
memcached_dict[installation.getReference()] = json.dumps(
{"created_at":"%s" % error_date, "text": "#error "}
)
self.assertEqual(installation.SoftwareInstallation_hasReportedError(), error_date)
try:
self.pinDateTime(error_date)
installation.setAccessStatus("#error ")
finally:
self.unpinDateTime()
memcached_dict[installation.getReference()] = json.dumps(
{"created_at":"%s" % error_date, "text": "#building "}
)
self.assertEqual(
rfc1123_date(installation.SoftwareInstallation_hasReportedError()),
rfc1123_date(error_date))
installation.setAccessStatus("#building ")
self.assertEqual(installation.SoftwareInstallation_hasReportedError(), None)
......@@ -1600,14 +1577,13 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
self._makeComputePartitionList()
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()
memcached_dict[instance.getReference()] = json.dumps(
value = json.dumps(
{"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(
'Visited by InstanceTree_createSupportRequestEvent %s %s' % \
......@@ -1615,9 +1591,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
"slapos-crm-instance-tree-instance-state.notification"),
instance_tree.InstanceTree_checkSoftwareInstanceState())
memcached_dict[instance.getReference()] = json.dumps(
{"created_at":"%s" % error_date, "text": "#access "}
)
instance.setAccessStatus("#access ")
self.assertEqual(None,
instance_tree.InstanceTree_checkSoftwareInstanceState())
......@@ -1720,13 +1694,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
instance.requestInstance(**kw)
self.tic()
memcached_dict = self.portal.portal_memcached.getMemcachedDict(
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 "}
)
instance.setAccessStatus("#access ")
self.assertEqual(
'Visited by InstanceTree_createSupportRequestEvent %s %s' % \
......@@ -1761,15 +1729,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
self._makeComputePartitionList()
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()
memcached_dict[instance.getReference()] = json.dumps(
{"created_at":"%s" % error_date, "text": "#error "}
)
instance.setAccessStatus("#error ")
self.assertEqual(
None,
instance_tree.InstanceTree_checkSoftwareInstanceState())
......
......@@ -3,12 +3,12 @@ if REQUEST is not None:
raise Unauthorized
def get_compute_partition_dict(reference):
compute_node_dict = context.Base_getNewsDict(context)
compute_node_dict = context.getAccessStatus()
compute_partition_dict = { }
for compute_partition in context.objectValues(portal_type="Compute Partition"):
software_instance = compute_partition.getAggregateRelatedValue(portal_type="Software Instance")
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,
"partition": compute_partition_dict}
......
......@@ -2,4 +2,4 @@ from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
return context.Base_getNewsDict(context)
return context.getAccessStatus()
......@@ -25,4 +25,4 @@ if portal_type == "Software Instance" and slap_state == "destroy_requested":
"is_destroyed": 1
}
return context.Base_getNewsDict(context)
return context.getAccessStatus()
......@@ -3,10 +3,7 @@ if REQUEST is not None:
raise Unauthorized
from DateTime import DateTime
import json
slap_state = context.getSlapState()
_translate = context.Base_translateString
NOT_ALLOCATED = _translate("Searching for partition")
......@@ -26,13 +23,10 @@ if compute_partition is not None:
if instance.getPortalType() == "Slave Instance":
instance = compute_partition.getAggregateRelatedValue(portal_type="Software Instance")
memcached_dict = instance.Base_getSlapToolMemcachedDict()
try:
d = memcached_dict[instance.getReference()]
except KeyError:
d = instance.getAccessStatus()
if d.get("no_data") == 1:
return _translate(instance.getSlapStateTitle())
d = json.loads(d)
result = d['text']
reported_state = d.get("state", "")
if reported_state == "":
......
......@@ -36,6 +36,6 @@ if len(full_software_installation_list) > 0 and \
len(full_software_installation_list) == len(set(compute_node_list)):
# Software is available for the root instance
software_installation = full_software_installation_list[0]
message = software_installation.Base_getNewsDict(software_installation)['text']
message = software_installation.getAccessStatusText()
if message.startswith("#access"):
return True
......@@ -297,7 +297,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
</tuple>
<dictionary id='i8'>
<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>%(compute_node_id)s</string>
<string>_connection_dict</string>
......@@ -373,7 +373,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
</tuple>
<dictionary id='i19'>
<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>%(compute_node_id)s</string>
<string>_connection_dict</string>
......@@ -449,7 +449,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
</tuple>
<dictionary id='i30'>
<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>%(compute_node_id)s</string>
<string>_connection_dict</string>
......@@ -642,6 +642,8 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</string>
<string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string>
<string>%(since)s</string>
<string>state</string>
......@@ -690,6 +692,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -743,6 +749,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -830,6 +840,8 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</string>
<string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string>
<string>%(since)s</string>
<string>state</string>
......@@ -898,6 +910,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -943,6 +959,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -988,6 +1008,10 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -1290,7 +1314,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
slave_1_software_type=self.start_requested_slave_instance.getSourceReference(),
slave_1_instance_guid=self.start_requested_slave_instance.getReference(),
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,
'\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
......@@ -1325,6 +1349,8 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</string>
<string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string>
<string>%(since)s</string>
<string>state</string>
......@@ -1374,6 +1400,8 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</string>
<string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string>
<string>%(since)s</string>
<string>state</string>
......@@ -1744,6 +1772,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -1788,6 +1820,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -1834,6 +1870,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -1890,6 +1930,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -2206,6 +2250,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -2249,6 +2297,10 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -2493,6 +2545,8 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</string>
<string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string>
<string>%(since)s</string>
<string>state</string>
......@@ -2541,6 +2595,10 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -2593,6 +2651,10 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</string>
<string>state</string>
......@@ -2646,6 +2708,8 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</string>
<string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string>
<string>%(since)s</string>
<string>state</string>
......@@ -2697,6 +2761,8 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</string>
<string>%(created_at)s</string>
<string>no_data</string>
<int>1</int>
<string>since</string>
<string>%(since)s</string>
<string>state</string>
......@@ -3004,6 +3070,10 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
<dictionary id='i2'>
<string>created_at</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)s</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/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/persistent_cache_plugin
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