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

Source Code for Module ZenModel.ZenPackLoader

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, 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__='Base Classes for loading gunk in a ZenPack' 
 15   
 16  import Globals 
 17  from Products.ZenReports.ReportLoader import ReportLoader 
 18  from Products.ZenUtils.Utils import zenPath, binPath 
 19   
 20  import os 
 21  import ConfigParser 
 22  import subprocess 
 23  import logging 
 24  log = logging.getLogger('zen.ZPLoader') 
 25   
 26  CONFIG_FILE = 'about.txt' 
 27  CONFIG_SECTION_ABOUT = 'about' 
 28   
29 -def findFiles(pack, directory, filter=None):
30 result = [] 31 if isinstance(pack, basestring): 32 path = os.path.join(pack, directory) 33 else: 34 path = pack.path(directory) 35 for p, ds, fs in os.walk(path): 36 if not os.path.split(p)[-1].startswith('.'): 37 for f in fs: 38 if filter is None or filter(f): 39 result.append(os.path.join(p, f)) 40 return result
41
42 -def findDirectories(pack, directory):
43 result = [] 44 for p, ds, fs in os.walk(pack.path(directory)): 45 if not os.path.split(p)[-1].startswith('.'): 46 for d in ds: 47 result.append(os.path.join(p, d)) 48 return result
49
50 -def branchAfter(filename, directory, prefix = ""):
51 "return the branch after the given directory name" 52 path = filename.split('/') 53 return prefix + '/'.join(path[path.index(directory)+1:])
54 55
56 -class ZenPackLoader:
57 58 name = "Set This Name" 59
60 - def load(self, pack, app):
61 """Load things from the ZenPack and put it 62 into the app"""
63
64 - def unload(self, pack, app, leaveObjects=False):
65 """Remove things from Zenoss defined in the ZenPack"""
66
67 - def list(self, pack, app):
68 "List the items that would be loaded from the given (unpacked) ZenPack"
69
70 - def upgrade(self, pack, app):
71 "Run an upgrade on an existing pack"
72 73 from xml.sax import make_parser 74
75 -class ZPLObject(ZenPackLoader):
76 77 name = "Objects" 78
79 - def load(self, pack, app):
80 from Products.ZenRelations.ImportRM import ImportRM 81 class AddToPack(ImportRM): 82 def endElement(self, name): 83 if name == 'object': 84 obj = self.objstack[-1] 85 log.debug('Now adding %s', obj.getPrimaryUrlPath()) 86 try: 87 obj.buildRelations() 88 obj.removeRelation('pack') 89 obj.addRelation('pack', pack) 90 except Exception, ex: 91 log.exception("Error adding pack to %s", 92 obj.getPrimaryUrlPath()) 93 94 ImportRM.endElement(self, name)
95 importer = AddToPack(noopts=True, app=app) 96 importer.options.noindex = True 97 for f in self.objectFiles(pack): 98 log.info("Loading %s", f) 99 importer.loadObjectFromXML(xmlfile=f) 100 101
102 - def parse(self, filename, handler):
103 parser = make_parser() 104 parser.setContentHandler(handler) 105 parser.parse(open(filename))
106 107
108 - def unload(self, pack, app, leaveObjects=False):
109 if leaveObjects: 110 return 111 from Products.ZenRelations.Exceptions import ObjectNotFound 112 dmd = app.zport.dmd 113 objs = pack.packables() 114 objs.sort(lambda x, y: cmp(x.getPrimaryPath(), y.getPrimaryPath())) 115 objs.reverse() 116 for obj in objs: 117 path = obj.getPrimaryPath() 118 path, id = path[:-1], path[-1] 119 obj = dmd.getObjByPath(path) 120 if len(path) > 3: # leave /Services, /Devices, etc. 121 try: 122 try: 123 obj._delObject(id) 124 except ObjectNotFound: 125 obj._delOb(id) 126 except (AttributeError, KeyError), ex: 127 log.warning("Unable to remove %s on %s", id, 128 '/'.join(path))
129
130 - def list(self, pack, unused):
131 return [obj.getPrimaryUrlPath() for obj in pack.packables()]
132 133
134 - def objectFiles(self, pack):
135 def isXml(f): return f.endswith('.xml') 136 return findFiles(pack, 'objects', isXml)
137 138
139 -class ZPLReport(ZPLObject):
140 141 name = "Reports" 142
143 - def load(self, pack, app):
144 class HookReportLoader(ReportLoader): 145 def loadFile(self, root, id, fullname): 146 rpt = ReportLoader.loadFile(self, root, id, fullname) 147 rpt.addRelation('pack', pack) 148 return rpt
149 rl = HookReportLoader(noopts=True, app=app) 150 rl.options.force = True 151 rl.loadDirectory(pack.path('reports')) 152
153 - def upgrade(self, pack, app):
154 self.unload(pack, app) 155 self.load(pack, app)
156
157 - def list(self, pack, unused):
158 return [branchAfter(r, 'reports') for r in findFiles(pack, 'reports')]
159 160
161 -class ZPLDaemons(ZenPackLoader):
162 163 name = "Daemons" 164 165 extensionsToIgnore = ('.svn-base', '.pyc' '~')
166 - def filter(self, f):
167 for ext in self.extensionsToIgnore: 168 if f.endswith(ext): 169 return False 170 return True
171 172
173 - def binPath(self, daemon):
174 return zenPath('bin', os.path.basename(daemon))
175 176
177 - def _genConfFile(self, pack):
178 """ 179 Attempt to generate a conf file for any daemons. 180 """ 181 # We just go on with business, not waiting for this to finish 182 # nor caring if it throws an exception. The conf file is nice 183 # to provide, but not important. 184 try: 185 subprocess.Popen(binPath('create_sample_config.sh'), 186 stdout=subprocess.PIPE, 187 stderr=subprocess.PIPE, 188 cwd=pack.path()) 189 except OSError: 190 pass
191 192
193 - def load(self, pack, unused):
194 for fs in findFiles(pack, 'daemons', filter=self.filter): 195 os.chmod(fs, 0755) 196 path = self.binPath(fs) 197 if os.path.lexists(path): 198 os.remove(path) 199 os.symlink(fs, path) 200 self._genConfFile(pack)
201 202
203 - def upgrade(self, pack, app):
204 self.unload(pack, app) 205 self.load(pack, app)
206 207
208 - def unload(self, pack, unused, leaveObjects=False):
209 for fs in findFiles(pack, 'daemons', filter=self.filter): 210 try: 211 os.remove(self.binPath(fs)) 212 except OSError: 213 pass
214
215 - def list(self, pack, unused):
216 return [branchAfter(d, 'daemons') 217 for d in findFiles(pack, 'daemons', filter=self.filter)]
218 219
220 -class ZPLBin(ZenPackLoader):
221 222 name = "Bin" 223 224 extensionsToIgnore = ('.svn-base', '.pyc' '~')
225 - def filter(self, f):
226 for ext in self.extensionsToIgnore: 227 if f.endswith(ext): 228 return False 229 return True
230
231 - def load(self, pack, unused):
232 for fs in findFiles(pack, 'bin', filter=self.filter): 233 os.chmod(fs, 0755)
234
235 - def upgrade(self, pack, app):
236 self.unload(pack, app) 237 self.load(pack, app)
238
239 - def list(self, pack, unused):
240 return [branchAfter(d, 'bin') 241 for d in findFiles(pack, 'bin', filter=self.filter)]
242 243
244 -class ZPLLibExec(ZenPackLoader):
245 246 name = "LibExec" 247 248 extensionsToIgnore = ('.svn-base', '.pyc' '~')
249 - def filter(self, f):
250 for ext in self.extensionsToIgnore: 251 if f.endswith(ext): 252 return False 253 return True
254
255 - def load(self, pack, unused):
256 for fs in findFiles(pack, 'libexec', filter=self.filter): 257 os.chmod(fs, 0755)
258
259 - def upgrade(self, pack, app):
260 self.unload(pack, app) 261 self.load(pack, app)
262
263 - def list(self, pack, unused):
264 return [branchAfter(d, 'libexec') 265 for d in findFiles(pack, 'libexec', filter=self.filter)]
266 267
268 -class ZPLModelers(ZenPackLoader):
269 270 name = "Modeler Plugins" 271 272
273 - def list(self, pack, unused):
274 return [branchAfter(d, 'plugins') 275 for d in findFiles(pack, 'modeler/plugins')]
276 277
278 -class ZPLSkins(ZenPackLoader):
279 280 name = "Skins" 281 282
283 - def load(self, pack, app):
284 from Products.ZenUtils.Skins import registerSkin 285 skinsDir = pack.path('') 286 if os.path.isdir(skinsDir): 287 registerSkin(app.zport.dmd, skinsDir)
288 289
290 - def upgrade(self, pack, app):
291 self.unload(pack, app) 292 return self.load(pack, app)
293 294
295 - def unload(self, pack, app, leaveObjects=False):
296 from Products.ZenUtils.Skins import unregisterSkin 297 skinsDir = pack.path('') 298 if os.path.isdir(skinsDir): 299 unregisterSkin(app.zport.dmd, skinsDir)
300 301
302 - def list(self, pack, unused):
303 return [branchAfter(d, 'skins') for d in findDirectories(pack, 'skins')]
304 305
306 -class ZPLDataSources(ZenPackLoader):
307 308 name = "DataSources" 309 310
311 - def list(self, pack, unused):
312 return [branchAfter(d, 'datasources') 313 for d in findFiles(pack, 'datasources', 314 lambda f: not f.endswith('.pyc') and f != '__init__.py')]
315 316 317
318 -class ZPLLibraries(ZenPackLoader):
319 320 name = "Libraries" 321 322
323 - def list(self, pack, unused):
324 d = pack.path('lib') 325 if os.path.isdir(d): 326 return [l for l in os.listdir(d)] 327 return []
328
329 -class ZPLAbout(ZenPackLoader):
330 331 name = "About" 332
333 - def getAttributeValues(self, pack):
334 about = pack.path(CONFIG_FILE) 335 result = [] 336 if os.path.exists(about): 337 parser = ConfigParser.SafeConfigParser() 338 parser.read(about) 339 result = [] 340 for key, value in parser.items(CONFIG_SECTION_ABOUT): 341 try: 342 value = eval(value) 343 except: 344 # Blanket exception catchers like this are evil. 345 pass 346 result.append((key, value)) 347 return result
348 349
350 - def load(self, pack, unused):
351 for name, value in self.getAttributeValues(pack): 352 setattr(pack, name, value)
353 354
355 - def upgrade(self, pack, app):
356 self.load(pack, app)
357 358
359 - def list(self, pack, unused):
360 return [('%s %s' % av) for av in self.getAttributeValues(pack)]
361