Package Products :: Package ZenEvents :: Module UpdateCheck |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenEvents.UpdateCheck

      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 as published by
      8  # the Free Software Foundation.
      9  #
     10  # For complete information please visit: http://www.zenoss.com/oss/
     11  #
     12  ###########################################################################
     13
     14  __doc__='''UpdateCheck
     15
     16  '''
     17
     18  import Globals
     19  import transaction
     20  from Products.ZenUtils.Version import Version
     21  from Products.ZenEvents import Event
     22  from Products.ZenEvents.ZenEventClasses import Status_Update
     23  import urllib
     24  import string
     25  import time
     26
     27  URL = 'http://update.zenoss.org/cgi-bin/version'
     28
     29  DAY_SECONDS = 60*60*24
     30  HOUR_SECONDS = 60*60
     31
     32 -def parseVersion(s):
     33      if s is None: return s
     34      v = Version.parse('Zenoss ' + s)
     35      v.revision = None
     36      return v
     37
     38 -class UpdateCheck:
     39
     40 -    def getUpdate(self, dmd, manual, product=None):
     41          """
     42          Send a GET request to dev.zenoss.org giving some parameters about this
     43          Zenoss installation and getting back the version number for the
     44          most recent product release.  The product can be passed in the product
     45          parameter, but if product is None then the code will attempt to
     46          figure out which product is currently running and use that.
     47          """
     48          if not product:
     49              product = dmd.getProductName()
     50          available = None
     51          args = {}
     52          args['pr'] = product
     53          args['sk'] = dmd.uuid or "NOT ACTIVATED"
     54          args['ac'] = (manual and '0') or '1'
     55          args['zv'] = dmd.About.getZenossVersion().long()
     56          args['pv'] = dmd.About.getPythonVersion().long()
     57          args['mv'] = dmd.About.getMySQLVersion().long()
     58          args['os'] = dmd.About.getOSVersion().long()
     59          args['osv'] = dmd.About.getOSVersion().full()
     60          #args['rv'] = Products.ZenUtils.Version.getZenossRevision()
     61          args['rv'] = 'bad bad bad'
     62          args['up'] = time.time() - dmd.getPhysicalRoot().Control_Panel.process_start
     63
     64          # If they have not opted-out and this is not a manual check then
     65          # gather usage numbers and include in request
     66          if not manual and dmd.reportMetricsOptIn:
     67              args['nd'] = dmd.Devices.countDevices()
     68              args['nu'] = len(dmd.ZenUsers.objectIds())
     69              args['nm'] = dmd.Events.countInstances()
     70              args['ne'] = dmd.ZenEventManager.countEventsSince(
     71                                              time.time() - 24 * 60 * 60)
     72              numProducts = 0
     73              manufacturers = dmd.Manufacturers.objectValues(spec='Manufacturer')
     74              for m in manufacturers:
     75                  numProducts += m.products.countObjects()
     76              args['np'] = numProducts
     77              args['nr'] = dmd.Reports.countReports()
     78              args['nt'] = dmd.Devices.rrdTemplates.countObjects()
     79              args['ns'] = dmd.Systems.countChildren()
     80              args['ng'] = dmd.Groups.countChildren()
     81              args['nl'] = dmd.Locations.countChildren()
     82
     83          query = urllib.urlencode(args.items())
     84          for line in urllib.urlopen(URL + '?' + query):
     85              # skip blank lines and http gunk
     86              if line.strip() and line[0] not in '<' + string.whitespace:
     87                  try:
     88                      available = parseVersion(line.strip())
     89                      break
     90                  except ValueError:
     91                      pass
     92          return available
     93
     94 -    def check(self, dmd, zem, manual=False):
     95          "call home with version information"
     96          if not manual:
     97              if time.time() - dmd.lastVersionCheck < DAY_SECONDS \
     98                or time.time() - dmd.lastVersionCheckAttempt < 2 * HOUR_SECONDS:
     99                  return
    100              if not dmd.versionCheckOptIn:
    101                  return
    102          now = long(time.time())
    103          dmd.lastVersionCheckAttempt = now
    104          if not manual:
    105              transaction.commit()
    106          try:
    107              available = self.getUpdate(dmd, manual)
    108          except IOError:
    109              available = None
    110          if not isinstance(available, Version):
    111              # We did not successfully get a version, don't continue
    112              return
    113          dmd.availableVersion = available.short()
    114          dmd.lastVersionCheck = now
    115          availableVersion = parseVersion(dmd.availableVersion)
    116          if (availableVersion is None
    117              or dmd.About.getZenossVersion() < availableVersion):
    118              if availableVersion != available:
    119                  import socket
    120                  summary = ('A new version of Zenoss (%s) has been released' %
    121                             available.short())
    122                  zem.sendEvent(Event.Event(device=socket.getfqdn(),
    123                                                eventClass=Status_Update,
    124                                                severity=Event.Info,
    125                                                summary=summary))
    126
    127          return True
    128
    129  if __name__ == "__main__":
    130      from Products.ZenUtils import ZCmdBase
    131 -    class zendmd(ZCmdBase.ZCmdBase):
    132          pass
    133      zendmd = zendmd()
    134      uc = UpdateCheck()
    135      uc.getUpdate = lambda *unused: parseVersion('0.24.0')
    136      uc.check(zendmd.dmd, zendmd.dmd.ZenEventManager, manual=True)
    137      transaction.commit()
    138