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

Source Code for Module 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 if REQUEST: 241 REQUEST['cmd'] = '' 242 header, footer = self.commandOutputTemplate().split('OUTPUT_TOKEN') 243 REQUEST.RESPONSE.write(str(header)) 244 out = REQUEST.RESPONSE 245 else: 246 out = None 247 248 tFile = None 249 child = None 250 try: 251 try: 252 # Write the zenpack to the filesystem 253 tDir = tempfile.gettempdir() 254 tFile = open(os.path.join(tDir, zenpack.filename), 'wb') 255 tFile.write(zenpack.read()) 256 tFile.close() 257 258 cmd = 'zenpack --install %s' % tFile.name 259 child = popen2.Popen4(cmd) 260 flags = fcntl.fcntl(child.fromchild, fcntl.F_GETFL) 261 fcntl.fcntl(child.fromchild, fcntl.F_SETFL, flags | os.O_NDELAY) 262 endtime = time.time() + ZENPACK_INSTALL_TIMEOUT 263 self.write(out, '%s' % cmd) 264 self.write(out, '') 265 pollPeriod = 1 266 firstPass = True 267 while time.time() < endtime and (firstPass or child.poll()==-1): 268 firstPass = False 269 r, w, e = select.select([child.fromchild],[],[], pollPeriod) 270 if r: 271 t = child.fromchild.read() 272 #We are sometimes getting to this point without any data 273 # from child.fromchild. I don't think that should happen 274 # but the conditional below seems to be necessary. 275 if t: 276 self.write(out, t) 277 if child.poll() == -1: 278 self.write(out, 279 'Command timed out for %s' % cmd + 280 ' (timeout is %s seconds)' % 281 ZENPACK_INSTALL_TIMEOUT) 282 except: 283 self.write(out, 'Error installing ZenPack.') 284 self.write( 285 out, 'type: %s value: %s' % tuple(sys.exc_info()[:2])) 286 self.write(out, '') 287 finally: 288 if child and child.poll() == -1: 289 os.kill(child.pid, signal.SIGKILL) 290 291 self.write(out, '') 292 self.write(out, 'Done installing ZenPack.') 293 if REQUEST: 294 REQUEST.RESPONSE.write(footer)
295 296
297 - def getZnetProjectOptions(self):
298 """ 299 Return a list of 2-tuples of (option value, option name) for the 300 user to select a Zenoss.net project from. 301 """ 302 projects = self.getZnetProjectsList() 303 return [(p, p.split('/')[-1]) for p in projects]
304 305
306 - def getZnetProjectsList(self):
307 """ 308 Return a list of the zenoss.net projects. 309 """ 310 import simplejson 311 import Products.ZenUtils.DotNetCommunication as DotNetCommunication 312 userSettings = self.dmd.ZenUsers.getUserSettings() 313 session = DotNetCommunication.getDotNetSession( 314 userSettings.zenossNetUser, 315 userSettings.zenossNetPassword) 316 projects = session.retrieve('projectList') 317 projects = simplejson.loads(projects) 318 return projects
319 320
321 - def getBrokenPackName(self, ob):
322 ''' Extract the zenpack name from the broken module 323 ''' 324 return ob.__class__.__module__
325 326 327 InitializeClass(ZenPackManager) 328