Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(813)

Side by Side Diff: lib/cros_build_lib.py

Issue 6840064: Restart codereview issue 6792042 (Closed) Base URL: http://git.chromium.org/git/chromite.git@master
Patch Set: Fix exec failures and other meta command failures to regular command failures. Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « buildbot/prebuilt_unittest.py ('k') | lib/cros_build_lib_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Common python commands used by various build scripts.""" 5 """Common python commands used by various build scripts."""
6 6
7 import inspect 7 import inspect
8 import os 8 import os
9 import re 9 import re
10 import signal 10 import signal
11 import subprocess 11 import subprocess
(...skipping 24 matching lines...) Expand all
36 return (type(self) == type(other) and 36 return (type(self) == type(other) and
37 str(self) == str(other) and 37 str(self) == str(other) and
38 self.cmd == other.cmd) 38 self.cmd == other.cmd)
39 39
40 def __ne__(self, other): 40 def __ne__(self, other):
41 return not self.__eq__(other) 41 return not self.__eq__(other)
42 42
43 def RunCommand(cmd, print_cmd=True, error_ok=False, error_message=None, 43 def RunCommand(cmd, print_cmd=True, error_ok=False, error_message=None,
44 exit_code=False, redirect_stdout=False, redirect_stderr=False, 44 exit_code=False, redirect_stdout=False, redirect_stderr=False,
45 cwd=None, input=None, enter_chroot=False, shell=False, 45 cwd=None, input=None, enter_chroot=False, shell=False,
46 env=None, ignore_sigint=False, combine_stdout_stderr=False): 46 env=None, extra_env=None, ignore_sigint=False,
47 combine_stdout_stderr=False):
47 """Runs a command. 48 """Runs a command.
48 49
49 Args: 50 Args:
50 cmd: cmd to run. Should be input to subprocess.Popen. 51 cmd: cmd to run. Should be input to subprocess.Popen. If a string, shell
52 must be true. Otherwise the command must be an array of arguments, and
53 shell must be false.
51 print_cmd: prints the command before running it. 54 print_cmd: prints the command before running it.
52 error_ok: does not raise an exception on error. 55 error_ok: does not raise an exception on error.
53 error_message: prints out this message when an error occurrs. 56 error_message: prints out this message when an error occurrs.
54 exit_code: returns the return code of the shell command. 57 exit_code: returns the return code of the shell command.
55 redirect_stdout: returns the stdout. 58 redirect_stdout: returns the stdout.
56 redirect_stderr: holds stderr output until input is communicated. 59 redirect_stderr: holds stderr output until input is communicated.
57 cwd: the working directory to run this cmd. 60 cwd: the working directory to run this cmd.
58 input: input to pipe into this command through stdin. 61 input: input to pipe into this command through stdin.
59 enter_chroot: this command should be run from within the chroot. If set, 62 enter_chroot: this command should be run from within the chroot. If set,
60 cwd must point to the scripts directory. 63 cwd must point to the scripts directory.
61 shell: If shell is True, the specified command will be executed through 64 shell: Controls whether we add a shell as a command interpreter. See cmd
62 the shell. 65 since it has to agree as to the type.
63 env: If non-None, this is the environment for the new process. 66 env: If non-None, this is the environment for the new process. If
67 enter_chroot is true then this is the environment of the enter_chroot,
68 most of which gets removed from the cmd run.
69 extra_env: If set, this is added to the environment for the new process.
70 In enter_chroot=True case, these are specified on the post-entry
71 side, and so are often more useful. This dictionary is not used to
72 clear any entries though.
64 ignore_sigint: If True, we'll ignore signal.SIGINT before calling the 73 ignore_sigint: If True, we'll ignore signal.SIGINT before calling the
65 child. This is the desired behavior if we know our child will handle 74 child. This is the desired behavior if we know our child will handle
66 Ctrl-C. If we don't do this, I think we and the child will both get 75 Ctrl-C. If we don't do this, I think we and the child will both get
67 Ctrl-C at the same time, which means we'll forcefully kill the child. 76 Ctrl-C at the same time, which means we'll forcefully kill the child.
68 combine_stdout_stderr: Combines stdout and stdin streams into stdout. 77 combine_stdout_stderr: Combines stdout and stdin streams into stdout.
69 78
70 Returns: 79 Returns:
71 A CommandResult object. 80 A CommandResult object.
72 81
73 Raises: 82 Raises:
74 Exception: Raises generic exception on error with optional error_message. 83 Exception: Raises generic exception on error with optional error_message.
75 """ 84 """
76 # Set default for variables. 85 # Set default for variables.
77 stdout = None 86 stdout = None
78 stderr = None 87 stderr = None
79 stdin = None 88 stdin = None
80 cmd_result = CommandResult() 89 cmd_result = CommandResult()
81 90
82 # Modify defaults based on parameters. 91 # Modify defaults based on parameters.
83 if redirect_stdout: stdout = subprocess.PIPE 92 if redirect_stdout: stdout = subprocess.PIPE
84 if redirect_stderr: stderr = subprocess.PIPE 93 if redirect_stderr: stderr = subprocess.PIPE
85 if combine_stdout_stderr: stderr = subprocess.STDOUT 94 if combine_stdout_stderr: stderr = subprocess.STDOUT
86 # TODO(sosa): gpylint complains about redefining built-in 'input'. 95 # TODO(sosa): gpylint complains about redefining built-in 'input'.
87 # Can we rename this variable? 96 # Can we rename this variable?
88 if input: stdin = subprocess.PIPE 97 if input: stdin = subprocess.PIPE
98
89 if isinstance(cmd, basestring): 99 if isinstance(cmd, basestring):
90 if enter_chroot: cmd = './enter_chroot.sh -- ' + cmd 100 if not shell:
91 cmd_str = cmd 101 raise Exception('Cannot run a string command without a shell')
92 else: 102 cmd = ['/bin/sh', '-c', cmd]
93 if enter_chroot: cmd = ['./enter_chroot.sh', '--'] + cmd 103 shell = False
94 cmd_str = ' '.join(cmd) 104 elif shell:
105 raise Exception('Cannot run an array command with a shell')
106
107 # If we are using enter_chroot we need to use enterchroot pass env through
108 # to the final command.
109 if enter_chroot:
110 cmd = ['./enter_chroot.sh', '--'] + cmd
111 if extra_env:
112 for (key, value) in extra_env.items():
113 cmd.insert(1, '%s=%s' % (key, value))
114 elif extra_env:
115 if env is not None:
116 env = env.copy()
117 else:
118 env = os.environ.copy()
119
120 env.update(extra_env)
95 121
96 # Print out the command before running. 122 # Print out the command before running.
97 if print_cmd: 123 if print_cmd:
98 if cwd: 124 if cwd:
99 Info('RunCommand: %s in %s' % (cmd_str, cwd)) 125 Info('RunCommand: %r in %s' % (cmd, cwd))
100 else: 126 else:
101 Info('RunCommand: %s' % cmd_str) 127 Info('RunCommand: %r' % cmd)
102 cmd_result.cmd = cmd 128 cmd_result.cmd = cmd
103 129
104 try: 130 try:
105 proc = subprocess.Popen(cmd, cwd=cwd, stdin=stdin, stdout=stdout, 131 proc = subprocess.Popen(cmd, cwd=cwd, stdin=stdin, stdout=stdout,
106 stderr=stderr, shell=shell, env=env) 132 stderr=stderr, shell=False, env=env)
107 if ignore_sigint: 133 if ignore_sigint:
108 old_sigint = signal.signal(signal.SIGINT, signal.SIG_IGN) 134 old_sigint = signal.signal(signal.SIGINT, signal.SIG_IGN)
109 try: 135 try:
110 (cmd_result.output, cmd_result.error) = proc.communicate(input) 136 (cmd_result.output, cmd_result.error) = proc.communicate(input)
111 finally: 137 finally:
112 if ignore_sigint: 138 if ignore_sigint:
113 signal.signal(signal.SIGINT, old_sigint) 139 signal.signal(signal.SIGINT, old_sigint)
114 140
115 if exit_code: 141 if exit_code:
116 cmd_result.returncode = proc.returncode 142 cmd_result.returncode = proc.returncode
117 143
118 if not error_ok and proc.returncode: 144 if not error_ok and proc.returncode:
119 msg = ('Command "%s" failed.\n' % cmd_str + 145 msg = ('Command "%r" failed.\n' % cmd +
120 (error_message or cmd_result.error or cmd_result.output or '')) 146 (error_message or cmd_result.error or cmd_result.output or ''))
121 raise RunCommandError(msg, cmd) 147 raise RunCommandError(msg, cmd)
122 # TODO(sosa): is it possible not to use the catch-all Exception here? 148 # TODO(sosa): is it possible not to use the catch-all Exception here?
149 except OSError, e:
150 if not error_ok:
151 raise RunCommandError(str(e), cmd)
152 else:
153 Warning(str(e))
154
davidjames 2011/04/19 22:42:37 no need for this newline
Peter Mayo 2011/04/19 23:14:58 Done.
123 except Exception, e: 155 except Exception, e:
124 if not error_ok: 156 if not error_ok:
125 raise 157 raise
126 else: 158 else:
127 Warning(str(e)) 159 Warning(str(e))
128 160
129 return cmd_result 161 return cmd_result
130 162
131 163
132 #TODO(sjg): Remove this in favor of operation.Die 164 #TODO(sjg): Remove this in favor of operation.Die
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 except RunCommandException as e: 409 except RunCommandException as e:
378 if not error_ok and retry_count == num_retries: 410 if not error_ok and retry_count == num_retries:
379 raise e 411 raise e
380 else: 412 else:
381 Warning(str(e)) 413 Warning(str(e))
382 if print_cmd: 414 if print_cmd:
383 Info('PROGRAM(%s) -> RunCommand: retrying %r in dir %s' % 415 Info('PROGRAM(%s) -> RunCommand: retrying %r in dir %s' %
384 (GetCallerName(), cmd, cwd)) 416 (GetCallerName(), cmd, cwd))
385 417
386 return output 418 return output
OLDNEW
« no previous file with comments | « buildbot/prebuilt_unittest.py ('k') | lib/cros_build_lib_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698