1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import os, types, re
17 from twisted.python import runtime
18 from twisted.internet import reactor
19 from buildbot.process.buildstep import BuildStep
20 from buildbot.process.buildstep import SUCCESS, FAILURE
21 from twisted.internet import error
22 from twisted.internet.protocol import ProcessProtocol
23
25 """
26 Run a shell command locally - on the buildmaster. The shell command
27 COMMAND is specified just as for a RemoteShellCommand. Note that extra
28 logfiles are not supported.
29 """
30 name='MasterShellCommand'
31 description='Running'
32 descriptionDone='Ran'
33 descriptionSuffix = None
34 renderables = [ 'command', 'env', 'description', 'descriptionDone', 'descriptionSuffix' ]
35 haltOnFailure = True
36 flunkOnFailure = True
37
38 - def __init__(self, command,
39 description=None, descriptionDone=None, descriptionSuffix=None,
40 env=None, path=None, usePTY=0, interruptSignal="KILL",
41 **kwargs):
61
65
68
71
73 if status_object.value.exitCode is not None:
74 self.step.stdio_log.addHeader("exit status %d\n" % status_object.value.exitCode)
75 if status_object.value.signal is not None:
76 self.step.stdio_log.addHeader("signal %s\n" % status_object.value.signal)
77 self.step.processEnded(status_object)
78
80
81 command = self.command
82
83 if type(command) in types.StringTypes:
84 if runtime.platformType == 'win32':
85 argv = os.environ['COMSPEC'].split()
86 if '/c' not in argv: argv += ['/c']
87 argv += [command]
88 else:
89
90
91 argv = ['/bin/sh', '-c', command]
92 else:
93 if runtime.platformType == 'win32':
94 argv = os.environ['COMSPEC'].split()
95 if '/c' not in argv: argv += ['/c']
96 argv += list(command)
97 else:
98 argv = command
99
100 self.stdio_log = stdio_log = self.addLog("stdio")
101
102 if type(command) in types.StringTypes:
103 stdio_log.addHeader(command.strip() + "\n\n")
104 else:
105 stdio_log.addHeader(" ".join(command) + "\n\n")
106 stdio_log.addHeader("** RUNNING ON BUILDMASTER **\n")
107 stdio_log.addHeader(" in dir %s\n" % os.getcwd())
108 stdio_log.addHeader(" argv: %s\n" % (argv,))
109 self.step_status.setText(self.describe())
110
111 if self.env is None:
112 env = os.environ
113 else:
114 assert isinstance(self.env, dict)
115 env = self.env
116
117
118 p = re.compile('\${([0-9a-zA-Z_]*)}')
119 def subst(match):
120 return os.environ.get(match.group(1), "")
121 newenv = {}
122 for key in env.keys():
123 if env[key] is not None:
124 newenv[key] = p.sub(subst, env[key])
125 env = newenv
126 stdio_log.addHeader(" env: %r\n" % (env,))
127
128
129 self.process = reactor.spawnProcess(self.LocalPP(self), argv[0], argv,
130 path=self.path, usePTY=self.usePTY, env=env )
131
132
145
152
161