Gentoo Archives: gentoo-commits

From: Brian Dolbec <brian.dolbec@×××××.com>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/catalyst:pending commit in: catalyst/, catalyst/targets/
Date: Tue, 02 Sep 2014 02:43:50
Message-Id: 1409624023.c4a6c1c2081264888486edc6a6b5106048ff73d6.dol-sen@gentoo
1 commit: c4a6c1c2081264888486edc6a6b5106048ff73d6
2 Author: Brian Dolbec <dolsen <AT> gentoo <DOT> org>
3 AuthorDate: Tue Feb 12 03:43:37 2013 +0000
4 Commit: Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
5 CommitDate: Tue Sep 2 02:13:43 2014 +0000
6 URL: http://sources.gentoo.org/gitweb/?p=proj/catalyst.git;a=commit;h=c4a6c1c2
7
8 remove redundant /bin/bash additions in cmd() calls
9
10 Conflicts:
11 catalyst/support.py
12
13 ---
14 catalyst/support.py | 301 +++----------------------------
15 catalyst/targets/generic_stage_target.py | 26 +--
16 catalyst/targets/grp_target.py | 2 +-
17 catalyst/targets/netboot2_target.py | 4 +-
18 catalyst/targets/netboot_target.py | 8 +-
19 catalyst/targets/tinderbox_target.py | 2 +-
20 6 files changed, 42 insertions(+), 301 deletions(-)
21
22 diff --git a/catalyst/support.py b/catalyst/support.py
23 index 6f66d3c..8fb5da2 100644
24 --- a/catalyst/support.py
25 +++ b/catalyst/support.py
26 @@ -4,9 +4,10 @@ import string
27 import os
28 import types
29 import re
30 -import signal
31 import traceback
32 import time
33 +from subprocess import Popen
34 +
35
36 from catalyst.defaults import verbosity, valid_config_file_values
37
38 @@ -31,34 +32,6 @@ except:
39 spawned_pids = []
40
41
42 -def cleanup(pids,block_exceptions=True):
43 - """function to go through and reap the list of pids passed to it"""
44 - global spawned_pids
45 - if type(pids) == int:
46 - pids = [pids]
47 - for x in pids:
48 - try:
49 - os.kill(x,signal.SIGTERM)
50 - if os.waitpid(x,os.WNOHANG)[1] == 0:
51 - # feisty bugger, still alive.
52 - os.kill(x,signal.SIGKILL)
53 - os.waitpid(x,0)
54 - except OSError, oe:
55 - if block_exceptions:
56 - pass
57 - if oe.errno not in (10,3):
58 - raise oe
59 - except SystemExit:
60 - raise
61 - except Exception:
62 - if block_exceptions:
63 - pass
64 - try:
65 - spawned_pids.remove(x)
66 - except IndexError:
67 - pass
68 -
69 -
70 # a function to turn a string of non-printable characters
71 # into a string of hex characters
72 def hexify(str):
73 @@ -79,8 +52,8 @@ def read_from_clst(file):
74 return -1
75 #raise CatalystError, "Could not open file "+file
76 for line in myf.readlines():
77 - #line = string.replace(line, "\n", "") # drop newline
78 - myline = myline + line
79 + #line = string.replace(line, "\n", "") # drop newline
80 + myline = myline + line
81 myf.close()
82 return myline
83
84 @@ -145,259 +118,27 @@ def find_binary(myc):
85 return None
86
87
88 -def spawn_bash(mycommand,env={},debug=False,opt_name=None,**keywords):
89 - """spawn mycommand as an arguement to bash"""
90 - args=[BASH_BINARY]
91 - if not opt_name:
92 - opt_name=mycommand.split()[0]
93 - if "BASH_ENV" not in env:
94 - env["BASH_ENV"] = "/etc/spork/is/not/valid/profile.env"
95 - if debug:
96 - args.append("-x")
97 - args.append("-c")
98 - args.append(mycommand)
99 - return spawn(args,env=env,opt_name=opt_name,**keywords)
100 -
101 -
102 -def spawn_get_output(mycommand,raw_exit_code=False,emulate_gso=True, \
103 - collect_fds=[1],fd_pipes=None,**keywords):
104 - """call spawn, collecting the output to fd's specified in collect_fds list
105 - emulate_gso is a compatability hack to emulate commands.getstatusoutput's return, minus the
106 - requirement it always be a bash call (spawn_type controls the actual spawn call), and minus the
107 - 'lets let log only stdin and let stderr slide by'.
108 -
109 - emulate_gso was deprecated from the day it was added, so convert your code over.
110 - spawn_type is the passed in function to call- typically spawn_bash, spawn, spawn_sandbox, or spawn_fakeroot"""
111 - global selinux_capable
112 - pr,pw=os.pipe()
113 -
114 - if fd_pipes==None:
115 - fd_pipes={}
116 - fd_pipes[0] = 0
117 -
118 - for x in collect_fds:
119 - fd_pipes[x] = pw
120 - keywords["returnpid"]=True
121 -
122 - mypid=spawn_bash(mycommand,fd_pipes=fd_pipes,**keywords)
123 - os.close(pw)
124 - if type(mypid) != types.ListType:
125 - os.close(pr)
126 - return [mypid, "%s: No such file or directory" % mycommand.split()[0]]
127 -
128 - fd=os.fdopen(pr,"r")
129 - mydata=fd.readlines()
130 - fd.close()
131 - if emulate_gso:
132 - mydata=string.join(mydata)
133 - if len(mydata) and mydata[-1] == "\n":
134 - mydata=mydata[:-1]
135 - retval=os.waitpid(mypid[0],0)[1]
136 - cleanup(mypid)
137 - if raw_exit_code:
138 - return [retval,mydata]
139 - retval=process_exit_code(retval)
140 - return [retval, mydata]
141 -
142 -
143 -# base spawn function
144 -def spawn(mycommand,env={},raw_exit_code=False,opt_name=None,fd_pipes=None,returnpid=False,\
145 - uid=None,gid=None,groups=None,umask=None,logfile=None,path_lookup=True,\
146 - selinux_context=None, raise_signals=False, func_call=False):
147 - """base fork/execve function.
148 - mycommand is the desired command- if you need a command to execute in a bash/sandbox/fakeroot
149 - environment, use the appropriate spawn call. This is a straight fork/exec code path.
150 - Can either have a tuple, or a string passed in. If uid/gid/groups/umask specified, it changes
151 - the forked process to said value. If path_lookup is on, a non-absolute command will be converted
152 - to an absolute command, otherwise it returns None.
153 -
154 - selinux_context is the desired context, dependant on selinux being available.
155 - opt_name controls the name the processor goes by.
156 - fd_pipes controls which file descriptor numbers are left open in the forked process- it's a dict of
157 - current fd's raw fd #, desired #.
158 -
159 - func_call is a boolean for specifying to execute a python function- use spawn_func instead.
160 - raise_signals is questionable. Basically throw an exception if signal'd. No exception is thrown
161 - if raw_input is on.
162 -
163 - logfile overloads the specified fd's to write to a tee process which logs to logfile
164 - returnpid returns the relevant pids (a list, including the logging process if logfile is on).
165 -
166 - non-returnpid calls to spawn will block till the process has exited, returning the exitcode/signal
167 - raw_exit_code controls whether the actual waitpid result is returned, or intrepretted."""
168 -
169 - myc=''
170 - if not func_call:
171 - if type(mycommand)==types.StringType:
172 - mycommand=mycommand.split()
173 - myc = mycommand[0]
174 - if not os.access(myc, os.X_OK):
175 - if not path_lookup:
176 - return None
177 - myc = find_binary(myc)
178 - if myc == None:
179 - return None
180 - mypid=[]
181 - if logfile:
182 - pr,pw=os.pipe()
183 - mypid.extend(spawn(('tee','-i','-a',logfile),returnpid=True,fd_pipes={0:pr,1:1,2:2}))
184 - retval=os.waitpid(mypid[-1],os.WNOHANG)[1]
185 - if retval != 0:
186 - # he's dead jim.
187 - if raw_exit_code:
188 - return retval
189 - return process_exit_code(retval)
190 -
191 - if fd_pipes == None:
192 - fd_pipes={}
193 - fd_pipes[0] = 0
194 - fd_pipes[1]=pw
195 - fd_pipes[2]=pw
196 -
197 - if not opt_name:
198 - opt_name = mycommand[0]
199 - myargs=[opt_name]
200 - myargs.extend(mycommand[1:])
201 - global spawned_pids
202 - mypid.append(os.fork())
203 - if mypid[-1] != 0:
204 - #log the bugger.
205 - spawned_pids.extend(mypid)
206 -
207 - if mypid[-1] == 0:
208 - if func_call:
209 - spawned_pids = []
210 -
211 - # this may look ugly, but basically it moves file descriptors around to ensure no
212 - # handles that are needed are accidentally closed during the final dup2 calls.
213 - trg_fd=[]
214 - if type(fd_pipes)==types.DictType:
215 - src_fd=[]
216 - k=fd_pipes.keys()
217 - k.sort()
218 -
219 - #build list of which fds will be where, and where they are at currently
220 - for x in k:
221 - trg_fd.append(x)
222 - src_fd.append(fd_pipes[x])
223 -
224 - # run through said list dup'ing descriptors so that they won't be waxed
225 - # by other dup calls.
226 - for x in range(0,len(trg_fd)):
227 - if trg_fd[x] == src_fd[x]:
228 - continue
229 - if trg_fd[x] in src_fd[x+1:]:
230 - os.close(trg_fd[x])
231 -
232 - # transfer the fds to their final pre-exec position.
233 - for x in range(0,len(trg_fd)):
234 - if trg_fd[x] != src_fd[x]:
235 - os.dup2(src_fd[x], trg_fd[x])
236 - else:
237 - trg_fd=[0,1,2]
238 -
239 - # wax all open descriptors that weren't requested be left open.
240 - for x in range(0,max_fd_limit):
241 - if x not in trg_fd:
242 - try:
243 - os.close(x)
244 - except SystemExit, e:
245 - raise
246 - except:
247 - pass
248 -
249 - # note this order must be preserved- can't change gid/groups if you change uid first.
250 - if selinux_capable and selinux_context:
251 - import selinux
252 - selinux.setexec(selinux_context)
253 - if gid:
254 - os.setgid(gid)
255 - if groups:
256 - os.setgroups(groups)
257 - if uid:
258 - os.setuid(uid)
259 - if umask:
260 - os.umask(umask)
261 - else:
262 - os.umask(022)
263 -
264 - try:
265 - #print "execing", myc, myargs
266 - if func_call:
267 - # either use a passed in func for interpretting the results, or return if no exception.
268 - # note the passed in list, and dict are expanded.
269 - if len(mycommand) == 4:
270 - os._exit(mycommand[3](mycommand[0](*mycommand[1],**mycommand[2])))
271 - try:
272 - mycommand[0](*mycommand[1],**mycommand[2])
273 - except Exception,e:
274 - print "caught exception",e," in forked func",mycommand[0]
275 - sys.exit(0)
276 -
277 - os.execve(myc,myargs,env)
278 - except SystemExit, e:
279 - raise
280 - except Exception, e:
281 - if not func_call:
282 - raise str(e)+":\n "+myc+" "+string.join(myargs)
283 - print "func call failed"
284 -
285 - # If the execve fails, we need to report it, and exit
286 - # *carefully* --- report error here
287 - os._exit(1)
288 - sys.exit(1)
289 - return # should never get reached
290 -
291 - # if we were logging, kill the pipes.
292 - if logfile:
293 - os.close(pr)
294 - os.close(pw)
295 -
296 - if returnpid:
297 - return mypid
298 -
299 - # loop through pids (typically one, unless logging), either waiting on their death, or waxing them
300 - # if the main pid (mycommand) returned badly.
301 - while len(mypid):
302 - retval=os.waitpid(mypid[-1],0)[1]
303 - if retval != 0:
304 - cleanup(mypid[0:-1],block_exceptions=False)
305 - # at this point we've killed all other kid pids generated via this call.
306 - # return now.
307 - if raw_exit_code:
308 - return retval
309 - return process_exit_code(retval,throw_signals=raise_signals)
310 - else:
311 - mypid.pop(-1)
312 - cleanup(mypid)
313 - return 0
314 -
315 -
316 -def cmd(mycmd,myexc="",env={}):
317 +def cmd(mycmd, myexc="", env={}, debug=False):
318 try:
319 sys.stdout.flush()
320 - retval=spawn_bash(mycmd,env)
321 - if retval != 0:
322 - raise CatalystError,myexc
323 + args=[BASH_BINARY]
324 + if "BASH_ENV" not in env:
325 + env["BASH_ENV"] = "/etc/spork/is/not/valid/profile.env"
326 + if debug:
327 + args.append("-x")
328 + args.append("-c")
329 + args.append(mycmd)
330 +
331 + if debug:
332 + print "cmd(); args =", args
333 + proc = Popen(args, env=env)
334 + if proc.wait() != 0:
335 + raise CatalystError("cmd() NON-zero return value from: %s" % myexc,
336 + print_traceback=False)
337 except:
338 raise
339
340
341 -def process_exit_code(retval,throw_signals=False):
342 - """process a waitpid returned exit code, returning exit code if it exit'd, or the
343 - signal if it died from signalling
344 - if throw_signals is on, it raises a SystemExit if the process was signaled.
345 - This is intended for usage with threads, although at the moment you can't signal individual
346 - threads in python, only the master thread, so it's a questionable option."""
347 - if (retval & 0xff)==0:
348 - return retval >> 8 # return exit code
349 - else:
350 - if throw_signals:
351 - #use systemexit, since portage is stupid about exception catching.
352 - raise SystemExit()
353 - return (retval & 0xff) << 8 # interrupted by signal
354 -
355 -
356 def file_locate(settings,filelist,expand=1):
357 #if expand=1, non-absolute paths will be accepted and
358 # expanded to os.getcwd()+"/"+localpath if file exists
359 @@ -459,8 +200,8 @@ def parse_makeconf(mylines):
360 mobj=pat.match(myline)
361 pos += 1
362 if mobj.group(2):
363 - clean_string = re.sub(r"\"",r"",mobj.group(2))
364 - mymakeconf[mobj.group(1)]=clean_string
365 + clean_string = re.sub(r"\"",r"",mobj.group(2))
366 + mymakeconf[mobj.group(1)]=clean_string
367 return mymakeconf
368
369
370
371 diff --git a/catalyst/targets/generic_stage_target.py b/catalyst/targets/generic_stage_target.py
372 index f297524..f65c770 100644
373 --- a/catalyst/targets/generic_stage_target.py
374 +++ b/catalyst/targets/generic_stage_target.py
375 @@ -1136,7 +1136,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
376 else:
377 if "fsscript" in self.settings:
378 if os.path.exists(self.settings["controller_file"]):
379 - cmd("/bin/bash "+self.settings["controller_file"]+\
380 + cmd(self.settings["controller_file"]+\
381 " fsscript","fsscript script failed.",env=self.env)
382 touch(fsscript_resume)
383
384 @@ -1147,7 +1147,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
385 print "Resume point detected, skipping rcupdate operation..."
386 else:
387 if os.path.exists(self.settings["controller_file"]):
388 - cmd("/bin/bash "+self.settings["controller_file"]+" rc-update",\
389 + cmd(self.settings["controller_file"]+" rc-update",\
390 "rc-update script failed.",env=self.env)
391 touch(rcupdate_resume)
392
393 @@ -1183,7 +1183,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
394 "Could not remove stray files in /etc",env=self.env)
395
396 if os.path.exists(self.settings["controller_file"]):
397 - cmd("/bin/bash "+self.settings["controller_file"]+" clean",\
398 + cmd(self.settings["controller_file"]+" clean",\
399 "clean script failed.",env=self.env)
400 touch(clean_resume)
401
402 @@ -1232,7 +1232,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
403 os.system("rm -rf "+self.settings["chroot_path"]+x)
404 try:
405 if os.path.exists(self.settings["controller_file"]):
406 - cmd("/bin/bash "+self.settings["controller_file"]+\
407 + cmd(self.settings["controller_file"]+\
408 " clean","Clean failed.",env=self.env)
409 touch(remove_resume)
410 except:
411 @@ -1247,7 +1247,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
412 else:
413 try:
414 if os.path.exists(self.settings["controller_file"]):
415 - cmd("/bin/bash "+self.settings["controller_file"]+\
416 + cmd(self.settings["controller_file"]+\
417 " preclean","preclean script failed.",env=self.env)
418 touch(preclean_resume)
419
420 @@ -1289,7 +1289,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
421 else:
422 try:
423 if os.path.exists(self.settings["controller_file"]):
424 - cmd("/bin/bash "+self.settings["controller_file"]+" run",\
425 + cmd(self.settings["controller_file"]+" run",\
426 "run script failed.",env=self.env)
427 touch(run_local_resume)
428
429 @@ -1388,7 +1388,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
430
431 """ Before cleaning, unmerge stuff """
432 try:
433 - cmd("/bin/bash "+self.settings["controller_file"]+\
434 + cmd(self.settings["controller_file"]+\
435 " unmerge "+ myunmerge,"Unmerge script failed.",\
436 env=self.env)
437 print "unmerge shell script"
438 @@ -1405,7 +1405,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
439 print "Resume point detected, skipping target_setup operation..."
440 else:
441 print "Setting up filesystems per filesystem type"
442 - cmd("/bin/bash "+self.settings["controller_file"]+\
443 + cmd(self.settings["controller_file"]+\
444 " target_image_setup "+ self.settings["target_path"],\
445 "target_image_setup script failed.",env=self.env)
446 touch(target_setup_resume)
447 @@ -1434,7 +1434,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
448 else:
449 """ Create the ISO """
450 if "iso" in self.settings:
451 - cmd("/bin/bash "+self.settings["controller_file"]+" iso "+\
452 + cmd(self.settings["controller_file"]+" iso "+\
453 self.settings["iso"],"ISO creation script failed.",\
454 env=self.env)
455 self.gen_contents_file(self.settings["iso"])
456 @@ -1461,7 +1461,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
457 list_bashify(self.settings[self.settings["spec_prefix"]\
458 +"/packages"])
459 try:
460 - cmd("/bin/bash "+self.settings["controller_file"]+\
461 + cmd(self.settings["controller_file"]+\
462 " build_packages "+mypack,\
463 "Error in attempt to build packages",env=self.env)
464 touch(build_packages_resume)
465 @@ -1486,7 +1486,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
466 """
467 Execute the script that sets up the kernel build environment
468 """
469 - cmd("/bin/bash "+self.settings["controller_file"]+\
470 + cmd(self.settings["controller_file"]+\
471 " pre-kmerge ","Runscript pre-kmerge failed",\
472 env=self.env)
473 for kname in mynames:
474 @@ -1603,7 +1603,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
475 print "Resume point detected, skipping bootloader operation..."
476 else:
477 try:
478 - cmd("/bin/bash "+self.settings["controller_file"]+\
479 + cmd(self.settings["controller_file"]+\
480 " bootloader " + self.settings["target_path"],\
481 "Bootloader script failed.",env=self.env)
482 touch(bootloader_resume)
483 @@ -1619,7 +1619,7 @@ class generic_stage_target(TargetBase, ClearBase, GenBase):
484 print "Resume point detected, skipping build_packages operation..."
485 else:
486 try:
487 - cmd("/bin/bash "+self.settings["controller_file"]+\
488 + cmd(self.settings["controller_file"]+\
489 " livecd-update","livecd-update failed.",env=self.env)
490 touch(livecd_update_resume)
491
492
493 diff --git a/catalyst/targets/grp_target.py b/catalyst/targets/grp_target.py
494 index a8309a8..033db75 100644
495 --- a/catalyst/targets/grp_target.py
496 +++ b/catalyst/targets/grp_target.py
497 @@ -54,7 +54,7 @@ class grp_target(generic_stage_target):
498 # example call: "grp.sh run pkgset cd1 xmms vim sys-apps/gleep"
499 mypackages=list_bashify(self.settings["grp/"+pkgset+"/packages"])
500 try:
501 - cmd("/bin/bash "+self.settings["controller_file"]+" run "+self.settings["grp/"+pkgset+"/type"]\
502 + cmd(self.settings["controller_file"]+" run "+self.settings["grp/"+pkgset+"/type"]\
503 +" "+pkgset+" "+mypackages,env=self.env)
504
505 except CatalystError:
506
507 diff --git a/catalyst/targets/netboot2_target.py b/catalyst/targets/netboot2_target.py
508 index 8809dd0..ea07d76 100644
509 --- a/catalyst/targets/netboot2_target.py
510 +++ b/catalyst/targets/netboot2_target.py
511 @@ -87,7 +87,7 @@ class netboot2_target(generic_stage_target):
512 myfiles.append(self.settings["netboot2/extra_files"])
513
514 try:
515 - cmd("/bin/bash "+self.settings["controller_file"]+\
516 + cmd(self.settings["controller_file"]+\
517 " image " + list_bashify(myfiles),env=self.env)
518 except CatalystError:
519 self.unbind()
520 @@ -112,7 +112,7 @@ class netboot2_target(generic_stage_target):
521 # no auto resume here as we always want the
522 # freshest images moved
523 try:
524 - cmd("/bin/bash "+self.settings["controller_file"]+\
525 + cmd(self.settings["controller_file"]+\
526 " final",env=self.env)
527 print ">>> Netboot Build Finished!"
528 except CatalystError:
529
530 diff --git a/catalyst/targets/netboot_target.py b/catalyst/targets/netboot_target.py
531 index 9d01b7e..ae1eb04 100644
532 --- a/catalyst/targets/netboot_target.py
533 +++ b/catalyst/targets/netboot_target.py
534 @@ -59,7 +59,7 @@ class netboot_target(generic_stage_target):
535 # if "netboot/packages" in self.settings:
536 # mypack=list_bashify(self.settings["netboot/packages"])
537 # try:
538 -# cmd("/bin/bash "+self.settings["controller_file"]+" packages "+mypack,env=self.env)
539 +# cmd(self.settings["controller_file"]+" packages "+mypack,env=self.env)
540 # except CatalystError:
541 # self.unbind()
542 # raise CatalystError,"netboot build aborting due to error."
543 @@ -71,7 +71,7 @@ class netboot_target(generic_stage_target):
544 else:
545 mycmd = ""
546 try:
547 - cmd("/bin/bash "+self.settings["controller_file"]+" busybox "+ mycmd,env=self.env)
548 + cmd(self.settings["controller_file"]+" busybox "+ mycmd,env=self.env)
549 except CatalystError:
550 self.unbind()
551 raise CatalystError,"netboot build aborting due to error."
552 @@ -99,7 +99,7 @@ class netboot_target(generic_stage_target):
553 myfiles.append(self.settings["netboot/extra_files"])
554
555 try:
556 - cmd("/bin/bash "+self.settings["controller_file"]+\
557 + cmd(self.settings["controller_file"]+\
558 " image " + list_bashify(myfiles),env=self.env)
559 except CatalystError:
560 self.unbind()
561 @@ -108,7 +108,7 @@ class netboot_target(generic_stage_target):
562 def create_netboot_files(self):
563 # finish it all up
564 try:
565 - cmd("/bin/bash "+self.settings["controller_file"]+" finish",env=self.env)
566 + cmd(self.settings["controller_file"]+" finish",env=self.env)
567 except CatalystError:
568 self.unbind()
569 raise CatalystError,"netboot build aborting due to error."
570
571 diff --git a/catalyst/targets/tinderbox_target.py b/catalyst/targets/tinderbox_target.py
572 index 1d31989..ea11d3f 100644
573 --- a/catalyst/targets/tinderbox_target.py
574 +++ b/catalyst/targets/tinderbox_target.py
575 @@ -21,7 +21,7 @@ class tinderbox_target(generic_stage_target):
576 # example call: "grp.sh run xmms vim sys-apps/gleep"
577 try:
578 if os.path.exists(self.settings["controller_file"]):
579 - cmd("/bin/bash "+self.settings["controller_file"]+" run "+\
580 + cmd(self.settings["controller_file"]+" run "+\
581 list_bashify(self.settings["tinderbox/packages"]),"run script failed.",env=self.env)
582
583 except CatalystError: