| 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 |