OLD | NEW |
1 # Copyright (c) 2011 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 """ChromiteCmd abstract class and related functions.""" | 5 """ChromiteCmd abstract class and related functions.""" |
6 | 6 |
7 # Python imports | 7 # Python imports |
8 import os | 8 import os |
9 import sys | 9 import sys |
10 | 10 |
(...skipping 17 matching lines...) Expand all Loading... |
28 def SetChromiteEnv(self, cros_env): | 28 def SetChromiteEnv(self, cros_env): |
29 """Sets the Chromite environment for this command | 29 """Sets the Chromite environment for this command |
30 | 30 |
31 This is split out from __init() since subclasses of ChromiteCmd do not | 31 This is split out from __init() since subclasses of ChromiteCmd do not |
32 have similar constructors and there are a lot of them, and the number is | 32 have similar constructors and there are a lot of them, and the number is |
33 likely to grow. | 33 likely to grow. |
34 | 34 |
35 Please call this method after the constructor. | 35 Please call this method after the constructor. |
36 """ | 36 """ |
37 self.cros_env = cros_env | 37 self.cros_env = cros_env |
38 self._oper = cros_env.GetOperation() | |
39 | 38 |
40 def Run(self, raw_argv, chroot_config=None): | 39 def Run(self, raw_argv, chroot_config=None): |
41 """Run the command. | 40 """Run the command. |
42 | 41 |
43 All subclasses must implement this. | 42 All subclasses must implement this. |
44 | 43 |
45 Args: | 44 Args: |
46 raw_argv: Command line arguments, including this command's name, but not | 45 raw_argv: Command line arguments, including this command's name, but not |
47 the chromite command name or chromite options. | 46 the chromite command name or chromite options. |
48 chroot_config: A SafeConfigParser for the chroot config; or None chromite | 47 chroot_config: A SafeConfigParser for the chroot config; or None chromite |
49 was called from within the chroot. | 48 was called from within the chroot. |
50 """ | 49 """ |
51 # Must be implemented by subclass... | 50 # Must be implemented by subclass... |
52 raise NotImplementedError() | 51 raise NotImplementedError() |
53 | 52 |
54 | 53 |
55 class WrappedChrootCmd(ChromiteCmd): | 54 class WrappedChrootCmd(ChromiteCmd): |
56 """Superclass for any command that is simply wrapped by chromite. | 55 """Superclass for any command that is simply wrapped by chromite. |
57 | 56 |
58 These are commands where: | 57 These are commands where: |
59 - We parse the command line only enough to figure out what board they | 58 - We parse the command line only enough to figure out what board they |
60 want. All othe command line parsing is handled by the wrapped command. | 59 want. All othe command line parsing is handled by the wrapped command. |
61 Because of this, the board name _needs_ to be specified first. | 60 Because of this, the board name _needs_ to be specified first. |
62 - Everything else (arg parsing, help, etc) is handled by the wrapped command. | 61 - Everything else (arg parsing, help, etc) is handled by the wrapped command. |
63 The usage string will be a little messed up, but hopefully that's OK. | 62 The usage string will be a little messed up, but hopefully that's OK. |
64 """ | 63 """ |
65 | 64 |
66 def __init__(self, name, target_cmd, host_cmd, need_args=False, | 65 def __init__(self, target_cmd, host_cmd, need_args=False, env_whitelist=None): |
67 env_whitelist=None): | |
68 """WrappedChrootCmd constructor. | 66 """WrappedChrootCmd constructor. |
69 | 67 |
70 Args: | 68 Args: |
71 name: This is a name for the command, displayed to the user. | |
72 target_cmd: We'll put this at the start of argv when calling a target | 69 target_cmd: We'll put this at the start of argv when calling a target |
73 command. We'll substiture %s with the target. | 70 command. We'll substiture %s with the target. |
74 Like - ['my_command-%s'] or ['my_command', '--board=%s'] | 71 Like - ['my_command-%s'] or ['my_command', '--board=%s'] |
75 host_cmd: We'll put this at the start of argv when calling a host command. | 72 host_cmd: We'll put this at the start of argv when calling a host command. |
76 Like - ['my_command'] or ['sudo', 'my_command'] | 73 Like - ['my_command'] or ['sudo', 'my_command'] |
77 need_args: If True, we'll prompt for arguments if they weren't specified. | 74 need_args: If True, we'll prompt for arguments if they weren't specified. |
78 This makes the most sense when someone runs chromite with no arguments | 75 This makes the most sense when someone runs chromite with no arguments |
79 and then walks through the menus. It's not ideal, but less sucky than | 76 and then walks through the menus. It's not ideal, but less sucky than |
80 just quitting. | 77 just quitting. |
81 env_whitelist: This is a whitelist of environment variables that will be | 78 env_whitelist: This is a whitelist of environment variables that will be |
82 read from the current environment and passed through to the command. | 79 read from the current environment and passed through to the command. |
83 Note that this doesn't matter much when we start inside the chroot, | 80 Note that this doesn't matter much when we start inside the chroot, |
84 but matters a lot when we transition into the chroot (since the | 81 but matters a lot when we transition into the chroot (since the |
85 environment is reset when that happens). | 82 environment is reset when that happens). |
86 Useful for portage commands. Like: ['USE', 'FEATURES'] | 83 Useful for portage commands. Like: ['USE', 'FEATURES'] |
87 """ | 84 """ |
88 # Call superclass constructor. | 85 # Call superclass constructor. |
89 super(WrappedChrootCmd, self).__init__() | 86 super(WrappedChrootCmd, self).__init__() |
90 | 87 |
91 # Save away params for use later in Run(). | 88 # Save away params for use later in Run(). |
92 self._name = name | |
93 self._target_cmd = target_cmd | 89 self._target_cmd = target_cmd |
94 self._host_cmd = host_cmd | 90 self._host_cmd = host_cmd |
95 self._need_args = need_args | 91 self._need_args = need_args |
96 | 92 |
97 # Handle the env_whitelist. We need to do this in __init__ rather than in | 93 # Handle the env_whitelist. We need to do this in __init__ rather than in |
98 # Run(), since we want the environment vars from outside the chroot. | 94 # Run(), since we want the environment vars from outside the chroot. |
99 if env_whitelist is None: | 95 if env_whitelist is None: |
100 self._env_to_add = {} | 96 self._env_to_add = {} |
101 else: | 97 else: |
102 self._env_to_add = dict((key, os.environ[key]) for key in env_whitelist | 98 self._env_to_add = dict((key, os.environ[key]) for key in env_whitelist |
(...skipping 17 matching lines...) Expand all Loading... |
120 # If we didn't get called through EnterChroot, we need to read the build | 116 # If we didn't get called through EnterChroot, we need to read the build |
121 # config. | 117 # config. |
122 if argv is None: | 118 if argv is None: |
123 # We look for the build config without calling OptionParser. This means | 119 # We look for the build config without calling OptionParser. This means |
124 # that the board _needs_ to be first (if it's specified) and all options | 120 # that the board _needs_ to be first (if it's specified) and all options |
125 # will be passed straight to our subcommand. | 121 # will be passed straight to our subcommand. |
126 argv, build_config = utils.GetBuildConfigFromArgs(raw_argv[1:]) | 122 argv, build_config = utils.GetBuildConfigFromArgs(raw_argv[1:]) |
127 | 123 |
128 # Enter the chroot if needed... | 124 # Enter the chroot if needed... |
129 if not cros_lib.IsInsideChroot(): | 125 if not cros_lib.IsInsideChroot(): |
130 self._oper.Info('ENTERING THE CHROOT') | |
131 utils.EnterChroot(chroot_config, (self, 'Run'), raw_argv, argv=argv, | 126 utils.EnterChroot(chroot_config, (self, 'Run'), raw_argv, argv=argv, |
132 build_config=build_config) | 127 build_config=build_config) |
133 else: | 128 else: |
134 # We'll put CWD as src/scripts when running the command. Since everyone | 129 # We'll put CWD as src/scripts when running the command. Since everyone |
135 # running by hand has their cwd there, it is probably the safest. | 130 # running by hand has their cwd there, it is probably the safest. |
136 cwd = os.path.join(utils.SRCROOT_PATH, 'src', 'scripts') | 131 cwd = os.path.join(utils.SRCROOT_PATH, 'src', 'scripts') |
137 | 132 |
138 # Get command to call. If build_config is None, it means host. | 133 # Get command to call. If build_config is None, it means host. |
139 if build_config is None: | 134 if build_config is None: |
140 argv_prefix = self._host_cmd | 135 argv_prefix = self._host_cmd |
(...skipping 12 matching lines...) Expand all Loading... |
153 break | 148 break |
154 argv.append(arg) | 149 argv.append(arg) |
155 | 150 |
156 # Add the prefix... | 151 # Add the prefix... |
157 argv = argv_prefix + argv | 152 argv = argv_prefix + argv |
158 | 153 |
159 # Update the environment with anything from the whitelist. | 154 # Update the environment with anything from the whitelist. |
160 env = os.environ.copy() | 155 env = os.environ.copy() |
161 env.update(self._env_to_add) | 156 env.update(self._env_to_add) |
162 | 157 |
163 self.cros_env.RunScript(self._name, '', argv, env=env) | 158 # Run ignoring errors (since some commands might return errors from |
| 159 # things like --help). |
| 160 # |
| 161 # TODO(dianders): "cros_workon --help" used to return errors, but that |
| 162 # has been fixed. Are there any other places where errors should |
| 163 # be ignored? If not, we should remove the error_ok parameter. |
| 164 cros_lib.RunCommand(argv, cwd=cwd, ignore_sigint=True, error_ok=True, |
| 165 env=env) |
OLD | NEW |