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

Side by Side Diff: appengine/swarming/swarming_bot/os_utilities.py

Issue 1306633002: Overhaul Android support and make Swarming bot use python-adb (Closed) Base URL: git@github.com:luci/luci-py.git@master
Patch Set: Packaged libusb1 as a relative package to fix import paths Created 5 years, 4 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
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2014 The Swarming Authors. All rights reserved. 2 # Copyright 2014 The Swarming Authors. All rights reserved.
3 # Use of this source code is governed by the Apache v2.0 license that can be 3 # Use of this source code is governed by the Apache v2.0 license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """OS specific utility functions. 6 """OS specific utility functions.
7 7
8 Includes code: 8 Includes code:
9 - to declare the current system this code is running under. 9 - to declare the current system this code is running under.
10 - to run a command on user login. 10 - to run a command on user login.
11 - to restart the host. 11 - to restart the host.
12 12
13 This file serves as an API to bot_config.py. bot_config.py can be replaced on 13 This file serves as an API to bot_config.py. bot_config.py can be replaced on
14 the server to allow additional server-specific functionality. 14 the server to allow additional server-specific functionality.
15 """ 15 """
16 16
17 import ctypes 17 import ctypes
18 import getpass 18 import getpass
19 import glob 19 import glob
20 import hashlib
20 import json 21 import json
21 import logging 22 import logging
22 import multiprocessing 23 import multiprocessing
23 import os 24 import os
24 import pipes 25 import pipes
25 import platform 26 import platform
26 import re 27 import re
27 import signal 28 import signal
28 import socket 29 import socket
29 import string 30 import string
30 import subprocess 31 import subprocess
31 import sys 32 import sys
32 import tempfile 33 import tempfile
33 import time 34 import time
34 import urllib2 35 import urllib2
35 36
37 import platforms
36 from utils import file_path 38 from utils import file_path
37 from utils import tools 39 from utils import tools
38 from utils import zip_package
39
40
41 import platforms
42
43
44 THIS_FILE = os.path.abspath(zip_package.get_main_script_path() or __file__)
45 40
46 41
47 # https://cloud.google.com/compute/pricing#machinetype 42 # https://cloud.google.com/compute/pricing#machinetype
48 GCE_MACHINE_COST_HOUR_US = { 43 GCE_MACHINE_COST_HOUR_US = {
49 u'n1-standard-1': 0.063, 44 u'n1-standard-1': 0.063,
50 u'n1-standard-2': 0.126, 45 u'n1-standard-2': 0.126,
51 u'n1-standard-4': 0.252, 46 u'n1-standard-4': 0.252,
52 u'n1-standard-8': 0.504, 47 u'n1-standard-8': 0.504,
53 u'n1-standard-16': 1.008, 48 u'n1-standard-16': 1.008,
54 u'f1-micro': 0.012, 49 u'f1-micro': 0.012,
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 token_info.Label.Sid, p_sid_size.contents.value - 1) 707 token_info.Label.Sid, p_sid_size.contents.value - 1)
713 value = res.contents.value 708 value = res.contents.value
714 return mapping.get(value) or u'0x%04x' % value 709 return mapping.get(value) or u'0x%04x' % value
715 finally: 710 finally:
716 ctypes.windll.kernel32.CloseHandle(token) 711 ctypes.windll.kernel32.CloseHandle(token)
717 712
718 713
719 ### Android. 714 ### Android.
720 715
721 716
717 def initialize_android(pub, priv):
718 # TODO(maruel): Remove.
719 return platforms.android.initialize(pub, priv)
720
721
722 def get_dimensions_all_devices_android(devices):
723 """Returns the default dimensions for an host with multiple android devices.
724 """
725 dimensions = get_dimensions()
726 if not devices:
727 return dimensions
728
729 # Pop a few dimensions otherwise there will be too many dimensions.
730 del dimensions[u'cpu']
731 del dimensions[u'cores']
732 del dimensions[u'gpu']
733 dimensions.pop(u'machine_type')
734
735 # Make sure all the devices use the same board.
736 keys = (u'build.id', u'product.board')
737 for key in keys:
738 dimensions[key] = set()
739 dimensions[u'android'] = []
740 for serial_number, cmd in devices.iteritems():
741 if cmd:
742 properties = platforms.android.get_build_prop(cmd)
743 if properties:
744 for key in keys:
745 dimensions[key].add(properties[u'ro.' + key])
746 dimensions[u'android'].append(serial_number)
747 dimensions[u'android'].sort()
748 for key in keys:
749 if not dimensions[key]:
750 del dimensions[key]
751 else:
752 dimensions[key] = sorted(dimensions[key])
753 nb_android = len(dimensions[u'android'])
754 dimensions[u'android_devices'] = map(
755 str, range(nb_android, max(0, nb_android-2), -1))
756 return dimensions
757
758
759 def get_state_all_devices_android(devices):
760 """Returns state information about all the devices connected to the host.
761 """
762 state = get_state()
763 if not devices:
764 return state
765
766 # Add a few values that were poped from dimensions.
767 cpu_type = get_cpu_type()
768 cpu_bitness = get_cpu_bitness()
769 state[u'cpu'] = [
770 cpu_type,
771 cpu_type + u'-' + cpu_bitness,
772 ]
773 state[u'cores'] = [unicode(get_num_processors())]
774 state[u'gpu'] = get_gpu()[0]
775 machine_type = get_machine_type()
776 if machine_type:
777 state[u'machine_type'] = [machine_type]
778
779 keys = (
780 u'board.platform', u'product.cpu.abi', u'build.tags', u'build.type',
781 u'build.version.sdk')
782 state['devices'] = {}
783 for serial_number, cmd in devices.iteritems():
784 if cmd:
785 properties = platforms.android.get_build_prop(cmd)
786 if properties:
787 # TODO(maruel): uptime, diskstats, wifi, power, throttle, etc.
788 device = {
789 u'build': {key: properties[u'ro.'+key] for key in keys},
790 u'disk': platforms.android.get_disk(cmd),
791 u'battery': platforms.android.get_battery(cmd),
792 u'state': u'available',
793 u'temp': platforms.android.get_temp(cmd),
794 }
795 else:
796 device = {u'state': u'unavailable'}
797 else:
798 device = {u'state': 'unauthenticated'}
799 state[u'devices'][serial_number] = device
800 return state
722 801
723 802
724 ### 803 ###
725 804
726 805
727 def get_dimensions(): 806 def get_dimensions():
728 """Returns the default dimensions.""" 807 """Returns the default dimensions."""
729 os_name = get_os_name() 808 os_name = get_os_name()
730 cpu_type = get_cpu_type() 809 cpu_type = get_cpu_type()
731 cpu_bitness = get_cpu_bitness() 810 cpu_bitness = get_cpu_bitness()
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 os.remove(item) 1123 os.remove(item)
1045 for item in glob.iglob('%s.???' % name): 1124 for item in glob.iglob('%s.???' % name):
1046 os.remove(item) 1125 os.remove(item)
1047 except Exception as e: 1126 except Exception as e:
1048 logging.exception('trim_rolled_log(%s) failed: %s', name, e) 1127 logging.exception('trim_rolled_log(%s) failed: %s', name, e)
1049 1128
1050 1129
1051 def main(): 1130 def main():
1052 """Prints out the output of get_dimensions() and get_state().""" 1131 """Prints out the output of get_dimensions() and get_state()."""
1053 # Pass an empty tag, so pop it up since it has no significance. 1132 # Pass an empty tag, so pop it up since it has no significance.
1054 data = { 1133 devices = None
1055 u'dimensions': get_dimensions(), 1134 if sys.platform == 'linux2':
1056 u'state': get_state(), 1135 devices = platforms.android.get_devices()
1057 } 1136 if devices:
1137 try:
1138 data = {
1139 u'dimensions': get_dimensions_all_devices_android(devices),
1140 u'state': get_state_all_devices_android(devices),
1141 }
1142 finally:
1143 platforms.android.close_devices(devices)
1144 if not devices:
1145 data = {
1146 u'dimensions': get_dimensions(),
1147 u'state': get_state(),
1148 }
1149
1058 json.dump(data, sys.stdout, indent=2, sort_keys=True, separators=(',', ': ')) 1150 json.dump(data, sys.stdout, indent=2, sort_keys=True, separators=(',', ': '))
1059 print('') 1151 print('')
1060 return 0 1152 return 0
1061 1153
1062 1154
1063 if __name__ == '__main__': 1155 if __name__ == '__main__':
1064 sys.exit(main()) 1156 sys.exit(main())
OLDNEW
« no previous file with comments | « appengine/swarming/swarming_bot/adb ('k') | appengine/swarming/swarming_bot/platforms/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698