Package Products :: Package ZenUtils :: Module ConfDaemon |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenUtils.ConfDaemon

      1  ###########################################################################
      2  #
      3  # This program is part of Zenoss Core, an open source monitoring platform.
      4  # Copyright (C) 2007, Zenoss Inc.
      5  #
      6  # This program is free software; you can redistribute it and/or modify it
      7  # under the terms of the GNU General Public License version 2 or (at your
      8  # option) any later version as published by the Free Software Foundation.
      9  #
     10  # For complete information please visit: http://www.zenoss.com/oss/
     11  #
     12  ###########################################################################
     13
     14  __doc__="""ConfDaemon
     15
     16  Base class for makeing deamon programs
     17
     18  $Id: ConfDaemon.py,v 1.9 2003/08/29 20:33:10 edahl Exp $"""
     19
     20  __version__ = "$Revision: 1.9 $"[11:-2]
     21
     22  import signal
     23  import os
     24  import sys
     25  import socket
     26  import time
     27
     28  from CmdBase import CmdBase
     29  from Utils import zenPath
     30
     31 -class ConfDaemon(CmdBase):
     32
     33 -    def __init__(self):
     34          CmdBase.__init__(self)
     35          signal.signal(signal.SIGINT, self.sigTerm)
     36          signal.signal(signal.SIGTERM, self.sigTerm)
     37          if self.options.daemon and sys.platform != 'win32':
     38              self.becomeDaemon()
     39          self.dnstries = 3
     40          self.forwarddnscache = {}
     41          self.reversednscache = {}
     42
     43 -    def becomeDaemon(self):
     44          """fork twice to become a daemon"""
     45          pid = 0
     46          try:
     47              pid = os.fork()
     48              if pid > 0:
     49                  sys.exit(0)
     50          except OSError, e:
     51              print >>sys.stderr, ("fork #1 failed: %d (%s)" %
     52                      (e.errno, e.strerror))
     53          os.chdir("/")
     54          os.setsid()
     55          os.umask(0)
     56          try:
     57              pid = os.fork()
     58              if pid > 0:
     59                  sys.exit(0)
     60          except OSError, e:
     61              print >>sys.stderr, ("fork #2 failed: %d (%s)" %
     62                      (e.errno, e.strerror))
     63          myname = sys.argv[0].split(os.sep)[-1] + ".pid"
     64          varhome = zenPath('var')
     65          pidfile = os.path.join(varhome, myname)
     66          if os.path.exists(varhome):
     67              file = open(pidfile, 'w')
     68              file.write(str(os.getpid()))
     69              file.close()
     70          else:
     71              print "ERROR: unable to open pid file %s" % pidfile
     72              sys.exit(1)
     73
     74
     75 -    def forwardDnsLookup(self, hostname):
     76          """try the forward lookup dnstries times if it fails look in cache"""
     77          try:
     78              ip = self._dnsLookup(socket.gethostbyname, hostname)
     79              self.forwarddnscache[hostname] = ip
     80              return ip
     81          except socket.error:
     82              if hostname in self.forwarddnscache:
     83                  return self.forwarddnscache[hostname]
     84              else:
     85                  raise
     86
     87
     88 -    def reverseDnsLookup(self, addr):
     89          """try the reverse lookup dnstries times if it fails look in cache"""
     90          try:
     91              ip = self._dsnLookup(socket.gethostbyaddr, addr)
     92              self.reversednscache[addr] = ip
     93              return ip
     94          except socket.error:
     95              if addr in self.reversednscache:
     96                  return self.reversednscache[addr]
     97              else:
     98                  raise
     99
    100
    101 -    def _dnsLookup(self, function, target):
    102          """try dns lookup dnstries times"""
    103          ip = None
    104          i=0
    105          while 1:
    106              try:
    107                  i+=1
    108                  ip = function(target)
    109              except socket.error:
    110                  if i > self.getDnsTries():
    111                      raise
    112              if ip: break
    113          return ip
    114
    115
    116 -    def getDnsTries(self):
    117          if not hasattr(self, 'dnstries'):
    118              self.dnstries=3
    119          return self.dnstries
    120
    121
    122 -    def sigTerm(self, signum=None, frame=None):
    123          from Products.ZenUtils.Utils import unused
    124          unused(signum, frame)
    125          self.log.info('Daemon %s shutting down' % self.__class__.__name__)
    126          sys.exit(0)
    127
    128
    129
    130 -    def getConfig(self):
    131          """handle errors when loading config from server
    132          we try configtries times if no previous config is found"""
    133          for i in range(self.options.configtries):
    134              try:
    135                  self.loadConfig()
    136                  return
    137              except SystemExit: raise
    138              except:
    139                  if self.validConfig():
    140                      self.log.exception(
    141                      "configuration load exception using previous configuration")
    142                      return
    143                  else:
    144                      self.log.exception('config load failed')
    145                      if i <= (self.options.configtries - 2):
    146                          self.log.warn(
    147                              "initial config load failed will retry")
    148                          time.sleep(self.options.configsleep)
    149                      else:
    150                          self.log.critical(
    151                              "initial config load failed %d times exiting"
    152                                      % self.options.configtries)
    153                          sys.exit(2)
    154
    155
    156 -    def buildOptions(self):
    157          CmdBase.buildOptions(self)
    158          self.parser.add_option('-c', '--cycle',
    159                      dest='cycle',
    160                      default=0,
    161                      action="store_true",
    162                      help="Cycle continuously on cycleInterval from zope")
    163          self.parser.add_option('-d', '--daemon',
    164                      dest='daemon',
    165                      default=0,
    166                      action="store_true",
    167                      help="Become a unix daemon")
    168          self.parser.add_option('-T', '--configtries',
    169                      dest='configtries',
    170                      default=5,
    171                      action="store",
    172                      help="How many times to retry config connection")
    173          self.parser.add_option('-S', '--configsleep',
    174                      dest='configsleep',
    175                      default=20,
    176                      action="store",
    177                      help="How long to sleep between config connections")
    178