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, |
| 70 | help="Sync to the external version of a manifest. Switch from " |
| 71 | "manifest-versions-internal to manifest-versions for buildspecs. " |
| 72 | "Not usable with --manifest.", |
| 73 | ) |
| 74 | manifest_url_ex.add_argument( |
| 75 | "--manifest-url", help="Manually set URL to fetch repo manifest from." |
| 76 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 77 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 78 | patch_group = parser.add_argument_group( |
| 79 | "Patch", description="Which patches should be included with the build?" |
| 80 | ) |
| 81 | patch_group.add_argument( |
| 82 | "-g", |
| 83 | "--gerrit-patches", |
| 84 | action="split_extend", |
| 85 | default=[], |
| 86 | metavar="Id1 *int_Id2...IdN", |
| 87 | help="Space-separated list of short-form Gerrit " |
| 88 | "Change-Id's or change numbers to patch. " |
| 89 | "Please prepend '*' to internal Change-Id's", |
| 90 | ) |
Don Garrett | 115df40 | 2018-11-09 14:43:42 -0800 | [diff] [blame] | 91 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 92 | resources_group = parser.add_argument_group( |
| 93 | "Resources", description="External resources that might be needed." |
| 94 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 95 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 96 | resources_group.add_argument( |
| 97 | "--manifest-versions-int", |
| 98 | type="path", |
| 99 | help="Directory for internal manifest versions checkout. " |
| 100 | "May be refreshed.", |
| 101 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 102 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 103 | resources_group.add_argument( |
| 104 | "--manifest-versions-ext", |
| 105 | type="path", |
| 106 | help="Directory for internal manifest versions checkout. " |
| 107 | "May be refreshed.", |
| 108 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 109 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 110 | optimization_group = parser.add_argument_group( |
| 111 | "Optimization", |
| 112 | description="Hints provided to possibly speed up initial sync.", |
| 113 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 114 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 115 | optimization_group.add_argument( |
| 116 | "--copy-repo", |
| 117 | type="path", |
| 118 | help="Path to an existing repo root. Used to preload the local " |
| 119 | "checkout if the local checkout doesn't exist.", |
| 120 | ) |
| 121 | optimization_group.add_argument( |
| 122 | "--git-cache-dir", type="path", help="Git cache directory to use." |
| 123 | ) |
| 124 | optimization_group.add_argument( |
| 125 | "--repo-url", help="Repo repository location." |
| 126 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 127 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 128 | return parser |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 129 | |
| 130 | |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 131 | def PrepareManifestVersions(options): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 132 | """Select manifest-versions checkout to use, and update it. |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 133 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 134 | Looks at command line options to decide which manifest-versions checkout to |
| 135 | use, and updates (or creates) it as needed. |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 136 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 137 | Args: |
| 138 | options: Parsed command line options. |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 139 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 140 | Returns: |
| 141 | Full path to manifest-versions directory to use for this sync. |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 142 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 143 | Raises: |
| 144 | AssertionError: If the needed manifest-versions path wasn't con the |
| 145 | command line. |
| 146 | """ |
| 147 | site_params = config_lib.GetSiteParams() |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 148 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 149 | if options.external: |
| 150 | assert ( |
| 151 | options.manifest_versions_ext |
| 152 | ), "--manifest-versions-ext required." |
| 153 | manifest_versions_url = site_params.MANIFEST_VERSIONS_GOB_URL |
| 154 | manifest_versions_path = options.manifest_versions_ext |
| 155 | else: |
| 156 | assert ( |
| 157 | options.manifest_versions_int |
| 158 | ), "--manifest-versions-int required." |
| 159 | manifest_versions_url = site_params.MANIFEST_VERSIONS_INT_GOB_URL |
| 160 | manifest_versions_path = options.manifest_versions_int |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 161 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 162 | # Resolve buildspecs against a current manifest versions value. |
| 163 | manifest_version.RefreshManifestCheckout( |
| 164 | manifest_versions_path, manifest_versions_url |
| 165 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 166 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 167 | return manifest_versions_path |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 168 | |
| 169 | |
| 170 | def ResolveLocalManifestPath(options): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 171 | """Based on command line options, decide what local manifest file to use. |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 172 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 173 | Args: |
| 174 | options: Our parsed command line options. |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 175 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 176 | Returns: |
| 177 | Path to local manifest file to use, or None for no file. |
| 178 | """ |
| 179 | if options.manifest_file: |
| 180 | # If the user gives us an explicit local manifest file, use it. |
| 181 | return options.manifest_file |
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 | elif options.buildspec: |
| 184 | # Buildspec builds use a manifest file from manifest_versions. We do NOT |
| 185 | # use manifest_versions as the manifest git repo, because it's so large that |
| 186 | # sync time would be a major performance problem. |
| 187 | manifest_versions_path = PrepareManifestVersions(options) |
| 188 | return manifest_version.ResolveBuildspec( |
| 189 | manifest_versions_path, options.buildspec |
| 190 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 191 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 192 | elif options.version: |
| 193 | # Versions are a short hand version of a buildspec. |
| 194 | manifest_versions_path = PrepareManifestVersions(options) |
| 195 | return manifest_version.ResolveBuildspecVersion( |
| 196 | manifest_versions_path, options.version |
| 197 | ) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 198 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 199 | elif options.branch: |
| 200 | # Branch checkouts use our normal manifest repos, not a local manifest file. |
| 201 | return None |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 202 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 203 | else: |
| 204 | assert False, "No sync options specified. Should not be possible." |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 205 | |
| 206 | |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 207 | def main(argv): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 208 | parser = GetParser() |
| 209 | options = parser.parse_args(argv) |
| 210 | options.Freeze() |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 211 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 212 | local_manifest = ResolveLocalManifestPath(options) |
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 | if local_manifest: |
| 215 | logging.info("Using local_manifest: %s", local_manifest) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 216 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 217 | if options.manifest_url: |
| 218 | manifest_url = options.manifest_url |
| 219 | elif options.external: |
| 220 | manifest_url = config_lib.GetSiteParams().MANIFEST_URL |
| 221 | else: |
| 222 | manifest_url = config_lib.GetSiteParams().MANIFEST_INT_URL |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 223 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 224 | osutils.SafeMakedirs(options.repo_root) |
| 225 | repo = repository.RepoRepository( |
| 226 | manifest_repo_url=manifest_url, |
| 227 | directory=options.repo_root, |
| 228 | branch=options.branch, |
| 229 | git_cache_dir=options.git_cache_dir, |
| 230 | repo_url=options.repo_url, |
| 231 | groups=options.groups, |
| 232 | ) |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 233 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 234 | if options.copy_repo: |
| 235 | repo.PreLoad(options.copy_repo) |
Lann Martin | 10f3ee9 | 2018-08-22 15:48:10 -0600 | [diff] [blame] | 236 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 237 | repo.Sync(local_manifest=local_manifest, detach=True) |
Don Garrett | 903fedc | 2018-11-02 17:04:26 -0700 | [diff] [blame] | 238 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 239 | if options.gerrit_patches: |
| 240 | patches = gerrit.GetGerritPatchInfo(options.gerrit_patches) |
| 241 | # TODO: Extract patches from manifest synced. |
Don Garrett | 115df40 | 2018-11-09 14:43:42 -0800 | [diff] [blame] | 242 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 243 | helper_pool = patch_series.HelperPool.SimpleCreate( |
| 244 | cros_internal=not options.external, cros=True |
| 245 | ) |
Don Garrett | 115df40 | 2018-11-09 14:43:42 -0800 | [diff] [blame] | 246 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 247 | series = patch_series.PatchSeries( |
| 248 | path=options.repo_root, |
| 249 | helper_pool=helper_pool, |
| 250 | forced_manifest=None, |
| 251 | ) |
Don Garrett | 115df40 | 2018-11-09 14:43:42 -0800 | [diff] [blame] | 252 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 253 | _, failed_tot, failed_inflight = series.Apply(patches) |
Don Garrett | f3976f9 | 2018-12-20 12:46:47 -0800 | [diff] [blame] | 254 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 255 | failed = failed_tot + failed_inflight |
| 256 | if failed: |
| 257 | logging.error( |
| 258 | "Failed to apply: %s", ", ".join(str(p) for p in failed) |
| 259 | ) |
| 260 | return 1 |