1
2
3
4
5
6
7
8
9
10
11
12
13 __doc__ = """RunCommand
14 Run an event command on the local device or on the remote collector.
15 Assumes that SSH keys have been set up to all remote collectors.
16
17 Example usage:
18
19 dcsh -collector=xxx 'zencommand run'
20
21 The actual command to run *MUST* be in quotes!
22 """
23
24 import logging
25 log = logging.getLogger('zen.runCommand')
26
27 import os
28 from subprocess import Popen, PIPE
29 import StringIO
30 import signal
31
32 import Globals
33 from Products.ZenUtils.ZenScriptBase import ZenScriptBase
34 from Products.ZenUtils.Utils import zenPath
35
36
44
45
49
51 ZenScriptBase.buildOptions(self)
52 self.parser.add_option('--collector', dest='collector',
53 help="Name of specific collector on which to run the command")
54 self.parser.add_option('--timeout', dest='timeout',
55 default=60, type="int",
56 help="Kill the process after this many seconds.")
57 self.parser.add_option('-n', '--useprefix', action='store_false',
58 dest='useprefix', default=True,
59 help="Prefix the collector name for remote servers")
60
68
70 if self.options.collector:
71 try:
72 collectors = [self.dmd.Monitors.Performance._getOb(
73 self.options.collector)]
74 except AttributeError:
75 log.critical("No collector named %s could be found. Exiting",
76 self.options.collector)
77 return
78 else:
79 collectors = self.dmd.Monitors.Performance.objectValues(
80 spec="PerformanceConf")
81
82 return [collectorStats(x.id, getattr(x, 'hostname', x.id)) \
83 for x in collectors]
84
86 header = """
87 Collector StdOut/Stderr"""
88 delimLen = 65
89 print header
90 print '-' * delimLen
91
92 collectorNames = dict(zip(map(lambda x: x.id, collectors), collectors))
93 for name in sorted(collectorNames.keys()):
94 collector = collectorNames[name]
95 print "%s %s %s" % (name, collector.stdout, collector.stderr)
96 print '-' * delimLen
97
99 def killTimedOutProc(signum, frame):
100 log.error("Killing process id %s ...", proc.pid)
101 try:
102 os.kill(proc.pid, signal.SIGKILL)
103 except OSError:
104 pass
105
106 if collector.hostname == 'localhost':
107 collectorCommand = self.args
108 else:
109
110
111
112
113
114
115
116
117
118
119 cmd = self.args[0]
120 if self.options.useprefix:
121 cmd = '%s_%s' % (collector.id, cmd)
122 collectorCommand = ['ssh', collector.hostname, cmd]
123
124 collectorCommand = ' '.join(collectorCommand)
125 log.debug("Runing command '%s' on collector %s (%s)",
126 collectorCommand, collector.id, collector.hostname)
127 proc = Popen(collectorCommand, stdout=PIPE, stderr=PIPE, shell=True)
128 signal.signal(signal.SIGALRM, killTimedOutProc)
129 signal.alarm(self.options.timeout)
130 collector.stdout, collector.stderr = proc.communicate()
131 proc.wait()
132 signal.alarm(0)
133
134
135 if __name__ == '__main__':
136 zrc = RunCommand()
137 zrc.run()
138