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