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, zenPackPath
17 from Products.ZenUtils.ZenScriptBase import ZenScriptBase
18 from Products.ZenUtils.Utils import cleanupSkins, zenPath
19 import transaction
20 from zipfile import ZipFile
21 from StringIO import StringIO
22 import ConfigParser
23 from Products.ZenModel.ZenPackLoader import CONFIG_FILE, CONFIG_SECTION_ABOUT
24 import os, sys
25 import os.path
26
28 "Manage ZenPacks"
29
30
32 "Execute the user's request"
33 self.connect()
34 if self.options.installPackName:
35 if not self.preInstallCheck():
36 self.stop('%s not installed' % self.options.installPackName)
37 if os.path.isfile(self.options.installPackName):
38 packName = self.extract(self.options.installPackName)
39 elif os.path.isdir(self.options.installPackName):
40 if self.options.link:
41 packName = self.linkDir(self.options.installPackName)
42 else:
43 packName = self.copyDir(self.options.installPackName)
44 else:
45 self.stop('%s does not appear to be a valid file or directory.'
46 % self.options.installPackName)
47
48
49
50
51
52 skinsSubdir = zenPath('Products', packName, 'skins', packName)
53 if not os.path.exists(skinsSubdir):
54 os.makedirs(skinsSubdir)
55 self.install(packName)
56
57 elif self.options.removePackName:
58 self.remove(self.options.removePackName)
59
60 elif self.options.list:
61 for zp in self.dmd.packs():
62 f = sys.modules[zp.__module__].__file__
63 if f.endswith('.pyc'):
64 f = f[:-1]
65 print '%s (%s)' % (zp.id, f)
66 for extensionType, lst in zp.list(self.app):
67 print ' %s:' % extensionType
68 for item in lst:
69 print ' %s' % item
70
71 transaction.commit()
72
73
75 ''' Check that prerequisite zenpacks are installed.
76 Return True if no prereqs specified or if they are present.
77 False otherwise.
78 '''
79 if os.path.isfile(self.options.installPackName):
80 zf = ZipFile(self.options.installPackName)
81 for name in zf.namelist():
82 if name.endswith == '/%s' % CONFIG_FILE:
83 sio = StringIO(zf.read())
84 else:
85 return True
86 else:
87 name = os.path.join(self.options.installPackName, CONFIG_FILE)
88 if os.path.isfile(name):
89 fp = open(name)
90 sio = StringIO(fp.read())
91 fp.close()
92 else:
93 return True
94
95 parser = ConfigParser.SafeConfigParser()
96 parser.readfp(sio, name)
97 if parser.has_section(CONFIG_SECTION_ABOUT) \
98 and parser.has_option(CONFIG_SECTION_ABOUT, 'requires'):
99 requires = eval(parser.get(CONFIG_SECTION_ABOUT, 'requires'))
100 if not isinstance(requires, list):
101 requires = [zp.strip() for zp in requires.split(',')]
102 missing = [zp for zp in requires
103 if zp not in self.dataroot.packs.objectIds()]
104 if missing:
105 self.log.error('ZenPack %s was not installed because'
106 % self.options.installPackName
107 + ' it requires the following ZenPack(s): %s'
108 % ', '.join(missing))
109 return False
110 return True
111
112
114 zp = None
115 try:
116 zp = self.dmd.packs._getOb(packName)
117 self.log.info('Upgrading %s' % packName)
118 zp.upgrade(self.app)
119 except AttributeError:
120 try:
121 module = __import__('Products.' + packName, globals(), {}, [''])
122 zp = module.ZenPack(packName)
123 except (ImportError, AttributeError), ex:
124 self.log.debug("Unable to find custom ZenPack (%s), "
125 "defaulting to generic ZenPack",
126 ex)
127 zp = ZenPack(packName)
128 self.dmd.packs._setObject(packName, zp)
129 zp.install(self.app)
130 if zp:
131 for required in zp.requires:
132 try:
133 self.packs._getOb(required)
134 except:
135 self.log.error("Pack %s requires pack %s: not installing",
136 packName, required)
137 return
138 transaction.commit()
139
164
165
167 "Unpack a ZenPack, and return the name"
168 if not os.path.isfile(fname):
169 self.stop('Unable to open file "%s"' % fname)
170 zf = ZipFile(fname)
171 name = zf.namelist()[0]
172 packName = name.split('/')[0]
173 root = zenPackPath(packName)
174 self.log.debug('Extracting ZenPack "%s"' % packName)
175 for name in zf.namelist():
176 fullname = zenPath('Products', name)
177 self.log.debug('Extracting %s' % name)
178 if name.find('/.svn') > -1: continue
179 if name.endswith('~'): continue
180 if name.endswith('/'):
181 if not os.path.exists(fullname):
182 os.makedirs(fullname, 0750)
183 else:
184 base = os.path.dirname(fullname)
185 if not os.path.isdir(base):
186 os.makedirs(base, 0750)
187 file(fullname, 'wb').write(zf.read(name))
188 return packName
189
190
192 '''Copy an unzipped zenpack to the appropriate location.
193 Return the name.
194 '''
195
196 if srcDir.endswith('/'):
197 srcDir = srcDir[:-1]
198
199 if not os.path.isdir(srcDir):
200 self.stop('Specified directory does not appear to exist: %s' %
201 srcDir)
202
203
204 packName = os.path.split(srcDir)[1]
205 root = zenPackPath(packName)
206
207
208 if os.path.exists(root) and os.path.samefile(root, srcDir):
209 self.log.debug('Directory already in %s, not copying.',
210 zenPath('Products'))
211 return packName
212
213
214 self.log.debug('Copying %s' % packName)
215 result = os.system('cp -r %s %s' % (srcDir, zenPath('Products')))
216 if result == -1:
217 self.stop('Error copying %s to %s' % (srcDir, zenPath('Products')))
218
219 return packName
220
221
223 '''Symlink the srcDir into Products
224 Return the name.
225 '''
226
227 if srcDir.endswith('/'):
228 srcDir = srcDir[:-1]
229
230
231 srcDir = os.path.abspath(srcDir)
232
233 if not os.path.isdir(srcDir):
234 self.stop('Specified directory does not appear to exist: %s' %
235 srcDir)
236
237
238 packName = os.path.split(srcDir)[1]
239 root = zenPackPath(packName)
240
241
242 if os.path.exists(root) and os.path.samefile(root, srcDir):
243 self.log.debug('Directory already in %s, not copying.',
244 zenPath('Products'))
245 return packName
246
247 targetdir = zenPath("Products", packName)
248 cmd = 'test -d %s && rm -rf %s' % (targetdir, targetdir)
249 r = os.system(cmd)
250 cmd = 'ln -s %s %s' % (srcDir, zenPath("Products"))
251 r = os.system(cmd)
252
253 return packName
254
255
256 - def stop(self, why):
257 self.log.error("zenpack stopped: %s", why)
258 import sys
259 sys.exit(1)
260
261
263 self.parser.add_option('--install',
264 dest='installPackName',
265 default=None,
266 help="name of the pack to install")
267 self.parser.add_option('--remove',
268 dest='removePackName',
269 default=None,
270 help="name of the pack to remove")
271 self.parser.add_option('--list',
272 dest='list',
273 action="store_true",
274 default=False,
275 help="list installed zenpacks"
276 " and associated files")
277 self.parser.add_option('--link',
278 dest='link',
279 action="store_true",
280 default=False,
281 help="symlink the zenpack dir instead of"
282 " copying to $ZENHOME/Products")
283 ZenScriptBase.buildOptions(self)
284
285 if __name__ == '__main__':
286 zp = ZenPackCmd()
287 zp.run()
288