1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
import os, types
from twisted.python import log, failure, runtime
from twisted.internet import reactor, defer, task
from buildbot.process.buildstep import RemoteCommand, BuildStep
from buildbot.process.buildstep import SUCCESS, FAILURE
from twisted.internet.protocol import ProcessProtocol
class MasterShellCommand(BuildStep):
"""
Run a shell command locally - on the buildmaster. The shell command
COMMAND is specified just as for a RemoteShellCommand. Note that extra
logfiles are not sopported.
"""
name='MasterShellCommand'
description='Running'
descriptionDone='Ran'
def __init__(self, command, **kwargs):
BuildStep.__init__(self, **kwargs)
self.addFactoryArguments(command=command)
self.command=command
class LocalPP(ProcessProtocol):
def __init__(self, step):
self.step = step
def outReceived(self, data):
self.step.stdio_log.addStdout(data)
def errReceived(self, data):
self.step.stdio_log.addStderr(data)
def processEnded(self, status_object):
self.step.stdio_log.addHeader("exit status %d\n" % status_object.value.exitCode)
self.step.processEnded(status_object)
def start(self):
# set up argv
if type(self.command) in types.StringTypes:
if runtime.platformType == 'win32':
argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args
if '/c' not in argv: argv += ['/c']
argv += [self.command]
else:
# for posix, use /bin/sh. for other non-posix, well, doesn't
# hurt to try
argv = ['/bin/sh', '-c', self.command]
else:
if runtime.platformType == 'win32':
argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args
if '/c' not in argv: argv += ['/c']
argv += list(self.command)
else:
argv = self.command
self.stdio_log = stdio_log = self.addLog("stdio")
if type(self.command) in types.StringTypes:
stdio_log.addHeader(self.command.strip() + "\n\n")
else:
stdio_log.addHeader(" ".join(self.command) + "\n\n")
stdio_log.addHeader("** RUNNING ON BUILDMASTER **\n")
stdio_log.addHeader(" in dir %s\n" % os.getcwd())
stdio_log.addHeader(" argv: %s\n" % (argv,))
# TODO add a timeout?
proc = reactor.spawnProcess(self.LocalPP(self), argv[0], argv)
# (the LocalPP object will call processEnded for us)
def processEnded(self, status_object):
if status_object.value.exitCode != 0:
self.step_status.setText(["failed (%d)" % status_object.value.exitCode])
self.finished(FAILURE)
else:
self.step_status.setText(["succeeded"])
self.finished(SUCCESS)
|