1
2
3
4
5
6
7
8
9
10
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
38
39
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
84
85
86
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')
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
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
147 zpDir = ZenPackCmd.CreateZenPack(packId)
148
149
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')
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')
213
214
215
216 security.declareProtected(ZEN_MANAGE_DMD, 'manage_installZenPack')
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
244
245 import re
246 base_filename = re.split(r"\\|/", zenpack.filename)[-1]
247
248
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
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
295
296
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