1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import os
17 import sys
18 import shutil
19
20 from twisted.internet import defer
21 from twisted.python import runtime, log
22
23 from buildslave import runprocess
24 from buildslave.commands import base, utils
27 """This is a Command which creates a directory. The args dict contains
28 the following keys:
29
30 - ['dir'] (required): subdirectory which the command will create,
31 relative to the builder dir
32
33 MakeDirectory creates the following status messages:
34 - {'rc': rc} : when the process has terminated
35 """
36
37 header = "mkdir"
38
40 args = self.args
41
42 assert args['dir'] is not None
43 dirname = os.path.join(self.builder.basedir, args['dir'])
44
45 try:
46 if not os.path.isdir(dirname):
47 os.makedirs(dirname)
48 self.sendStatus({'rc': 0})
49 except:
50 self.sendStatus({'rc': 1})
51
53 """This is a Command which removes a directory. The args dict contains
54 the following keys:
55
56 - ['dir'] (required): subdirectory which the command will create,
57 relative to the builder dir. This argument
58 can be either a single directory name as a string
59 or list of directory names as a list.
60
61 - ['timeout']: seconds of silence tolerated before we kill off the
62 command
63
64 - ['maxTime']: seconds before we kill off the command
65
66
67 RemoveDirectory creates the following status messages:
68 - {'rc': rc} : when the process has terminated
69 """
70
71 header = "rmdir"
72
74 self.logEnviron = args.get('logEnviron',True)
75
76
77 @defer.deferredGenerator
79 args = self.args
80
81 assert args['dir'] is not None
82 dirnames = args['dir']
83
84 self.timeout = args.get('timeout', 120)
85 self.maxTime = args.get('maxTime', None)
86 self.rc = 0
87 if type(dirnames) is list:
88 assert len(dirnames) != 0
89 for dirname in dirnames:
90 wfd = defer.waitForDeferred(self.removeSingleDir(dirname))
91 yield wfd
92 res = wfd.getResult()
93
94
95
96 if res != 0:
97 self.rc = res
98 else:
99 wfd = defer.waitForDeferred(self.removeSingleDir(dirnames))
100 yield wfd
101 self.rc = wfd.getResult()
102
103 self.sendStatus({'rc': self.rc})
104
106
107 self.dir = os.path.join(self.builder.basedir, dirname)
108 if runtime.platformType != "posix":
109
110
111 utils.rmdirRecursive(self.dir)
112 d = defer.succeed(0)
113 else:
114 d = self._clobber(None)
115
116 return d
117
118 - def _clobber(self, dummy, chmodDone = False):
135
137 assert isinstance(rc, int)
138 if rc == 0:
139 return defer.succeed(0)
140
141
142 command = ["chmod", "-Rf", "u+rwx", os.path.join(self.builder.basedir, self.dir)]
143 if sys.platform.startswith('freebsd'):
144
145
146
147 command = ["find", os.path.join(self.builder.basedir, self.dir),
148 '-exec', 'chmod', 'u+rwx', '{}', ';' ]
149 c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
150 sendRC=0, timeout=self.timeout, maxTime=self.maxTime,
151 logEnviron=self.logEnviron, usePTY=False)
152
153 self.command = c
154 d = c.start()
155 d.addCallback(lambda dummy: self._clobber(dummy, True))
156 return d
157
159 """This is a Command which copies a directory. The args dict contains
160 the following keys:
161
162 - ['fromdir'] (required): subdirectory which the command will copy,
163 relative to the builder dir
164 - ['todir'] (required): subdirectory which the command will create,
165 relative to the builder dir
166
167 - ['timeout']: seconds of silence tolerated before we kill off the
168 command
169
170 - ['maxTime']: seconds before we kill off the command
171
172
173 CopyDirectory creates the following status messages:
174 - {'rc': rc} : when the process has terminated
175 """
176
177 header = "rmdir"
178
180 self.logEnviron = args.get('logEnviron',True)
181
183 args = self.args
184
185
186 assert args['todir'] is not None
187 assert args['fromdir'] is not None
188
189 fromdir = os.path.join(self.builder.basedir, args['fromdir'])
190 todir = os.path.join(self.builder.basedir, args['todir'])
191
192 self.timeout = args.get('timeout', 120)
193 self.maxTime = args.get('maxTime', None)
194
195 if runtime.platformType != "posix":
196 self.sendStatus({'header': "Since we're on a non-POSIX platform, "
197 "we're not going to try to execute cp in a subprocess, but instead "
198 "use shutil.copytree(), which will block until it is complete. "
199 "fromdir: %s, todir: %s\n" % (fromdir, todir)})
200 shutil.copytree(fromdir, todir)
201 d = defer.succeed(0)
202 else:
203 if not os.path.exists(os.path.dirname(todir)):
204 os.makedirs(os.path.dirname(todir))
205 if os.path.exists(todir):
206
207 log.msg("cp target '%s' already exists -- cp will not do what you think!" % todir)
208
209 command = ['cp', '-R', '-P', '-p', fromdir, todir]
210 c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
211 sendRC=False, timeout=self.timeout, maxTime=self.maxTime,
212 logEnviron=self.logEnviron, usePTY=False)
213 self.command = c
214 d = c.start()
215 d.addCallback(self._abandonOnFailure)
216
217
218 d.addCallbacks(self._sendRC, self._checkAbandoned)
219 return d
220
222 """This is a command which stats a file on the slave. The args dict contains the following keys:
223
224 - ['file'] (required): file to stat
225
226 StatFile creates the following status messages:
227 - {'rc': rc} : 0 if the file is found, 1 otherwise
228 - {'stat': stat} : if the files is found, stat contains the result of os.stat
229 """
230
231 header = "stat"
232
245