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

Side by Side Diff: scripts/common/chromium_utils.py

Issue 12300004: Build scripts refactor to support multislave (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: rebase Created 7 years, 9 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 | « no previous file | scripts/master/master_utils.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) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium 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 """ Set of basic operations/utilities that are used by the build. """ 5 """ Set of basic operations/utilities that are used by the build. """
6 6
7 import copy 7 import copy
8 import errno 8 import errno
9 import fnmatch 9 import fnmatch
10 import glob 10 import glob
11 import math 11 import math
12 import os 12 import os
13 import shutil 13 import shutil
14 import socket
14 import stat 15 import stat
15 import string # pylint: disable=W0402 16 import string # pylint: disable=W0402
16 import subprocess 17 import subprocess
17 import sys 18 import sys
18 import threading 19 import threading
19 import time 20 import time
20 import urllib 21 import urllib
21 import zipfile 22 import zipfile
22 23
23 try: 24 try:
24 import json # pylint: disable=F0401 25 import json # pylint: disable=F0401
25 except ImportError: 26 except ImportError:
26 import simplejson as json 27 import simplejson as json
27 28
28 29
30 BUILD_DIR = os.path.realpath(os.path.join(
31 os.path.dirname(__file__), os.pardir, os.pardir))
32
33
29 # Local errors. 34 # Local errors.
30 class MissingArgument(Exception): pass 35 class MissingArgument(Exception): pass
31 class PathNotFound(Exception): pass 36 class PathNotFound(Exception): pass
32 class ExternalError(Exception): pass 37 class ExternalError(Exception): pass
33 38
34 def IsWindows(): 39 def IsWindows():
35 return sys.platform == 'cygwin' or sys.platform.startswith('win') 40 return sys.platform == 'cygwin' or sys.platform.startswith('win')
36 41
37 def IsLinux(): 42 def IsLinux():
38 return sys.platform.startswith('linux') 43 return sys.platform.startswith('linux')
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 command = ['scp', '-r', '-p', srctree, host + ':' + dst] 977 command = ['scp', '-r', '-p', srctree, host + ':' + dst]
973 result = RunCommand(command) 978 result = RunCommand(command)
974 if result: 979 if result:
975 raise ExternalError('Failed to scp "%s" to "%s" (%s)' % 980 raise ExternalError('Failed to scp "%s" to "%s" (%s)' %
976 (srctree, host + ':' + dst, result)) 981 (srctree, host + ':' + dst, result))
977 982
978 983
979 def ListMasters(cue='master.cfg', include_public=True, include_internal=True): 984 def ListMasters(cue='master.cfg', include_public=True, include_internal=True):
980 """Returns all the masters found.""" 985 """Returns all the masters found."""
981 # Look for "internal" masters first. 986 # Look for "internal" masters first.
982 path_internal = os.path.join(os.path.dirname(__file__), '..', '..', '..', 987 path_internal = os.path.join(
983 'build_internal', 'masters/*/' + cue) 988 BUILD_DIR, os.pardir, 'build_internal', 'masters/*/' + cue)
984 path = os.path.join(os.path.dirname(__file__), '..', '..', 989 path = os.path.join(BUILD_DIR, 'masters/*/' + cue)
985 'masters/*/' + cue)
986 filenames = [] 990 filenames = []
987 if include_public: 991 if include_public:
988 filenames += glob.glob(path) 992 filenames += glob.glob(path)
989 if include_internal: 993 if include_internal:
990 filenames += glob.glob(path_internal) 994 filenames += glob.glob(path_internal)
991 return [os.path.abspath(os.path.dirname(f)) for f in filenames] 995 return [os.path.abspath(os.path.dirname(f)) for f in filenames]
992 996
993 997
998 def GetAllSlaves():
999 """Return all slave objects from masters."""
1000 slaves = []
1001 for master in ListMasters(cue='slaves.cfg'):
1002 cur_slaves = RunSlavesCfg(os.path.join(master, 'slaves.cfg'))
1003 for slave in cur_slaves:
1004 slave['mastername'] = os.path.basename(master)
1005 slaves.extend(cur_slaves)
1006 return slaves
1007
1008
1009 def GetActiveSlavename():
1010 testing_slavename = os.getenv('TESTING_SLAVENAME')
1011 if testing_slavename:
1012 return testing_slavename
1013 return socket.getfqdn().split('.', 1)[0].lower()
1014
1015
1016 def EntryToSlaveName(entry):
1017 """Produces slave name from the slaves config dict."""
1018 return entry.get('slavename') or entry.get('hostname')
1019
1020
1021 def GetActiveMaster(slavename=None):
1022 """Parses all the slaves.cfg and returns the name of the active master
1023 determined by the hostname. Returns None otherwise.
1024
1025 It will be matched against *both* the 'slavename' and 'hostname' fields
1026 in slaves.cfg.
1027 """
1028 slavename = slavename or GetActiveSlavename()
1029 for slave in GetAllSlaves():
1030 if slavename == EntryToSlaveName(slave):
1031 return slave['master']
1032
1033
994 def ParsePythonCfg(cfg_filepath): 1034 def ParsePythonCfg(cfg_filepath):
995 """Retrieves data from a python config file.""" 1035 """Retrieves data from a python config file."""
996 if not os.path.exists(cfg_filepath): 1036 if not os.path.exists(cfg_filepath):
997 return None 1037 return None
998 base_path = os.path.dirname(os.path.abspath(cfg_filepath)) 1038 base_path = os.path.dirname(os.path.abspath(cfg_filepath))
999 old_sys_path = sys.path 1039 old_sys_path = sys.path
1000 sys.path = sys.path + [base_path] 1040 sys.path = sys.path + [base_path]
1001 old_path = os.getcwd() 1041 old_cwd = os.getcwd()
1002 try: 1042 try:
1003 os.chdir(base_path) 1043 os.chdir(base_path)
1004 local_vars = {} 1044 local_vars = {}
1005 execfile(os.path.join(cfg_filepath), local_vars) 1045 execfile(os.path.join(cfg_filepath), local_vars)
1006 del local_vars['__builtins__'] 1046 del local_vars['__builtins__']
1007 return local_vars 1047 return local_vars
1008 finally: 1048 finally:
1009 os.chdir(old_path) 1049 os.chdir(old_cwd)
1010 sys.path = old_sys_path 1050 sys.path = old_sys_path
1011 1051
1012 1052
1013 def RunSlavesCfg(slaves_cfg): 1053 def RunSlavesCfg(slaves_cfg):
1014 """Runs slaves.cfg in a consistent way.""" 1054 """Runs slaves.cfg in a consistent way."""
1015 if not os.path.exists(slaves_cfg): 1055 slave_config = ParsePythonCfg(slaves_cfg) or {}
1016 return [] 1056 return slave_config.get('slaves', [])
1017 slaves_path = os.path.dirname(os.path.abspath(slaves_cfg))
1018 old_sys_path = sys.path
1019 sys.path = sys.path + [slaves_path]
1020 try:
1021 old_path = os.getcwd()
1022 try:
1023 os.chdir(slaves_path)
1024 local_vars = {}
1025 execfile(os.path.join(slaves_cfg), local_vars)
1026 return local_vars['slaves']
1027 finally:
1028 os.chdir(old_path)
1029 finally:
1030 sys.path = old_sys_path
1031 1057
1032 1058
1033 def convert_json(option, opt, value, parser): 1059 def convert_json(option, opt, value, parser):
1034 """Provide an OptionParser callback to unmarshal a JSON string.""" 1060 """Provide an OptionParser callback to unmarshal a JSON string."""
1035 setattr(parser.values, option.dest, json.loads(value)) 1061 setattr(parser.values, option.dest, json.loads(value))
1036 1062
1037 1063
1038 def SafeTranslate(inputstr): 1064 def SafeTranslate(inputstr):
1039 """Convert a free form string to one that can be used in a path. 1065 """Convert a free form string to one that can be used in a path.
1040 1066
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 output, error = proc.communicate() 1099 output, error = proc.communicate()
1074 if proc.returncode != 0: 1100 if proc.returncode != 0:
1075 raise ExternalError('%s failed with error %s\n' % (config_path, error)) 1101 raise ExternalError('%s failed with error %s\n' % (config_path, error))
1076 1102
1077 config_list = json.loads(output).values() # pylint: disable=E1103 1103 config_list = json.loads(output).values() # pylint: disable=E1103
1078 config_list.sort(key=lambda cfg: cfg['display_position']) 1104 config_list.sort(key=lambda cfg: cfg['display_position'])
1079 return config_list 1105 return config_list
1080 except ImportError: 1106 except ImportError:
1081 # To get around CQ pylint failures, because CQ doesn't check out chromite. 1107 # To get around CQ pylint failures, because CQ doesn't check out chromite.
1082 # TODO(maruel): Remove this try block when this issue is resolved. 1108 # TODO(maruel): Remove this try block when this issue is resolved.
1083 print 'cbuildbot_chromite not found! Returning empty config dictionary.'
1084 return {} 1109 return {}
1085 1110
1086 1111
1087 def AddPropertiesOptions(option_parser): 1112 def AddPropertiesOptions(option_parser):
1088 """Registers command line options for parsing build and factory properties. 1113 """Registers command line options for parsing build and factory properties.
1089 1114
1090 After parsing, the options object will have the 'build_properties' and 1115 After parsing, the options object will have the 'build_properties' and
1091 'factory_properties' attributes. The corresponding values will be python 1116 'factory_properties' attributes. The corresponding values will be python
1092 dictionaries containing the properties. If the options are not given on 1117 dictionaries containing the properties. If the options are not given on
1093 the command line, the dictionaries will be empty. 1118 the command line, the dictionaries will be empty.
(...skipping 11 matching lines...) Expand all
1105 nargs=1, default={}, 1130 nargs=1, default={},
1106 help='factory properties in JSON format') 1131 help='factory properties in JSON format')
1107 1132
1108 1133
1109 def AddThirdPartyLibToPath(lib, override=False): 1134 def AddThirdPartyLibToPath(lib, override=False):
1110 """Adds the specified dir in build/third_party to sys.path. 1135 """Adds the specified dir in build/third_party to sys.path.
1111 1136
1112 Setting 'override' to true will place the directory in the beginning of 1137 Setting 'override' to true will place the directory in the beginning of
1113 sys.path, useful for overriding previously set packages. 1138 sys.path, useful for overriding previously set packages.
1114 """ 1139 """
1115 libpath = os.path.abspath(os.path.join(os.path.dirname(__file__), 1140 libpath = os.path.abspath(os.path.join(BUILD_DIR, 'third_party', lib))
1116 '..', '..', 'third_party', lib))
1117 if override: 1141 if override:
1118 sys.path.insert(0, libpath) 1142 sys.path.insert(0, libpath)
1119 else: 1143 else:
1120 sys.path.append(libpath) 1144 sys.path.append(libpath)
1121 1145
1122 1146
1123 def GetLKGR(): 1147 def GetLKGR():
1124 """Connect to chromium LKGR server and get LKGR revision. 1148 """Connect to chromium LKGR server and get LKGR revision.
1125 1149
1126 On success, returns the LKGR and 'ok'. On error, returns None and the text of 1150 On success, returns the LKGR and 'ok'. On error, returns None and the text of
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 'This is almost certainly incorrect.' % (build_dir, platform_key)) 1203 'This is almost certainly incorrect.' % (build_dir, platform_key))
1180 if use_out: 1204 if use_out:
1181 legacy_path = 'out' 1205 legacy_path = 'out'
1182 else: 1206 else:
1183 legacy_path = legacy_paths[platform_key] 1207 legacy_path = legacy_paths[platform_key]
1184 build_dir = os.path.join(os.path.dirname(build_dir), legacy_path) 1208 build_dir = os.path.join(os.path.dirname(build_dir), legacy_path)
1185 print >> sys.stderr, ('Assuming you meant "%s"' % build_dir) 1209 print >> sys.stderr, ('Assuming you meant "%s"' % build_dir)
1186 bad = True 1210 bad = True
1187 1211
1188 return (build_dir, bad) 1212 return (build_dir, bad)
OLDNEW
« no previous file with comments | « no previous file | scripts/master/master_utils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698