cbuildbot: Add --repo-cache option.

Give the builders an option to give us a warm repo cache to copy in if
we need to create our build root from scratch. This allows us to avoid
overloading GoB when we bring up large numbers of new builders.

BUG=chromium:609886
TEST=run_tests

Change-Id: Ib79f219554b4a8e0e256f366916c376d716025d0
Reviewed-on: https://chromium-review.googlesource.com/348011
Commit-Ready: Don Garrett <dgarrett@chromium.org>
Tested-by: Don Garrett <dgarrett@chromium.org>
Reviewed-by: Don Garrett <dgarrett@chromium.org>
(cherry picked from commit 0af6ba52f3943e09ee84eb90954ffbf4ddcd086b)
Reviewed-on: https://chromium-review.googlesource.com/351261
Reviewed-by: Josafat Garcia <josafat@chromium.org>
Commit-Queue: Josafat Garcia <josafat@chromium.org>
Tested-by: Josafat Garcia <josafat@chromium.org>
diff --git a/cbuildbot/stages/sync_stages.py b/cbuildbot/stages/sync_stages.py
index 3b3dc95..eb9fdcb 100644
--- a/cbuildbot/stages/sync_stages.py
+++ b/cbuildbot/stages/sync_stages.py
@@ -13,6 +13,7 @@
 import itertools
 import os
 import re
+import shutil
 import sys
 import time
 from xml.etree import ElementTree
@@ -386,6 +387,20 @@
 
   def _InitializeRepo(self):
     """Set up the RepoRepository object."""
+    # If we have no repository at all, but we have a warm cache path, copy in
+    # the warm cache. This is done so builders can try to avoid doing a sync
+    # from scratch on a new builder (especially GCE instances).
+    if (not repository.IsARepoRoot(self._build_root) and
+        self.options.repo_cache and
+        os.path.isdir(self.options.repo_cache)):
+      # If the warm cache is invalid the wrong branch, or from the wrong
+      # manifest, Repository will repair it.
+      logging.info('Using warm cache "%s" to populate buildroot "%s"',
+                   self.options.repo_cache,
+                   self._build_root)
+      shutil.copytree(self.options.repo_cache,
+                      self._build_root)
+
     self.repo = self.GetRepoRepository()
 
   def GetNextManifest(self):
diff --git a/scripts/cbuildbot.py b/scripts/cbuildbot.py
index aa0acb2..de8da2b 100644
--- a/scripts/cbuildbot.py
+++ b/scripts/cbuildbot.py
@@ -519,6 +519,10 @@
                                 'to skip verification by the bootstrap code'))
   group.add_remote_option('--buildbot', dest='buildbot', action='store_true',
                           default=False, help='This is running on a buildbot')
+  parser.add_remote_option('--repo-cache', type='path',
+                           help='Directory from which to copy a repo checkout '
+                                'if our build root is empty, to avoid '
+                                'excessive GoB load with a fresh sync.')
   group.add_remote_option('--no-buildbot-tags', action='store_false',
                           dest='enable_buildbot_tags', default=True,
                           help='Suppress buildbot specific tags from log '