blob: 25e16912f0dcffdbce683b9c2d02071db9fdf67f [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
195 # use manifest_versions as the manifest git repo, because it's so large that
196 # sync time would be a major performance problem.
197 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:
210 # Branch checkouts use our normal manifest repos, not a local manifest file.
211 return None
Don Garrett903fedc2018-11-02 17:04:26 -0700212
Alex Klein1699fab2022-09-08 08:46:06 -0600213 else:
214 assert False, "No sync options specified. Should not be possible."
Don Garrett903fedc2018-11-02 17:04:26 -0700215
216
Lann Martin10f3ee92018-08-22 15:48:10 -0600217def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600218 parser = GetParser()
219 options = parser.parse_args(argv)
220 options.Freeze()
Lann Martin10f3ee92018-08-22 15:48:10 -0600221
Alex Klein1699fab2022-09-08 08:46:06 -0600222 local_manifest = ResolveLocalManifestPath(options)
Don Garrett903fedc2018-11-02 17:04:26 -0700223
Alex Klein1699fab2022-09-08 08:46:06 -0600224 if local_manifest:
225 logging.info("Using local_manifest: %s", local_manifest)
Don Garrett903fedc2018-11-02 17:04:26 -0700226
Alex Klein1699fab2022-09-08 08:46:06 -0600227 if options.manifest_url:
228 manifest_url = options.manifest_url
229 elif options.external:
230 manifest_url = config_lib.GetSiteParams().MANIFEST_URL
231 else:
232 manifest_url = config_lib.GetSiteParams().MANIFEST_INT_URL
Don Garrett903fedc2018-11-02 17:04:26 -0700233
Alex Klein1699fab2022-09-08 08:46:06 -0600234 osutils.SafeMakedirs(options.repo_root)
235 repo = repository.RepoRepository(
236 manifest_repo_url=manifest_url,
237 directory=options.repo_root,
238 branch=options.branch,
239 git_cache_dir=options.git_cache_dir,
240 repo_url=options.repo_url,
241 groups=options.groups,
242 )
Lann Martin10f3ee92018-08-22 15:48:10 -0600243
Alex Klein1699fab2022-09-08 08:46:06 -0600244 if options.copy_repo:
245 repo.PreLoad(options.copy_repo)
Lann Martin10f3ee92018-08-22 15:48:10 -0600246
Alex Klein1699fab2022-09-08 08:46:06 -0600247 repo.Sync(local_manifest=local_manifest, detach=True)
Don Garrett903fedc2018-11-02 17:04:26 -0700248
Alex Klein1699fab2022-09-08 08:46:06 -0600249 if options.gerrit_patches:
250 patches = gerrit.GetGerritPatchInfo(options.gerrit_patches)
251 # TODO: Extract patches from manifest synced.
Don Garrett115df402018-11-09 14:43:42 -0800252
Alex Klein1699fab2022-09-08 08:46:06 -0600253 helper_pool = patch_series.HelperPool.SimpleCreate(
254 cros_internal=not options.external, cros=True
255 )
Don Garrett115df402018-11-09 14:43:42 -0800256
Alex Klein1699fab2022-09-08 08:46:06 -0600257 series = patch_series.PatchSeries(
258 path=options.repo_root,
259 helper_pool=helper_pool,
260 forced_manifest=None,
261 )
Don Garrett115df402018-11-09 14:43:42 -0800262
Alex Klein1699fab2022-09-08 08:46:06 -0600263 _, failed_tot, failed_inflight = series.Apply(patches)
Don Garrettf3976f92018-12-20 12:46:47 -0800264
Alex Klein1699fab2022-09-08 08:46:06 -0600265 failed = failed_tot + failed_inflight
266 if failed:
267 logging.error(
268 "Failed to apply: %s", ", ".join(str(p) for p in failed)
269 )
270 return 1