blob: 5650783d36fc100ae3d98a90808579c11d9c0304 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2018 The ChromiumOS Authors
Lann Martin10f3ee92018-08-22 15:48:10 -06002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
Don Garrett903fedc2018-11-02 17:04:26 -07005"""Sync a git repository to a given manifest.
6
7This script is intended to define all of the ways that a source checkout can be
8defined for a Chrome OS builder.
9
10If a sync completes successfully, the checked out code will exactly match
11whatever manifest is defined, and no local git branches will remain. Extraneous
12files not under version management will be ignored.
13
14It is NOT safe to assume that the checkout can be further updated with
15a simple "repo sync", instead you should call this script again with
16the same options.
17"""
Lann Martin10f3ee92018-08-22 15:48:10 -060018
Chris McDonald59650c32021-07-20 15:29:28 -060019import logging
20
Don Garrett903fedc2018-11-02 17:04:26 -070021from chromite.cbuildbot import manifest_version
Don Garrett115df402018-11-09 14:43:42 -080022from chromite.cbuildbot import patch_series
Don Garrett903fedc2018-11-02 17:04:26 -070023from chromite.cbuildbot import repository
Lann Martin10f3ee92018-08-22 15:48:10 -060024from chromite.lib import commandline
Don Garrett903fedc2018-11-02 17:04:26 -070025from chromite.lib import config_lib
Don Garrett115df402018-11-09 14:43:42 -080026from chromite.lib import gerrit
Don Garrett903fedc2018-11-02 17:04:26 -070027from chromite.lib import osutils
Lann Martin10f3ee92018-08-22 15:48:10 -060028
29
30def GetParser():
Alex Klein1699fab2022-09-08 08:46:06 -060031 """Creates the argparse parser."""
32 parser = commandline.ArgumentParser(description=__doc__)
Don Garrett903fedc2018-11-02 17:04:26 -070033
Alex Klein1699fab2022-09-08 08:46:06 -060034 parser.add_argument(
35 "--repo-root",
36 type="path",
37 default=".",
38 help="Path to the repo root to sync.",
39 )
Don Garrett903fedc2018-11-02 17:04:26 -070040
Alex Klein1699fab2022-09-08 08:46:06 -060041 manifest_group = parser.add_argument_group(
42 "Manifest", description="What manifest do we sync?"
43 )
Don Garrett903fedc2018-11-02 17:04:26 -070044
Alex Klein1699fab2022-09-08 08:46:06 -060045 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 Garrett903fedc2018-11-02 17:04:26 -070062
Alex Klein1699fab2022-09-08 08:46:06 -060063 manifest_group.add_argument("--groups", help="manifest groups to sync.")
Raul E Rangel5a7c5002019-11-08 09:18:32 -070064
Alex Klein1699fab2022-09-08 08:46:06 -060065 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 Aptedc20bb6d2023-05-10 15:00:03 +100070 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 Klein1699fab2022-09-08 08:46:06 -060075 )
76 manifest_url_ex.add_argument(
77 "--manifest-url", help="Manually set URL to fetch repo manifest from."
78 )
Don Garrett903fedc2018-11-02 17:04:26 -070079
Alex Klein1699fab2022-09-08 08:46:06 -060080 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 Aptedc20bb6d2023-05-10 15:00:03 +100089 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 Klein1699fab2022-09-08 08:46:06 -060094 )
Don Garrett115df402018-11-09 14:43:42 -080095
Alex Klein1699fab2022-09-08 08:46:06 -060096 resources_group = parser.add_argument_group(
97 "Resources", description="External resources that might be needed."
98 )
Don Garrett903fedc2018-11-02 17:04:26 -070099
Alex Klein1699fab2022-09-08 08:46:06 -0600100 resources_group.add_argument(
101 "--manifest-versions-int",
102 type="path",
Trent Aptedc20bb6d2023-05-10 15:00:03 +1000103 help=(
104 "Directory for internal manifest versions checkout. "
105 "May be refreshed."
106 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600107 )
Don Garrett903fedc2018-11-02 17:04:26 -0700108
Alex Klein1699fab2022-09-08 08:46:06 -0600109 resources_group.add_argument(
110 "--manifest-versions-ext",
111 type="path",
Trent Aptedc20bb6d2023-05-10 15:00:03 +1000112 help=(
113 "Directory for internal manifest versions checkout. "
114 "May be refreshed."
115 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600116 )
Don Garrett903fedc2018-11-02 17:04:26 -0700117
Alex Klein1699fab2022-09-08 08:46:06 -0600118 optimization_group = parser.add_argument_group(
119 "Optimization",
120 description="Hints provided to possibly speed up initial sync.",
121 )
Don Garrett903fedc2018-11-02 17:04:26 -0700122
Alex Klein1699fab2022-09-08 08:46:06 -0600123 optimization_group.add_argument(
124 "--copy-repo",
125 type="path",
Trent Aptedc20bb6d2023-05-10 15:00:03 +1000126 help=(
127 "Path to an existing repo root. Used to preload the local "
128 "checkout if the local checkout doesn't exist."
129 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600130 )
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 Garrett903fedc2018-11-02 17:04:26 -0700137
Alex Klein1699fab2022-09-08 08:46:06 -0600138 return parser
Lann Martin10f3ee92018-08-22 15:48:10 -0600139
140
Don Garrett903fedc2018-11-02 17:04:26 -0700141def PrepareManifestVersions(options):
Alex Klein1699fab2022-09-08 08:46:06 -0600142 """Select manifest-versions checkout to use, and update it.
Don Garrett903fedc2018-11-02 17:04:26 -0700143
Alex Klein1699fab2022-09-08 08:46:06 -0600144 Looks at command line options to decide which manifest-versions checkout to
145 use, and updates (or creates) it as needed.
Don Garrett903fedc2018-11-02 17:04:26 -0700146
Alex Klein1699fab2022-09-08 08:46:06 -0600147 Args:
Trent Aptedc20bb6d2023-05-10 15:00:03 +1000148 options: Parsed command line options.
Don Garrett903fedc2018-11-02 17:04:26 -0700149
Alex Klein1699fab2022-09-08 08:46:06 -0600150 Returns:
Trent Aptedc20bb6d2023-05-10 15:00:03 +1000151 Full path to manifest-versions directory to use for this sync.
Don Garrett903fedc2018-11-02 17:04:26 -0700152
Alex Klein1699fab2022-09-08 08:46:06 -0600153 Raises:
Trent Aptedc20bb6d2023-05-10 15:00:03 +1000154 AssertionError: If the needed manifest-versions path wasn't con the
Alex Klein1699fab2022-09-08 08:46:06 -0600155 command line.
156 """
157 site_params = config_lib.GetSiteParams()
Don Garrett903fedc2018-11-02 17:04:26 -0700158
Alex Klein1699fab2022-09-08 08:46:06 -0600159 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 Garrett903fedc2018-11-02 17:04:26 -0700171
Alex Klein1699fab2022-09-08 08:46:06 -0600172 # Resolve buildspecs against a current manifest versions value.
173 manifest_version.RefreshManifestCheckout(
174 manifest_versions_path, manifest_versions_url
175 )
Don Garrett903fedc2018-11-02 17:04:26 -0700176
Alex Klein1699fab2022-09-08 08:46:06 -0600177 return manifest_versions_path
Don Garrett903fedc2018-11-02 17:04:26 -0700178
179
180def ResolveLocalManifestPath(options):
Alex Klein1699fab2022-09-08 08:46:06 -0600181 """Based on command line options, decide what local manifest file to use.
Don Garrett903fedc2018-11-02 17:04:26 -0700182
Alex Klein1699fab2022-09-08 08:46:06 -0600183 Args:
Trent Aptedc20bb6d2023-05-10 15:00:03 +1000184 options: Our parsed command line options.
Don Garrett903fedc2018-11-02 17:04:26 -0700185
Alex Klein1699fab2022-09-08 08:46:06 -0600186 Returns:
Trent Aptedc20bb6d2023-05-10 15:00:03 +1000187 Path to local manifest file to use, or None for no file.
Alex Klein1699fab2022-09-08 08:46:06 -0600188 """
189 if options.manifest_file:
190 # If the user gives us an explicit local manifest file, use it.
191 return options.manifest_file
Don Garrett903fedc2018-11-02 17:04:26 -0700192
Alex Klein1699fab2022-09-08 08:46:06 -0600193 elif options.buildspec:
194 # Buildspec builds use a manifest file from manifest_versions. We do NOT
Trent Apted4a0812b2023-05-15 15:33:55 +1000195 # use manifest_versions as the manifest git repo, because it's so large
196 # that sync time would be a major performance problem.
Alex Klein1699fab2022-09-08 08:46:06 -0600197 manifest_versions_path = PrepareManifestVersions(options)
198 return manifest_version.ResolveBuildspec(
199 manifest_versions_path, options.buildspec
200 )
Don Garrett903fedc2018-11-02 17:04:26 -0700201
Alex Klein1699fab2022-09-08 08:46:06 -0600202 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 Garrett903fedc2018-11-02 17:04:26 -0700208
Alex Klein1699fab2022-09-08 08:46:06 -0600209 elif options.branch:
Trent Apted4a0812b2023-05-15 15:33:55 +1000210 # Branch checkouts use our normal manifest repos, not a local manifest
211 # file.
Alex Klein1699fab2022-09-08 08:46:06 -0600212 return None
Don Garrett903fedc2018-11-02 17:04:26 -0700213
Alex Klein1699fab2022-09-08 08:46:06 -0600214 else:
215 assert False, "No sync options specified. Should not be possible."
Don Garrett903fedc2018-11-02 17:04:26 -0700216
217
Lann Martin10f3ee92018-08-22 15:48:10 -0600218def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600219 parser = GetParser()
220 options = parser.parse_args(argv)
221 options.Freeze()
Lann Martin10f3ee92018-08-22 15:48:10 -0600222
Alex Klein1699fab2022-09-08 08:46:06 -0600223 local_manifest = ResolveLocalManifestPath(options)
Don Garrett903fedc2018-11-02 17:04:26 -0700224
Alex Klein1699fab2022-09-08 08:46:06 -0600225 if local_manifest:
226 logging.info("Using local_manifest: %s", local_manifest)
Don Garrett903fedc2018-11-02 17:04:26 -0700227
Alex Klein1699fab2022-09-08 08:46:06 -0600228 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 Garrett903fedc2018-11-02 17:04:26 -0700234
Alex Klein1699fab2022-09-08 08:46:06 -0600235 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 Martin10f3ee92018-08-22 15:48:10 -0600244
Alex Klein1699fab2022-09-08 08:46:06 -0600245 if options.copy_repo:
246 repo.PreLoad(options.copy_repo)
Lann Martin10f3ee92018-08-22 15:48:10 -0600247
Alex Klein1699fab2022-09-08 08:46:06 -0600248 repo.Sync(local_manifest=local_manifest, detach=True)
Don Garrett903fedc2018-11-02 17:04:26 -0700249
Alex Klein1699fab2022-09-08 08:46:06 -0600250 if options.gerrit_patches:
251 patches = gerrit.GetGerritPatchInfo(options.gerrit_patches)
252 # TODO: Extract patches from manifest synced.
Don Garrett115df402018-11-09 14:43:42 -0800253
Alex Klein1699fab2022-09-08 08:46:06 -0600254 helper_pool = patch_series.HelperPool.SimpleCreate(
255 cros_internal=not options.external, cros=True
256 )
Don Garrett115df402018-11-09 14:43:42 -0800257
Alex Klein1699fab2022-09-08 08:46:06 -0600258 series = patch_series.PatchSeries(
259 path=options.repo_root,
260 helper_pool=helper_pool,
261 forced_manifest=None,
262 )
Don Garrett115df402018-11-09 14:43:42 -0800263
Alex Klein1699fab2022-09-08 08:46:06 -0600264 _, failed_tot, failed_inflight = series.Apply(patches)
Don Garrettf3976f92018-12-20 12:46:47 -0800265
Alex Klein1699fab2022-09-08 08:46:06 -0600266 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