From 14202d05b305f48d21691391260c910db546f814 Mon Sep 17 00:00:00 2001 From: Sebastien Robin <seb@nexedi.com> Date: Wed, 11 Jul 2007 17:20:09 +0000 Subject: [PATCH] allow to define wich node starts alarms on a cluster git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@15197 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5/Tool/AlarmTool.py | 81 +++++++++++++---- product/ERP5/dtml/manageAlarmNode.dtml | 117 +++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 18 deletions(-) create mode 100755 product/ERP5/dtml/manageAlarmNode.dtml diff --git a/product/ERP5/Tool/AlarmTool.py b/product/ERP5/Tool/AlarmTool.py index ac3d82658d..a0489f85d6 100644 --- a/product/ERP5/Tool/AlarmTool.py +++ b/product/ERP5/Tool/AlarmTool.py @@ -37,9 +37,15 @@ from Products.ERP5Type.Tool.BaseTool import BaseTool from Products.ERP5Type import Permissions from Products.ERP5 import _dtmldir from DateTime import DateTime +import urllib +import socket from zLOG import LOG, INFO +import re +# minimal IP:Port regexp +NODE_RE = re.compile('^\d+\.\d+\.\d+\.\d+:\d+$') + try: from Products.TimerService import getTimerService except ImportError: @@ -68,21 +74,15 @@ class AlarmTool(BaseTool): security.declareProtected( Permissions.ManagePortal, 'manage_overview' ) manage_overview = DTMLFile( 'explainAlarmTool', _dtmldir ) - security.declareProtected( Permissions.ManagePortal , 'manageAlarmList' ) - manageAlarmList = DTMLFile( 'manageAlarmList', _dtmldir ) - - security.declareProtected( Permissions.ManagePortal , 'manageAlarmAdvanced' ) - manageAlarmAdvanced = DTMLFile( 'manageAlarmAdvanced', _dtmldir ) + security.declareProtected( Permissions.ManagePortal , 'manageAlarmNode' ) + manageAlarmNode = DTMLFile( 'manageAlarmNode', _dtmldir ) manage_options = ( ( { 'label' : 'Overview' , 'action' : 'manage_overview' } - , { 'label' : 'All Alarms' - , 'action' : 'manageAlarmList' - } - , { 'label' : 'Advanced' - , 'action' : 'manageAlarmAdvanced' + , { 'label' : 'Alarm Node' + , 'action' : 'manageAlarmNode' } , ) @@ -91,6 +91,7 @@ class AlarmTool(BaseTool): _properties = ( {'id': 'interval', 'type': 'int', 'mode': 'w', }, ) interval = 60 # Default interval for alarms is 60 seconds + alarmNode = '' # API to manage alarms # Aim of this API: @@ -192,12 +193,56 @@ class AlarmTool(BaseTool): This method is called by TimerService in the interval given in zope.conf. The Default is every 5 seconds. """ - global last_tic - last_tic_lock.acquire(1) - try: - if tick.timeTime() - last_tic >= self.interval: - self.tic() - last_tic = tick.timeTime() - finally: - last_tic_lock.release() + # only start when we are the alarmNode or if it's empty + if (self.alarmNode == self.getCurrentNode()) \ + or not self.alarmNode: + global last_tic + last_tic_lock.acquire(1) + try: + if tick.timeTime() - last_tic >= self.interval: + self.tic() + last_tic = tick.timeTime() + finally: + last_tic_lock.release() + + def getCurrentNode(self): + """ Return current node in form ip:port """ + port = '' + from asyncore import socket_map + for k, v in socket_map.items(): + if hasattr(v, 'port'): + # see Zope/lib/python/App/ApplicationManager.py: def getServers(self) + type = str(getattr(v, '__class__', 'unknown')) + if type == 'ZServer.HTTPServer.zhttp_server': + port = v.port + break + ip = socket.gethostbyname(socket.gethostname()) + currentNode = '%s:%s' %(ip, port) + return currentNode + + security.declarePublic('getAlarmNode') + def getAlarmNode(self): + """ Return the alarmNode """ + return self.alarmNode + + def _isValidNodeName(self, node_name) : + """Check we have been provided a good node name""" + return isinstance(node_name, str) and NODE_RE.match(node_name) + + security.declarePublic('manage_setAlarmNode') + def manage_setAlarmNode(self, alarmNode, REQUEST=None): + """ set the alarm node """ + if not alarmNode or self._isValidNodeName(alarmNode): + self.alarmNode = alarmNode + if REQUEST is not None: + REQUEST.RESPONSE.redirect( + REQUEST.URL1 + + '/manageAlarmNode?manage_tabs_message=' + + urllib.quote("Distributing Node successfully changed.")) + else : + if REQUEST is not None: + REQUEST.RESPONSE.redirect( + REQUEST.URL1 + + '/manageAlarmNode?manage_tabs_message=' + + urllib.quote("Malformed Distributing Node.")) diff --git a/product/ERP5/dtml/manageAlarmNode.dtml b/product/ERP5/dtml/manageAlarmNode.dtml new file mode 100755 index 0000000000..3a1149f27c --- /dev/null +++ b/product/ERP5/dtml/manageAlarmNode.dtml @@ -0,0 +1,117 @@ +<dtml-comment> +Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved. + Sebastien Robin <seb@nexedi.com> + +WARNING: This program as such is intended to be used by professional +programmers who take the whole responsability of assessing all potential +consequences resulting from its eventual inadequacies and bugs + +This program as such is not intended to be used by end users. End +users who are looking for a ready-to-use solution with commercial +garantees 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. +</dtml-comment> + +<dtml-var manage_page_header> +<dtml-var manage_tabs> + +<p class="form-help"> + This tab defines the node wich starts Alarms. + To provide high performance, alarms should start a script wich only start + some activities. Like this, the activity tool will be in charge to distribute + the work on many nodes. + + The format to adress a node in this configuration is therfore + <code>IP-Address</code>:<code>Port-Number</code>. +</p> + +<p class="form-help"> + The interval of distribution and activation of the activities is per default 5 seconds. This can be + changed by altering the value of <i>interval</i> in the section <i>time-server</i> in the + Zope Configuration File <i>zope.conf</i>. +</p> + +<p class="form-help"> + The <i>Alarm node</i> is responsible for the start of Alarms. The default value is empty + which means that every existing node will try to do launch of alarms, which is fine when there + is only one ZServer running. + To change the Alarm Node, edit the value and click "Change". +</p> + +<form action="&dtml-URL1;"> + +<table cellspacing="0" cellpadding="2" border="0" width="100%"> + <tr class="list-header"> + <td align="left" valign="top" colspan=2> + <div class="form-label">Alarm Node</div> + </td> + </tr> + <tr> + <td> + <div class="form-label">IP:Port</div> + </td> + <td align="left"> + <div class="form-item"> + <input type="text" name="alarmNode" value="&dtml-getAlarmNode;" size="19" /> + </div> + </td> + </tr> + <tr> + <td> </td> + <td align="left"> + <div class="form-element"> + <input type="submit" class="form-element" name="manage_setAlarmNode:method" value=" Change "> + </div> + </td> + </tr> + <tr> + <td> </td> + <td> </td> + </tr> + <tr> + <td align="left" colspan=2> + <p class="form-help"> + Subscribe/Unsubscribe from Timer Service + </p> + </td> + </tr> + <tr class="list-header"> + <td align="left" valign="top" colspan=2> + <div class="form-label"> + Status: + <dtml-if isSubscribed> + Subscribed + <dtml-else> + Not Subscribed + </dtml-if> + </div> + </td> + </tr> + <tr> + <td align="left"> + <div class="form-element"> + <dtml-if isSubscribed> + <input type="submit" class="form-element" name="unsubscribe:method" value=" Unsubscribe "> + <dtml-else> + <input type="submit" class="form-element" name="subscribe:method" value=" Subscribe "> + </dtml-if> + </div> + </td> + </tr> +</table> +</form> +<dtml-var manage_page_footer> -- 2.30.9