Package Products :: Package ZenModel :: Module DataRoot
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenModel.DataRoot

  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__="""DataRoot 
 15   
 16  DataRoot is the object manager which contains all confmon 
 17  data objects.  It can be used as a global acquisition  
 18  name space. 
 19  """ 
 20   
 21  import re 
 22  from zope.interface import implements 
 23  from AccessControl import ClassSecurityInfo 
 24  from AccessControl import getSecurityManager 
 25  from OFS.OrderedFolder import OrderedFolder 
 26  from Globals import DTMLFile 
 27  from Globals import InitializeClass 
 28  from Globals import DevelopmentMode 
 29  from Products.ZenModel.SiteError import SiteError 
 30  from Products.ZenModel.ZenModelBase import ZenModelBase 
 31  from Products.ZenModel.ZenMenuable import ZenMenuable 
 32  from Products.ZenRelations.RelSchema import * 
 33  from Products.ZenUtils.IpUtil import IpAddressError 
 34  from Products.ZenWidgets import messaging 
 35  from Commandable import Commandable 
 36  import socket 
 37  import os 
 38  import sys 
 39  from sets import Set 
 40  import string 
 41   
 42  from Products.ZenUtils.Utils import zenPath, binPath 
 43  from Products.ZenUtils.Utils import extractPostContent 
 44  from Products.ZenUtils.jsonutils import json 
 45   
 46  from Products.ZenEvents.Exceptions import * 
 47   
 48  from ZenModelRM import ZenModelRM 
 49  from ZenossSecurity import ZEN_COMMON, ZEN_MANAGE_DMD, ZEN_VIEW 
 50  from interfaces import IDataRoot 
51 52 -def manage_addDataRoot(context, id, title = None, REQUEST = None):
53 """make a device""" 54 dr = DataRoot(id, title) 55 context._setObject(id, dr) 56 57 if REQUEST is not None: 58 REQUEST['RESPONSE'].redirect(context.absolute_url() + '/manage_main')
59 60 61 addDataRoot = DTMLFile('dtml/addDataRoot',globals()) 62 63 __pychecker__='no-override'
64 65 -class DataRoot(ZenModelRM, OrderedFolder, Commandable, ZenMenuable):
66 implements(IDataRoot) 67 68 meta_type = portal_type = 'DataRoot' 69 70 manage_main = OrderedFolder.manage_main 71 72 manage_options = OrderedFolder.manage_options 73 74 #setTitle = DTMLFile('dtml/setTitle',globals()) 75 76 _rq = True 77 uuid = None 78 availableVersion = None 79 lastVersionCheck = 0 80 lastVersionCheckAttempt = 0 81 versionCheckOptIn = True 82 reportMetricsOptIn = True 83 acceptedTerms = True 84 instanceIdentifier = 'Zenoss' 85 smtpHost = 'localhost' 86 pageCommand = '$ZENHOME/bin/zensnpp localhost 444 $RECIPIENT' 87 smtpPort = 25 88 smtpUser = '' 89 smtpPass = '' 90 smtpUseTLS = 0 91 emailFrom = '' 92 iconMap = {} 93 geomapapikey = '' 94 geocache = '' 95 version = "" 96 97 _properties=( 98 {'id':'title', 'type': 'string', 'mode':'w'}, 99 {'id':'prodStateDashboardThresh','type':'int','mode':'w'}, 100 {'id':'prodStateConversions','type':'lines','mode':'w'}, 101 {'id':'priorityConversions','type':'lines','mode':'w'}, 102 {'id':'priorityDashboardThresh','type':'int','mode':'w'}, 103 {'id':'statusConversions','type':'lines','mode':'w'}, 104 {'id':'interfaceStateConversions','type':'lines','mode':'w'}, 105 {'id':'administrativeRoles','type':'lines','mode':'w'}, 106 {'id':'uuid', 'type': 'string', 'mode':'w'}, 107 {'id':'availableVersion', 'type': 'string', 'mode':'w'}, 108 {'id':'lastVersionCheck', 'type': 'long', 'mode':'w'}, 109 {'id':'lastVersionCheckAttempt', 'type': 'long', 'mode':'w'}, 110 {'id':'versionCheckOptIn', 'type': 'boolean', 'mode':'w'}, 111 {'id':'reportMetricsOptIn', 'type': 'boolean', 'mode':'w'}, 112 {'id':'instanceIdentifier', 'type': 'string', 'mode':'w'}, 113 {'id':'smtpHost', 'type': 'string', 'mode':'w'}, 114 {'id':'smtpPort', 'type': 'int', 'mode':'w'}, 115 {'id':'pageCommand', 'type': 'string', 'mode':'w'}, 116 {'id':'smtpUser', 'type': 'string', 'mode':'w'}, 117 {'id':'smtpPass', 'type': 'string', 'mode':'w'}, 118 {'id':'smtpUseTLS', 'type': 'int', 'mode':'w'}, 119 {'id':'emailFrom', 'type': 'string', 'mode':'w'}, 120 {'id':'geomapapikey', 'type': 'string', 'mode':'w'}, 121 {'id':'geocache', 'type': 'string', 'mode':'w'}, 122 ) 123 124 _relations = ( 125 ('userCommands', ToManyCont(ToOne, 'Products.ZenModel.UserCommand', 'commandable')), 126 # packs is depracated. Has been moved to dmd.ZenPackManager.packs 127 # Should be removed post Zenoss 2.2 128 # TODO 129 ('packs', ToManyCont(ToOne, 'Products.ZenModel.ZenPack', 'root')), 130 ('zenMenus', ToManyCont( 131 ToOne, 'Products.ZenModel.ZenMenu', 'menuable')), 132 ) 133 134 # Screen action bindings (and tab definitions) 135 factory_type_information = ( 136 { 137 'id' : 'DataRoot', 138 'meta_type' : 'DataRoot', 139 'description' : """Arbitrary device grouping class""", 140 'icon' : 'DataRoot_icon.gif', 141 'product' : 'ZenModel', 142 'factory' : 'manage_addStatusMonitorconf', 143 'immediate_view' : 'Dashboard', 144 'actions' : 145 ( 146 { 'id' : 'settings' 147 , 'name' : 'Settings' 148 , 'action' : 'editSettings' 149 , 'permissions' : ( "Manage DMD", ) 150 }, 151 { 'id' : 'manage' 152 , 'name' : 'Commands' 153 , 'action' : 'dataRootManage' 154 , 'permissions' : ('Manage DMD',) 155 }, 156 { 'id' : 'users' 157 , 'name' : 'Users' 158 , 'action' : 'ZenUsers/manageUserFolder' 159 , 'permissions' : ( 'Manage DMD', ) 160 }, 161 { 'id' : 'packs' 162 , 'name' : 'ZenPacks' 163 , 'action' : 'ZenPackManager/viewZenPacks' 164 , 'permissions' : ( "Manage DMD", ) 165 }, 166 { 'id' : 'jobs' 167 , 'name' : 'Jobs' 168 , 'action' : 'joblist' 169 , 'permissions' : ( "Manage DMD", ) 170 }, 171 { 'id' : 'portlets' 172 , 'name' : 'Portlets' 173 , 'action' : 'editPortletPerms' 174 , 'permissions' : ( "Manage DMD", ) 175 }, 176 { 'id' : 'daemons' 177 , 'name' : 'Daemons' 178 , 'action' : '../About/zenossInfo' 179 , 'permissions' : ( "Manage DMD", ) 180 }, 181 { 'id' : 'versions' 182 , 'name' : 'Versions' 183 , 'action' : '../About/zenossVersions' 184 , 'permissions' : ( "Manage DMD", ) 185 }, 186 { 'id' : 'backups' 187 , 'name' : 'Backups' 188 , 'action' : 'backupInfo' 189 , 'permissions' : ( "Manage DMD", ) 190 }, 191 ) 192 }, 193 ) 194 195 security = ClassSecurityInfo() 196 197 # production state threshold at which devices show on dashboard 198 prodStateDashboardThresh = 1000 199 200 # priority threshold at which devices show on dashboard 201 priorityDashboardThresh = 2 202 203 prodStateConversions = [ 204 'Production:1000', 205 'Pre-Production:500', 206 'Test:400', 207 'Maintenance:300', 208 'Decommissioned:-1', 209 ] 210 211 priorityConversions = [ 212 'Highest:5', 213 'High:4', 214 'Normal:3', 215 'Low:2', 216 'Lowest:1', 217 'Trivial:0', 218 ] 219 220 statusConversions = [ 221 'Up:0', 222 'None:-1', 223 'No DNS:-2', 224 ] 225 226 interfaceStateConversions = [ 227 'up:1', 228 'down:2', 229 'testing:3', 230 'unknown:4', 231 'dormant:5', 232 'notPresent:6', 233 'lowerLayerDown:7', 234 ] 235 236 administrativeRoles = ( 237 "Administrator", 238 "Analyst", 239 "Engineer", 240 "Tester", 241 ) 242 243 defaultDateRange = 129600 244 performanceDateRanges = [ 245 ('Hourly',129600,), 246 ('Daily',864000,), 247 ('Weekly',3628800,), 248 ('Monthly',41472000,), 249 ('Yearly',62208000,) 250 ] 251 252 253 # when calculating the primary path this will be its root 254 zPrimaryBasePath = ("", "zport") 255 256
257 - def __init__(self, id, title=None):
258 ZenModelRM.__init__(self, id, title) 259 from ZVersion import VERSION 260 self.version = "Zenoss " + VERSION
261
262 - def index_html(self):
263 """ 264 Override to force redirection to quickstart. 265 """ 266 if not self._rq: 267 return self.unrestrictedTraverse('quickstart')() 268 return self()
269
270 - def getEventCount(self, **kwargs):
271 """Return the current event list for this managed entity. 272 """ 273 return self.ZenEventManager.getEventCount(**kwargs)
274 275 security.declareProtected(ZEN_COMMON, 'getEventClassNames')
276 - def getEventClassNames(self):
277 """ 278 Get a list of all event class names within the permission scope. 279 """ 280 return self.Events.getOrganizerNames()
281 282
283 - def getDmdRoots(self):
284 return filter(lambda o: o.isInTree, self.objectValues())
285 286
287 - def exportXmlHook(self,ofile, ignorerels):
288 map(lambda x: x.exportXml(ofile, ignorerels), self.getDmdRoots())
289 290 291 security.declareProtected(ZEN_COMMON, 'getProdStateConversions')
292 - def getProdStateConversions(self):
293 """getProdStateConversions() -> return a list of tuples 294 for prodstat select edit box""" 295 return self.getConversions(self.prodStateConversions)
296 297 298 security.declareProtected(ZEN_COMMON, 'convertProdState')
299 - def convertProdState(self, prodState):
300 '''convert a numeric production state to a 301 textual representation using the prodStateConversions 302 map''' 303 return self.convertAttribute(prodState, self.prodStateConversions)
304 305 306 security.declareProtected(ZEN_COMMON, 'getStatusConversions')
307 - def getStatusConversions(self):
308 """get text strings for status field""" 309 return self.getConversions(self.statusConversions)
310 311 312 security.declareProtected(ZEN_COMMON, 'convertStatus')
313 - def convertStatus(self, status):
314 """get text strings for status field""" 315 return self.convertAttribute(status, self.statusConversions)
316 317 security.declareProtected(ZEN_COMMON, 'getPriorityConversions')
318 - def getPriorityConversions(self):
319 return self.getConversions(self.priorityConversions)
320 321 security.declareProtected(ZEN_COMMON, 'convertPriority')
322 - def convertPriority(self, priority):
324 325 security.declareProtected(ZEN_COMMON, 'getInterfaceStateConversions')
327 """get text strings for interface status""" 328 if hasattr(self, 'interfaceStateConversions'): 329 return self.getConversions(self.interfaceStateConversions)
330 331 332 security.declareProtected(ZEN_COMMON, 'convertAttribute')
333 - def convertAttribute(self, numbValue, conversions):
334 '''convert a numeric production state to a 335 textual representation using the prodStateConversions 336 map''' 337 numbValue = int(numbValue) 338 for line in conversions: 339 line = line.rstrip() 340 (name, number) = line.split(':') 341 if int(number) == numbValue: 342 return name 343 return numbValue
344 345 security.declareProtected(ZEN_COMMON, 'convertStatusToDot')
346 - def convertStatusToDot(self, status):
347 colors = ['green', 'yellow', 'orange', 'red'] 348 try: 349 return colors[status] 350 except IndexError: 351 return 'grey'
352 353 security.declareProtected(ZEN_COMMON, 'getConversions')
354 - def getConversions(self, attribute):
355 """get the text list of itmes that convert to ints""" 356 convs = [] 357 for item in attribute: 358 tup = item.split(':') 359 try: 360 tup[1] = int(tup[1]) 361 except (IndexError, ValueError): 362 continue 363 convs.append(tup) 364 return convs
365 366 security.declarePublic('filterObjectsRegex')
367 - def filterObjectsRegex(self, filter, objects, 368 filteratt='id', negatefilter=0):
369 """filter a list of objects based on a regex""" 370 filter = re.compile(filter).search 371 filteredObjects = [] 372 for obj in objects: 373 value = getattr(obj, filteratt, None) 374 if callable(value): 375 value = value() 376 fvalue = filter(value) 377 if (fvalue and not negatefilter) or (not fvalue and negatefilter): 378 filteredObjects.append(obj) 379 return filteredObjects
380 381 382 security.declareProtected('View', 'myUserGroups')
383 - def myUserGroups(self):
384 user = self.REQUEST.get('AUTHENTICATED_USER') 385 if hasattr(user, 'getGroups'): 386 return user.getGroups() 387 else: 388 return ()
389 390 391 security.declareProtected('View', 'getAllUserGroups')
392 - def getAllUserGroups(self):
393 return self.acl_users.getGroups()
394 395 396 security.declareProtected(ZEN_VIEW, 'zenoss_error_message')
397 - def zenoss_error_message(self,error_type,error_value, 398 error_traceback,error_message):
399 """Return an error page that is more friendly then the standard stack 400 trace + feedback page for ConflictErrors and MySQL errors (we need to 401 add out of disk space errors). If one of these is not found we return 402 the old stacktrace page 403 """ 404 from ZODB.POSException import ConflictError 405 from Products.ZenEvents.Exceptions import MySQLConnectionError 406 from _mysql_exceptions import MySQLError 407 if isinstance(error_value, ConflictError): 408 return self.zenoss_conflict_error_message() 409 elif isinstance(error_value, MySQLConnectionError) \ 410 or isinstance(error_value, MySQLError): 411 return self.zenoss_mysql_error_message(error_value=error_value) 412 return self.zenoss_feedback_error_message(error_type=error_type, 413 error_value=error_value, 414 error_traceback=error_traceback)
415 416
417 - def reportError(self):
418 ''' send an email to the zenoss error email address 419 then send user to a thankyou page or an email error page. 420 ''' 421 if self.smtpHost: host = self.smtpHost 422 else: host = None 423 port = self.smtpPort and self.smtpPort or 25 424 usetls = self.smtpUseTLS 425 usr = self.smtpUser 426 pwd = self.smtpPass 427 428 mailSent = SiteError.sendErrorEmail( 429 self.REQUEST.errorType, 430 self.REQUEST.errorValue, 431 self.REQUEST.errorTrace, 432 self.REQUEST.errorUrl, 433 self.About.getZenossRevision(), 434 self.About.getZenossVersionShort(), 435 self.REQUEST.contactName, 436 self.REQUEST.contactEmail, 437 self.REQUEST.comments, 438 host, port, usetls, usr, pwd) 439 if not mailSent: 440 body = SiteError.createReport( 441 self.REQUEST.errorType, 442 self.REQUEST.errorValue, 443 self.REQUEST.errorTrace, 444 self.REQUEST.errorUrl, 445 self.About.getZenossRevision(), 446 self.About.getZenossVersionShort(), 447 True, 448 self.REQUEST.contactName, 449 self.REQUEST.contactEmail, 450 self.REQUEST.comments) 451 return self.errorEmailFailure(toAddress=SiteError.ERRORS_ADDRESS, 452 body=body) 453 return self.errorEmailThankYou()
454 455 456 #security.declareProtected('View', 'writeExportRows')
457 - def writeExportRows(self, fieldsAndLabels, objects, out=None):
458 '''Write out csv rows with the given objects and fields. 459 If out is not None then call out.write() with the result and return None 460 otherwise return the result. 461 Each item in fieldsAndLabels is either a string representing a 462 field/key/index (see getDataField) or it is a tuple of (field, label) 463 where label is the string to be used in the first row as label 464 for that column. 465 Objects can be either dicts, lists/tuples or other objects. Field 466 is interpreted as a key, index or attribute depending on what 467 object is. 468 Method names can be passed instead of attribute/key/indices as field. 469 In this case the method is called and the return value is used in 470 the export. 471 ''' 472 import csv 473 import StringIO 474 if out: 475 buffer = out 476 else: 477 buffer = StringIO.StringIO() 478 fields = [] 479 labels = [] 480 if not fieldsAndLabels: 481 fieldsAndLabels = [] 482 if not objects: 483 objects = [] 484 for p in fieldsAndLabels: 485 if isinstance(p, tuple): 486 fields.append(p[0]) 487 labels.append(p[1]) 488 else: 489 fields.append(p) 490 labels.append(p) 491 writer = csv.writer(buffer) 492 writer.writerow(labels) 493 def getDataField(thing, field): 494 if isinstance(thing, dict): 495 value = thing.get(field, '') 496 elif isinstance(thing, list) or isinstance(thing, tuple): 497 value = thing[int(field)] 498 else: 499 value = getattr(thing, field, '') 500 if isinstance(value, ZenModelBase): 501 value = value.id 502 elif callable(value): 503 value = value() 504 if value == None: 505 value = '' 506 return str(value)
507 for o in objects: 508 writer.writerow([getDataField(o,f) for f in fields]) 509 if out: 510 result = None 511 else: 512 result = buffer.getvalue() 513 return result
514 515
516 - def getUserCommandTargets(self):
517 ''' Called by Commandable.doCommand() to ascertain objects on which 518 a UserCommand should be executed. 519 ''' 520 raise NotImplemented
521 522
523 - def getUrlForUserCommands(self):
524 return self.getPrimaryUrlPath() + '/dataRootManage'
525 526
527 - def getEmailFrom(self):
528 ''' Return self.emailFrom or a suitable default 529 ''' 530 return self.emailFrom or 'zenossuser_%s@%s' % ( 531 getSecurityManager().getUser().getId(), socket.getfqdn())
532 533
534 - def checkValidId(self, id, prep_id = False):
535 """Checks a valid id 536 """ 537 if len(id) > 128: 538 return 'ZenPack names can not be longer than 128 characters.' 539 allowed = Set(list(string.ascii_letters) 540 + list(string.digits) 541 + ['_']) 542 attempted = Set(list(id)) 543 if not attempted.issubset(allowed): 544 return 'Only letters, digits and underscores are allowed' + \ 545 ' in ZenPack names.' 546 return ZenModelRM.checkValidId(self, id, prep_id)
547 548
549 - def setGeocodeCache(self, REQUEST=None):
550 """ Store a JSON representation of 551 the Google Maps geocode cache 552 """ 553 cache = extractPostContent(REQUEST) 554 try: cache = cache.decode('utf-8') 555 except: pass 556 self.geocache = cache 557 return True
558
559 - def clearGeocodeCache(self, REQUEST=None):
560 """ 561 Clear the Google Maps cache. 562 """ 563 self.geocache = ''
564 565 security.declareProtected(ZEN_COMMON, 'getGeoCache') 566 @json
567 - def getGeoCache(self):
568 cachestr = self.geocache 569 for char in ('\\r', '\\n'): 570 cachestr = cachestr.replace(char, ' ') 571 cachestr = cachestr.replace("'", r"\'") 572 return cachestr
573
574 - def goToStatusPage(self, objid, REQUEST=None):
575 """ Find a device or network and redirect 576 to its status page. 577 """ 578 import urllib 579 objid = urllib.unquote(objid) 580 try: 581 devid = objid 582 if not devid.endswith('*'): devid += '*' 583 obj = self.Devices.findDevice(devid) 584 except: 585 obj=None 586 if not obj: 587 try: 588 obj = self.Networks.getNet(objid) 589 except IpAddressError: 590 return None 591 if not obj: return None 592 if REQUEST is not None: 593 REQUEST['RESPONSE'].redirect(obj.getPrimaryUrlPath())
594 595
596 - def getXMLEdges(self, objid, depth=1, filter="/"):
597 """ Get the XML representation of network nodes 598 and edges using the obj with objid as a root 599 """ 600 import urllib 601 objid = urllib.unquote(objid) 602 try: 603 devid = objid 604 if not devid.endswith('*'): devid += '*' 605 obj = self.Devices.findDevice(devid) 606 except: obj=None 607 if not obj: 608 obj = self.Networks.getNet(objid) 609 if not obj: 610 return '<graph><Start name="%s"/></graph>' % objid 611 return obj.getXMLEdges(int(depth), filter, 612 start=(obj.id,obj.getPrimaryUrlPath()))
613 614 615 security.declareProtected(ZEN_MANAGE_DMD, 'getBackupFilesInfo')
616 - def getBackupFilesInfo(self):
617 """ 618 Retrieve a list of dictionaries describing the files in 619 $ZENHOME/backups. 620 """ 621 import stat 622 import os 623 import datetime 624 import operator 625 626 def FmtFileSize(size): 627 for power, units in ((3, 'GB'), (2, 'MB'), (1, 'KB')): 628 if size > pow(1024, power): 629 fmt = '%.2f %s' % ((size * 1.0)/pow(1024, power), units) 630 break 631 else: 632 fmt = '%s bytes' % size 633 return fmt
634 635 backupsDir = zenPath('backups') 636 fileInfo = [] 637 if os.path.isdir(backupsDir): 638 for dirPath, dirNames, fileNames in os.walk(backupsDir): 639 dirNames[:] = [] 640 for fileName in fileNames: 641 filePath = os.path.join(backupsDir, fileName) 642 info = os.stat(filePath) 643 fileInfo.append({ 644 'fileName': fileName, 645 'size': info[stat.ST_SIZE], 646 'sizeFormatted': FmtFileSize(info[stat.ST_SIZE]), 647 'modDate': info[stat.ST_MTIME], 648 'modDateFormatted': datetime.datetime.fromtimestamp( 649 info[stat.ST_MTIME]).strftime( 650 '%c'), 651 }) 652 fileInfo.sort(key=operator.itemgetter('modDate')) 653 return fileInfo 654 655 656 security.declareProtected(ZEN_MANAGE_DMD, 'manage_createBackup')
657 - def manage_createBackup(self, includeEvents=None, includeMysqlLogin=None, 658 timeout=120, REQUEST=None, writeMethod=None):
659 """ 660 Create a new backup file using zenbackup and the options specified 661 in the request. 662 663 This method makes use of the fact that DataRoot is a Commandable 664 in order to use Commandable.write 665 """ 666 import popen2 667 import fcntl 668 import time 669 import select 670 671 def write(s): 672 if writeMethod: 673 writeMethod(s) 674 elif REQUEST: 675 self.write(REQUEST.RESPONSE, s)
676 677 footer = None 678 if REQUEST and not writeMethod: 679 header, footer = self.commandOutputTemplate().split('OUTPUT_TOKEN') 680 REQUEST.RESPONSE.write(str(header)) 681 write('') 682 try: 683 cmd = binPath('zenbackup') + ' -v10' 684 if not includeEvents: 685 cmd += ' --no-eventsdb' 686 if includeMysqlLogin: 687 cmd += ' --save-mysql-access' 688 try: 689 timeout = int(timeout) 690 except ValueError: 691 timeout = 120 692 timeout = max(timeout, 1) 693 child = popen2.Popen4(cmd) 694 flags = fcntl.fcntl(child.fromchild, fcntl.F_GETFL) 695 fcntl.fcntl(child.fromchild, fcntl.F_SETFL, flags | os.O_NDELAY) 696 endtime = time.time() + timeout 697 write('%s' % cmd) 698 write('') 699 pollPeriod = 1 700 firstPass = True 701 while time.time() < endtime and (firstPass or child.poll() == -1): 702 firstPass = False 703 r, w, e = select.select([child.fromchild], [], [], pollPeriod) 704 if r: 705 t = child.fromchild.read() 706 # We are sometimes getting to this point without any data 707 # from child.fromchild. I don't think that should happen 708 # but the conditional below seems to be necessary. 709 if t: 710 write(t) 711 712 if child.poll() == -1: 713 write('Backup timed out after %s seconds.' % timeout) 714 import signal 715 os.kill(child.pid, signal.SIGKILL) 716 717 write('DONE') 718 except: 719 write('Exception while performing backup.') 720 write('type: %s value: %s' % tuple(sys.exc_info()[:2])) 721 write('') 722 if REQUEST and footer: 723 REQUEST.RESPONSE.write(footer) 724 725 726 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteBackups')
727 - def manage_deleteBackups(self, fileNames=(), REQUEST=None):
728 """ 729 Delete the specified files from $ZENHOME/backups 730 """ 731 backupsDir = zenPath('backups') 732 count = 0 733 if os.path.isdir(backupsDir): 734 for dirPath, dirNames, dirFileNames in os.walk(backupsDir): 735 dirNames[:] = [] 736 for fileName in fileNames: 737 if fileName in dirFileNames: 738 res = os.remove(os.path.join(dirPath, fileName)) 739 if res == 0: 740 count += 1 741 if REQUEST: 742 messaging.IMessageSender(self).sendToBrowser( 743 'Backups Deleted', 744 '%s backup files have been deleted.' % count 745 ) 746 else: 747 if REQUEST: 748 messaging.IMessageSender(self).sendToBrowser( 749 'Backup Directory Missing', 750 'Unable to find $ZENHOME/backups.', 751 priority=messaging.WARNING 752 ) 753 if REQUEST: 754 return self.callZenScreen(REQUEST)
755 756
757 - def getProductName(self):
758 """ 759 Return a string that represents the Zenoss product that is installed. 760 Currently this is something like 'core' or 'enterprise'. This is 761 used in the version check code to retrieve the available version 762 for the correct product. 763 """ 764 return getattr(self, 'productName', 'core')
765 766
767 - def error_handler(self, error=None):
768 """ 769 Returns pretty messages when errors are raised in templates. 770 771 Access this method from a template like so: 772 <div tal:content="..." 773 ... 774 tal:on-error="structure python:here.dmd.error_handler(error)"> 775 776 @param error: A TALES.ErrorInfo instance with attributes type, value 777 and traceback. 778 @return: HTML fragment with an error message 779 """ 780 if error.type==MySQLConnectionError: 781 msg = "Unable to connect to the MySQL server." 782 783 elif error.type in [ pythonThresholdException, rpnThresholdException ]: 784 msg= error.value 785 786 else: 787 raise 788 789 return '<b class="errormsg">%s</b>' % msg
790 791 @json
792 - def isDebugMode(self):
793 """ 794 Whether we're in debug mode, so that javascript will behave accordingly 795 """ 796 return DevelopmentMode
797
798 - def versionId(self):
799 """ 800 Get a string representative of the code version, to override JS 801 caching. 802 """ 803 return self.About.getZenossVersion().full().replace( 804 'Zenoss','').replace(' ','').replace('.','')
805 806 807 InitializeClass(DataRoot) 808