Package Products :: Package ZenModel :: Module ZenPackManager |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenModel.ZenPackManager

      1  ###########################################################################
      2  #
      3  # This program is part of Zenoss Core, an open source monitoring platform.
      4  # Copyright (C) 2008, 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__="""ZenPackManager
     15  ZenPackManager is a Zope Product that helps manage ZenPacks
     16  """
     17
     18  from Globals import InitializeClass
     19  from ZenModelRM import ZenModelRM
     20  from Products.ZenRelations.RelSchema import *
     21  from AccessControl import ClassSecurityInfo
     22  from ZenossSecurity import ZEN_MANAGE_DMD
     23  from Products.ZenUtils.Utils import binPath
     24  from Products.ZenWidgets import messaging
     25  import os
     26
     27 -def manage_addZenPackManager(context, newId='', REQUEST=None):
     28      """
     29      Create a ZenPackManager instance
     30      """
     31      if not newId:
     32          newId = 'ZenPackManager'
     33      zpm = ZenPackManager(newId)
     34      context._setObject(newId, zpm)
     35      zpm = context._getOb(newId)
     36      if REQUEST is not None:
     37          REQUEST.RESPONSE.redirect(context.absolute_url() + '/manage_main')
     38
     39
     40 -class ZenPackManager(ZenModelRM):
     41      """
     42      ZenPackManager is responsibe for managing ZenPacks
     43      """
     44
     45      portal_type = meta_type = 'ZenPackManager'
     46
     47      default_catalog = 'zenPackNameSearch'
     48
     49      _relations = ZenModelRM._relations + (
     50          ('packs', ToManyCont(ToOne, 'Products.ZenModel.ZenPack', 'manager')),
     51          )
     52
     53      factory_type_information = (
     54          {
     55              'immediate_view' : 'viewZenPacks',
     56              'actions'        :
     57              (
     58                  { 'id'            : 'settings'
     59                  , 'name'          : 'Settings'
     60                  , 'action'        : '../editSettings'
     61                  , 'permissions'   : ( "Manage DMD", )
     62                  },
     63                  { 'id'            : 'manage'
     64                  , 'name'          : 'Commands'
     65                  , 'action'        : '../dataRootManage'
     66                  , 'permissions'   : ('Manage DMD',)
     67                  },
     68                  { 'id'            : 'users'
     69                  , 'name'          : 'Users'
     70                  , 'action'        : '../ZenUsers/manageUserFolder'
     71                  , 'permissions'   : ( 'Manage DMD', )
     72                  },
     73                  { 'id'            : 'packs'
     74                  , 'name'          : 'ZenPacks'
     75                  , 'action'        : 'viewZenPacks'
     76                  , 'permissions'   : ( "Manage DMD", )
     77                  },
     78                  { 'id'            : 'jobs'
     79                  , 'name'          : 'Jobs'
     80                  , 'action'        : '../joblist'
     81                  , 'permissions'   : ( "Manage DMD", )
     82                  },
     83                  #{ 'id'            : 'menus'
     84                  #, 'name'          : 'Menus'
     85                  #, 'action'        : '../editMenus'
     86                  #, 'permissions'   : ( "Manage DMD", )
     87                  #},
     88                  { 'id'            : 'portlets'
     89                  , 'name'          : 'Portlets'
     90                  , 'action'        : '../editPortletPerms'
     91                  , 'permissions'   : ( "Manage DMD", )
     92                  },
     93                  { 'id'            : 'daemons'
     94                  , 'name'          : 'Daemons'
     95                  , 'action'        : '../About/zenossInfo'
     96                  , 'permissions'   : ( "Manage DMD", )
     97                  },
     98                  { 'id'            : 'versions'
     99                  , 'name'          : 'Versions'
    100                  , 'action'        : '../About/zenossVersions'
    101                  , 'permissions'   : ( "Manage DMD", )
    102                  },
    103                  { 'id'            : 'backups'
    104                  , 'name'          : 'Backups'
    105                  , 'action'        : '../backupInfo'
    106                  , 'permissions'   : ( "Manage DMD", )
    107                  },
    108              )
    109           },
    110          )
    111
    112      security = ClassSecurityInfo()
    113
    114
    115      security.declareProtected(ZEN_MANAGE_DMD, 'manage_addZenPack')
    116 -    def manage_addZenPack(self, packId, REQUEST=None):
    117          """
    118          Create a new zenpack on the filesystem with the given info.
    119          Install the pack.  If REQUEST then render the REQUEST otherwise
    120          return the new zenpack.
    121          """
    122          import Products.ZenUtils.ZenPackCmd as ZenPackCmd
    123
    124          if not getattr(self.dmd, 'ZenPackManager'):
    125              msg = 'Your Zenoss database appears to be out of date. Try ' \
    126                      'running zenmigrate to update.'
    127              if REQUEST:
    128                  messaging.IMessageSender(self).sendToBrowser(
    129                      'Error', msg, priority=messaging.WARNING)
    130                  return self.callZenScreen(REQUEST)
    131              from ZenPack import ZenPackNeedMigrateException
    132              raise ZenPackNeedMigrateException(msg)
    133
    134          # Make sure a zenpack can be created with given info
    135          canCreate, msgOrId = ZenPackCmd.CanCreateZenPack(self, packId)
    136          if canCreate:
    137              packId = msgOrId
    138          else:
    139              if REQUEST:
    140                  messaging.IMessageSender(self).sendToBrowser(
    141                      'Add ZenPack', msgOrId)
    142                  return self.callZenScreen(REQUEST, redirect=False)
    143              from ZenPack import ZenPackException
    144              raise ZenPackException(msgOrId)
    145
    146          # Create it
    147          zpDir = ZenPackCmd.CreateZenPack(packId)
    148
    149          # Install it
    150          zenPacks = ZenPackCmd.InstallEggAndZenPack(self.dmd, zpDir, link=True)
    151          zenPack = self.packs._getOb(packId, None)
    152          if REQUEST:
    153              if zenPack:
    154                  return REQUEST['RESPONSE'].redirect(zenPack.getPrimaryUrlPath())
    155              messaging.IMessageSender(self).sendToBrowser(
    156                  'Error', 'There was an error creating the ZenPack.',
    157                  priority=messaging.WARNING)
    158              return self.callZenScreen(REQUEST)
    159          return zenPack
    160
    161
    162      security.declareProtected(ZEN_MANAGE_DMD, 'manage_removeZenPacks')
    163 -    def manage_removeZenPacks(self, ids=(), REQUEST=None):
    164          """
    165          Uninstall the given zenpacks.  Uninstall the zenpack egg.  If not in
    166          development mode then also delete the egg from the filesystem.
    167          """
    168          import Products.ZenUtils.ZenPackCmd as ZenPackCmd
    169
    170          if not getattr(self.dmd, 'ZenPackManager'):
    171              msg = 'Your Zenoss database appears to be out of date. Try ' \
    172                      'running zenmigrate to update.'
    173              if REQUEST:
    174                  messaging.IMessageSender(self).sendToBrowser(
    175                      'Error', msg, priority=messaging.WARNING)
    176                  return self.callZenScreen(REQUEST)
    177              from ZenPack import ZenPackNeedMigrateException
    178              raise ZenPackNeedMigrateException(msg)
    179
    180          canRemove, dependents = ZenPackCmd.CanRemoveZenPacks(self.dmd, ids)
    181          if not canRemove:
    182              msg = 'The following ZenPacks depend on one or more of the ' + \
    183                  ' ZenPacks you are trying to remove: %s' % ','.join(dependents)
    184              if REQUEST:
    185                  messaging.IMessageSender(self).sendToBrowser(
    186                      'Error', msg, priority=messaging.WARNING)
    187                  return self.callZenScreen(REQUEST)
    188              from ZenPack import ZenPackDependentsException
    189              raise ZenPackDependentsException(msg)
    190          for zpId in ids:
    191              zp = self.packs._getOb(zpId, None)
    192              if zp:
    193                  if zp.isEggPack():
    194                      ZenPackCmd.RemoveZenPack(self.dmd, zpId, skipDepsCheck=True)
    195                  else:
    196                      os.system('%s --remove %s' % (
    197                                              binPath('zenpack'), zpId))
    198                      self._p_jar.sync()
    199          if REQUEST:
    200              return self.callZenScreen(REQUEST)
    201
    202
    203      security.declareProtected(ZEN_MANAGE_DMD, 'fetchZenPack')
    204 -    def fetchZenPack(self, packName, packVersion=''):
    205          """
    206          Retrieve the given zenpack from Zenoss.net and install.
    207          """
    208          import Products.ZenUtils.ZenPackCmd as ZenPackCmd
    209          zp = ZenPackCmd.FetchAndInstallZenPack(self.dmd, packName, packVersion)
    210          if REQUEST:
    211              return REQUEST['RESPONSE'].redirect(zp.getPrimaryUrlPath())
    212          return zp
    213
    214
    215
    216      security.declareProtected(ZEN_MANAGE_DMD, 'manage_installZenPack')
    217 -    def manage_installZenPack(self, zenpack=None, REQUEST=None):
    218          """
    219          Installs the given zenpack.  Zenpack is a file upload from the browser.
    220          """
    221          import tempfile
    222          import fcntl
    223          import popen2
    224          import signal
    225          import time
    226          import select
    227
    228          ZENPACK_INSTALL_TIMEOUT = 120
    229
    230          if not getattr(self.dmd, 'ZenPackManager'):
    231              msg = 'Your Zenoss database appears to be out of date. Try ' \
    232                      'running zenmigrate to update.'
    233              if REQUEST:
    234                  messaging.IMessageSender(self).sendToBrowser(
    235                      'Error', msg, priority=messaging.WARNING)
    236                  return self.callZenScreen(REQUEST)
    237              from ZenPack import ZenPackNeedMigrateException
    238              raise ZenPackNeedMigrateException(msg)
    239
    240          tFile = None
    241          child = None
    242          try:
    243              # zenpack.filename gives us filename of the zenpack with the
    244              # path as it exists on the client. We need just the filename.
    245              import re
    246              base_filename = re.split(r"\\|/", zenpack.filename)[-1]
    247
    248              # Write the zenpack to the filesystem
    249              tDir = tempfile.gettempdir()
    250              tFile = open(os.path.join(tDir, base_filename), 'wb')
    251              tFile.write(zenpack.read())
    252              tFile.close()
    253
    254              cmd = 'zenpack --install %s' % tFile.name
    255              child = popen2.Popen4(cmd)
    256              flags = fcntl.fcntl(child.fromchild, fcntl.F_GETFL)
    257              fcntl.fcntl(child.fromchild, fcntl.F_SETFL, flags | os.O_NDELAY)
    258              endtime = time.time() + ZENPACK_INSTALL_TIMEOUT
    259              pollPeriod = 1
    260              firstPass = True
    261              while time.time() < endtime and (firstPass or child.poll()==-1):
    262                  firstPass = False
    263                  r, w, e = select.select([child.fromchild],[],[], pollPeriod)
    264                  if r:
    265                      t = child.fromchild.read()
    266          finally:
    267              if child and child.poll() == -1:
    268                  os.kill(child.pid, signal.SIGKILL)
    269
    270          REQUEST['RESPONSE'].redirect(REQUEST['HTTP_REFERER'])
    271
    272
    273 -    def getZnetProjectOptions(self):
    274          """
    275          Return a list of 2-tuples of (option value, option name) for the
    276          user to select a Zenoss.net project from.
    277          """
    278          projects = self.getZnetProjectsList()
    279          return [(p, p.split('/')[-1]) for p in projects]
    280
    281
    282 -    def getZnetProjectsList(self):
    283          """
    284          Return a list of the zenoss.net projects.
    285          """
    286          import json
    287          import Products.ZenUtils.DotNetCommunication as DotNetCommunication
    288          userSettings = self.dmd.ZenUsers.getUserSettings()
    289          session = DotNetCommunication.getDotNetSession(
    290                      userSettings.zenossNetUser,
    291                      userSettings.zenossNetPassword)
    292          projects = session.retrieve('projectList')
    293          projects = json.loads(projects)
    294          return projects
    295
    296
    297 -    def getBrokenPackName(self, ob):
    298          ''' Extract the zenpack name from the broken module
    299          '''
    300          return ob.id if ob.id else ob.__class__.__module__
    301
    302
    303  InitializeClass(ZenPackManager)
    304