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

Source Code for Module Products.ZenModel.PerformanceConf

  1  #! /usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  # ########################################################################## 
  4  # 
  5  # This program is part of Zenoss Core, an open source monitoring platform. 
  6  # Copyright (C) 2006-2009 Zenoss Inc. 
  7  # 
  8  # This program is free software; you can redistribute it and/or modify it 
  9  # under the terms of the GNU General Public License version 2 or (at your 
 10  # option) any later version as published by the Free Software Foundation. 
 11  # 
 12  # For complete information please visit: http://www.zenoss.com/oss/ 
 13  # 
 14  # ########################################################################## 
 15   
 16  __doc__ = """PerformanceConf 
 17  The configuration object for Performance servers 
 18  """ 
 19   
 20  import os 
 21  import zlib 
 22  import socket 
 23  from urllib import urlencode 
 24  from ipaddr import IPAddress 
 25  import logging 
 26  log = logging.getLogger('zen.PerformanceConf') 
 27   
 28  from Products.ZenUtils.IpUtil import ipwrap 
 29   
 30  try: 
 31      from base64 import urlsafe_b64encode 
 32      raise ImportError 
 33  except ImportError: 
 34   
 35   
36 - def urlsafe_b64encode(s):
37 """ 38 Encode a string so that it's okay to be used in an URL 39 40 @param s: possibly unsafe string passed in by the user 41 @type s: string 42 @return: sanitized, url-safe version of the string 43 @rtype: string 44 """ 45 46 import base64 47 s = base64.encodestring(s) 48 s = s.replace('+', '-') 49 s = s.replace('/', '_') 50 s = s.replace('\n', '') 51 return s
52 53 54 import xmlrpclib 55 56 from AccessControl import ClassSecurityInfo 57 from AccessControl import Permissions as permissions 58 from Globals import DTMLFile 59 from Globals import InitializeClass 60 from Monitor import Monitor 61 from Products.PythonScripts.standard import url_quote 62 from Products.Jobber.jobs import ShellCommandJob 63 from Products.ZenModel.ZenossSecurity import * 64 from Products.ZenRelations.RelSchema import * 65 from Products.ZenUtils.Utils import basicAuthUrl, zenPath, binPath 66 from Products.ZenUtils.Utils import unused 67 from Products.ZenUtils.Utils import isXmlRpc 68 from Products.ZenUtils.Utils import setupLoggingHeader 69 from Products.ZenUtils.Utils import executeCommand 70 from Products.ZenUtils.Utils import clearWebLoggingStream 71 from Products.ZenModel.Device import manage_createDevice 72 from Products.ZenModel.ZDeviceLoader import DeviceCreationJob 73 from Products.ZenWidgets import messaging 74 from StatusColor import StatusColor 75 76 PERF_ROOT = None 77 78
79 -def performancePath(target):
80 """ 81 Return the base directory where RRD performance files are kept. 82 83 @param target: path to performance file 84 @type target: string 85 @return: sanitized path to performance file 86 @rtype: string 87 """ 88 global PERF_ROOT 89 if PERF_ROOT is None: 90 PERF_ROOT = zenPath('perf') 91 if target.startswith('/'): 92 target = target[1:] 93 return os.path.join(PERF_ROOT, target)
94 95
96 -def manage_addPerformanceConf(context, id, title=None, REQUEST=None,):
97 """ 98 Make a device class 99 100 @param context: Where you are in the Zope acquisition path 101 @type context: Zope context object 102 @param id: unique identifier 103 @type id: string 104 @param title: user readable label (unused) 105 @type title: string 106 @param REQUEST: Zope REQUEST object 107 @type REQUEST: Zope REQUEST object 108 @return: 109 @rtype: 110 """ 111 unused(title) 112 dc = PerformanceConf(id) 113 context._setObject(id, dc) 114 115 if REQUEST is not None: 116 REQUEST['RESPONSE'].redirect(context.absolute_url() 117 + '/manage_main')
118 119 120 addPerformanceConf = DTMLFile('dtml/addPerformanceConf', globals()) 121 122
123 -class PerformanceConf(Monitor, StatusColor):
124 """ 125 Configuration for Performance servers 126 """ 127 portal_type = meta_type = 'PerformanceConf' 128 129 monitorRootName = 'Performance' 130 131 security = ClassSecurityInfo() 132 security.setDefaultAccess('allow') 133 134 eventlogCycleInterval = 60 135 perfsnmpCycleInterval = 300 136 processCycleInterval = 180 137 statusCycleInterval = 60 138 winCycleInterval = 60 139 wmibatchSize = 10 140 wmiqueryTimeout = 100 141 configCycleInterval = 6 * 60 142 143 zenProcessParallelJobs = 10 144 145 pingTimeOut = 1.5 146 pingTries = 2 147 pingChunk = 75 148 pingCycleInterval = 60 149 maxPingFailures = 1440 150 151 modelerCycleInterval = 720 152 153 renderurl = '/zport/RenderServer' 154 renderuser = '' 155 renderpass = '' 156 157 discoveryNetworks = () 158 159 # make the default rrdfile size smaller 160 # we need the space to live within the disk cache 161 defaultRRDCreateCommand = ( 162 'RRA:AVERAGE:0.5:1:600', # every 5 mins for 2 days 163 'RRA:AVERAGE:0.5:6:600', # every 30 mins for 12 days 164 'RRA:AVERAGE:0.5:24:600', # every 2 hours for 50 days 165 'RRA:AVERAGE:0.5:288:600', # every day for 600 days 166 'RRA:MAX:0.5:6:600', 167 'RRA:MAX:0.5:24:600', 168 'RRA:MAX:0.5:288:600', 169 ) 170 171 _properties = ( 172 {'id': 'eventlogCycleInterval', 'type': 'int', 'mode': 'w'}, 173 {'id': 'perfsnmpCycleInterval', 'type': 'int', 'mode': 'w'}, 174 {'id': 'processCycleInterval', 'type': 'int', 'mode': 'w'}, 175 {'id': 'statusCycleInterval', 'type': 'int', 'mode': 'w'}, 176 {'id': 'winCycleInterval', 'type': 'int', 'mode': 'w'}, 177 {'id': 'wmibatchSize', 'type': 'int', 'mode': 'w', 178 'description':"Number of data objects to retrieve in a single WMI query",}, 179 {'id': 'wmiqueryTimeout', 'type': 'int', 'mode': 'w', 180 'description':"Number of milliseconds to wait for WMI query to respond",}, 181 {'id': 'configCycleInterval', 'type': 'int', 'mode': 'w'}, 182 {'id': 'renderurl', 'type': 'string', 'mode': 'w'}, 183 {'id': 'renderuser', 'type': 'string', 'mode': 'w'}, 184 {'id': 'renderpass', 'type': 'string', 'mode': 'w'}, 185 {'id': 'defaultRRDCreateCommand', 'type': 'lines', 'mode': 'w' 186 }, 187 {'id': 'zenProcessParallelJobs', 'type': 'int', 'mode': 'w'}, 188 {'id': 'pingTimeOut', 'type': 'float', 'mode': 'w'}, 189 {'id': 'pingTries', 'type': 'int', 'mode': 'w'}, 190 {'id': 'pingChunk', 'type': 'int', 'mode': 'w'}, 191 {'id': 'pingCycleInterval', 'type': 'int', 'mode': 'w'}, 192 {'id': 'maxPingFailures', 'type': 'int', 'mode': 'w'}, 193 {'id': 'modelerCycleInterval', 'type': 'int', 'mode': 'w'}, 194 {'id': 'discoveryNetworks', 'type': 'lines', 'mode': 'w'}, 195 ) 196 197 _relations = Monitor._relations + ( 198 ("devices", ToMany(ToOne,"Products.ZenModel.Device","perfServer")), 199 ) 200 201 # Screen action bindings (and tab definitions) 202 factory_type_information = ( 203 { 204 'immediate_view' : 'viewPerformanceConfOverview', 205 'actions' : 206 ( 207 { 'id' : 'overview' 208 , 'name' : 'Overview' 209 , 'action' : 'viewPerformanceConfOverview' 210 , 'permissions' : ( 211 permissions.view, ) 212 }, 213 { 'id' : 'edit' 214 , 'name' : 'Edit' 215 , 'action' : 'editPerformanceConf' 216 , 'permissions' : ("Manage DMD",) 217 }, 218 { 'id' : 'performance' 219 , 'name' : 'Performance' 220 , 'action' : 'viewDaemonPerformance' 221 , 'permissions' : (permissions.view,) 222 }, 223 { 'id' : 'viewHistory' 224 , 'name' : 'Modifications' 225 , 'action' : 'viewNewHistory' 226 , 'permissions' : (ZEN_VIEW_MODIFICATIONS,) 227 }, 228 ) 229 }, 230 ) 231 232 233 security.declareProtected('View', 'getDefaultRRDCreateCommand')
235 """ 236 Get the default RRD Create Command, as a string. 237 For example: 238 '''RRA:AVERAGE:0.5:1:600 239 RRA:AVERAGE:0.5:6:600 240 RRA:AVERAGE:0.5:24:600 241 RRA:AVERAGE:0.5:288:600 242 RRA:MAX:0.5:288:600''' 243 244 @return: RRD create command 245 @rtype: string 246 """ 247 return '\n'.join(self.defaultRRDCreateCommand)
248 249
250 - def findDevice(self, deviceName):
251 """ 252 Return the object given the name 253 254 @param deviceName: Name of a device 255 @type deviceName: string 256 @return: device corresponding to the name, or None 257 @rtype: device object 258 """ 259 brains = self.dmd.Devices._findDevice(deviceName) 260 if brains: 261 return brains[0].getObject()
262 263
264 - def getNetworkRoot(self, version=None):
265 """ 266 Get the root of the Network object in the DMD 267 268 @return: base DMD Network object 269 @rtype: Network object 270 """ 271 return self.dmd.Networks.getNetworkRoot(version)
272 273
274 - def buildGraphUrlFromCommands(self, gopts, drange):
275 """ 276 Return an URL for the given graph options and date range 277 278 @param gopts: graph options 279 @type gopts: string 280 @param drange: time range to use 281 @type drange: string 282 @return: URL to a graphic 283 @rtype: string 284 """ 285 newOpts = [] 286 width = 0 287 for o in gopts: 288 if o.startswith('--width'): 289 width = o.split('=')[1].strip() 290 continue 291 newOpts.append(o) 292 293 encodedOpts = urlsafe_b64encode( 294 zlib.compress('|'.join(newOpts), 9)) 295 params = { 296 'gopts': encodedOpts, 297 'drange': drange, 298 'width': width, 299 } 300 if self.renderurl.startswith('proxy'): 301 url = url.replace('proxy', 'http', 1) 302 params['remoteUrl'] = url 303 return '/zport/RenderServer/render?%s' % (urlencode(params),) 304 else: 305 return '%s/render?%s' % (self.renderurl, urlencode(params),)
306 307
308 - def performanceGraphUrl(self, context, targetpath, targettype, view, drange):
309 """ 310 Set the full path of the target and send to view 311 312 @param context: Where you are in the Zope acquisition path 313 @type context: Zope context object 314 @param targetpath: device path of performance metric 315 @type targetpath: string 316 @param targettype: unused 317 @type targettype: string 318 @param view: view object 319 @type view: Zope object 320 @param drange: date range 321 @type drange: string 322 @return: URL to graph 323 @rtype: string 324 """ 325 unused(targettype) 326 targetpath = performancePath(targetpath) 327 gopts = view.getGraphCmds(context, targetpath) 328 return self.buildGraphUrlFromCommands(gopts, drange)
329 330
331 - def performanceMGraphUrl(self, context, targetsmap, view, drange):
332 """ 333 Set the full paths for all targts in map and send to view 334 335 @param context: Where you are in the Zope acquisition path 336 @type context: Zope context object 337 @param targetsmap: list of (target, targettype) tuples 338 @type targetsmap: list 339 @param view: view object 340 @type view: Zope object 341 @param drange: date range 342 @type drange: string 343 @return: URL to graph 344 @rtype: string 345 """ 346 ntm = [] 347 for (target, targettype) in targetsmap: 348 if target.find('.rrd') == -1: 349 target += '.rrd' 350 fulltarget = performancePath(target) 351 ntm.append((fulltarget, targettype)) 352 gopts = view.multiGraphOpts(context, ntm) 353 gopts = url_quote('|'.join(gopts)) 354 url = '%s/render?gopts=%s&drange=%d' % (self.renderurl, gopts, drange) 355 if self.renderurl.startswith('http'): 356 return '/zport/RenderServer/render?remoteUrl=%s&gopts=%s&drange=%d' % ( 357 url_quote(url), gopts, drange) 358 else: 359 return url
360 361
362 - def renderCustomUrl(self, gopts, drange):
363 """ 364 Return the URL for a list of custom gopts for a graph 365 366 @param gopts: graph options 367 @type gopts: string 368 @param drange: date range 369 @type drange: string 370 @return: URL to graph 371 @rtype: string 372 """ 373 gopts = self._fullPerformancePath(gopts) 374 gopts = url_quote('|'.join(gopts)) 375 url = '%s/render?gopts=%s&drange=%d' % (self.renderurl, gopts, 376 drange) 377 if self.renderurl.startswith('http'): 378 return '/zport/RenderServer/render?remoteUrl=%s&gopts=%s&drange=%d'\ 379 % (url_quote(url), gopts, drange) 380 else: 381 return url
382 383
384 - def performanceCustomSummary(self, gopts):
385 """ 386 Fill out full path for custom gopts and call to server 387 388 @param gopts: graph options 389 @type gopts: string 390 @return: URL 391 @rtype: string 392 """ 393 gopts = self._fullPerformancePath(gopts) 394 renderurl = str(self.renderurl) 395 if renderurl.startswith('proxy'): 396 renderurl = self.renderurl.replace('proxy', 'http') 397 if renderurl.startswith('http'): 398 url = basicAuthUrl(str(self.renderuser), 399 str(self.renderpass), renderurl) 400 server = xmlrpclib.Server(url) 401 else: 402 server = self.getObjByPath(renderurl) 403 return server.summary(gopts)
404 405
406 - def fetchValues(self, paths, cf, resolution, start, end=""):
407 """ 408 Return values 409 410 @param paths: paths to performance metrics 411 @type paths: list 412 @param cf: RRD CF 413 @type cf: string 414 @param resolution: resolution 415 @type resolution: string 416 @param start: start time 417 @type start: string 418 @param end: end time 419 @type end: string 420 @return: values 421 @rtype: list 422 """ 423 url = self.renderurl 424 if url.startswith("http"): 425 url = basicAuthUrl(self.renderuser, self.renderpass, self.renderurl) 426 server = xmlrpclib.Server(url, allow_none=True) 427 else: 428 if not self.renderurl: 429 raise KeyError 430 server = self.getObjByPath(self.renderurl) 431 return server.fetchValues(map(performancePath, paths), cf, 432 resolution, start, end)
433 434
435 - def currentValues(self, paths):
436 """ 437 Fill out full path and call to server 438 439 @param paths: paths to performance metrics 440 @type paths: list 441 @return: values 442 @rtype: list 443 """ 444 url = self.renderurl 445 if url.startswith('proxy'): 446 url = self.renderurl.replace('proxy', 'http') 447 if url.startswith('http'): 448 url = basicAuthUrl(self.renderuser, self.renderpass, 449 self.renderurl) 450 server = xmlrpclib.Server(url) 451 else: 452 if not self.renderurl: 453 raise KeyError 454 server = self.getObjByPath(self.renderurl) 455 return server.currentValues(map(performancePath, paths))
456 457
458 - def _fullPerformancePath(self, gopts):
459 """ 460 Add full path to a list of custom graph options 461 462 @param gopts: graph options 463 @type gopts: string 464 @return: full path + graph options 465 @rtype: string 466 """ 467 for i in range(len(gopts)): 468 opt = gopts[i] 469 if opt.find('DEF') == 0: 470 opt = opt.split(':') 471 (var, file) = opt[1].split('=') 472 file = performancePath(file) 473 opt[1] = '%s=%s' % (var, file) 474 opt = ':'.join(opt) 475 gopts[i] = opt 476 return gopts
477 478 479 security.declareProtected('View', 'performanceDeviceList')
480 - def performanceDeviceList(self, force=True):
481 """ 482 Return a list of URLs that point to our managed devices 483 484 @param force: unused 485 @type force: boolean 486 @return: list of device objects 487 @rtype: list 488 """ 489 unused(force) 490 devlist = [] 491 for dev in self.devices(): 492 dev = dev.primaryAq() 493 if not dev.pastSnmpMaxFailures() and dev.monitorDevice(): 494 devlist.append(dev.getPrimaryUrlPath(full=True)) 495 return devlist
496 497 498 security.declareProtected('View', 'performanceDataSources')
499 - def performanceDataSources(self):
500 """ 501 Return a string that has all the definitions for the performance DS's. 502 503 @return: list of Data Sources 504 @rtype: string 505 """ 506 dses = [] 507 oidtmpl = 'OID %s %s' 508 dstmpl = """datasource %s 509 rrd-ds-type = %s 510 ds-source = snmp://%%snmp%%/%s%s 511 """ 512 rrdconfig = self.getDmdRoot('Devices').rrdconfig 513 for ds in rrdconfig.objectValues(spec='RRDDataSource'): 514 if ds.isrow: 515 inst = '.%inst%' 516 else: 517 inst = '' 518 dses.append(oidtmpl % (ds.getName(), ds.oid)) 519 dses.append(dstmpl % (ds.getName(), ds.rrdtype, 520 ds.getName(), inst)) 521 return '\n'.join(dses)
522
523 - def deleteRRDFiles(self, device, datasource=None, datapoint=None):
524 """ 525 Remove RRD performance data files 526 527 @param device: Name of a device or entry in DMD 528 @type device: string 529 @param datasource: datasource name 530 @type datasource: string 531 @param datapoint: datapoint name 532 @type datapoint: string 533 """ 534 remoteUrl = None 535 if self.renderurl.startswith('http'): 536 if datapoint: 537 remoteUrl = '%s/deleteRRDFiles?device=%s&datapoint=%s' % ( 538 self.renderurl, device, datapoint) 539 elif datasource: 540 remoteUrl = '%s/deleteRRDFiles?device=%s&datasource=%s' % ( 541 self.renderurl, device, datasource) 542 else: 543 remoteUrl = '%s/deleteRRDFiles?device=%s' % ( 544 self.renderurl, device) 545 rs = self.getDmd().getParentNode().RenderServer 546 rs.deleteRRDFiles(device, datasource, datapoint, remoteUrl)
547 548
549 - def setPerformanceMonitor(self, performanceMonitor=None, deviceNames=None, REQUEST=None):
550 """ 551 Provide a method to set performance monitor from any organizer 552 553 @param performanceMonitor: DMD object that collects from a device 554 @type performanceMonitor: DMD object 555 @param deviceNames: list of device names 556 @type deviceNames: list 557 @param REQUEST: Zope REQUEST object 558 @type REQUEST: Zope REQUEST object 559 """ 560 if not performanceMonitor: 561 if REQUEST: 562 messaging.IMessageSender(self).sendToBrowser('Error', 563 'No monitor was selected.', 564 priority=messaging.WARNING) 565 return self.callZenScreen(REQUEST) 566 if deviceNames is None: 567 if REQUEST: 568 messaging.IMessageSender(self).sendToBrowser('Error', 569 'No devices were selected.', 570 priority=messaging.WARNING) 571 return self.callZenScreen(REQUEST) 572 for devName in deviceNames: 573 dev = self.devices._getOb(devName) 574 dev = dev.primaryAq() 575 dev.setPerformanceMonitor(performanceMonitor) 576 if REQUEST: 577 messaging.IMessageSender(self).sendToBrowser('Monitor Set', 578 'Performance monitor was set to %s.' 579 % performanceMonitor) 580 if REQUEST.has_key('oneKeyValueSoInstanceIsntEmptyAndEvalToFalse'): 581 return REQUEST['message'] 582 else: 583 return self.callZenScreen(REQUEST)
584 585 586 security.declareProtected('View', 'getPingDevices')
587 - def getPingDevices(self):
588 """ 589 Return devices associated with this monitor configuration. 590 591 @return: list of devices for this monitor 592 @rtype: list 593 """ 594 devices = [] 595 for dev in self.devices.objectValuesAll(): 596 dev = dev.primaryAq() 597 if dev.monitorDevice() and not dev.zPingMonitorIgnore: 598 devices.append(dev) 599 return devices
600
601 - def addDeviceCreationJob(self, deviceName, devicePath, title=None, 602 discoverProto="none", 603 performanceMonitor='localhost', 604 rackSlot=0, productionState=1000, comments="", 605 hwManufacturer="", hwProductName="", 606 osManufacturer="", osProductName="", priority = 3, 607 locationPath="", systemPaths=[], groupPaths=[], 608 tag="", serialNumber="", zProperties={}):
609 610 # Check to see if we got passed in an IPv6 address 611 try: 612 ipv6addr = IPAddress(deviceName) 613 if not title: 614 title = deviceName 615 deviceName = ipwrap(deviceName) 616 except ValueError: 617 pass 618 619 zendiscCmd = self._getZenDiscCommand(deviceName, devicePath, 620 performanceMonitor) 621 622 jobStatus = self.dmd.JobManager.addJob(DeviceCreationJob, 623 deviceName=deviceName, 624 devicePath=devicePath, 625 title=title, 626 discoverProto=discoverProto, 627 performanceMonitor=performanceMonitor, 628 rackSlot=rackSlot, 629 productionState=productionState, 630 comments=comments, 631 hwManufacturer=hwManufacturer, 632 hwProductName=hwProductName, 633 osManufacturer=osManufacturer, 634 osProductName=osProductName, 635 priority=priority, 636 tag=tag, 637 serialNumber=serialNumber, 638 locationPath=locationPath, 639 systemPaths=systemPaths, 640 groupPaths=groupPaths, 641 zProperties=zProperties, 642 zendiscCmd=zendiscCmd) 643 return jobStatus
644
645 - def _executeZenDiscCommand(self, deviceName, devicePath= "/Discovered", 646 performanceMonitor="localhost", 647 background=False, REQUEST=None):
648 """ 649 Execute zendisc on the new device and return result 650 651 @param deviceName: Name of a device 652 @type deviceName: string 653 @param devicePath: DMD path to create the new device in 654 @type devicePath: string 655 @param performanceMonitor: DMD object that collects from a device 656 @type performanceMonitor: DMD object 657 @param background: should command be scheduled job? 658 @type background: boolean 659 @param REQUEST: Zope REQUEST object 660 @type REQUEST: Zope REQUEST object 661 @return: 662 @rtype: 663 """ 664 zendiscCmd = self._getZenDiscCommand(deviceName, devicePath, 665 performanceMonitor, REQUEST) 666 if background: 667 log.info('queued job: %s', " ".join(zendiscCmd)) 668 result = self.dmd.JobManager.addJob(ShellCommandJob, 669 zendiscCmd) 670 else: 671 result = executeCommand(zendiscCmd, REQUEST) 672 return result
673
674 - def _getZenDiscCommand(self, deviceName, devicePath, 675 performanceMonitor, REQUEST=None):
676 677 zm = binPath('zendisc') 678 zendiscCmd = [zm] 679 zendiscOptions = ['run', '--now','-d', deviceName, 680 '--monitor', performanceMonitor, 681 '--deviceclass', devicePath] 682 if REQUEST: 683 zendiscOptions.append("--weblog") 684 zendiscCmd.extend(zendiscOptions) 685 log.info('local zendiscCmd is "%s"' % ' '.join(zendiscCmd)) 686 return zendiscCmd
687
688 - def getCollectorCommand(self, command):
689 return [binPath(command)]
690
691 - def executeCollectorCommand(self, command, args, REQUEST=None):
692 """ 693 Executes the collector based daemon command. 694 695 @param command: the collector daemon to run, should not include path 696 @type command: string 697 @param args: list of arguments for the command 698 @type args: list of strings 699 @param REQUEST: Zope REQUEST object 700 @type REQUEST: Zope REQUEST object 701 @return: result of the command 702 @rtype: string 703 """ 704 cmd = binPath(command) 705 daemonCmd = [cmd] 706 daemonCmd.extend(args) 707 result = executeCommand(daemonCmd, REQUEST) 708 return result
709 710
711 - def collectDevice(self, device=None, setlog=True, REQUEST=None, 712 generateEvents=False, background=False, write=None):
713 """ 714 Collect the configuration of this device AKA Model Device 715 716 @permission: ZEN_MANAGE_DEVICE 717 @param device: Name of a device or entry in DMD 718 @type device: string 719 @param setlog: If true, set up the output log of this process 720 @type setlog: boolean 721 @param REQUEST: Zope REQUEST object 722 @type REQUEST: Zope REQUEST object 723 @param generateEvents: unused 724 @type generateEvents: string 725 """ 726 xmlrpc = isXmlRpc(REQUEST) 727 zenmodelerOpts = ['run', '--now', '--monitor', self.id, 728 '-F', '-d', device.id] 729 result = self._executeZenModelerCommand(zenmodelerOpts, background, 730 REQUEST, write) 731 if result and xmlrpc: 732 return result 733 log.info('configuration collected') 734 735 if xmlrpc: 736 return 0
737 738
739 - def _executeZenModelerCommand(self, zenmodelerOpts, background=False, 740 REQUEST=None, write=None):
741 """ 742 Execute zenmodeler and return result 743 744 @param zenmodelerOpts: zenmodeler command-line options 745 @type zenmodelerOpts: string 746 @param REQUEST: Zope REQUEST object 747 @type REQUEST: Zope REQUEST object 748 @return: results of command 749 @rtype: string 750 """ 751 zm = binPath('zenmodeler') 752 zenmodelerCmd = [zm] 753 zenmodelerCmd.extend(zenmodelerOpts) 754 if background: 755 log.info('queued job: %s', " ".join(zenmodelerCmd)) 756 result = self.dmd.JobManager.addJob(ShellCommandJob,zenmodelerCmd) 757 else: 758 result = executeCommand(zenmodelerCmd, REQUEST, write) 759 return result
760 761 762 InitializeClass(PerformanceConf) 763