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

# Source Code for Module Products.ZenUtils.ZCmdBase

      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__="""ZenDaemon
     12
     13  $Id: ZC.py,v 1.9 2004/02/16 17:19:31 edahl Exp $"""
     14
     15  __version__ = "$Revision: 1.9 $"[11:-2]
     16
     17  import time
     18
     19  from threading import Lock
     20  from zope.component import getUtility
     21
     22  from AccessControl.SecurityManagement import newSecurityManager
     23  from AccessControl.SecurityManagement import noSecurityManager
     24
     25  from Products.ZenUtils.Utils import getObjByPath, zenPath
     26  from Products.ZenUtils.ZodbFactory import IZodbFactoryLookup
     27
     28  from Exceptions import ZentinelException
     29  from ZenDaemon import ZenDaemon
     30
     31  from Products.ZenRelations.ZenPropertyManager import setDescriptors
     32  from Products.ZenUtils.mysql import MySQLdb
     33
     34  defaultCacheDir = zenPath('var')
     35
     36 -class DataRootError(Exception):pass
     37
     38 -def login(context, name='admin', userfolder=None):
     39      """Logs in."""
     40      if userfolder is None:
     41          userfolder = context.getPhysicalRoot().acl_users
     42      user = userfolder.getUserById(name)
     43      if user is None: return
     44      if not hasattr(user, 'aq_base'):
     45          user = user.__of__(userfolder)
     46      newSecurityManager(None, user)
     47      return user
     48
     49 -class ZCmdBase(ZenDaemon):
     50
     51 -    def __init__(self, noopts=0, app=None, keeproot=False):
     52          ZenDaemon.__init__(self, noopts, keeproot)
     53          self.dataroot = None
     54          self.app = app
     55          self.db = None
     56          if not app:
     57              self.zodbConnect()
     58          self.poollock = Lock()
     59          self.getDataRoot()
     60          self.login()
     61          setDescriptors(self.dmd)
     62
     63 -    def zodbConnect(self):
     64          connectionFactory = getUtility(IZodbFactoryLookup).get()
     65          self.db, self.storage = connectionFactory.getConnection(**self.options.__dict__)
     66
     67 -    def login(self, name='admin', userfolder=None):
     68          """Logs in."""
     69          login(self.dmd, name, userfolder)
     70
     71
     72 -    def logout(self):
     73          """Logs out."""
     74          noSecurityManager()
     75
     76
     77 -    def getConnection(self):
     78          """Return a wrapped app connection from the connection pool.
     79          """
     80          if not self.db:
     81              raise ZentinelException(
     82                  "running inside zope can't open connections.")
     83          with self.poollock:
     84              connection=self.db.open()
     85              root=connection.root()
     86              app=root['Application']
     87              app = self.getContext(app)
     88              app._p_jar.sync()
     89              return app
     90
     91
     92 -    def closeAll(self):
     93          """Close all connections in both free an inuse pools.
     94          """
     95          self.db.close()
     96
     97
     98 -    def opendb(self):
     99          if self.app: return
    100          self.connection=self.db.open()
    101          root=self.connection.root()
    102          app=root['Application']
    103          self.app = self.getContext(app)
    104
    105
    106 -    def syncdb(self):
    107          MAX_RETRY_TIME_MINUTES = 10
    108          MAX_RETRY_DELAY_SECONDS = 30
    109
    110          retryStartedAt = None
    111          def timedOut():
    112              if retryStartedAt is None:
    113                  return False
    114              else:
    115                  return retryStartedAt + MAX_RETRY_TIME_MINUTES * 60 < time.time()
    116
    117          retryMultiplier = 1.618
    118          retryDelay = 1
    119
    120          keepTrying = True
    121          while keepTrying:
    122              try:
    123                  self.connection.sync()
    124
    125              except MySQLdb.OperationalError, e:
    126                  if timedOut():
    127                      self.log.info("Timed out trying to reconnect to ZODB.")
    128                      self.log.exception(e)
    129                      keepTrying = False
    130                      break
    131
    132                  if retryDelay * retryMultiplier >= MAX_RETRY_DELAY_SECONDS:
    133                      retryDelay = MAX_RETRY_DELAY_SECONDS
    134                  else:
    135                      retryDelay *= retryMultiplier
    136
    137                  self.log.warn("Connection to ZODB interrupted, will try to reconnect again in %d seconds.", retryDelay)
    138
    139                  if retryStartedAt is None:
    140                      retryStartedAt = time.time()
    141
    142                  try:
    143                      time.sleep(retryDelay)
    144                  except Exception, e:
    145                      break
    146
    147              else:
    148                  keepTrying = False
    149
    150
    151 -    def closedb(self):
    152          self.connection.close()
    153          #self.db.close()
    154          self.app = None
    155          self.dataroot = None
    156          self.dmd = None
    157
    158
    159 -    def getDataRoot(self):
    160          if not self.app: self.opendb()
    161          if not self.dataroot:
    162              self.dataroot = getObjByPath(self.app, self.options.dataroot)
    163              self.dmd = self.dataroot
    164
    165
    166 -    def getContext(self, app):
    167          from ZPublisher.HTTPRequest import HTTPRequest
    168          from ZPublisher.HTTPResponse import HTTPResponse
    169          from ZPublisher.BaseRequest import RequestContainer
    170          resp = HTTPResponse(stdout=None)
    171          env = {
    172              'SERVER_NAME':'localhost',
    173              'SERVER_PORT':'8080',
    174              'REQUEST_METHOD':'GET'
    175              }
    176          req = HTTPRequest(None, env, resp)
    177          return app.__of__(RequestContainer(REQUEST = req))
    178
    179
    180 -    def getDmdObj(self, path):
    181          """return an object based on a path starting from the dmd"""
    182          return getObjByPath(self.app, self.options.dataroot+path)
    183
    184
    185 -    def findDevice(self, name):
    186          """return a device based on its FQDN"""
    187          devices = self.dataroot.getDmdRoot("Devices")
    188          return devices.findDevice(name)
    189
    190 -    def sigTerm(self, signum=None, frame=None):
    191          pass
    192
    193 -    def buildOptions(self):
    194          """basic options setup sub classes can add more options here"""
    195          ZenDaemon.buildOptions(self)
    196
    197          connectionFactory = getUtility(IZodbFactoryLookup).get()
    198          connectionFactory.buildOptions(self.parser)
    199