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