1
2
3
4
5
6
7
8
9
10
11
12
13 __doc__ = "Manage ZenPacks"
14
15 import Globals
16 from Products.ZenModel.ZenPack import ZenPack, ZenPackException, \
17 ZenPackNeedMigrateException
18 from Products.ZenUtils.ZenScriptBase import ZenScriptBase
19 from Products.ZenUtils.Utils import cleanupSkins, zenPath
20 import transaction
21 from zipfile import ZipFile
22 from StringIO import StringIO
23 import ConfigParser
24 import Products.ZenModel.ZenPackLoader as ZPL
25 from Products.ZenModel.ZenPackLoader import CONFIG_FILE, CONFIG_SECTION_ABOUT
26 import os, sys
27 import ZenPackCmd as EggPackCmd
28
29
30 -def RemoveZenPack(dmd, packName, log=None,
31 skipDepsCheck=False, leaveObjects=True,
32 deleteFiles=True):
69
70
72 "Manage ZenPacks"
73
74
76 "Execute the user's request"
77
78 if self.args:
79 print "Require one of --install, --remove or --list flags."
80 self.parser.print_help()
81 return
82
83 if self.options.installPackName:
84 eggInstall = (self.options.installPackName.lower().endswith('.egg')
85 or os.path.exists(os.path.join(self.options.installPackName,
86 'setup.py')))
87
88
89
90 class ZPProxy:
91 def __init__(self, zpId):
92 self.id = zpId
93 def path(self, *parts):
94 return zenPath('Products', self.id, *parts)
95 if self.options.installPackName and self.options.filesOnly:
96 if eggInstall:
97 return EggPackCmd.InstallZenPack(None,
98 self.options.installPackName,
99 filesOnly=True)
100 packName = self.extract(self.options.installPackName)
101 proxy = ZPProxy(packName)
102 for loader in (ZPL.ZPLDaemons(), ZPL.ZPLBin(), ZPL.ZPLLibExec()):
103 loader.load(proxy, None)
104 return
105 if self.options.removePackName and self.options.filesOnly:
106
107
108 proxy = ZPProxy(self.options.removePackName)
109 for loader in (ZPL.ZPLDaemons(), ZPL.ZPLBin(), ZPL.ZPLLibExec()):
110 loader.unload(proxy, None)
111 os.system('rm -rf %s' % zenPath('Products',
112 self.options.removePackName))
113 return
114
115
116
117 self.connect()
118
119 if not getattr(self.dmd, 'ZenPackManager', None):
120 raise ZenPackNeedMigrateException('Your Zenoss database appears'
121 ' to be out of date. Try running zenmigrate to update.')
122
123 if self.options.installPackName:
124 if eggInstall:
125 return EggPackCmd.InstallEggAndZenPack(
126 self.dmd,
127 self.options.installPackName,
128 link=self.options.link,
129 filesOnly=False,
130 previousVersion= self.options.previousVersion)
131 if not self.preInstallCheck():
132 self.stop('%s not installed' % self.options.installPackName)
133 if os.path.isfile(self.options.installPackName):
134 packName = self.extract(self.options.installPackName)
135 elif os.path.isdir(self.options.installPackName):
136 if self.options.link:
137 packName = self.linkDir(self.options.installPackName)
138 else:
139 packName = self.copyDir(self.options.installPackName)
140 else:
141 self.stop('%s does not appear to be a valid file or directory.'
142 % self.options.installPackName)
143
144
145
146
147
148 skinsSubdir = zenPath('Products', packName, 'skins', packName)
149 if not os.path.exists(skinsSubdir):
150 os.makedirs(skinsSubdir, 0750)
151 self.install(packName)
152
153
154
155
156 elif self.options.removePackName:
157 pack = self.dmd.ZenPackManager.packs._getOb(
158 self.options.removePackName, None)
159 if not pack:
160 raise ZenPackException('ZenPack %s is not installed.' %
161 self.options.removePackName)
162 if pack.isEggPack():
163 return EggPackCmd.RemoveZenPack(self.dmd,
164 self.options.removePackName)
165 RemoveZenPack(self.dmd, self.options.removePackName, self.log)
166
167 elif self.options.list:
168 for zpId in self.dmd.ZenPackManager.packs.objectIds():
169 try:
170 zp = self.dmd.ZenPackManager.packs._getOb(zpId, None)
171 except AttributeError:
172 zp = None
173 if not zp:
174 desc = 'broken'
175 elif zp.isEggPack():
176 desc = zp.eggPath()
177 else:
178 desc = zp.path()
179 print('%s (%s)' % (zpId, desc))
180
181 transaction.commit()
182
183
221
222
224 zp = None
225 try:
226 zp = self.dmd.ZenPackManager.packs._getOb(packName)
227 self.log.info('Upgrading %s' % packName)
228 zp.upgrade(self.app)
229 except AttributeError:
230 try:
231 module = __import__('Products.' + packName, globals(), {}, [''])
232 zp = module.ZenPack(packName)
233 except (ImportError, AttributeError), ex:
234 self.log.debug("Unable to find custom ZenPack (%s), "
235 "defaulting to generic ZenPack",
236 ex)
237 zp = ZenPack(packName)
238 self.dmd.ZenPackManager.packs._setObject(packName, zp)
239 zp = self.dmd.ZenPackManager.packs._getOb(packName)
240 zp.install(self.app)
241 if zp:
242 for required in zp.requires:
243 try:
244 self.dmd.ZenPackManager.packs._getOb(required)
245 except:
246 self.log.error("Pack %s requires pack %s: not installing",
247 packName, required)
248 return
249 transaction.commit()
250
252 "Unpack a ZenPack, and return the name"
253 if not os.path.isfile(fname):
254 self.stop('Unable to open file "%s"' % fname)
255 zf = ZipFile(fname)
256 name = zf.namelist()[0]
257 packName = name.split('/')[0]
258 self.log.debug('Extracting ZenPack "%s"' % packName)
259 for name in zf.namelist():
260 fullname = zenPath('Products', name)
261 self.log.debug('Extracting %s' % name)
262 if name.find('/.svn') > -1: continue
263 if name.endswith('~'): continue
264 if name.endswith('/'):
265 if not os.path.exists(fullname):
266 os.makedirs(fullname, 0750)
267 else:
268 base = os.path.dirname(fullname)
269 if not os.path.isdir(base):
270 os.makedirs(base, 0750)
271 file(fullname, 'wb').write(zf.read(name))
272 return packName
273
274
276 '''Copy an unzipped zenpack to the appropriate location.
277 Return the name.
278 '''
279
280 if srcDir.endswith('/'):
281 srcDir = srcDir[:-1]
282
283 if not os.path.isdir(srcDir):
284 self.stop('Specified directory does not appear to exist: %s' %
285 srcDir)
286
287
288 packName = os.path.split(srcDir)[1]
289 root = zenPath('Products', packName)
290
291
292 if os.path.exists(root) and os.path.samefile(root, srcDir):
293 self.log.debug('Directory already in %s, not copying.',
294 zenPath('Products'))
295 return packName
296
297
298 self.log.debug('Copying %s' % packName)
299 result = os.system('cp -r %s %s' % (srcDir, zenPath('Products')))
300 if result == -1:
301 self.stop('Error copying %s to %s' % (srcDir, zenPath('Products')))
302
303 return packName
304
305
307 '''Symlink the srcDir into Products
308 Return the name.
309 '''
310
311 if srcDir.endswith('/'):
312 srcDir = srcDir[:-1]
313
314
315 srcDir = os.path.abspath(srcDir)
316
317 if not os.path.isdir(srcDir):
318 self.stop('Specified directory does not appear to exist: %s' %
319 srcDir)
320
321
322 packName = os.path.split(srcDir)[1]
323 root = zenPath('Products', packName)
324
325
326 if os.path.exists(root) and os.path.samefile(root, srcDir):
327 self.log.debug('Directory already in %s, not copying.',
328 zenPath('Products'))
329 return packName
330
331 targetdir = zenPath("Products", packName)
332 cmd = 'test -d %s && rm -rf %s' % (targetdir, targetdir)
333 os.system(cmd)
334 cmd = 'ln -s %s %s' % (srcDir, zenPath("Products"))
335 os.system(cmd)
336
337 return packName
338
339
340 - def stop(self, why):
341 self.log.error("zenpack stopped: %s", why)
342 sys.exit(1)
343
344
346 self.parser.add_option('--install',
347 dest='installPackName',
348 default=None,
349 help="Path to the ZenPack to install.")
350
351
352
353
354
355
356
357
358
359
360 self.parser.add_option('--remove',
361 dest='removePackName',
362 default=None,
363 help="Name of the ZenPack to remove.")
364 self.parser.add_option('--list',
365 dest='list',
366 action="store_true",
367 default=False,
368 help='List installed ZenPacks')
369 self.parser.add_option('--link',
370 dest='link',
371 action="store_true",
372 default=False,
373 help="Install the ZenPack in place, without "
374 "copying into $ZENHOME/ZenPacks.")
375 self.parser.add_option('--files-only',
376 dest='filesOnly',
377 action="store_true",
378 default=False,
379 help='Install the ZenPack files onto the '
380 'filesystem, but do not install the '
381 'ZenPack into Zenoss.')
382 self.parser.add_option('--previousversion',
383 dest='previousVersion',
384 default=None,
385 help="Previous version of the zenpack;"
386 ' used during upgrades')
387
388 ZenScriptBase.buildOptions(self)
389
390 if __name__ == '__main__':
391 try:
392 zp = ZenPackCmd()
393 zp.run()
394 except Exception, e:
395 sys.stderr.write('ERROR: zenpack command failed. Reason: %s\n' % str(e))
396 sys.exit(-1)
397