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

# Source Code for Module Products.ZenUtils.ConfDaemon

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