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