setup_chromeos.py revision f81680c018729fd4499e1e200d04b48c4b90127c
1#!/usr/bin/python
2#
3# Copyright 2010 Google Inc. All Rights Reserved.
4
5"""Script to checkout the ChromeOS source.
6
7This script sets up the ChromeOS source in the given directory, matching a
8particular release of ChromeOS.
9"""
10
11__author__ = "raymes@google.com (Raymes Khoury)"
12
13from datetime import datetime
14import getpass
15import optparse
16import os
17import pickle
18import sys
19import tempfile
20import time
21from utils import command_executer
22from utils import logger
23
24GCLIENT_FILE = """solutions = [
25  { "name"        : "CHROME_DEPS",
26    "url"         :
27    "svn://svn.chromium.org/chrome-internal/trunk/tools/buildspec/releases/%s",
28    "custom_deps" : {
29      "src/third_party/WebKit/LayoutTests": None,
30      "src-pdf": None,
31      "src/pdf": None,
32    },
33    "safesync_url": "",
34   },
35]
36"""
37
38# List of stable versions used for common team image
39# Sheriff must update this list when a new common version becomes available
40COMMON_VERSIONS = "/home/mobiletc-prebuild/common_images/common_list.txt"
41
42def Usage(parser):
43  parser.print_help()
44  sys.exit(0)
45
46
47def TimeToVersion(my_time, versions_git):
48  """Convert timestamp to version number."""
49  cur_time = time.mktime(time.gmtime())
50  des_time = float(my_time)
51  if cur_time - des_time > 7000000:
52    logger.GetLogger().LogFatal("The time you specify is too early.")
53  temp = tempfile.mkdtemp()
54  commands = ["cd {0}".format(temp), "git clone {0}".format(versions_git),
55              "cd manifest-versions", "git checkout -f $(git rev-list" +
56              " --max-count=1 --before={0} origin/master)".format(my_time)]
57  cmd_executer = command_executer.GetCommandExecuter()
58  ret = cmd_executer.RunCommands(commands)
59  if ret:
60    logger.GetLogger().LogFatal("Failed to checkout manifest-versions.")
61  path = os.path.realpath("{0}/manifest-versions/LKGM/lkgm.xml".format(temp))
62  pp = path.split("/")
63  small = os.path.basename(path).split(".xml")[0]
64  version = pp[-2] + "." + small
65  commands = ["rm -rf {0}".format(temp)]
66  cmd_executer.RunCommands(commands)
67  return version
68
69# Get version spec file, either from "paladin" or "buildspec" directory.
70def GetVersionSpecFile(version, versions_git):
71  temp = tempfile.mkdtemp()
72  commands = ["cd {0}".format(temp), \
73              "git clone {0} versions".format(versions_git)]
74  cmd_executer = command_executer.GetCommandExecuter()
75  ret = cmd_executer.RunCommands(commands)
76  err_msg = None
77  if ret:
78    err_msg = "Failed to checkout versions_git - {0}".format(versions_git)
79    ret = None
80  else:
81    v, m = version.split(".", 1)
82    paladin_spec = "paladin/buildspecs/{0}/{1}.xml".format(v, m)
83    generic_spec = "buildspecs/{0}/{1}.xml".format(v, m)
84    paladin_path = "{0}/versions/{1}".format(temp, paladin_spec)
85    generic_path = "{0}/versions/{1}".format(temp, generic_spec)
86    if os.path.exists(paladin_path):
87      ret = paladin_spec
88    elif os.path.exists(generic_path):
89      ret = generic_spec
90    else:
91      err_msg = "No spec found for version {0}".format(version)
92      ret = None
93    # Fall through to clean up.
94
95  commands = ["rm -rf {0}".format(temp)]
96  cmd_executer.RunCommands(commands)
97  if err_msg:
98    logger.GetLogger().LogFatal(err_msg)
99  return ret
100
101def TimeToCommonVersion(timestamp):
102  """Convert timestamp to common image version."""
103  tdt = datetime.fromtimestamp(float(timestamp))
104  with open(COMMON_VERSIONS, "r") as f:
105    common_list = pickle.load(f)
106    for sv in common_list:
107      sdt = datetime.strptime(sv["date"], "%Y-%m-%d %H:%M:%S.%f")
108      if tdt >= sdt:
109        return "%s.%s" % (sv["chrome_major_version"], sv["chromeos_version"])
110    # should never reach here
111    logger.GetLogger().LogFatal("No common version for timestamp")
112  return None
113
114
115def Main(argv):
116  """Checkout the ChromeOS source."""
117  parser = optparse.OptionParser()
118  parser.add_option("--dir", dest="directory",
119                    help="Target directory for ChromeOS installation.")
120  parser.add_option("--version", dest="version", default="latest_lkgm",
121                    help="""ChromeOS version. Can be:
122(1) A release version in the format: 'X.X.X.X'
123(2) 'top' for top of trunk
124(3) 'latest_lkgm' for the latest lkgm version
125(4) 'lkgm' for the lkgm release before timestamp
126(5) 'latest_common' for the latest team common stable version
127(6) 'common' for the team common stable version before timestamp
128Default is 'latest_lkgm'.""")
129  parser.add_option("--timestamp", dest="timestamp", default=None,
130                    help="""Timestamps in epoch format. It will check out the
131latest LKGM or the latest COMMON version of ChromeOS before the timestamp.
132Use in combination with --version=latest or --version=common. Use
133'date -d <date string> +%s' to find epoch time""")
134  parser.add_option("--minilayout", dest="minilayout", default=False,
135                    action="store_true",
136                    help="""Whether to checkout the minilayout
137(smaller checkout).'""")
138  parser.add_option("--jobs", "-j", dest="jobs", default="1",
139                    help="Number of repo sync threads to use.")
140  parser.add_option("--public", "-p", dest="public", default=False,
141                    action="store_true",
142                    help="Use the public checkout instead of the private one.")
143
144  options = parser.parse_args(argv)[0]
145
146  if not options.version:
147    parser.print_help()
148    logger.GetLogger().LogFatal("No version specified.")
149  else:
150    version = options.version.strip()
151
152  if not options.timestamp:
153    timestamp = ""
154  else:
155    timestamp = options.timestamp.strip()
156    if version not in ("lkgm", "common"):
157      parser.print_help()
158      logger.GetLogger().LogFatal("timestamp option only applies for "
159                                  "versions \"lkgm\" or \"common\"")
160
161  if not options.directory:
162    parser.print_help()
163    logger.GetLogger().LogFatal("No directory specified.")
164
165  directory = options.directory.strip()
166
167  if options.public:
168    manifest_repo = "http://git.chromium.org/chromiumos/manifest.git"
169    versions_repo = "http://git.chromium.org/chromiumos/manifest-versions.git"
170  else:
171    manifest_repo = (
172        "ssh://gerrit-int.chromium.org:29419/chromeos/manifest-internal.git")
173    versions_repo = (
174        "ssh://gerrit-int.chromium.org:29419/chromeos/manifest-versions.git")
175
176  if version == "top":
177    init = "repo init -u %s" % manifest_repo
178  elif version == "latest_lkgm":
179    version = TimeToVersion(time.mktime(time.gmtime()), versions_repo)
180    version, manifest = version.split(".", 1)
181    logger.GetLogger().LogOutput("found version %s.%s for latest LKGM" % (
182        version, manifest))
183    init = ("repo init -u %s -m paladin/buildspecs/%s/%s.xml" % (
184        versions_repo, version, manifest))
185  elif version == "lkgm":
186    if not timestamp:
187      parser.print_help()
188      logger.GetLogger().LogFatal("No timestamp specified for version=lkgm")
189    version = TimeToVersion(timestamp, versions_repo)
190    version, manifest = version.split(".", 1)
191    logger.GetLogger().LogOutput("found version %s.%s for LKGM at timestamp %s"
192                                 % (version, manifest, timestamp))
193    init = ("repo init -u %s -m paladin/buildspecs/%s/%s.xml" % (
194        versions_repo, version, manifest))
195  elif version == "latest_common":
196    version = TimeToCommonVersion(time.mktime(time.gmtime()))
197    version, manifest = version.split(".", 1)
198    logger.GetLogger().LogOutput("found version %s.%s for latest Common image" %
199                                 (version, manifest))
200    init = ("repo init -u %s -m buildspecs/%s/%s.xml" % (
201        versions_repo, version, manifest))
202  elif version == "common":
203    if not timestamp:
204      parser.print_help()
205      logger.GetLogger().LogFatal("No timestamp specified for version=lkgm")
206    version = TimeToCommonVersion(timestamp)
207    version, manifest = version.split(".", 1)
208    logger.GetLogger().LogOutput("found version %s.%s for latest common image "
209                                 "at timestamp %s" % (
210                                     version, manifest, timestamp))
211    init = ("repo init -u %s -m buildspecs/%s/%s.xml" % (
212        versions_repo, version, manifest))
213  else:
214    # user specified a specific version number
215    version_spec_file = GetVersionSpecFile(version, versions_repo)
216    if not version_spec_file:
217      return 1
218    init = "repo init -u %s -m %s" % (versions_repo, version_spec_file)
219
220  if options.minilayout:
221    init += " -g minilayout"
222
223  init += " --repo-url=http://git.chromium.org/external/repo.git"
224
225  commands = ["mkdir -p %s" % directory,
226              "cd %s" % directory,
227              init,
228              # crosbug#31837 - "Sources need to be world-readable to properly
229              # function inside the chroot"
230              "umask 022 && repo sync -j %s" % options.jobs]
231  cmd_executer = command_executer.GetCommandExecuter()
232  ret = cmd_executer.RunCommands(commands)
233  if ret:
234    return ret
235
236  # Setup svn credentials for use inside the chroot
237  if getpass.getuser() == "mobiletc-prebuild":
238    chromium_username = "raymes"
239  else:
240    chromium_username = "$USER"
241
242  return cmd_executer.RunCommand(
243      "svn ls --config-option config:auth:password-stores= "
244      "--config-option "
245      "servers:global:store-plaintext-passwords=yes "
246      "--username " + chromium_username + "@google.com "
247      "svn://svn.chromium.org/leapfrog-internal "
248      "svn://svn.chromium.org/chrome "
249      "svn://svn.chromium.org/chrome-internal > /dev/null")
250
251
252if __name__ == "__main__":
253  retval = Main(sys.argv)
254  sys.exit(retval)
255