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:
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 return ""
...@@ -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:
d = memcached_dict[context.getReference()]
except KeyError:
result = context.getSlapStateTitle() result = context.getSlapStateTitle()
else: else:
d = json.loads(d)
result = d['text'] result = d['text']
if result.startswith('#access '): if result.startswith('#access '):
result = result[len('#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"]:
result = 'Looking for a free partition' result = 'Looking for a free partition'
......
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,21 +17,19 @@ if document is None: ...@@ -18,21 +17,19 @@ 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 = context.getAccessStatus()
d = json.loads(d) if d.get("no_data", None) == 1:
return "No Contact Information"
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:
return "All OK, latest contact: %s " % last_contact return "All OK, latest contact: %s " % last_contact
else: else:
return "Problem, latest contact: %s" % last_contact return "Problem, latest contact: %s" % last_contact
except KeyError:
return "No Contact Information"
if aggregate_portal_type == "Software Installation": if aggregate_portal_type == "Software Installation":
compute_node_title = document.getAggregateTitle() compute_node_title = document.getAggregateTitle()
...@@ -42,9 +39,11 @@ if aggregate_portal_type == "Software Installation": ...@@ -42,9 +39,11 @@ 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) 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')) last_contact = DateTime(d.get('created_at'))
if d.get("text").startswith("building"): if d.get("text").startswith("building"):
return "The software release %s is building for mode them 12 hours on %s, started on %s" % \ 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": ...@@ -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" % \ return "The software release %s is failing to build for too long on %s, started on %s" % \
(document.getUrlString(), compute_node_title, document.getCreationDate()) (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 aggregate_portal_type == "Instance Tree":
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()
......
...@@ -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,14 +1514,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin): ...@@ -1524,14 +1514,7 @@ 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)
...@@ -1539,10 +1522,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin): ...@@ -1539,10 +1522,7 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
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 == "":
......
...@@ -24,6 +24,7 @@ from erp5.component.test.SlapOSTestCaseMixin import \ ...@@ -24,6 +24,7 @@ from erp5.component.test.SlapOSTestCaseMixin import \
SlapOSTestCaseMixinWithAbort, simulate SlapOSTestCaseMixinWithAbort, simulate
from zExceptions import Unauthorized from zExceptions import Unauthorized
from App.Common import rfc1123_date from App.Common import rfc1123_date
from Products.ERP5Type.Cache import DEFAULT_CACHE_SCOPE
from DateTime import DateTime from DateTime import DateTime
import json import json
...@@ -38,10 +39,18 @@ class TestSlapOSHalJsonStyleMixin(SlapOSTestCaseMixinWithAbort): ...@@ -38,10 +39,18 @@ class TestSlapOSHalJsonStyleMixin(SlapOSTestCaseMixinWithAbort):
maxDiff = None maxDiff = None
def afterSetUp(self): def afterSetUp(self):
SlapOSTestCaseMixinWithAbort.afterSetUp(self) SlapOSTestCaseMixinWithAbort.afterSetUp(self)
self.created_at = rfc1123_date(DateTime()) d = DateTime()
self.pinDateTime(d)
self.created_at = rfc1123_date(d)
self.changeSkin('Hal') self.changeSkin('Hal')
def _logFakeAccess(self, reference, text="#access OK", state='start_requested'):
def beforeTearDown(self):
SlapOSTestCaseMixinWithAbort.beforeTearDown(self)
self.unpinDateTime()
def _logFakeAccess(self, document, text="#access OK", state='start_requested'):
value = json.dumps({ value = json.dumps({
'user': 'SlapOS Master', 'user': 'SlapOS Master',
'created_at': '%s' % self.created_at, 'created_at': '%s' % self.created_at,
...@@ -49,8 +58,9 @@ class TestSlapOSHalJsonStyleMixin(SlapOSTestCaseMixinWithAbort): ...@@ -49,8 +58,9 @@ class TestSlapOSHalJsonStyleMixin(SlapOSTestCaseMixinWithAbort):
'since': '%s' % self.created_at, 'since': '%s' % self.created_at,
'state': state 'state': state
}) })
memcached_dict = self.portal.Base_getSlapToolMemcachedDict() cache_duration = document._getAccessStatusCacheFactory().cache_duration
memcached_dict[reference] = value document._getAccessStatusPlugin().set(document._getAccessStatusCacheKey(),
DEFAULT_CACHE_SCOPE, value, cache_duration=cache_duration)
def _makePerson(self, **kw): def _makePerson(self, **kw):
person_user = self.makePerson(**kw) person_user = self.makePerson(**kw)
...@@ -71,8 +81,8 @@ class TestSlapOSHalJsonStyleMixin(SlapOSTestCaseMixinWithAbort): ...@@ -71,8 +81,8 @@ class TestSlapOSHalJsonStyleMixin(SlapOSTestCaseMixinWithAbort):
.template_software_instance.Base_createCloneDocument(batch_mode=1) .template_software_instance.Base_createCloneDocument(batch_mode=1)
instance.edit(reference="TESTSOFTINST-%s" % instance.getId()) instance.edit(reference="TESTSOFTINST-%s" % instance.getId())
instance.validate() instance.validate()
self.changeSkin('Hal')
self.tic() self.tic()
self.changeSkin('Hal')
return instance return instance
def _makeSlaveInstance(self): def _makeSlaveInstance(self):
...@@ -80,6 +90,7 @@ class TestSlapOSHalJsonStyleMixin(SlapOSTestCaseMixinWithAbort): ...@@ -80,6 +90,7 @@ class TestSlapOSHalJsonStyleMixin(SlapOSTestCaseMixinWithAbort):
.template_slave_instance.Base_createCloneDocument(batch_mode=1) .template_slave_instance.Base_createCloneDocument(batch_mode=1)
instance.validate() instance.validate()
self.tic() self.tic()
self.changeSkin('Hal')
return instance return instance
def _makeComputeNode(self, owner=None, allocation_scope='open/public'): def _makeComputeNode(self, owner=None, allocation_scope='open/public'):
...@@ -179,7 +190,10 @@ class TestInstanceTree_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -179,7 +190,10 @@ class TestInstanceTree_getNewsDict(TestSlapOSHalJsonStyleMixin):
self.tic() self.tic()
self.changeSkin('Hal') self.changeSkin('Hal')
news_dict = instance_tree.InstanceTree_getNewsDict() news_dict = instance_tree.InstanceTree_getNewsDict()
expected_news_dict = {'instance': [{'no_data': 1, expected_news_dict = {'instance': [{'created_at': self.created_at,
'no_data': 1,
'since': self.created_at,
'state': '',
'text': '#error no data found for %s' % instance.getReference(), 'text': '#error no data found for %s' % instance.getReference(),
'user': 'SlapOS Master'}]} 'user': 'SlapOS Master'}]}
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
...@@ -208,10 +222,16 @@ class TestInstanceTree_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -208,10 +222,16 @@ class TestInstanceTree_getNewsDict(TestSlapOSHalJsonStyleMixin):
self.tic() self.tic()
self.changeSkin('Hal') self.changeSkin('Hal')
news_dict = instance_tree.InstanceTree_getNewsDict() news_dict = instance_tree.InstanceTree_getNewsDict()
expected_news_dict = {'instance': [{'no_data': 1, expected_news_dict = {'instance': [{'created_at': self.created_at,
'no_data': 1,
'since': self.created_at,
'state': '',
'text': '#error no data found for %s' % instance0.getReference(), 'text': '#error no data found for %s' % instance0.getReference(),
'user': 'SlapOS Master'}, 'user': 'SlapOS Master'},
{'no_data': 1, {'created_at': self.created_at,
'no_data': 1,
'since': self.created_at,
'state': '',
'text': '#error no data found for %s' % instance.getReference(), 'text': '#error no data found for %s' % instance.getReference(),
'user': 'SlapOS Master'}]} 'user': 'SlapOS Master'}]}
self.assertEqual(news_dict["instance"], expected_news_dict["instance"]) self.assertEqual(news_dict["instance"], expected_news_dict["instance"])
...@@ -222,15 +242,15 @@ class TestSoftwareInstance_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -222,15 +242,15 @@ class TestSoftwareInstance_getNewsDict(TestSlapOSHalJsonStyleMixin):
def test(self): def test(self):
instance = self._makeInstance() instance = self._makeInstance()
self._logFakeAccess(instance.getReference()) self._logFakeAccess(instance)
news_dict = instance.SoftwareInstance_getNewsDict() news_dict = instance.SoftwareInstance_getNewsDict()
expected_news_dict = {u'created_at': self.created_at, expected_news_dict = {'created_at': self.created_at,
'no_data_since_15_minutes': 0, 'no_data_since_15_minutes': 0,
'no_data_since_5_minutes': 0, 'no_data_since_5_minutes': 0,
'since': self.created_at, 'since': self.created_at,
'state': 'start_requested', 'state': 'start_requested',
'text': u'#access OK', 'text': '#access OK',
u'user': u'SlapOS Master'} 'user': 'SlapOS Master'}
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
# Ensure it don't raise error when converting to JSON # Ensure it don't raise error when converting to JSON
json.dumps(news_dict) json.dumps(news_dict)
...@@ -238,8 +258,13 @@ class TestSoftwareInstance_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -238,8 +258,13 @@ class TestSoftwareInstance_getNewsDict(TestSlapOSHalJsonStyleMixin):
def test_no_data(self): def test_no_data(self):
instance = self._makeInstance() instance = self._makeInstance()
self.changeSkin('Hal')
news_dict = instance.SoftwareInstance_getNewsDict() news_dict = instance.SoftwareInstance_getNewsDict()
expected_news_dict = {'no_data': 1, expected_news_dict = {'created_at': self.created_at,
'no_data': 1,
'since': self.created_at,
'state': '',
'text': '#error no data found for %s' % instance.getReference(), 'text': '#error no data found for %s' % instance.getReference(),
'user': 'SlapOS Master'} 'user': 'SlapOS Master'}
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
...@@ -286,51 +311,51 @@ class TestSoftwareInstallation_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -286,51 +311,51 @@ class TestSoftwareInstallation_getNewsDict(TestSlapOSHalJsonStyleMixin):
def test(self): def test(self):
installation = self._makeSoftwareInstallation() installation = self._makeSoftwareInstallation()
self._logFakeAccess(installation.getReference()) self._logFakeAccess(installation)
news_dict = installation.SoftwareInstallation_getNewsDict() news_dict = installation.SoftwareInstallation_getNewsDict()
expected_news_dict = {u'created_at': self.created_at, expected_news_dict = {'created_at': self.created_at,
'no_data_since_15_minutes': 0, 'no_data_since_15_minutes': 0,
'no_data_since_5_minutes': 0, 'no_data_since_5_minutes': 0,
'since': self.created_at, 'since': self.created_at,
'state': 'start_requested', 'state': 'start_requested',
'text': u'#access OK', 'text': '#access OK',
u'user': u'SlapOS Master'} 'user': 'SlapOS Master'}
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
# Ensure it don't raise error when converting to JSON # Ensure it don't raise error when converting to JSON
json.dumps(news_dict) json.dumps(news_dict)
def test_stopped(self): def test_stopped(self):
installation = self._makeSoftwareInstallation() installation = self._makeSoftwareInstallation()
self._logFakeAccess(installation.getReference(), self._logFakeAccess(installation,
state='stop_requested') state='stop_requested')
news_dict = installation.SoftwareInstallation_getNewsDict() news_dict = installation.SoftwareInstallation_getNewsDict()
installation.getSlapState = fakeStopRequestedSlapState installation.getSlapState = fakeStopRequestedSlapState
expected_news_dict = {u'created_at': self.created_at, expected_news_dict = {'created_at': self.created_at,
'no_data_since_15_minutes': 0, 'no_data_since_15_minutes': 0,
'no_data_since_5_minutes': 0, 'no_data_since_5_minutes': 0,
'since': self.created_at, 'since': self.created_at,
'state': 'stop_requested', 'state': 'stop_requested',
'text': u'#access OK', 'text': '#access OK',
u'user': u'SlapOS Master'} 'user': 'SlapOS Master'}
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
# Ensure it don't raise error when converting to JSON # Ensure it don't raise error when converting to JSON
json.dumps(news_dict) json.dumps(news_dict)
def test_destroyed(self): def test_destroyed(self):
installation = self._makeSoftwareInstallation() installation = self._makeSoftwareInstallation()
self._logFakeAccess(installation.getReference(), self._logFakeAccess(installation,
state='destroy_requested') state='destroy_requested')
news_dict = installation.SoftwareInstallation_getNewsDict() news_dict = installation.SoftwareInstallation_getNewsDict()
installation.getSlapState = fakeDestroyRequestedSlapState installation.getSlapState = fakeDestroyRequestedSlapState
expected_news_dict = {u'created_at': self.created_at, expected_news_dict = {'created_at': self.created_at,
'no_data_since_15_minutes': 0, 'no_data_since_15_minutes': 0,
'no_data_since_5_minutes': 0, 'no_data_since_5_minutes': 0,
'since': self.created_at, 'since': self.created_at,
'state': 'destroy_requested', 'state': 'destroy_requested',
'text': u'#access OK', 'text': '#access OK',
u'user': u'SlapOS Master'} 'user': 'SlapOS Master'}
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
# Ensure it don't raise error when converting to JSON # Ensure it don't raise error when converting to JSON
json.dumps(news_dict) json.dumps(news_dict)
...@@ -338,7 +363,10 @@ class TestSoftwareInstallation_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -338,7 +363,10 @@ class TestSoftwareInstallation_getNewsDict(TestSlapOSHalJsonStyleMixin):
def test_no_data(self): def test_no_data(self):
installation = self._makeSoftwareInstallation() installation = self._makeSoftwareInstallation()
news_dict = installation.SoftwareInstallation_getNewsDict() news_dict = installation.SoftwareInstallation_getNewsDict()
expected_news_dict = {'no_data': 1, expected_news_dict = {'created_at': self.created_at,
'no_data': 1,
'since': self.created_at,
'state': '',
'text': '#error no data found for %s' % installation.getReference(), 'text': '#error no data found for %s' % installation.getReference(),
'user': 'SlapOS Master'} 'user': 'SlapOS Master'}
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
...@@ -349,16 +377,16 @@ class TestComputeNode_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -349,16 +377,16 @@ class TestComputeNode_getNewsDict(TestSlapOSHalJsonStyleMixin):
def test(self): def test(self):
compute_node = self._makeComputeNode() compute_node = self._makeComputeNode()
self._logFakeAccess(compute_node.getReference()) self._logFakeAccess(compute_node)
news_dict = compute_node.ComputeNode_getNewsDict() news_dict = compute_node.ComputeNode_getNewsDict()
expected_news_dict = {'compute_node': expected_news_dict = {'compute_node':
{u'created_at': self.created_at, {'created_at': self.created_at,
'no_data_since_15_minutes': 0, 'no_data_since_15_minutes': 0,
'no_data_since_5_minutes': 0, 'no_data_since_5_minutes': 0,
'since': self.created_at, 'since': self.created_at,
'state': 'start_requested', 'state': 'start_requested',
'text': u'#access OK', 'text': '#access OK',
u'user': u'SlapOS Master'}, 'user': 'SlapOS Master'},
'partition': {} 'partition': {}
} }
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
...@@ -367,7 +395,7 @@ class TestComputeNode_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -367,7 +395,7 @@ class TestComputeNode_getNewsDict(TestSlapOSHalJsonStyleMixin):
def test_stopped(self): def test_stopped(self):
compute_node = self._makeComputeNode() compute_node = self._makeComputeNode()
self._logFakeAccess(compute_node.getReference(), self._logFakeAccess(compute_node,
state='stop_requested') state='stop_requested')
news_dict = compute_node.ComputeNode_getNewsDict() news_dict = compute_node.ComputeNode_getNewsDict()
compute_node.getSlapState = fakeStopRequestedSlapState compute_node.getSlapState = fakeStopRequestedSlapState
...@@ -388,7 +416,7 @@ class TestComputeNode_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -388,7 +416,7 @@ class TestComputeNode_getNewsDict(TestSlapOSHalJsonStyleMixin):
def test_destroyed(self): def test_destroyed(self):
compute_node = self._makeComputeNode() compute_node = self._makeComputeNode()
self._logFakeAccess(compute_node.getReference(), self._logFakeAccess(compute_node,
state='destroy_requested') state='destroy_requested')
news_dict = compute_node.ComputeNode_getNewsDict() news_dict = compute_node.ComputeNode_getNewsDict()
compute_node.getSlapState = fakeDestroyRequestedSlapState compute_node.getSlapState = fakeDestroyRequestedSlapState
...@@ -399,8 +427,8 @@ class TestComputeNode_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -399,8 +427,8 @@ class TestComputeNode_getNewsDict(TestSlapOSHalJsonStyleMixin):
'no_data_since_5_minutes': 0, 'no_data_since_5_minutes': 0,
'since': self.created_at, 'since': self.created_at,
'state': 'destroy_requested', 'state': 'destroy_requested',
'text': u'#access OK', 'text': '#access OK',
'user': u'SlapOS Master'}, 'user': 'SlapOS Master'},
'partition': {} 'partition': {}
} }
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
...@@ -411,7 +439,10 @@ class TestComputeNode_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -411,7 +439,10 @@ class TestComputeNode_getNewsDict(TestSlapOSHalJsonStyleMixin):
compute_node = self._makeComputeNode() compute_node = self._makeComputeNode()
news_dict = compute_node.ComputeNode_getNewsDict() news_dict = compute_node.ComputeNode_getNewsDict()
expected_news_dict = {'compute_node': expected_news_dict = {'compute_node':
{'no_data': 1, {'created_at': self.created_at,
'no_data': 1,
'since': self.created_at,
'state': '',
'text': '#error no data found for %s' % compute_node.getReference(), 'text': '#error no data found for %s' % compute_node.getReference(),
'user': 'SlapOS Master'}, 'user': 'SlapOS Master'},
'partition': {} 'partition': {}
...@@ -426,17 +457,20 @@ class TestComputeNode_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -426,17 +457,20 @@ class TestComputeNode_getNewsDict(TestSlapOSHalJsonStyleMixin):
instance.setAggregateValue(compute_node.slappart0) instance.setAggregateValue(compute_node.slappart0)
self.tic() self.tic()
self._logFakeAccess(compute_node.getReference()) self._logFakeAccess(compute_node)
news_dict = compute_node.ComputeNode_getNewsDict() news_dict = compute_node.ComputeNode_getNewsDict()
expected_news_dict = {'compute_node': expected_news_dict = {'compute_node':
{'created_at': self.created_at, {u'created_at': u'%s' % self.created_at,
'no_data_since_15_minutes': 0, 'no_data_since_15_minutes': 0,
'no_data_since_5_minutes': 0, 'no_data_since_5_minutes': 0,
u'since': u'%s' % self.created_at,
u'state': u'start_requested',
u'text': u'#access OK',
u'user': u'SlapOS Master'},
'partition': {'slappart0': {'created_at': self.created_at,
'no_data': 1,
'since': self.created_at, 'since': self.created_at,
'state': 'start_requested', 'state': '',
'text': '#access OK',
'user': 'SlapOS Master'},
'partition': {'slappart0': {'no_data': 1,
'text': '#error no data found for %s' % (instance.getReference()), 'text': '#error no data found for %s' % (instance.getReference()),
'user': 'SlapOS Master'}} 'user': 'SlapOS Master'}}
} }
...@@ -454,34 +488,36 @@ class TestComputerNetwork_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -454,34 +488,36 @@ class TestComputerNetwork_getNewsDict(TestSlapOSHalJsonStyleMixin):
compute_node.setSubordinationValue(network) compute_node.setSubordinationValue(network)
self.tic() self.tic()
self._logFakeAccess(compute_node.getReference()) self._logFakeAccess(compute_node)
news_dict = network.ComputerNetwork_getNewsDict() news_dict = network.ComputerNetwork_getNewsDict()
expected_news_dict = {'compute_node': expected_news_dict = {'compute_node':
{ compute_node.getReference(): { compute_node.getReference():
{'created_at': self.created_at, {u'created_at': u'%s' % self.created_at,
'no_data_since_15_minutes': 0, 'no_data_since_15_minutes': 0,
'no_data_since_5_minutes': 0, 'no_data_since_5_minutes': 0,
'since': self.created_at, u'since': u'%s' % self.created_at,
'state': 'start_requested', u'state': u'start_requested',
'text': '#access OK', u'text': u'#access OK',
'user': 'SlapOS Master'} u'user': u'SlapOS Master'}},
},
'partition': 'partition':
{ compute_node.getReference(): { compute_node.getReference():
{'slappart0': {'no_data': 1, {'slappart0': {'created_at': self.created_at,
'no_data': 1,
'since': self.created_at,
'state': '',
'text': '#error no data found for %s' % (instance.getReference()), 'text': '#error no data found for %s' % (instance.getReference()),
'user': 'SlapOS Master'} 'user': 'SlapOS Master'}
} }
} }
} }
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
# Ensure it don't raise error when converting to JSON # Ensure it don't raise error when converting to JSON
json.dumps(news_dict) json.dumps(news_dict)
def test_no_data(self): def test_no_data(self):
network = self._makeComputerNetwork() network = self._makeComputerNetwork()
self._logFakeAccess(network.getReference())
news_dict = network.ComputerNetwork_getNewsDict() news_dict = network.ComputerNetwork_getNewsDict()
expected_news_dict = {'compute_node': {}, 'partition': {}} expected_news_dict = {'compute_node': {}, 'partition': {}}
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
...@@ -500,27 +536,30 @@ class TestOrganisation_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -500,27 +536,30 @@ class TestOrganisation_getNewsDict(TestSlapOSHalJsonStyleMixin):
organisation.fake_compute_node_list = [compute_node] organisation.fake_compute_node_list = [compute_node]
self.tic() self.tic()
self._logFakeAccess(compute_node.getReference()) self._logFakeAccess(compute_node)
news_dict = organisation.Organisation_getNewsDict() news_dict = organisation.Organisation_getNewsDict()
expected_news_dict = {'compute_node': expected_news_dict = {'compute_node':
{ compute_node.getReference(): { compute_node.getReference():
{'created_at': self.created_at, {u'created_at': u'%s' % self.created_at,
'no_data_since_15_minutes': 0, 'no_data_since_15_minutes': 0,
'no_data_since_5_minutes': 0, 'no_data_since_5_minutes': 0,
'since': self.created_at, u'since': u'%s' % self.created_at,
'state': 'start_requested', u'state': u'start_requested',
'text': '#access OK', u'text': u'#access OK',
'user': 'SlapOS Master'} u'user': u'SlapOS Master'}},
},
'partition': 'partition':
{ compute_node.getReference(): { compute_node.getReference():
{'slappart0': {'no_data': 1, {'slappart0': {'created_at': self.created_at,
'no_data': 1,
'since': self.created_at,
'state': '',
'text': '#error no data found for %s' % (instance.getReference()), 'text': '#error no data found for %s' % (instance.getReference()),
'user': 'SlapOS Master'} 'user': 'SlapOS Master'}
} }
} }
} }
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
# Ensure it don't raise error when converting to JSON # Ensure it don't raise error when converting to JSON
json.dumps(news_dict) json.dumps(news_dict)
...@@ -545,27 +584,30 @@ class TestProject_getNewsDict(TestSlapOSHalJsonStyleMixin): ...@@ -545,27 +584,30 @@ class TestProject_getNewsDict(TestSlapOSHalJsonStyleMixin):
project.fake_compute_node_list = [compute_node] project.fake_compute_node_list = [compute_node]
self.tic() self.tic()
self._logFakeAccess(compute_node.getReference()) self._logFakeAccess(compute_node)
news_dict = project.Project_getNewsDict() news_dict = project.Project_getNewsDict()
expected_news_dict = {'compute_node': expected_news_dict = {'compute_node':
{ compute_node.getReference(): { compute_node.getReference():
{'created_at': self.created_at, {u'created_at': u'%s' % self.created_at,
'no_data_since_15_minutes': 0, 'no_data_since_15_minutes': 0,
'no_data_since_5_minutes': 0, 'no_data_since_5_minutes': 0,
'since': self.created_at, u'since': u'%s' % self.created_at,
'state': 'start_requested', u'state': u'start_requested',
'text': '#access OK', u'text': u'#access OK',
'user': 'SlapOS Master'} u'user': u'SlapOS Master'}},
},
'partition': 'partition':
{ compute_node.getReference(): { compute_node.getReference():
{'slappart0': {'no_data': 1, {'slappart0': {'created_at': self.created_at,
'no_data': 1,
'since': self.created_at,
'state': '',
'text': '#error no data found for %s' % (instance.getReference()), 'text': '#error no data found for %s' % (instance.getReference()),
'user': 'SlapOS Master'} 'user': 'SlapOS Master'}
} }
} }
} }
self.assertEqual(news_dict, expected_news_dict) self.assertEqual(news_dict, expected_news_dict)
# Ensure it don't raise error when converting to JSON # Ensure it don't raise error when converting to JSON
json.dumps(news_dict) json.dumps(news_dict)
...@@ -1158,11 +1200,3 @@ class TestInstanceTree_edit(TestSlapOSHalJsonStyleMixin): ...@@ -1158,11 +1200,3 @@ class TestInstanceTree_edit(TestSlapOSHalJsonStyleMixin):
self.assertEqual(new_parameter, self.assertEqual(new_parameter,
self.instance_tree.getTextContent()) self.instance_tree.getTextContent())
\ No newline at end of file
...@@ -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>
......
...@@ -79,7 +79,6 @@ except ImportError: ...@@ -79,7 +79,6 @@ except ImportError:
from zLOG import LOG, INFO from zLOG import LOG, INFO
import StringIO import StringIO
import pkg_resources import pkg_resources
import json
from DateTime import DateTime from DateTime import DateTime
from App.Common import rfc1123_date from App.Common import rfc1123_date
class SoftwareInstanceNotReady(Exception): class SoftwareInstanceNotReady(Exception):
...@@ -119,6 +118,25 @@ def convertToREST(function): ...@@ -119,6 +118,25 @@ def convertToREST(function):
wrapper.__doc__ = function.__doc__ wrapper.__doc__ = function.__doc__
return wrapper return wrapper
def convertToStatus(function):
def wrapper(self, *args, **kwd):
data_dict = function(self, *args, **kwd)
last_modified = rfc1123_date(DateTime())
# Keep in cache server for 7 days
self.REQUEST.response.setStatus(200)
self.REQUEST.response.setHeader('Cache-Control',
'public, max-age=60, stale-if-error=604800')
self.REQUEST.response.setHeader('Vary',
'REMOTE_USER')
self.REQUEST.response.setHeader('Last-Modified', last_modified)
self.REQUEST.response.setHeader('Content-Type', 'text/xml; charset=utf-8')
self.REQUEST.response.setBody(dumps(data_dict))
return self.REQUEST.response
return wrapper
def _assertACI(document): def _assertACI(document):
sm = getSecurityManager() sm = getSecurityManager()
if sm.checkPermission(access_contents_information, if sm.checkPermission(access_contents_information,
...@@ -216,25 +234,6 @@ class SlapTool(BaseTool): ...@@ -216,25 +234,6 @@ class SlapTool(BaseTool):
# called on site # called on site
pass pass
def _storeLastData(self, key, value):
cache_plugin = self.getPortalObject().portal_caches\
.getRamCacheRoot().get('last_stored_data_cache_factory')\
.getCachePluginList()[0]
cache_plugin.set(key, DEFAULT_CACHE_SCOPE, value,
cache_duration=self.getPortalObject().portal_caches\
.getRamCacheRoot().get('last_stored_data_cache_factory').cache_duration)
def _getLastData(self, key):
cache_plugin = self.getPortalObject().portal_caches\
.getRamCacheRoot().get('last_stored_data_cache_factory')\
.getCachePluginList()[0]
try:
entry = cache_plugin.get(key, DEFAULT_CACHE_SCOPE)
except KeyError:
entry = None
else:
entry = entry.getValue()
return entry
def _activateFillComputeNodeInformationCache(self, compute_node_id, user): def _activateFillComputeNodeInformationCache(self, compute_node_id, user):
tag = 'compute_node_information_cache_fill_%s_%s' % (compute_node_id, user) tag = 'compute_node_information_cache_fill_%s_%s' % (compute_node_id, user)
...@@ -380,7 +379,8 @@ class SlapTool(BaseTool): ...@@ -380,7 +379,8 @@ class SlapTool(BaseTool):
""" """
user = self.getPortalObject().portal_membership.getAuthenticatedMember().getUserName() user = self.getPortalObject().portal_membership.getAuthenticatedMember().getUserName()
if str(user) == computer_id: if str(user) == computer_id:
self._logAccess(user, user, '#access %s' % computer_id) compute_node = self.getPortalObject().portal_membership.getAuthenticatedMember().getUserValue()
compute_node.setAccessStatus('#access %s' % computer_id)
refresh_etag = self._calculateRefreshEtag() refresh_etag = self._calculateRefreshEtag()
body, etag = self._getComputeNodeInformation(computer_id, user, refresh_etag) body, etag = self._getComputeNodeInformation(computer_id, user, refresh_etag)
...@@ -448,6 +448,7 @@ class SlapTool(BaseTool): ...@@ -448,6 +448,7 @@ class SlapTool(BaseTool):
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getComputerPartitionStatus') 'getComputerPartitionStatus')
@convertToStatus
def getComputerPartitionStatus(self, computer_id, computer_partition_id): def getComputerPartitionStatus(self, computer_id, computer_partition_id):
""" """
Get the connection status of the partition Get the connection status of the partition
...@@ -459,10 +460,11 @@ class SlapTool(BaseTool): ...@@ -459,10 +460,11 @@ class SlapTool(BaseTool):
except NotFound: except NotFound:
return self._getAccessStatus(None) return self._getAccessStatus(None)
else: else:
return self._getAccessStatus(instance.getReference()) return instance.getAccessStatus()
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getComputerStatus') 'getComputerStatus')
@convertToStatus
def getComputerStatus(self, computer_id): def getComputerStatus(self, computer_id):
""" """
Get the connection status of the partition Get the connection status of the partition
...@@ -472,10 +474,11 @@ class SlapTool(BaseTool): ...@@ -472,10 +474,11 @@ class SlapTool(BaseTool):
validation_state="validated")[0].getObject() validation_state="validated")[0].getObject()
# Be sure to prevent accessing information to disallowed users # Be sure to prevent accessing information to disallowed users
compute_node = _assertACI(compute_node) compute_node = _assertACI(compute_node)
return self._getAccessStatus(computer_id) return compute_node.getAccessStatus()
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getSoftwareInstallationStatus') 'getSoftwareInstallationStatus')
@convertToStatus
def getSoftwareInstallationStatus(self, url, computer_id): def getSoftwareInstallationStatus(self, url, computer_id):
""" """
Get the connection status of the software installation Get the connection status of the software installation
...@@ -492,7 +495,7 @@ class SlapTool(BaseTool): ...@@ -492,7 +495,7 @@ class SlapTool(BaseTool):
except NotFound: except NotFound:
return self._getAccessStatus(None) return self._getAccessStatus(None)
else: else:
return self._getAccessStatus(software_installation.getReference()) return software_installation.getAccessStatus()
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getSoftwareReleaseListFromSoftwareProduct') 'getSoftwareReleaseListFromSoftwareProduct')
...@@ -771,11 +774,9 @@ class SlapTool(BaseTool): ...@@ -771,11 +774,9 @@ class SlapTool(BaseTool):
""" """
Fire up bung on Compute Node Fire up bung on Compute Node
""" """
user = self.getPortalObject().portal_membership.getAuthenticatedMember()\ compute_node = self._getComputeNodeDocument(compute_node_id)
.getUserName() compute_node.setAccessStatus('#error bang')
self._logAccess(user, compute_node_id, '#error bang') return compute_node.reportComputeNodeBang(comment=message)
return self._getComputeNodeDocument(compute_node_id).reportComputeNodeBang(
comment=message)
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'computerBang') 'computerBang')
...@@ -925,34 +926,6 @@ class SlapTool(BaseTool): ...@@ -925,34 +926,6 @@ class SlapTool(BaseTool):
# Internal methods # Internal methods
#################################################### ####################################################
def _logAccess(self, user_reference, context_reference, text, state=""):
memcached_dict = self.Base_getSlapToolMemcachedDict()
previous = self._getCachedAccessInfo(context_reference)
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
})
memcached_dict[context_reference] = value
return status_changed
def _validateXML(self, to_be_validated, xsd_model): def _validateXML(self, to_be_validated, xsd_model):
"""Will validate the xml file""" """Will validate the xml file"""
#We parse the XSD model #We parse the XSD model
...@@ -1015,8 +988,7 @@ class SlapTool(BaseTool): ...@@ -1015,8 +988,7 @@ class SlapTool(BaseTool):
slap_partition._requested_state = 'stopped' slap_partition._requested_state = 'stopped'
if state == "start_requested": if state == "start_requested":
slap_partition._requested_state = 'started' slap_partition._requested_state = 'started'
slap_partition._access_status = self._getTextAccessStatus( slap_partition._access_status = software_instance.getTextAccessStatus()
software_instance.getReference())
slap_partition._software_release_document = SoftwareRelease( slap_partition._software_release_document = SoftwareRelease(
software_release=software_instance.getUrlString().decode("UTF-8"), software_release=software_instance.getUrlString().decode("UTF-8"),
...@@ -1061,11 +1033,9 @@ class SlapTool(BaseTool): ...@@ -1061,11 +1033,9 @@ class SlapTool(BaseTool):
Log the software release status Log the software release status
""" """
compute_node_document = self._getComputeNodeDocument(compute_node_id) compute_node_document = self._getComputeNodeDocument(compute_node_id)
software_installation_reference = self._getSoftwareInstallationReference(url, software_installation = self._getSoftwareInstallationForComputeNode(url,
compute_node_document) compute_node_document)
user = self.getPortalObject().portal_membership.\ software_installation.setAccessStatus(
getAuthenticatedMember().getUserName()
self._logAccess(user, software_installation_reference,
'#building software release %s' % url, "building") '#building software release %s' % url, "building")
@convertToREST @convertToREST
...@@ -1074,11 +1044,9 @@ class SlapTool(BaseTool): ...@@ -1074,11 +1044,9 @@ class SlapTool(BaseTool):
Log the software release status Log the software release status
""" """
compute_node_document = self._getComputeNodeDocument(compute_node_id) compute_node_document = self._getComputeNodeDocument(compute_node_id)
software_installation_reference = self._getSoftwareInstallationReference(url, software_installation = self._getSoftwareInstallationForComputeNode(url,
compute_node_document) compute_node_document)
user = self.getPortalObject().portal_membership.\ software_installation.setAccessStatus(
getAuthenticatedMember().getUserName()
self._logAccess(user, software_installation_reference,
'#access software release %s available' % url, "available") '#access software release %s available' % url, "available")
@convertToREST @convertToREST
...@@ -1108,9 +1076,8 @@ class SlapTool(BaseTool): ...@@ -1108,9 +1076,8 @@ class SlapTool(BaseTool):
instance = self._getSoftwareInstanceForComputePartition( instance = self._getSoftwareInstanceForComputePartition(
compute_node_id, compute_node_id,
compute_partition_id) compute_partition_id)
user = self.getPortalObject().portal_membership.getAuthenticatedMember()\
.getUserName() status_changed = instance.setAccessStatus(
status_changed = self._logAccess(user, instance.getReference(),
'#error while instanciating: %s' % error_log[-80:]) '#error while instanciating: %s' % error_log[-80:])
if status_changed: if status_changed:
...@@ -1126,7 +1093,7 @@ class SlapTool(BaseTool): ...@@ -1126,7 +1093,7 @@ class SlapTool(BaseTool):
for name in [software_instance.getTitle(), new_name]: for name in [software_instance.getTitle(), new_name]:
# reset request cache # reset request cache
key = '_'.join([hosting, name]) key = '_'.join([hosting, name])
self._storeLastData(key, {}) software_instance.setLastData({}, key=key)
return software_instance.rename(new_name=new_name, return software_instance.rename(new_name=new_name,
comment="Rename %s into %s" % (software_instance.title, new_name)) comment="Rename %s into %s" % (software_instance.title, new_name))
...@@ -1140,79 +1107,19 @@ class SlapTool(BaseTool): ...@@ -1140,79 +1107,19 @@ class SlapTool(BaseTool):
software_instance = self._getSoftwareInstanceForComputePartition( software_instance = self._getSoftwareInstanceForComputePartition(
compute_node_id, compute_node_id,
compute_partition_id) compute_partition_id)
user = self.getPortalObject().portal_membership.\
getAuthenticatedMember().getUserName() software_instance.setAccessStatus('#error bang called')
self._logAccess(user, software_instance.getReference(),
'#error bang called')
timestamp = str(int(software_instance.getModificationDate())) timestamp = str(int(software_instance.getModificationDate()))
key = "%s_bangstamp" % software_instance.getReference() key = "%s_bangstamp" % software_instance.getReference()
self.getPortalObject().portal_workflow.getInfoFor( self.getPortalObject().portal_workflow.getInfoFor(
software_instance, 'action', wf_id='instance_slap_interface_workflow') software_instance, 'action', wf_id='instance_slap_interface_workflow')
if (self._getLastData(key) != timestamp): if (software_instance.getLastData(key) != timestamp):
software_instance.bang(bang_tree=True, comment=message) software_instance.bang(bang_tree=True, comment=message)
self._storeLastData(key, str(int(software_instance.getModificationDate()))) software_instance.setLastData(key, str(int(software_instance.getModificationDate())))
return "OK" return "OK"
def _getCachedAccessInfo(self, context_reference):
memcached_dict = self.Base_getSlapToolMemcachedDict()
try:
if context_reference is None:
raise KeyError
else:
data = memcached_dict[context_reference]
except KeyError:
return None
return data
def _getTextAccessStatus(self, context_reference):
status_string = self._getCachedAccessInfo(context_reference)
access_status = "#error no data found!"
if status_string is not None:
try:
access_status = json.loads(status_string)['text']
except ValueError:
pass
return access_status
def _getAccessStatus(self, context_reference):
d = self._getCachedAccessInfo(context_reference)
last_modified = rfc1123_date(DateTime())
if d is None:
if context_reference is None:
d = {
"user": "SlapOS Master",
'created_at': '%s' % last_modified,
'since': '%s' % last_modified,
'state': "",
"text": "#error no data found"
}
else:
d = {
"user": "SlapOS Master",
'created_at': '%s' % last_modified,
'since': '%s' % last_modified,
'state': "",
"text": "#error no data found for %s" % context_reference
}
# Prepare for xml marshalling
d["user"] = d["user"].decode("UTF-8")
d["text"] = d["text"].decode("UTF-8")
else:
d = json.loads(d)
# Keep in cache server for 7 days
self.REQUEST.response.setStatus(200)
self.REQUEST.response.setHeader('Cache-Control',
'public, max-age=60, stale-if-error=604800')
self.REQUEST.response.setHeader('Vary',
'REMOTE_USER')
self.REQUEST.response.setHeader('Last-Modified', last_modified)
self.REQUEST.response.setHeader('Content-Type', 'text/xml; charset=utf-8')
self.REQUEST.response.setBody(dumps(d))
return self.REQUEST.response
@convertToREST @convertToREST
def _startedComputePartition(self, compute_node_id, compute_partition_id): def _startedComputePartition(self, compute_node_id, compute_partition_id):
""" """
...@@ -1221,10 +1128,7 @@ class SlapTool(BaseTool): ...@@ -1221,10 +1128,7 @@ class SlapTool(BaseTool):
instance = self._getSoftwareInstanceForComputePartition( instance = self._getSoftwareInstanceForComputePartition(
compute_node_id, compute_node_id,
compute_partition_id) compute_partition_id)
user = self.getPortalObject().portal_membership.getAuthenticatedMember()\ status_changed = instance.setAccessStatus('#access Instance correctly started', "started")
.getUserName()
status_changed = self._logAccess(user, instance.getReference(),
'#access Instance correctly started', "started")
if status_changed: if status_changed:
instance.reindexObject() instance.reindexObject()
...@@ -1236,10 +1140,7 @@ class SlapTool(BaseTool): ...@@ -1236,10 +1140,7 @@ class SlapTool(BaseTool):
instance = self._getSoftwareInstanceForComputePartition( instance = self._getSoftwareInstanceForComputePartition(
compute_node_id, compute_node_id,
compute_partition_id) compute_partition_id)
user = self.getPortalObject().portal_membership.getAuthenticatedMember()\ status_changed = instance.setAccessStatus('#access Instance correctly stopped', "stopped")
.getUserName()
status_changed = self._logAccess(user, instance.getReference(),
'#access Instance correctly stopped', "stopped")
if status_changed: if status_changed:
instance.reindexObject() instance.reindexObject()
...@@ -1288,12 +1189,11 @@ class SlapTool(BaseTool): ...@@ -1288,12 +1189,11 @@ class SlapTool(BaseTool):
compute_partition_id, compute_partition_id,
slave_reference) slave_reference)
connection_xml = dict2xml(loads(connection_xml)) connection_xml = dict2xml(loads(connection_xml))
reference = software_instance.getReference() if software_instance.getLastData() != connection_xml:
if self._getLastData(reference) != connection_xml:
software_instance.updateConnection( software_instance.updateConnection(
connection_xml=connection_xml, connection_xml=connection_xml,
) )
self._storeLastData(reference, connection_xml) software_instance.setLastData(connection_xml)
@convertToREST @convertToREST
def _requestComputePartition(self, compute_node_id, compute_partition_id, def _requestComputePartition(self, compute_node_id, compute_partition_id,
...@@ -1368,7 +1268,7 @@ class SlapTool(BaseTool): ...@@ -1368,7 +1268,7 @@ class SlapTool(BaseTool):
value = dict( value = dict(
hash='_'.join([software_instance_document.getRelativeUrl(), str(kw)]), hash='_'.join([software_instance_document.getRelativeUrl(), str(kw)]),
) )
last_data = self._getLastData(key) last_data = software_instance_document.getLastData(key)
requested_software_instance = None requested_software_instance = None
if last_data is not None and isinstance(last_data, dict): if last_data is not None and isinstance(last_data, dict):
requested_software_instance = portal.restrictedTraverse( requested_software_instance = portal.restrictedTraverse(
...@@ -1381,7 +1281,7 @@ class SlapTool(BaseTool): ...@@ -1381,7 +1281,7 @@ class SlapTool(BaseTool):
if requested_software_instance is not None: if requested_software_instance is not None:
value['request_instance'] = requested_software_instance\ value['request_instance'] = requested_software_instance\
.getRelativeUrl() .getRelativeUrl()
self._storeLastData(key, value) software_instance_document.setLastData(value, key=key)
else: else:
# requested as root, so done by human # requested as root, so done by human
person = portal.portal_membership.getAuthenticatedMember().getUserValue() person = portal.portal_membership.getAuthenticatedMember().getUserValue()
...@@ -1396,7 +1296,7 @@ class SlapTool(BaseTool): ...@@ -1396,7 +1296,7 @@ class SlapTool(BaseTool):
value = dict( value = dict(
hash=str(kw) hash=str(kw)
) )
last_data = self._getLastData(key) last_data = person.getLastData(key)
if last_data is not None and isinstance(last_data, dict): if last_data is not None and isinstance(last_data, dict):
requested_software_instance = portal.restrictedTraverse( requested_software_instance = portal.restrictedTraverse(
last_data.get('request_instance'), None) last_data.get('request_instance'), None)
...@@ -1408,7 +1308,7 @@ class SlapTool(BaseTool): ...@@ -1408,7 +1308,7 @@ class SlapTool(BaseTool):
if requested_software_instance is not None: if requested_software_instance is not None:
value['request_instance'] = requested_software_instance\ value['request_instance'] = requested_software_instance\
.getRelativeUrl() .getRelativeUrl()
self._storeLastData(key, value) requested_software_instance.setLastData(value, key=key)
if requested_software_instance is None: if requested_software_instance is None:
raise SoftwareInstanceNotReady raise SoftwareInstanceNotReady
...@@ -1452,7 +1352,7 @@ class SlapTool(BaseTool): ...@@ -1452,7 +1352,7 @@ class SlapTool(BaseTool):
compute_partition_id) compute_partition_id)
cache_reference = '%s-PREDLIST' % software_instance_document.getReference() cache_reference = '%s-PREDLIST' % software_instance_document.getReference()
if self._getLastData(cache_reference) != instance_reference_xml: if software_instance_document.getLastData(cache_reference) != instance_reference_xml:
instance_reference_list = loads(instance_reference_xml) instance_reference_list = loads(instance_reference_xml)
current_successor_list = software_instance_document.getSuccessorValueList( current_successor_list = software_instance_document.getSuccessorValueList(
...@@ -1470,7 +1370,7 @@ class SlapTool(BaseTool): ...@@ -1470,7 +1370,7 @@ class SlapTool(BaseTool):
compute_node_id, compute_partition_id, successor_list), error=False) compute_node_id, compute_partition_id, successor_list), error=False)
software_instance_document.edit(successor_list=successor_list, software_instance_document.edit(successor_list=successor_list,
comment='successor_list edited to unlink non commited instances') comment='successor_list edited to unlink non commited instances')
self._storeLastData(cache_reference, instance_reference_xml) software_instance_document.setLastData(instance_reference_xml, key=cache_reference)
#################################################### ####################################################
# Internals methods # Internals methods
...@@ -1678,7 +1578,7 @@ class SlapTool(BaseTool): ...@@ -1678,7 +1578,7 @@ class SlapTool(BaseTool):
else: else:
software_release_response._requested_state = 'available' software_release_response._requested_state = 'available'
known_state = self._getTextAccessStatus(software_installation.getReference()) known_state = software_installation.getTextAccessStatus()
if known_state.startswith("#access"): if known_state.startswith("#access"):
software_release_response._known_state = 'available' software_release_response._known_state = 'available'
elif known_state.startswith("#building"): elif known_state.startswith("#building"):
...@@ -1695,11 +1595,8 @@ class SlapTool(BaseTool): ...@@ -1695,11 +1595,8 @@ class SlapTool(BaseTool):
Log the compute_node status Log the compute_node status
""" """
compute_node_document = self._getComputeNodeDocument(compute_node_id) compute_node_document = self._getComputeNodeDocument(compute_node_id)
software_installation_reference = self._getSoftwareInstallationReference(url, software_installation = self._getSoftwareInstallationForComputeNode(url,
compute_node_document) compute_node_document)
user = self.getPortalObject().portal_membership.\ software_installation.setAccessStatus('#error while installing %s' % url)
getAuthenticatedMember().getUserName()
self._logAccess(user, software_installation_reference,
'#error while installing %s' % url)
InitializeClass(SlapTool) InitializeClass(SlapTool)
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