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

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: Created 7 years, 10 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
1034 def ParsePythonCfg(cfg_filepath):
1035 """Retrieves data from a python config file."""
1036 base_path = os.path.dirname(os.path.abspath(cfg_filepath))
1037 old_sys_path = sys.path
1038 sys.path = sys.path + [base_path]
1039 old_path = os.getcwd()
1040 try:
1041 os.chdir(base_path)
1042 local_vars = {}
1043 execfile(os.path.join(cfg_filepath), local_vars)
1044 return local_vars
1045 finally:
1046 os.chdir(old_path)
1047 sys.path = old_sys_path
1048
1049
994 def RunSlavesCfg(slaves_cfg): 1050 def RunSlavesCfg(slaves_cfg):
995 """Runs slaves.cfg in a consistent way.""" 1051 """Runs slaves.cfg in a consistent way."""
996 if not os.path.exists(slaves_cfg): 1052 if not os.path.exists(slaves_cfg):
997 return [] 1053 return []
998 slaves_path = os.path.dirname(os.path.abspath(slaves_cfg)) 1054 return ParsePythonCfg(slaves_cfg).get('slaves', [])
999 old_sys_path = sys.path
1000 sys.path = sys.path + [slaves_path]
1001 try:
1002 old_path = os.getcwd()
1003 try:
1004 os.chdir(slaves_path)
1005 local_vars = {}
1006 execfile(os.path.join(slaves_cfg), local_vars)
1007 return local_vars['slaves']
1008 finally:
1009 os.chdir(old_path)
1010 finally:
1011 sys.path = old_sys_path
1012 1055
1013 1056
1014 def convert_json(option, opt, value, parser): 1057 def convert_json(option, opt, value, parser):
1015 """Provide an OptionParser callback to unmarshal a JSON string.""" 1058 """Provide an OptionParser callback to unmarshal a JSON string."""
1016 setattr(parser.values, option.dest, json.loads(value)) 1059 setattr(parser.values, option.dest, json.loads(value))
1017 1060
1018 1061
1019 def SafeTranslate(inputstr): 1062 def SafeTranslate(inputstr):
1020 """Convert a free form string to one that can be used in a path. 1063 """Convert a free form string to one that can be used in a path.
1021 1064
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 output, error = proc.communicate() 1097 output, error = proc.communicate()
1055 if proc.returncode != 0: 1098 if proc.returncode != 0:
1056 raise ExternalError('%s failed with error %s\n' % (config_path, error)) 1099 raise ExternalError('%s failed with error %s\n' % (config_path, error))
1057 1100
1058 config_list = json.loads(output).values() # pylint: disable=E1103 1101 config_list = json.loads(output).values() # pylint: disable=E1103
1059 config_list.sort(key=lambda cfg: cfg['display_position']) 1102 config_list.sort(key=lambda cfg: cfg['display_position'])
1060 return config_list 1103 return config_list
1061 except ImportError: 1104 except ImportError:
1062 # To get around CQ pylint failures, because CQ doesn't check out chromite. 1105 # To get around CQ pylint failures, because CQ doesn't check out chromite.
1063 # TODO(maruel): Remove this try block when this issue is resolved. 1106 # TODO(maruel): Remove this try block when this issue is resolved.
1064 print 'cbuildbot_chromite not found! Returning empty config dictionary.'
1065 return {} 1107 return {}
1066 1108
1067 1109
1068 def AddPropertiesOptions(option_parser): 1110 def AddPropertiesOptions(option_parser):
1069 """Registers command line options for parsing build and factory properties. 1111 """Registers command line options for parsing build and factory properties.
1070 1112
1071 After parsing, the options object will have the 'build_properties' and 1113 After parsing, the options object will have the 'build_properties' and
1072 'factory_properties' attributes. The corresponding values will be python 1114 'factory_properties' attributes. The corresponding values will be python
1073 dictionaries containing the properties. If the options are not given on 1115 dictionaries containing the properties. If the options are not given on
1074 the command line, the dictionaries will be empty. 1116 the command line, the dictionaries will be empty.
(...skipping 11 matching lines...) Expand all
1086 nargs=1, default={}, 1128 nargs=1, default={},
1087 help='factory properties in JSON format') 1129 help='factory properties in JSON format')
1088 1130
1089 1131
1090 def AddThirdPartyLibToPath(lib, override=False): 1132 def AddThirdPartyLibToPath(lib, override=False):
1091 """Adds the specified dir in build/third_party to sys.path. 1133 """Adds the specified dir in build/third_party to sys.path.
1092 1134
1093 Setting 'override' to true will place the directory in the beginning of 1135 Setting 'override' to true will place the directory in the beginning of
1094 sys.path, useful for overriding previously set packages. 1136 sys.path, useful for overriding previously set packages.
1095 """ 1137 """
1096 libpath = os.path.abspath(os.path.join(os.path.dirname(__file__), 1138 libpath = os.path.abspath(os.path.join(BUILD_DIR, 'third_party', lib))
1097 '..', '..', 'third_party', lib))
1098 if override: 1139 if override:
1099 sys.path.insert(0, libpath) 1140 sys.path.insert(0, libpath)
1100 else: 1141 else:
1101 sys.path.append(libpath) 1142 sys.path.append(libpath)
1102 1143
1103 1144
1104 def GetLKGR(): 1145 def GetLKGR():
1105 """Connect to chromium LKGR server and get LKGR revision. 1146 """Connect to chromium LKGR server and get LKGR revision.
1106 1147
1107 On success, returns the LKGR and 'ok'. On error, returns None and the text of 1148 On success, returns the LKGR and 'ok'. On error, returns None and the text of
(...skipping 16 matching lines...) Expand all
1124 conn.close() 1165 conn.close()
1125 1166
1126 return rev, 'ok' 1167 return rev, 'ok'
1127 1168
1128 1169
1129 def AbsoluteCanonicalPath(*path): 1170 def AbsoluteCanonicalPath(*path):
1130 """Return the most canonical path Python can provide.""" 1171 """Return the most canonical path Python can provide."""
1131 1172
1132 file_path = os.path.join(*path) 1173 file_path = os.path.join(*path)
1133 return os.path.realpath(os.path.abspath(os.path.expanduser(file_path))) 1174 return os.path.realpath(os.path.abspath(os.path.expanduser(file_path)))
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