OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """Provisions Android devices with settings required for bots. | 7 """Provisions Android devices with settings required for bots. |
8 | 8 |
9 Usage: | 9 Usage: |
10 ./provision_devices.py [-d <device serial number>] | 10 ./provision_devices.py [-d <device serial number>] |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 def should_run_phase(phase_name): | 78 def should_run_phase(phase_name): |
79 return not options.phases or phase_name in options.phases | 79 return not options.phases or phase_name in options.phases |
80 | 80 |
81 def run_phase(phase_func, reboot=True): | 81 def run_phase(phase_func, reboot=True): |
82 device.WaitUntilFullyBooted(timeout=reboot_timeout) | 82 device.WaitUntilFullyBooted(timeout=reboot_timeout) |
83 phase_func(device, options) | 83 phase_func(device, options) |
84 if reboot: | 84 if reboot: |
85 device.Reboot(False, retries=0) | 85 device.Reboot(False, retries=0) |
86 device.adb.WaitForDevice() | 86 device.adb.WaitForDevice() |
87 | 87 |
88 if should_run_phase(_PHASES.WIPE): | 88 try: |
89 run_phase(WipeDevice) | 89 if should_run_phase(_PHASES.WIPE): |
| 90 run_phase(WipeDevice) |
90 | 91 |
91 if should_run_phase(_PHASES.PROPERTIES): | 92 if should_run_phase(_PHASES.PROPERTIES): |
92 run_phase(SetProperties) | 93 run_phase(SetProperties) |
93 | 94 |
94 if should_run_phase(_PHASES.FINISH): | 95 if should_run_phase(_PHASES.FINISH): |
95 run_phase(FinishProvisioning, reboot=False) | 96 run_phase(FinishProvisioning, reboot=False) |
| 97 |
| 98 except (errors.WaitForResponseTimedOutError, |
| 99 device_errors.CommandTimeoutError): |
| 100 logging.exception('Timed out waiting for device %s. Adding to blacklist.', |
| 101 str(device)) |
| 102 device_blacklist.ExtendBlacklist([str(device)]) |
| 103 |
| 104 except device_errors.CommandFailedError: |
| 105 logging.exception('Failed to provision device %s. Adding to blacklist.', |
| 106 str(device)) |
| 107 device_blacklist.ExtendBlacklist([str(device)]) |
96 | 108 |
97 | 109 |
98 def WipeDevice(device, options): | 110 def WipeDevice(device, options): |
99 """Wipes data from device, keeping only the adb_keys for authorization. | 111 """Wipes data from device, keeping only the adb_keys for authorization. |
100 | 112 |
101 After wiping data on a device that has been authorized, adb can still | 113 After wiping data on a device that has been authorized, adb can still |
102 communicate with the device, but after reboot the device will need to be | 114 communicate with the device, but after reboot the device will need to be |
103 re-authorized because the adb keys file is stored in /data/misc/adb/. | 115 re-authorized because the adb keys file is stored in /data/misc/adb/. |
104 Thus, adb_keys file is rewritten so the device does not need to be | 116 Thus, adb_keys file is rewritten so the device does not need to be |
105 re-authorized. | 117 re-authorized. |
106 | 118 |
107 Arguments: | 119 Arguments: |
108 device: the device to wipe | 120 device: the device to wipe |
109 """ | 121 """ |
110 if options.skip_wipe: | 122 if options.skip_wipe: |
111 return | 123 return |
112 | 124 |
113 device.EnableRoot() | |
114 device_authorized = device.FileExists(constants.ADB_KEYS_FILE) | |
115 if device_authorized: | |
116 adb_keys = device.ReadFile(constants.ADB_KEYS_FILE, | |
117 as_root=True).splitlines() | |
118 try: | 125 try: |
| 126 device.EnableRoot() |
| 127 device_authorized = device.FileExists(constants.ADB_KEYS_FILE) |
| 128 if device_authorized: |
| 129 adb_keys = device.ReadFile(constants.ADB_KEYS_FILE, |
| 130 as_root=True).splitlines() |
119 device.RunShellCommand(['wipe', 'data'], | 131 device.RunShellCommand(['wipe', 'data'], |
120 as_root=True, check_return=True) | 132 as_root=True, check_return=True) |
| 133 device.adb.WaitForDevice() |
| 134 |
| 135 if device_authorized: |
| 136 adb_keys_set = set(adb_keys) |
| 137 for adb_key_file in options.adb_key_files or []: |
| 138 try: |
| 139 with open(adb_key_file, 'r') as f: |
| 140 adb_public_keys = f.readlines() |
| 141 adb_keys_set.update(adb_public_keys) |
| 142 except IOError: |
| 143 logging.warning('Unable to find adb keys file %s.' % adb_key_file) |
| 144 _WriteAdbKeysFile(device, '\n'.join(adb_keys_set)) |
121 except device_errors.CommandFailedError: | 145 except device_errors.CommandFailedError: |
122 logging.exception('Possible failure while wiping the device. ' | 146 logging.exception('Possible failure while wiping the device. ' |
123 'Attempting to continue.') | 147 'Attempting to continue.') |
124 device.adb.WaitForDevice() | |
125 | |
126 if device_authorized: | |
127 adb_keys_set = set(adb_keys) | |
128 for adb_key_file in options.adb_key_files or []: | |
129 try: | |
130 with open(adb_key_file, 'r') as f: | |
131 adb_public_keys = f.readlines() | |
132 adb_keys_set.update(adb_public_keys) | |
133 except IOError: | |
134 logging.warning('Unable to find adb keys file %s.' % adb_key_file) | |
135 _WriteAdbKeysFile(device, '\n'.join(adb_keys_set)) | |
136 | 148 |
137 | 149 |
138 def _WriteAdbKeysFile(device, adb_keys_string): | 150 def _WriteAdbKeysFile(device, adb_keys_string): |
139 dir_path = posixpath.dirname(constants.ADB_KEYS_FILE) | 151 dir_path = posixpath.dirname(constants.ADB_KEYS_FILE) |
140 device.RunShellCommand(['mkdir', '-p', dir_path], | 152 device.RunShellCommand(['mkdir', '-p', dir_path], |
141 as_root=True, check_return=True) | 153 as_root=True, check_return=True) |
142 device.RunShellCommand(['restorecon', dir_path], | 154 device.RunShellCommand(['restorecon', dir_path], |
143 as_root=True, check_return=True) | 155 as_root=True, check_return=True) |
144 device.WriteFile(constants.ADB_KEYS_FILE, adb_keys_string, as_root=True) | 156 device.WriteFile(constants.ADB_KEYS_FILE, adb_keys_string, as_root=True) |
145 device.RunShellCommand(['restorecon', constants.ADB_KEYS_FILE], | 157 device.RunShellCommand(['restorecon', constants.ADB_KEYS_FILE], |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 local_props.append('%s=all' % android_commands.JAVA_ASSERT_PROPERTY) | 199 local_props.append('%s=all' % android_commands.JAVA_ASSERT_PROPERTY) |
188 local_props.append('debug.checkjni=1') | 200 local_props.append('debug.checkjni=1') |
189 try: | 201 try: |
190 device.WriteFile( | 202 device.WriteFile( |
191 constants.DEVICE_LOCAL_PROPERTIES_PATH, | 203 constants.DEVICE_LOCAL_PROPERTIES_PATH, |
192 '\n'.join(local_props), as_root=True) | 204 '\n'.join(local_props), as_root=True) |
193 # Android will not respect the local props file if it is world writable. | 205 # Android will not respect the local props file if it is world writable. |
194 device.RunShellCommand( | 206 device.RunShellCommand( |
195 ['chmod', '644', constants.DEVICE_LOCAL_PROPERTIES_PATH], | 207 ['chmod', '644', constants.DEVICE_LOCAL_PROPERTIES_PATH], |
196 as_root=True, check_return=True) | 208 as_root=True, check_return=True) |
197 except device_errors.CommandFailedError as e: | 209 except device_errors.CommandFailedError: |
198 logging.warning(str(e)) | 210 logging.exception('Failed to configure local properties.') |
199 | 211 |
200 | 212 |
201 def FinishProvisioning(device, options): | 213 def FinishProvisioning(device, options): |
202 try: | 214 device.RunShellCommand( |
203 device.RunShellCommand( | 215 ['date', '-s', time.strftime('%Y%m%d.%H%M%S', time.gmtime())], |
204 ['date', '-s', time.strftime('%Y%m%d.%H%M%S', time.gmtime())], | 216 as_root=True, check_return=True) |
205 as_root=True, check_return=True) | 217 props = device.RunShellCommand('getprop', check_return=True) |
206 props = device.RunShellCommand('getprop', check_return=True) | 218 for prop in props: |
207 for prop in props: | 219 logging.info(' %s' % prop) |
208 logging.info(' %s' % prop) | 220 if options.auto_reconnect: |
209 if options.auto_reconnect: | 221 _PushAndLaunchAdbReboot(device, options.target) |
210 _PushAndLaunchAdbReboot(device, options.target) | |
211 except (errors.WaitForResponseTimedOutError, | |
212 device_errors.CommandTimeoutError): | |
213 logging.info('Timed out waiting for device %s. Adding to blacklist.', | |
214 str(device)) | |
215 # Device black list is reset by bb_device_status_check.py per build. | |
216 device_blacklist.ExtendBlacklist([str(device)]) | |
217 except device_errors.CommandFailedError: | |
218 logging.exception('Failed to provision device %s. Adding to blacklist.', | |
219 str(device)) | |
220 device_blacklist.ExtendBlacklist([str(device)]) | |
221 | 222 |
222 | 223 |
223 def _PushAndLaunchAdbReboot(device, target): | 224 def _PushAndLaunchAdbReboot(device, target): |
224 """Pushes and launches the adb_reboot binary on the device. | 225 """Pushes and launches the adb_reboot binary on the device. |
225 | 226 |
226 Arguments: | 227 Arguments: |
227 device: The DeviceUtils instance for the device to which the adb_reboot | 228 device: The DeviceUtils instance for the device to which the adb_reboot |
228 binary should be pushed. | 229 binary should be pushed. |
229 target: The build target (example, Debug or Release) which helps in | 230 target: The build target (example, Debug or Release) which helps in |
230 locating the adb_reboot binary. | 231 locating the adb_reboot binary. |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 args = parser.parse_args() | 318 args = parser.parse_args() |
318 constants.SetBuildType(args.target) | 319 constants.SetBuildType(args.target) |
319 | 320 |
320 run_tests_helper.SetLogLevel(args.verbose) | 321 run_tests_helper.SetLogLevel(args.verbose) |
321 | 322 |
322 return ProvisionDevices(args) | 323 return ProvisionDevices(args) |
323 | 324 |
324 | 325 |
325 if __name__ == '__main__': | 326 if __name__ == '__main__': |
326 sys.exit(main()) | 327 sys.exit(main()) |
OLD | NEW |