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

Side by Side Diff: scripts/slave/annotated_run.py

Issue 1178733003: Modify annotated_run to read factory configs from the slave checkout. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: add --override-lookup to run_recipe and annotated_run Created 5 years, 6 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/tools/run_recipe.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 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import json
6 import optparse 7 import optparse
7 import os 8 import os
8 import subprocess 9 import subprocess
9 import sys 10 import sys
10 11
11 BUILD_ROOT = os.path.dirname(os.path.dirname(os.path.dirname( 12 BUILD_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(
12 os.path.abspath(__file__)))) 13 os.path.abspath(__file__))))
13 sys.path.append(os.path.join(BUILD_ROOT, 'scripts')) 14 sys.path.append(os.path.join(BUILD_ROOT, 'scripts'))
14 sys.path.append(os.path.join(BUILD_ROOT, 'third_party')) 15 sys.path.append(os.path.join(BUILD_ROOT, 'third_party'))
15 16
16 from common import annotator 17 from common import annotator
17 from common import chromium_utils 18 from common import chromium_utils
18 from slave import recipe_universe 19 from slave import recipe_universe
19 20
20 from recipe_engine import main as recipe_main 21 from recipe_engine import main as recipe_main
21 22
22 23
23 def get_recipe_properties(factory_properties, build_properties): 24 def get_recipe_properties(factory_properties, build_properties,
25 override_lookup):
24 """Constructs the recipe's properties from buildbot's properties. 26 """Constructs the recipe's properties from buildbot's properties.
25 27
26 This merges factory_properties and build_properties. Furthermore, it 28 This retrieves the current factory properties from the master_config
27 tries to reconstruct the 'recipe' property from builders.pyl if it isn't 29 in the slave's checkout (the factory properties handed to us from the
28 already there, and in that case merges in properties form builders.pyl. 30 master might be out of date), and merges in the build properties.
31
32 Using the values from the checkout allows us to do things like change
33 the recipe and other factory properties for a builder without needing
34 a master restart.
29 """ 35 """
30 properties = factory_properties.copy() 36 mastername = factory_properties['mastername']
37 buildername = factory_properties['buildername']
38
39 properties = {}
40
41 if mastername and buildername:
42 properties = get_on_disk_factory_properties(mastername, buildername)
43
44 if override_lookup:
45 if properties['recipe'] != factory_properties['recipe']:
46 print >> sys.stderr, (
47 'WARNING: Using recipe "%s" given on the command line '
48 'command line, rather than "%s" as listed in the master.cfg' %
49 (properties['recipe'], factory_properties['recipe']))
Dirk Pranke 2015/06/11 22:40:21 I don't warn about other factory properties also o
iannucci 2015/06/11 23:01:49 I'd err on the side of enumerating the mismatches
Dirk Pranke 2015/06/11 23:22:47 Ok. It's easy enough to do.
50 properties.update(factory_properties)
51 else:
52 properties = factory_properties.copy()
53
31 properties.update(build_properties) 54 properties.update(build_properties)
55 return properties
32 56
33 # Try to reconstruct the recipe from builders.pyl if not given.
34 if 'recipe' not in properties:
35 mastername = properties['mastername']
36 buildername = properties['buildername']
37 57
38 master_path = chromium_utils.MasterPath(mastername) 58 def get_on_disk_factory_properties(mastername, buildername):
39 builders_file = os.path.join(master_path, 'builders.pyl') 59 script_path = os.path.join(BUILD_ROOT, 'scripts', 'tools',
40 if os.path.isfile(builders_file): 60 'dump_master_cfg.py')
41 builders = chromium_utils.ReadBuildersFile(builders_file) 61 dump_cmd = [sys.executable,
42 assert buildername in builders['builders'], ( 62 script_path,
43 'buildername %s is not listed in %s' % (buildername, builders_file)) 63 mastername]
44 builder = builders['builders'][buildername] 64 proc = subprocess.Popen(dump_cmd, cwd=BUILD_ROOT, stdout=subprocess.PIPE)
65 out, _ = proc.communicate()
66 exit_code = proc.returncode
45 67
46 # Update properties with builders.pyl data. 68 if exit_code:
47 properties['recipe'] = builder['recipe'] 69 raise LookupError('Failed to get the master config; dump_master_cfg %s'
48 properties.update(builder.get('properties', {})) 70 'returned %d):\n%s\n'% (
49 else: 71 mastername, exit_code, out))
50 raise LookupError('Cannot find recipe for %s on %s' % 72
51 (build_properties['buildername'], 73 config = json.loads(out)
52 build_properties['mastername'])) 74
53 return properties 75 # Now extract just the factory properties for the requested builder
76 # from the master config.
77 props = None
78 for builder_dict in config['builders']:
79 if builder_dict['name'] == buildername:
80 props = dict((k, v) for k, v, _ in
81 builder_dict['factory'].properties.asList())
iannucci 2015/06/11 23:01:49 hm... isn't config json though? I don't think ther
Dirk Pranke 2015/06/11 23:22:47 Yeah, that's probably true. I need to run this, be
82
83 if not props:
84 raise LookupError('builder "%s" not found on in master "%s"' %
85 (buildername, mastername))
86
87 if 'recipe' not in props:
88 raise LookupError('Cannot find recipe for %s on %s' %
89 (buildername, mastername))
90
91 return props
54 92
55 93
56 def get_args(argv): 94 def get_args(argv):
57 """Process command-line arguments.""" 95 """Process command-line arguments."""
58 96
59 parser = optparse.OptionParser( 97 parser = optparse.OptionParser(
60 description='Entry point for annotated builds.') 98 description='Entry point for annotated builds.')
61 parser.add_option('--build-properties', 99 parser.add_option('--build-properties',
62 action='callback', callback=chromium_utils.convert_json, 100 action='callback', callback=chromium_utils.convert_json,
63 type='string', default={}, 101 type='string', default={},
64 help='build properties in JSON format') 102 help='build properties in JSON format')
65 parser.add_option('--factory-properties', 103 parser.add_option('--factory-properties',
66 action='callback', callback=chromium_utils.convert_json, 104 action='callback', callback=chromium_utils.convert_json,
67 type='string', default={}, 105 type='string', default={},
68 help='factory properties in JSON format') 106 help='factory properties in JSON format')
69 parser.add_option('--build-properties-gz', 107 parser.add_option('--build-properties-gz',
70 action='callback', callback=chromium_utils.convert_gz_json, 108 action='callback', callback=chromium_utils.convert_gz_json,
71 type='string', default={}, dest='build_properties', 109 type='string', default={}, dest='build_properties',
72 help='build properties in b64 gz JSON format') 110 help='build properties in b64 gz JSON format')
73 parser.add_option('--factory-properties-gz', 111 parser.add_option('--factory-properties-gz',
74 action='callback', callback=chromium_utils.convert_gz_json, 112 action='callback', callback=chromium_utils.convert_gz_json,
75 type='string', default={}, dest='factory_properties', 113 type='string', default={}, dest='factory_properties',
76 help='factory properties in b64 gz JSON format') 114 help='factory properties in b64 gz JSON format')
77 parser.add_option('--keep-stdin', action='store_true', default=False, 115 parser.add_option('--keep-stdin', action='store_true', default=False,
78 help='don\'t close stdin when running recipe steps') 116 help='don\'t close stdin when running recipe steps')
117 parser.add_option('--override-lookup', action='store_true',
118 help='use the recipe and other factory properties '
119 'given on the command line rather than the '
120 'properties in the master.cfg')
iannucci 2015/06/11 23:01:49 IIRC, run_recipe passes all args as build properti
Dirk Pranke 2015/06/11 23:22:47 looks like run_recipe passes all args as both, jus
79 return parser.parse_args(argv) 121 return parser.parse_args(argv)
80 122
81 123
82 def update_scripts(): 124 def update_scripts():
83 if os.environ.get('RUN_SLAVE_UPDATED_SCRIPTS'): 125 if os.environ.get('RUN_SLAVE_UPDATED_SCRIPTS'):
84 os.environ.pop('RUN_SLAVE_UPDATED_SCRIPTS') 126 os.environ.pop('RUN_SLAVE_UPDATED_SCRIPTS')
85 return False 127 return False
86 128
87 stream = annotator.StructuredAnnotationStream() 129 stream = annotator.StructuredAnnotationStream()
88 130
(...skipping 17 matching lines...) Expand all
106 # After running update scripts, set PYTHONIOENCODING=UTF-8 for the real 148 # After running update scripts, set PYTHONIOENCODING=UTF-8 for the real
107 # annotated_run. 149 # annotated_run.
108 os.environ['PYTHONIOENCODING'] = 'UTF-8' 150 os.environ['PYTHONIOENCODING'] = 'UTF-8'
109 151
110 return True 152 return True
111 153
112 154
113 def main(argv): 155 def main(argv):
114 opts, _ = get_args(argv) 156 opts, _ = get_args(argv)
115 properties = get_recipe_properties( 157 properties = get_recipe_properties(
116 opts.factory_properties, opts.build_properties) 158 opts.factory_properties, opts.build_properties, opts.override_lookup)
117 stream = annotator.StructuredAnnotationStream() 159 stream = annotator.StructuredAnnotationStream()
118 ret = recipe_main.run_steps(properties, stream, 160 ret = recipe_main.run_steps(properties, stream,
119 universe=recipe_universe.get_universe()) 161 universe=recipe_universe.get_universe())
120 return ret.status_code 162 return ret.status_code
121 163
122 164
123 def shell_main(argv): 165 def shell_main(argv):
124 if update_scripts(): 166 if update_scripts():
125 return subprocess.call([sys.executable] + argv) 167 return subprocess.call([sys.executable] + argv)
126 else: 168 else:
127 return main(argv) 169 return main(argv)
128 170
129 if __name__ == '__main__': 171 if __name__ == '__main__':
130 sys.exit(shell_main(sys.argv)) 172 sys.exit(shell_main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | scripts/tools/run_recipe.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698