[Erp5-report] r33892 rafael - in /erp5/trunk/utils/erp5.timmy: ./ src/erp5/timmy/

nobody at svn.erp5.org nobody at svn.erp5.org
Fri Mar 19 03:59:11 CET 2010


Author: rafael
Date: Fri Mar 19 03:59:11 2010
New Revision: 33892

URL: http://svn.erp5.org?rev=33892&view=rev
Log:
Implemented a simple lock system based in pid file. This prevents run same timmy 2 times in parallel. 

It creates pid file given as parameter and disallow to run if pid file exists and process with pid exists. if pid file exists and process with such pid do not exists, it assume that it is killed process, overwriting with exists process.


Modified:
    erp5/trunk/utils/erp5.timmy/README.txt
    erp5/trunk/utils/erp5.timmy/src/erp5/timmy/timmy.py

Modified: erp5/trunk/utils/erp5.timmy/README.txt
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.timmy/README.txt?rev=33892&r1=33891&r2=33892&view=diff
==============================================================================
--- erp5/trunk/utils/erp5.timmy/README.txt [utf8] (original)
+++ erp5/trunk/utils/erp5.timmy/README.txt [utf8] Fri Mar 19 03:59:11 2010
@@ -34,4 +34,4 @@
 
   bin/timmy -k /path/to/server.key -s url://server/path -b timmy-base.cfg \
   -t local-eggs/erp5.timmy/src/erp5/timmy/examples/ -o timmy-controller.cfg \
-  -d timmy-instances -r bin/buildout
+  -d timmy-instances -r bin/buildout -p var/timmy.pid

Modified: erp5/trunk/utils/erp5.timmy/src/erp5/timmy/timmy.py
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.timmy/src/erp5/timmy/timmy.py?rev=33892&r1=33891&r2=33892&view=diff
==============================================================================
--- erp5/trunk/utils/erp5.timmy/src/erp5/timmy/timmy.py [utf8] (original)
+++ erp5/trunk/utils/erp5.timmy/src/erp5/timmy/timmy.py [utf8] Fri Mar 19 03:59:11 2010
@@ -1,6 +1,8 @@
 import uuid, os, xmlrpclib, subprocess, logging
 from string import Template
 from optparse import OptionParser
+import sys
+import socket
 
 REQUIRED_TEMPLATE_LIST = [
   'instance-template.cfg',
@@ -60,6 +62,9 @@
   parser.add_option("-r", "--buildout-binary",
     help="Buildout binary to run")
 
+  parser.add_option("-p", "--pid-file",
+    help="Lock file with the pid file.")
+
   (options, args) = parser.parse_args()
   required_option_list = [
       'base_profile',
@@ -69,6 +74,7 @@
       'main_output',
       'server_url',
       'template_directory',
+      'pid_file'
     ]
   for o in required_option_list:
     if not getattr(options, o, None):
@@ -90,6 +96,34 @@
     raise ValueError('Missing templates: %s' % ','.join(missing_template_list))
   return options, args
 
+def setRunning(value, pid_file):
+  if value:
+    if os.path.exists(pid_file):
+      # Pid file is present
+      logging.warning('Timmy already have the pid file %s' % pid_file)
+      pid = open(pid_file, 'r').readline()
+      # XXX This could use psutil library.
+      if os.path.exists("/proc/%s" % pid):
+        # In case process is present, ignore.
+        logging.critical('A Timmy process is running with pid %s' % pid)
+        sys.exit(1)
+    # Start new process
+    write_pid(pid_file)
+  else:
+    os.remove(pid_file)
+
+def write_pid(pid_file):
+  pid = os.getpid()
+  try:
+    f = open(pid_file, 'w')
+    f.write('%s' % pid)
+    f.close()
+  except (IOError, OSError):
+    logging.critical('Timmy could not write pidfile %s' % pid_file)
+  else:
+    logging.info('Timmy started with the pid %s' % pid)
+  
+
 def updateBaseProfile(template_directory, file_output, base_profile,
     instances_directory, instance_dict_list):
   # TODO:
@@ -351,40 +385,54 @@
 def run():
   logging.basicConfig(level=logging.INFO)
   (options, args) = parseOptions()
-  server = XMLRPCServer(options.server_url, getServerKey(options.key_file))
-  partition_dict_list = server.call('getComputerConfigurationDictList')
-  # prepare - run supervisor
-  subprocess.call(SUPERVISORD)
-  # 1a pass - main profile
-  updateBaseProfile(options.template_directory, options.main_output,
-      options.base_profile, options.instances_directory, partition_dict_list)
-  # 1b pass - instance profiles
-  updateInstanceProfiles(options.template_directory,
-      options.instances_directory, partition_dict_list)
-  # 2 pass - run buildout
-  runBuildout(options.buildout_binary, options.main_output)
-
-  # 3 pass - manage instances
-  updated_partition_list = []
-  helper = Helper()
-  for partition_dict in partition_dict_list:
-    # install
-    # stop
-    # switch to special management
-    # start
-    partition = Partition(partition_dict['PARTITION_ID'],
-        partition_dict['ID'], partition_dict['TYPE'])
-    switcher_dict = dict(
-        start = 'manageStart',
-        stop = 'manageStop',
-        nothing = 'manageNothing',
-        install = 'manageInstall',
-    )
-    action = getattr(helper, switcher_dict[partition_dict['ACTION']])
-    action(partition, server)
-
-  # force supervisor to reload its configuration
-  subprocess.call([SUPERVISORCTL, 'update'])
+  setRunning(True, options.pid_file)
+  try:
+    try:
+      server = XMLRPCServer(options.server_url, getServerKey(options.key_file))
+      partition_dict_list = server.call('getComputerConfigurationDictList')
+    except socket.error, e:
+      print 'ERROR: Unable to connect to remote server, verify if the URL is' + \
+            ' accessible.'
+      sys.exit(1)
+    except xmlrpclib.Fault, e:
+      print 'ERROR: Error found on server side, unable to continue.'
+      print e.faultString
+      sys.exit(1)
+  
+    # prepare - run supervisor
+    subprocess.call(SUPERVISORD)
+    # 1a pass - main profile
+    updateBaseProfile(options.template_directory, options.main_output,
+        options.base_profile, options.instances_directory, partition_dict_list)
+    # 1b pass - instance profiles
+    updateInstanceProfiles(options.template_directory,
+        options.instances_directory, partition_dict_list)
+    # 2 pass - run buildout
+    runBuildout(options.buildout_binary, options.main_output)
+  
+    # 3 pass - manage instances
+    updated_partition_list = []
+    helper = Helper()
+    for partition_dict in partition_dict_list:
+      # install
+      # stop
+      # switch to special management
+      # start
+      partition = Partition(partition_dict['PARTITION_ID'],
+          partition_dict['ID'], partition_dict['TYPE'])
+      switcher_dict = dict(
+          start = 'manageStart',
+          stop = 'manageStop',
+          nothing = 'manageNothing',
+          install = 'manageInstall',
+      )
+      action = getattr(helper, switcher_dict[partition_dict['ACTION']])
+      action(partition, server)
+  
+    # force supervisor to reload its configuration
+    subprocess.call([SUPERVISORCTL, 'update'])
+  finally:
+    setRunning(False, options.pid_file)
 
 if __name__ == '__main__':
   run()




More information about the Erp5-report mailing list