Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 | 6 |
| 7 """ Launch multiple buildbot slave instances on a single machine. This script | 7 """ Launch multiple buildbot slave instances on a single machine. This script |
| 8 is intended to be run at boot time. """ | 8 is intended to be run at boot time. """ |
| 9 | 9 |
| 10 | 10 |
| 11 import multiprocessing | 11 import multiprocessing |
| 12 import os | 12 import os |
| 13 import shutil | 13 import shutil |
| 14 import socket | 14 import socket |
| 15 import subprocess | 15 import subprocess |
| 16 import sys | 16 import sys |
| 17 import time | 17 import time |
| 18 | 18 |
| 19 | 19 |
| 20 buildbot_path = os.path.abspath(os.path.join(os.path.dirname(__file__), | 20 buildbot_path = os.path.abspath(os.path.join(os.path.dirname(__file__), |
| 21 os.pardir)) | 21 os.pardir)) |
| 22 sys.path.append(os.path.join(buildbot_path, 'master')) | |
| 23 sys.path.append(os.path.join(buildbot_path, 'site_config')) | 22 sys.path.append(os.path.join(buildbot_path, 'site_config')) |
| 24 sys.path.append(os.path.join(buildbot_path, 'third_party', 'chromium_buildbot', | |
| 25 'scripts')) | |
| 26 sys.path.append(os.path.join(buildbot_path, 'third_party', 'chromium_buildbot', | |
| 27 'site_config')) | |
| 28 sys.path.append(os.path.join(buildbot_path, 'third_party', 'chromium_buildbot', | |
| 29 'third_party', 'buildbot_8_4p1')) | |
| 30 sys.path.append(os.path.join(buildbot_path, 'third_party', 'chromium_buildbot', | |
| 31 'third_party', 'jinja2')) | |
| 32 sys.path.append(os.path.join(buildbot_path, 'third_party', 'chromium_buildbot', | |
| 33 'third_party', 'twisted_8_1')) | |
| 34 | 23 |
| 35 | |
| 36 import config | |
| 37 import slave_hosts_cfg | 24 import slave_hosts_cfg |
| 38 import slaves_cfg | |
| 39 | 25 |
| 40 | 26 |
| 41 CHROME_INTERNAL = 'https://chrome-internal.googlesource.com/' | 27 CHROME_INTERNAL = 'https://chrome-internal.googlesource.com/' |
| 42 CHROME_SLAVE_DEPS_URL = CHROME_INTERNAL + 'chrome/tools/build/slave.DEPS' | 28 CHROME_SLAVE_DEPS_URL = CHROME_INTERNAL + 'chrome/tools/build/slave.DEPS' |
| 43 CHROME_SLAVE_INTERNAL_DEPS_URL = ( | 29 CHROME_SLAVE_INTERNAL_DEPS_URL = ( |
| 44 CHROME_INTERNAL + 'chrome/tools/build/internal.DEPS') | 30 CHROME_INTERNAL + 'chrome/tools/build/internal.DEPS') |
| 45 SKIA_URL = 'https://skia.googlesource.com/buildbot.git' | |
| 46 GCLIENT = 'gclient.bat' if os.name == 'nt' else 'gclient' | 31 GCLIENT = 'gclient.bat' if os.name == 'nt' else 'gclient' |
| 47 GIT = 'git.bat' if os.name == 'nt' else 'git' | |
| 48 NEW_MASTER_NAME = { | |
| 49 'Skia': 'Skia', | |
| 50 'AndroidSkia': 'SkiaAndroid', | |
| 51 'CompileSkia': 'SkiaCompile', | |
| 52 'FYISkia': 'SkiaFYI', | |
| 53 'PrivateSkia': 'SkiaInternal', | |
| 54 } | |
| 55 UPSTREAM_MASTER_PREFIX = 'client.skia' | |
| 56 | |
| 57 | 32 |
| 58 # How often we should check each buildslave's keepalive conditions, in seconds. | 33 # How often we should check each buildslave's keepalive conditions, in seconds. |
| 59 DEFAULT_POLL_INTERVAL = 60 | 34 PID_FILE = os.path.join('build', 'slave', 'twistd.pid') |
| 60 PID_FILE = os.path.join('buildbot', 'third_party', 'chromium_buildbot', 'slave', | 35 |
| 61 'twistd.pid') | |
| 62 # Maximum time (in seconds) to wait for PID_FILE to be written after the slave | 36 # Maximum time (in seconds) to wait for PID_FILE to be written after the slave |
| 63 # is launched. If PID_FILE is not written by then, we assume an error occurred. | 37 # is launched. If PID_FILE is not written by then, we assume an error occurred. |
| 64 PID_TIMEOUT = 60.0 | 38 PID_TIMEOUT = 60.0 |
| 65 | 39 |
| 66 | 40 |
| 67 | |
| 68 logger = None | 41 logger = None |
| 69 | 42 |
| 70 | 43 |
| 71 # TODO(borenet): Share this code with launch_master.py. | |
| 72 def IsRunning(pid): | 44 def IsRunning(pid): |
| 73 """ Determine whether a process with the given PID is running. | 45 """ Determine whether a process with the given PID is running. |
| 74 | 46 |
| 75 pid: string; the PID to test. If pid is None, return False. | 47 pid: string; the PID to test. If pid is None, return False. |
| 76 """ | 48 """ |
| 77 if pid is None: | 49 if pid is None: |
| 78 return False | 50 return False |
| 79 if os.name == 'nt': | 51 if os.name == 'nt': |
| 80 cmd = ['tasklist', '/FI', '"PID eq %s"' % pid] | 52 cmd = ['tasklist', '/FI', '"PID eq %s"' % pid] |
| 81 output = subprocess.check_output(cmd, stdout=subprocess.PIPE, | 53 output = subprocess.check_output(cmd, stdout=subprocess.PIPE, |
| 82 stderr=subprocess.STDOUT) | 54 stderr=subprocess.STDOUT) |
| 83 is_running = pid in output | 55 is_running = pid in output |
| 84 else: | 56 else: |
| 85 cmd = ['cat', '/proc/%s/stat' % pid] | 57 cmd = ['cat', '/proc/%s/stat' % pid] |
| 86 is_running = subprocess.call(cmd, stdout=subprocess.PIPE, | 58 is_running = subprocess.call(cmd, stdout=subprocess.PIPE, |
| 87 stderr=subprocess.STDOUT) == 0 | 59 stderr=subprocess.STDOUT) == 0 |
| 88 return is_running | 60 return is_running |
| 89 | 61 |
| 90 | 62 |
| 63 def _IsRunning(): | |
| 64 """Determine if the BuildSlave is running in CWD | |
| 65 | |
| 66 If so, return its PID. Otherwise, return None. | |
| 67 """ | |
| 68 if os.path.isfile(PID_FILE): | |
| 69 with open(PID_FILE) as f: | |
| 70 pid = str(f.read()).rstrip() | |
| 71 if IsRunning(pid): | |
| 72 return pid | |
| 73 return None | |
| 74 | |
| 75 | |
| 76 def _KillSlave(): | |
| 77 """Kill the BuildSlave running in CWD.""" | |
| 78 pid = _IsRunning() | |
| 79 if not pid: | |
| 80 print '_KillSlave: Slave not running.' | |
| 81 return | |
| 82 if os.name == 'nt': | |
| 83 cmd = ['taskkill', '/F', '/T', '/PID', str(pid)] | |
| 84 else: | |
| 85 cmd = ['make', 'stop'] | |
| 86 subprocess.check_call(cmd, cwd=os.path.join('buildbot', 'slave')) | |
| 87 | |
| 88 | |
| 91 class BuildSlaveManager(multiprocessing.Process): | 89 class BuildSlaveManager(multiprocessing.Process): |
| 92 """ Manager process for BuildSlaves. Periodically checks that any | 90 """Manager process for BuildSlaves.""" |
| 93 keepalive_conditions are met and kills or starts the slave accordingly. """ | |
| 94 | 91 |
| 95 def __init__(self, slavename, checkout_path, copies, copy_src_dir, | 92 def __init__(self, slavename, checkout_path, copies, copy_src_dir, |
| 96 master_name, keepalive_conditions, poll_interval): | 93 is_internal): |
| 97 """ Construct the BuildSlaveManager. | 94 """ Construct the BuildSlaveManager. |
| 98 | 95 |
| 99 slavename: string; the name of the slave to start. | 96 slavename: string; the name of the slave to start. |
| 100 checkout_path: string; the directory in which to launch the slave. | 97 checkout_path: string; the directory in which to launch the slave. |
| 101 copies: list of dictionaries; files to copy into the slave's source | 98 copies: list of dictionaries; files to copy into the slave's source |
| 102 checkout. | 99 checkout. |
| 103 copy_src_dir: string; directory in which the files to copy reside. | 100 copy_src_dir: string; directory in which the files to copy reside. |
| 104 master_name: string; name of the master to which this build slave connects. | 101 is_internal: bool; whether this buildslave uses internal code. |
| 105 This is NOT the hostname of the master, which is obtained from the | |
| 106 master class in config_private.py. | |
| 107 keepalive_conditions: list; commands which must succeed in order for the | |
| 108 slave to stay alive. | |
| 109 poll_interval: number; how often to verify the keepalive_conditions, in | |
| 110 seconds. | |
| 111 """ | 102 """ |
| 112 self._slavename = slavename | 103 self._slavename = slavename |
| 113 self._checkout_path = checkout_path | 104 self._checkout_path = checkout_path |
| 114 self._copies = copies | 105 self._copies = copies |
| 115 self._copy_src_dir = os.path.abspath(copy_src_dir) | 106 self._copy_src_dir = os.path.abspath(copy_src_dir) |
| 116 self._keepalive_conditions = keepalive_conditions | 107 self._is_internal = is_internal |
| 117 self._poll_interval = poll_interval | |
| 118 self._master_name = master_name | |
| 119 multiprocessing.Process.__init__(self) | 108 multiprocessing.Process.__init__(self) |
| 120 | 109 |
| 121 def _GClientConfig(self): | 110 def _GClientConfig(self): |
| 122 """Run 'gclient config'.""" | 111 """Run 'gclient config'.""" |
| 123 subprocess.check_call([GCLIENT, 'config', SKIA_URL]) | 112 config_url = (CHROME_SLAVE_INTERNAL_DEPS_URL if self._is_internal |
| 113 else CHROME_SLAVE_DEPS_URL) | |
| 114 cmd = [GCLIENT, 'config', config_url, '--deps-file', '.DEPS.git'] | |
| 115 print 'Running command: %s' % ' '.join(cmd) | |
| 116 subprocess.check_call(cmd) | |
| 124 | 117 |
| 125 def _SyncSources(self): | 118 def _SyncSources(self): |
| 126 """ Run 'gclient sync' on the buildbot sources. """ | 119 """ Run 'gclient sync' on the buildbot sources. """ |
| 127 # Check out or update the buildbot scripts | 120 # Check out or update the buildbot scripts |
| 128 self._GClientConfig() | 121 self._GClientConfig() |
| 129 subprocess.check_call([GCLIENT, 'sync', '-j1', '--force']) | 122 subprocess.check_call([GCLIENT, 'sync', '-j1', '--force']) |
| 130 | 123 |
| 131 if os.name == 'nt': | 124 if os.name == 'nt': |
| 132 os.environ['WIN_TOOLS_FORCE'] = '1' | 125 os.environ['WIN_TOOLS_FORCE'] = '1' |
| 133 subprocess.check_call([self.local_gclient]) | 126 subprocess.check_call([os.path.join(os.getcwd(), 'depot_tools', GCLIENT)]) |
| 134 del os.environ['WIN_TOOLS_FORCE'] | 127 del os.environ['WIN_TOOLS_FORCE'] |
| 135 | 128 |
| 136 # Perform Copies | 129 # Perform Copies |
| 137 if self._copies: | 130 if self._copies: |
| 138 for copy in self._copies: | 131 for copy in self._copies: |
| 139 src = os.path.join(self._copy_src_dir, os.path.normpath(copy['source'])) | 132 src = os.path.join(self._copy_src_dir, os.path.normpath(copy['source'])) |
| 140 dest = os.path.normpath(copy['destination']) | 133 dest = os.path.normpath(copy['destination']) |
| 141 print 'Copying %s to %s' % (src, dest) | 134 print 'Copying %s to %s' % (src, dest) |
| 142 shutil.copy(src, dest) | 135 shutil.copy(src, dest) |
| 143 | 136 |
| 144 @property | |
| 145 def master_host(self): | |
| 146 """Return the hostname of the master for this buildslave.""" | |
| 147 return config.Master.set_active_master(self._master_name).master_host | |
| 148 | |
| 149 @property | |
| 150 def slave_dir(self): | |
| 151 """Directory in which to launch the slave.""" | |
| 152 return os.path.join('buildbot', 'slave') | |
| 153 | |
| 154 @property | |
| 155 def local_gclient(self): | |
| 156 """Path to the local version of gclient within this slave's checkout.""" | |
| 157 return os.path.join(os.getcwd(), 'buildbot', 'third_party', 'depot_tools', | |
| 158 GCLIENT) | |
| 159 | |
| 160 def _LaunchSlave(self): | 137 def _LaunchSlave(self): |
| 161 """ Launch the BuildSlave. """ | 138 """ Launch the BuildSlave. """ |
| 162 self._KillSlave() | 139 _KillSlave() |
| 163 | 140 |
| 164 self._SyncSources() | 141 self._SyncSources() |
| 165 | 142 |
| 166 if os.name == 'nt': | 143 if os.name == 'nt': |
| 167 # We run different commands for the Windows shell | 144 # We run different commands for the Windows shell |
| 168 cmd = 'setlocal&&' | 145 cmd = 'setlocal&&' |
| 169 cmd += 'set TESTING_SLAVENAME=%s&&' % self._slavename | 146 cmd += 'set TESTING_SLAVENAME=%s&&' % self._slavename |
| 170 cmd += 'set TESTING_MASTER=%s&&' % self._master_name | |
| 171 if self.master_host: | |
| 172 cmd += 'set TESTING_MASTER_HOST=%s&&' % self.master_host | |
| 173 cmd += 'run_slave.bat' | 147 cmd += 'run_slave.bat' |
| 174 cmd += '&& endlocal' | 148 cmd += '&& endlocal' |
| 175 else: | 149 else: |
| 176 cmd = 'TESTING_SLAVENAME=%s ' % self._slavename | 150 cmd = 'TESTING_SLAVENAME=%s ' % self._slavename |
| 177 cmd += 'TESTING_MASTER=%s ' % self._master_name | |
| 178 if self.master_host: | |
| 179 cmd += 'TESTING_MASTER_HOST=%s ' % self.master_host | |
| 180 cmd += 'make start' | 151 cmd += 'make start' |
| 181 print 'Running cmd: %s' % cmd | 152 print 'Running cmd: %s' % cmd |
| 182 subprocess.check_call(cmd, shell=True, cwd=self.slave_dir) | 153 subprocess.check_call(cmd, shell=True, cwd=os.path.join('build', 'slave')) |
| 183 | 154 |
| 184 start_time = time.time() | 155 start_time = time.time() |
| 185 while not self._IsRunning(): | 156 while not _IsRunning(): |
| 186 if time.time() - start_time > PID_TIMEOUT: | 157 if time.time() - start_time > PID_TIMEOUT: |
| 187 raise Exception('Failed to launch %s' % self._slavename) | 158 raise Exception('Failed to launch %s' % self._slavename) |
| 188 time.sleep(1) | 159 time.sleep(1) |
| 189 | 160 |
| 190 def _IsRunning(self): | |
| 191 """ Determine if this BuildSlave is running. If so, return its PID, | |
| 192 otherwise, return None. """ | |
| 193 if os.path.isfile(PID_FILE): | |
| 194 with open(PID_FILE) as f: | |
| 195 pid = str(f.read()).rstrip() | |
| 196 if IsRunning(pid): | |
| 197 return pid | |
| 198 return None | |
| 199 | |
| 200 def _KillSlave(self): | |
| 201 """ Kill the BuildSlave. """ | |
| 202 pid = self._IsRunning() | |
| 203 if not pid: | |
| 204 print 'BuildSlaveManager._KillSlave: Slave not running.' | |
| 205 return | |
| 206 if os.name == 'nt': | |
| 207 cmd = ['taskkill', '/F', '/T', '/PID', str(pid)] | |
| 208 else: | |
| 209 cmd = ['make', 'stop'] | |
| 210 subprocess.check_call(cmd, cwd=os.path.join('buildbot', 'slave')) | |
| 211 | |
| 212 def run(self): | 161 def run(self): |
| 213 """ Run the BuildSlaveManager. This overrides multiprocessing.Process's | 162 """ Run the BuildSlaveManager. This overrides multiprocessing.Process's |
| 214 run() method. """ | 163 run() method. """ |
| 215 os.chdir(self._checkout_path) | 164 os.chdir(self._checkout_path) |
| 216 self._SyncSources() | 165 self._SyncSources() |
| 217 self._checkout_path = os.path.abspath(os.curdir) | 166 self._checkout_path = os.path.abspath(os.curdir) |
| 218 self._KillSlave() | 167 _KillSlave() |
| 219 while True: | 168 self._LaunchSlave() |
| 220 print 'Checking keepalive conditions for %s' % self._slavename | 169 print 'Successfully launched slave %s.' % self._slavename |
|
borenet
2014/10/17 18:04:18
We lose keepalive_conditions as part of this chang
rmistry
2014/10/17 18:19:21
Acknowledged.
| |
| 221 slave_can_run = True | |
| 222 for keepalive_condition in self._keepalive_conditions: | |
| 223 print 'Executing keepalive condition: %s' % keepalive_condition | |
| 224 proc = subprocess.Popen(keepalive_condition, stdout=subprocess.PIPE, | |
| 225 stderr=subprocess.STDOUT) | |
| 226 if proc.wait() != 0: | |
| 227 print 'Keepalive condition failed for %s: %s' % (self._slavename, | |
| 228 keepalive_condition) | |
| 229 print proc.communicate()[0] | |
| 230 slave_can_run = False | |
| 231 break | |
| 232 print proc.communicate()[0] | |
| 233 if not slave_can_run and self._IsRunning(): | |
| 234 self._KillSlave() | |
| 235 elif slave_can_run and not self._IsRunning(): | |
| 236 self._LaunchSlave() | |
| 237 print 'Successfully launched slave %s.' % self._slavename | |
| 238 time.sleep(self._poll_interval) | |
| 239 print 'Slave process for %s has finished.' % self._slavename | 170 print 'Slave process for %s has finished.' % self._slavename |
| 240 | 171 |
| 241 | 172 |
| 242 class ChromeBuildSlaveManager(BuildSlaveManager): | |
| 243 """BuildSlaveManager for slaves using Chromium build code.""" | |
| 244 | |
| 245 def _GClientConfig(self): | |
| 246 """Run 'gclient config'.""" | |
| 247 config_url = ( | |
| 248 CHROME_SLAVE_INTERNAL_DEPS_URL if self._master_name == 'SkiaInternal' | |
| 249 else CHROME_SLAVE_DEPS_URL) | |
| 250 cmd = [GCLIENT, 'config', config_url, '--deps-file', '.DEPS.git'] | |
| 251 print 'Running command: %s' % ' '.join(cmd) | |
| 252 subprocess.check_call(cmd) | |
| 253 | |
| 254 @property | |
| 255 def master_host(self): | |
| 256 """Return the hostname of the master for this buildslave.""" | |
| 257 return None # Just use the default. | |
| 258 | |
| 259 @property | |
| 260 def slave_dir(self): | |
| 261 """Directory from which to launch the buildslave.""" | |
| 262 return os.path.join('build', 'slave') | |
| 263 | |
| 264 @property | |
| 265 def local_gclient(self): | |
| 266 """Path to the local version of gclient within this slave's checkout.""" | |
| 267 return os.path.join(os.getcwd(), 'depot_tools', GCLIENT) | |
| 268 | |
| 269 | |
| 270 def ReadSlavesCfg(slaves_cfg_path): | 173 def ReadSlavesCfg(slaves_cfg_path): |
| 271 """Read the given slaves.cfg path and return the slaves dict.""" | 174 """Read the given slaves.cfg path and return the slaves dict.""" |
| 272 cfg = {} | 175 cfg = {} |
| 273 execfile(slaves_cfg_path, cfg) | 176 execfile(slaves_cfg_path, cfg) |
| 274 return cfg['slaves'] | 177 return cfg['slaves'] |
| 275 | 178 |
| 276 | 179 |
| 277 def RunSlave(slavename, slave_num, connects_to_new_master=False): | 180 def RunSlave(slavename, slave_num, is_internal): |
| 278 """ Launch a single slave, checking out the buildbot tree if necessary. | 181 """ Launch a single slave, checking out the buildbot tree if necessary. |
| 279 | 182 |
| 280 slavename: string indicating the hostname of the build slave to launch. | 183 slavename: string indicating the hostname of the build slave to launch. |
| 281 copies: dictionary with 'source' and 'destination' keys whose values are the | 184 copies: dictionary with 'source' and 'destination' keys whose values are the |
|
rmistry
2014/10/17 18:19:21
Can you replace copies with slave_num.
borenet
2014/10/17 18:39:26
Done.
| |
| 282 current location and destination location within the buildbot checkout of | 185 current location and destination location within the buildbot checkout of |
| 283 files to be copied. | 186 files to be copied. |
| 187 is_internal: bool; whether this slave uses internal code. | |
| 284 """ | 188 """ |
| 285 print 'Starting slave: %s%s' % ( | 189 print 'Starting slave: %s' % slavename |
| 286 slavename, ' (new)' if connects_to_new_master else '') | |
| 287 start_dir = os.path.realpath(os.curdir) | 190 start_dir = os.path.realpath(os.curdir) |
| 288 slave_dir = os.path.join(start_dir, slavename) | 191 slave_dir = os.path.join(start_dir, slavename) |
| 289 if connects_to_new_master and os.name == 'nt': | 192 if os.name == 'nt': |
| 290 slave_dir = os.path.join('c:\\', slave_num) | 193 slave_dir = os.path.join('c:\\', slave_num) |
| 291 copies = (slave_hosts_cfg.CHROMEBUILD_COPIES if connects_to_new_master | 194 copies = slave_hosts_cfg.CHROMEBUILD_COPIES |
| 292 else slave_hosts_cfg.DEFAULT_COPIES) | |
| 293 | 195 |
| 294 # Create the slave directory if needed | 196 # Create the slave directory if needed |
| 295 if not os.path.isdir(slave_dir): | 197 if not os.path.isdir(slave_dir): |
| 296 print 'Creating directory: %s' % slave_dir | 198 print 'Creating directory: %s' % slave_dir |
| 297 os.makedirs(slave_dir) | 199 os.makedirs(slave_dir) |
| 298 | 200 |
| 299 # Find the slave config dict and BuildSlaveManager type for this slave. | |
| 300 slave_cfg = {} | |
| 301 manager = (ChromeBuildSlaveManager if connects_to_new_master | |
| 302 else BuildSlaveManager) | |
| 303 for cfg in slaves_cfg.SLAVES: | |
| 304 if cfg['hostname'] == slavename: | |
| 305 slave_cfg = cfg | |
| 306 break | |
| 307 if not slave_cfg: | |
| 308 # Try looking at upstream masters. | |
| 309 upstream_masters_dir = os.path.join('third_party', | |
| 310 'chromium_buildbot_tot', | |
| 311 'masters') | |
| 312 for master_dir in os.listdir(upstream_masters_dir): | |
| 313 if master_dir.startswith('master.%s' % UPSTREAM_MASTER_PREFIX): | |
| 314 slaves_cfg_path = os.path.join( | |
| 315 upstream_masters_dir, master_dir, 'slaves.cfg') | |
| 316 for cfg in ReadSlavesCfg(slaves_cfg_path): | |
| 317 if cfg['hostname'] == slavename: | |
| 318 slave_cfg = cfg | |
| 319 break | |
| 320 if not slave_cfg: | |
| 321 raise Exception('No buildslave config found for %s!' % slavename) | |
| 322 | |
| 323 # Launch the buildslave. | 201 # Launch the buildslave. |
| 324 master_name = slave_cfg['master'] | 202 BuildSlaveManager(slavename, slave_dir, copies, os.pardir, is_internal |
| 325 if connects_to_new_master: | 203 ).start() |
| 326 master_name = NEW_MASTER_NAME[master_name] | |
| 327 manager(slavename, slave_dir, copies, os.pardir, master_name, | |
| 328 slave_cfg.get('keepalive_conditions', []), DEFAULT_POLL_INTERVAL | |
| 329 ).start() | |
| 330 | 204 |
| 331 | 205 |
| 332 class FileLogger: | 206 class FileLogger: |
| 333 """ Write stdout to a log file. """ | 207 """ Write stdout to a log file. """ |
| 334 def __init__(self, log_file_name): | 208 def __init__(self, log_file_name): |
| 335 # Open the log file. | 209 # Open the log file. |
| 336 self._logfile = open(log_file_name, 'w') | 210 self._logfile = open(log_file_name, 'w') |
| 337 self._stdout = sys.stdout | 211 self._stdout = sys.stdout |
| 338 sys.stdout = self | 212 sys.stdout = self |
| 339 | 213 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 if os.name == 'nt': | 266 if os.name == 'nt': |
| 393 os.environ['HOME'] = os.path.join('c:\\', 'Users', 'chrome-bot') | 267 os.environ['HOME'] = os.path.join('c:\\', 'Users', 'chrome-bot') |
| 394 | 268 |
| 395 # Sync the buildbot code. | 269 # Sync the buildbot code. |
| 396 subprocess.check_call([GCLIENT, 'sync', '--force', '-j1']) | 270 subprocess.check_call([GCLIENT, 'sync', '--force', '-j1']) |
| 397 | 271 |
| 398 # Obtain configuration information about this build slave host machine. | 272 # Obtain configuration information about this build slave host machine. |
| 399 slave_host = slave_hosts_cfg.get_slave_host_config(socket.gethostname()) | 273 slave_host = slave_hosts_cfg.get_slave_host_config(socket.gethostname()) |
| 400 slaves = slave_host.slaves | 274 slaves = slave_host.slaves |
| 401 print 'Attempting to launch build slaves:' | 275 print 'Attempting to launch build slaves:' |
| 402 for slavename, _, connects_to_new_master in slaves: | 276 for slavename, _, _ in slaves: |
| 403 print ' %s%s' % (slavename, | 277 print ' %s' % slavename |
| 404 (' (new master)' if connects_to_new_master else '')) | |
| 405 | 278 |
| 406 # Launch the build slaves | 279 # Launch the build slaves |
| 407 for slavename, slave_num, connects_to_new_master in slaves: | 280 for slavename, slave_num, is_internal in slaves: |
| 408 RunSlave(slavename, slave_num, connects_to_new_master) | 281 RunSlave(slavename, slave_num, is_internal) |
| 409 | 282 |
| 410 | 283 |
| 411 if '__main__' == __name__: | 284 if '__main__' == __name__: |
| 412 # Pipe all output to a log file. | 285 # Pipe all output to a log file. |
| 413 logfile = 'launch_slaves.log' | 286 logfile = 'launch_slaves.log' |
| 414 if os.path.isfile(logfile): | 287 if os.path.isfile(logfile): |
| 415 num = 1 | 288 num = 1 |
| 416 new_filename = logfile + '.' + str(num) | 289 new_filename = logfile + '.' + str(num) |
| 417 while os.path.isfile(new_filename): | 290 while os.path.isfile(new_filename): |
| 418 num += 1 | 291 num += 1 |
| 419 new_filename = logfile + '.' + str(num) | 292 new_filename = logfile + '.' + str(num) |
| 420 os.rename(logfile, new_filename) | 293 os.rename(logfile, new_filename) |
| 421 logger = FileLogger(logfile) | 294 logger = FileLogger(logfile) |
| 422 sys.exit(main()) | 295 sys.exit(main()) |
| OLD | NEW |