Mike Frysinger | f1ba7ad | 2022-09-12 05:42:57 -0400 | [diff] [blame] | 1 | # Copyright 2018 The ChromiumOS Authors |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 5 | """Sync a git repository to a given manifest. |
| 6 | |
| 7 | This script is intended to define all of the ways that a source checkout can be |
| 8 | defined for a Chrome OS builder. |
| 9 | |
| 10 | If a sync completes successfully, the checked out code will exactly match |
| 11 | whatever manifest is defined, and no local git branches will remain. Extraneous |
| 12 | files not under version management will be ignored. |
| 13 | |
| 14 | It is NOT safe to assume that the checkout can be further updated with |
| 15 | a simple "repo sync", instead you should call this script again with |
| 16 | the same options. |
| 17 | """ |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 18 | |
Chris McDonald | 59650c3 | 2021-07-20 15:29:28 -0600 | [diff] [blame] | 19 | import logging |
| 20 | |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 21 | from chromite.cbuildbot import manifest_version |
Don Garrett | 115df40 | 2018-11-09 14:43:42 -0800 | [diff] [blame] | 22 | from chromite.cbuildbot import patch_series |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 23 | from chromite.cbuildbot import repository |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 24 | from chromite.lib import commandline |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 25 | from chromite.lib import config_lib |
Don Garrett | 115df40 | 2018-11-09 14:43:42 -0800 | [diff] [blame] | 26 | from chromite.lib import gerrit |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 27 | from chromite.lib import osutils |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 28 | |
| 29 | |
| 30 | def GetParser(): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 31 | """Creates the argparse parser.""" |
| 32 | parser = commandline.ArgumentParser(description=__doc__) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 33 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 34 | parser.add_argument( |
| 35 | "--repo-root", |
| 36 | type="path", |
| 37 | default=".", |
| 38 | help="Path to the repo root to sync.", |
| 39 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 40 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 41 | manifest_group = parser.add_argument_group( |
| 42 | "Manifest", description="What manifest do we sync?" |
| 43 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 44 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 45 | manifest_ex = manifest_group.add_mutually_exclusive_group() |
| 46 | manifest_ex.add_argument( |
| 47 | "--branch", default="master", help="Sync to top of given branch." |
| 48 | ) |
| 49 | manifest_ex.add_argument( |
| 50 | "--buildspec", |
| 51 | help="Path to manifest, relative to manifest-versions root.", |
| 52 | ) |
| 53 | manifest_ex.add_argument( |
| 54 | "--version", |
| 55 | help="Shorthand for an official release buildspec. e.g. 9799.0.0", |
| 56 | ) |
| 57 | manifest_ex.add_argument( |
| 58 | "--manifest-file", |
| 59 | type="path", |
| 60 | help="Sync to an existing local manifest file.", |
| 61 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 62 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 63 | manifest_group.add_argument("--groups", help="manifest groups to sync.") |
Raul E Rangel | 5a7c500 | 2019-11-08 09:18:32 -0700 | [diff] [blame] | 64 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 65 | manifest_url_ex = manifest_group.add_mutually_exclusive_group() |
| 66 | manifest_url_ex.add_argument( |
| 67 | "--external", |
| 68 | action="store_true", |
| 69 | default=False, |
Trent Apted | c20bb6d | 2023-05-10 15:00:03 +1000 | [diff] [blame] | 70 | help=( |
| 71 | "Sync to the external version of a manifest. Switch from " |
| 72 | "manifest-versions-internal to manifest-versions for buildspecs. " |
| 73 | "Not usable with --manifest." |
| 74 | ), |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 75 | ) |
| 76 | manifest_url_ex.add_argument( |
| 77 | "--manifest-url", help="Manually set URL to fetch repo manifest from." |
| 78 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 79 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 80 | patch_group = parser.add_argument_group( |
| 81 | "Patch", description="Which patches should be included with the build?" |
| 82 | ) |
| 83 | patch_group.add_argument( |
| 84 | "-g", |
| 85 | "--gerrit-patches", |
| 86 | action="split_extend", |
| 87 | default=[], |
| 88 | metavar="Id1 *int_Id2...IdN", |
Trent Apted | c20bb6d | 2023-05-10 15:00:03 +1000 | [diff] [blame] | 89 | help=( |
| 90 | "Space-separated list of short-form Gerrit " |
| 91 | "Change-Id's or change numbers to patch. " |
| 92 | "Please prepend '*' to internal Change-Id's" |
| 93 | ), |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 94 | ) |
Don Garrett | 115df40 | 2018-11-09 14:43:42 -0800 | [diff] [blame] | 95 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 96 | resources_group = parser.add_argument_group( |
| 97 | "Resources", description="External resources that might be needed." |
| 98 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 99 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 100 | resources_group.add_argument( |
| 101 | "--manifest-versions-int", |
| 102 | type="path", |
Trent Apted | c20bb6d | 2023-05-10 15:00:03 +1000 | [diff] [blame] | 103 | help=( |
| 104 | "Directory for internal manifest versions checkout. " |
| 105 | "May be refreshed." |
| 106 | ), |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 107 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 108 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 109 | resources_group.add_argument( |
| 110 | "--manifest-versions-ext", |
| 111 | type="path", |
Trent Apted | c20bb6d | 2023-05-10 15:00:03 +1000 | [diff] [blame] | 112 | help=( |
| 113 | "Directory for internal manifest versions checkout. " |
| 114 | "May be refreshed." |
| 115 | ), |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 116 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 117 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 118 | optimization_group = parser.add_argument_group( |
| 119 | "Optimization", |
| 120 | description="Hints provided to possibly speed up initial sync.", |
| 121 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 122 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 123 | optimization_group.add_argument( |
| 124 | "--copy-repo", |
| 125 | type="path", |
Trent Apted | c20bb6d | 2023-05-10 15:00:03 +1000 | [diff] [blame] | 126 | help=( |
| 127 | "Path to an existing repo root. Used to preload the local " |
| 128 | "checkout if the local checkout doesn't exist." |
| 129 | ), |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 130 | ) |
| 131 | optimization_group.add_argument( |
| 132 | "--git-cache-dir", type="path", help="Git cache directory to use." |
| 133 | ) |
| 134 | optimization_group.add_argument( |
| 135 | "--repo-url", help="Repo repository location." |
| 136 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 137 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 138 | return parser |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 139 | |
| 140 | |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 141 | def PrepareManifestVersions(options): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 142 | """Select manifest-versions checkout to use, and update it. |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 143 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 144 | Looks at command line options to decide which manifest-versions checkout to |
| 145 | use, and updates (or creates) it as needed. |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 146 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 147 | Args: |
Trent Apted | c20bb6d | 2023-05-10 15:00:03 +1000 | [diff] [blame] | 148 | options: Parsed command line options. |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 149 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 150 | Returns: |
Trent Apted | c20bb6d | 2023-05-10 15:00:03 +1000 | [diff] [blame] | 151 | Full path to manifest-versions directory to use for this sync. |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 152 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 153 | Raises: |
Trent Apted | c20bb6d | 2023-05-10 15:00:03 +1000 | [diff] [blame] | 154 | AssertionError: If the needed manifest-versions path wasn't con the |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 155 | command line. |
| 156 | """ |
| 157 | site_params = config_lib.GetSiteParams() |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 158 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 159 | if options.external: |
| 160 | assert ( |
| 161 | options.manifest_versions_ext |
| 162 | ), "--manifest-versions-ext required." |
| 163 | manifest_versions_url = site_params.MANIFEST_VERSIONS_GOB_URL |
| 164 | manifest_versions_path = options.manifest_versions_ext |
| 165 | else: |
| 166 | assert ( |
| 167 | options.manifest_versions_int |
| 168 | ), "--manifest-versions-int required." |
| 169 | manifest_versions_url = site_params.MANIFEST_VERSIONS_INT_GOB_URL |
| 170 | manifest_versions_path = options.manifest_versions_int |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 171 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 172 | # Resolve buildspecs against a current manifest versions value. |
| 173 | manifest_version.RefreshManifestCheckout( |
| 174 | manifest_versions_path, manifest_versions_url |
| 175 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 176 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 177 | return manifest_versions_path |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 178 | |
| 179 | |
| 180 | def ResolveLocalManifestPath(options): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 181 | """Based on command line options, decide what local manifest file to use. |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 182 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 183 | Args: |
Trent Apted | c20bb6d | 2023-05-10 15:00:03 +1000 | [diff] [blame] | 184 | options: Our parsed command line options. |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 185 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 186 | Returns: |
Trent Apted | c20bb6d | 2023-05-10 15:00:03 +1000 | [diff] [blame] | 187 | Path to local manifest file to use, or None for no file. |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 188 | """ |
| 189 | if options.manifest_file: |
| 190 | # If the user gives us an explicit local manifest file, use it. |
| 191 | return options.manifest_file |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 192 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 193 | elif options.buildspec: |
| 194 | # Buildspec builds use a manifest file from manifest_versions. We do NOT |
Trent Apted | 4a0812b | 2023-05-15 15:33:55 +1000 | [diff] [blame^] | 195 | # use manifest_versions as the manifest git repo, because it's so large |
| 196 | # that sync time would be a major performance problem. |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 197 | manifest_versions_path = PrepareManifestVersions(options) |
| 198 | return manifest_version.ResolveBuildspec( |
| 199 | manifest_versions_path, options.buildspec |
| 200 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 201 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 202 | elif options.version: |
| 203 | # Versions are a short hand version of a buildspec. |
| 204 | manifest_versions_path = PrepareManifestVersions(options) |
| 205 | return manifest_version.ResolveBuildspecVersion( |
| 206 | manifest_versions_path, options.version |
| 207 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 208 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 209 | elif options.branch: |
Trent Apted | 4a0812b | 2023-05-15 15:33:55 +1000 | [diff] [blame^] | 210 | # Branch checkouts use our normal manifest repos, not a local manifest |
| 211 | # file. |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 212 | return None |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 213 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 214 | else: |
| 215 | assert False, "No sync options specified. Should not be possible." |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 216 | |
| 217 | |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 218 | def main(argv): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 219 | parser = GetParser() |
| 220 | options = parser.parse_args(argv) |
| 221 | options.Freeze() |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 222 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 223 | local_manifest = ResolveLocalManifestPath(options) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 224 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 225 | if local_manifest: |
| 226 | logging.info("Using local_manifest: %s", local_manifest) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 227 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 228 | if options.manifest_url: |
| 229 | manifest_url = options.manifest_url |
| 230 | elif options.external: |
| 231 | manifest_url = config_lib.GetSiteParams().MANIFEST_URL |
| 232 | else: |
| 233 | manifest_url = config_lib.GetSiteParams().MANIFEST_INT_URL |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 234 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 235 | osutils.SafeMakedirs(options.repo_root) |
| 236 | repo = repository.RepoRepository( |
| 237 | manifest_repo_url=manifest_url, |
| 238 | directory=options.repo_root, |
| 239 | branch=options.branch, |
| 240 | git_cache_dir=options.git_cache_dir, |
| 241 | repo_url=options.repo_url, |
| 242 | groups=options.groups, |
| 243 | ) |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 244 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 245 | if options.copy_repo: |
| 246 | repo.PreLoad(options.copy_repo) |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 247 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 248 | repo.Sync(local_manifest=local_manifest, detach=True) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 249 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 250 | if options.gerrit_patches: |
| 251 | patches = gerrit.GetGerritPatchInfo(options.gerrit_patches) |
| 252 | # TODO: Extract patches from manifest synced. |
Don Garrett | 115df40 | 2018-11-09 14:43:42 -0800 | [diff] [blame] | 253 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 254 | helper_pool = patch_series.HelperPool.SimpleCreate( |
| 255 | cros_internal=not options.external, cros=True |
| 256 | ) |
Don Garrett | 115df40 | 2018-11-09 14:43:42 -0800 | [diff] [blame] | 257 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 258 | series = patch_series.PatchSeries( |
| 259 | path=options.repo_root, |
| 260 | helper_pool=helper_pool, |
| 261 | forced_manifest=None, |
| 262 | ) |
Don Garrett | 115df40 | 2018-11-09 14:43:42 -0800 | [diff] [blame] | 263 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 264 | _, failed_tot, failed_inflight = series.Apply(patches) |
Don Garrett | f3976f9 | 2018-12-20 12:46:47 -0800 | [diff] [blame] | 265 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 266 | failed = failed_tot + failed_inflight |
| 267 | if failed: |
| 268 | logging.error( |
| 269 | "Failed to apply: %s", ", ".join(str(p) for p in failed) |
| 270 | ) |
| 271 | return 1 |