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 or (at your 
  8  # option) any later version as published by 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 { 'id' : 'eventConfig' 109 , 'name' : 'Events' 110 , 'action' : 'eventConfig' 111 , 'permissions' : ( "Manage DMD", ) 112 }, 113 ) 114 }, 115 ) 116 117 security = ClassSecurityInfo() 118 119 120 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addZenPack')
121 - def manage_addZenPack(self, packId, REQUEST=None):
122 """ 123 Create a new zenpack on the filesystem with the given info. 124 Install the pack. If REQUEST then render the REQUEST otherwise 125 return the new zenpack. 126 """ 127 import Products.ZenUtils.ZenPackCmd as ZenPackCmd 128 129 if not getattr(self.dmd, 'ZenPackManager'): 130 msg = 'Your Zenoss database appears to be out of date. Try ' \ 131 'running zenmigrate to update.' 132 if REQUEST: 133 messaging.IMessageSender(self).sendToBrowser( 134 'Error', msg, priority=messaging.WARNING) 135 return self.callZenScreen(REQUEST) 136 from ZenPack import ZenPackNeedMigrateException 137 raise ZenPackNeedMigrateException(msg) 138 139 # Make sure a zenpack can be created with given info 140 canCreate, msgOrId = ZenPackCmd.CanCreateZenPack(self, packId) 141 if canCreate: 142 packId = msgOrId 143 else: 144 if REQUEST: 145 messaging.IMessageSender(self).sendToBrowser( 146 'Add ZenPack', msgOrId) 147 return self.callZenScreen(REQUEST, redirect=False) 148 from ZenPack import ZenPackException 149 raise ZenPackException(msgOrId) 150 151 # Create it 152 zpDir = ZenPackCmd.CreateZenPack(packId) 153 154 # Install it 155 zenPacks = ZenPackCmd.InstallEggAndZenPack(self.dmd, zpDir, link=True, 156 forceRunExternal=True) 157 zenPack = self.packs._getOb(packId, None) 158 if REQUEST: 159 if zenPack: 160 return REQUEST['RESPONSE'].redirect(zenPack.getPrimaryUrlPath()) 161 messaging.IMessageSender(self).sendToBrowser( 162 'Error', 'There was an error creating the ZenPack.', 163 priority=messaging.WARNING) 164 return self.callZenScreen(REQUEST) 165 return zenPack
166 167 168 security.declareProtected(ZEN_MANAGE_DMD, 'manage_removeZenPacks')
169 - def manage_removeZenPacks(self, ids=(), REQUEST=None):
170 """ 171 Uninstall the given zenpacks. Uninstall the zenpack egg. If not in 172 development mode then also delete the egg from the filesystem. 173 """ 174 import Products.ZenUtils.ZenPackCmd as ZenPackCmd 175 176 if not getattr(self.dmd, 'ZenPackManager'): 177 msg = 'Your Zenoss database appears to be out of date. Try ' \ 178 'running zenmigrate to update.' 179 if REQUEST: 180 messaging.IMessageSender(self).sendToBrowser( 181 'Error', msg, priority=messaging.WARNING) 182 return self.callZenScreen(REQUEST) 183 from ZenPack import ZenPackNeedMigrateException 184 raise ZenPackNeedMigrateException(msg) 185 186 canRemove, dependents = ZenPackCmd.CanRemoveZenPacks(self.dmd, ids) 187 if not canRemove: 188 msg = 'The following ZenPacks depend on one or more of the ' + \ 189 ' ZenPacks you are trying to remove: %s' % ','.join(dependents) 190 if REQUEST: 191 messaging.IMessageSender(self).sendToBrowser( 192 'Error', msg, priority=messaging.WARNING) 193 return self.callZenScreen(REQUEST) 194 from ZenPack import ZenPackDependentsException 195 raise ZenPackDependentsException(msg) 196 for zpId in ids: 197 zp = self.packs._getOb(zpId, None) 198 if zp: 199 if zp.isEggPack(): 200 ZenPackCmd.RemoveZenPack(self.dmd, zpId, skipDepsCheck=True) 201 else: 202 os.system('%s --remove %s' % ( 203 binPath('zenpack'), zpId)) 204 self._p_jar.sync() 205 if REQUEST: 206 return self.callZenScreen(REQUEST)
207 208 209 security.declareProtected(ZEN_MANAGE_DMD, 'fetchZenPack')
210 - def fetchZenPack(self, packName, packVersion=''):
211 """ 212 Retrieve the given zenpack from Zenoss.net and install. 213 """ 214 import Products.ZenUtils.ZenPackCmd as ZenPackCmd 215 zp = ZenPackCmd.FetchAndInstallZenPack(self.dmd, packName, packVersion) 216 if REQUEST: 217 return REQUEST['RESPONSE'].redirect(zp.getPrimaryUrlPath()) 218 return zp
219 220 221 222 security.declareProtected(ZEN_MANAGE_DMD, 'manage_installZenPack')
223 - def manage_installZenPack(self, zenpack=None, REQUEST=None):
224 """ 225 Installs the given zenpack. Zenpack is a file upload from the browser. 226 """ 227 import os 228 import re 229 from subprocess import Popen, PIPE, STDOUT 230 import time 231 232 from Products.ZenUtils.Utils import get_temp_dir 233 234 ZENPACK_INSTALL_TIMEOUT = 10 * 60 # 10 minutes 235 236 if not getattr(self.dmd, 'ZenPackManager'): 237 msg = 'Your Zenoss database appears to be out of date. Try ' \ 238 'running zenmigrate to update.' 239 if REQUEST: 240 messaging.IMessageSender(self).sendToBrowser( 241 'Error', msg, priority=messaging.WARNING) 242 return self.callZenScreen(REQUEST) 243 from ZenPack import ZenPackNeedMigrateException 244 raise ZenPackNeedMigrateException(msg) 245 246 msg = '' 247 with get_temp_dir() as tempDir: 248 # zenpack.filename gives us filename of the zenpack with the 249 # path as it exists on the client. We need just the filename. 250 base_filename = re.split(r"\\|/", zenpack.filename)[-1] 251 # Macs (and other broswers/OSs) always append a .zip to files they 252 # believe to be zip files. Remedy that: 253 if base_filename.endswith('.egg.zip'): 254 base_filename = base_filename[:-7] + 'egg' 255 256 # Write the zenpack to the filesystem 257 tFile = open(os.path.join(tempDir, base_filename), 'wb') 258 tFile.write(zenpack.read()) 259 tFile.close() 260 261 p = None # zenpack install process 262 try: 263 # Run zenpack install 264 cmd = 'zenpack --install %s' % tFile.name 265 p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT) 266 endWait = time.time() + ZENPACK_INSTALL_TIMEOUT 267 # Wait for install to complete or fail 268 while p.poll() is None and time.time() < endWait: 269 time.sleep(1) 270 if p.poll() is not None: 271 msg = p.stdout.read() 272 finally: 273 if p and p.poll() is None: 274 p.kill() 275 msg += 'Zenpack install killed due to timeout' 276 277 if REQUEST: 278 # format command result for HTML 279 msg = '<br>'.join(line.strip() for line in msg.split('\n') if line.strip()) 280 messaging.IMessageSender(self).sendToBrowser('Zenpack', msg, 281 priority = messaging.CRITICAL if 'ERROR' in msg 282 else messaging.INFO) 283 return self.callZenScreen(REQUEST)
284 285
286 - def getZnetProjectOptions(self):
287 """ 288 Return a list of 2-tuples of (option value, option name) for the 289 user to select a Zenoss.net project from. 290 """ 291 projects = self.getZnetProjectsList() 292 return [(p, p.split('/')[-1]) for p in projects]
293 294
295 - def getZnetProjectsList(self):
296 """ 297 Return a list of the zenoss.net projects. 298 """ 299 import json 300 import Products.ZenUtils.DotNetCommunication as DotNetCommunication 301 userSettings = self.dmd.ZenUsers.getUserSettings() 302 session = DotNetCommunication.getDotNetSession( 303 userSettings.zenossNetUser, 304 userSettings.zenossNetPassword) 305 projects = session.retrieve('projectList') 306 projects = json.loads(projects) 307 return projects
308 309
310 - def getBrokenPackName(self, ob):
311 ''' Extract the zenpack name from the broken module 312 ''' 313 return ob.id if ob.id else ob.__class__.__module__
314 315 316 InitializeClass(ZenPackManager) 317