blob: b6f5c06654272e64203ab824ec849653289a74eb [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2018 The ChromiumOS Authors
Xiaochu Liudeed0232018-06-26 10:25:34 -07002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
Xiaochu Liudeed0232018-06-26 10:25:34 -07004
Mike Frysinger88770ef2021-05-21 11:04:00 -04005"""Script to generate a DLC (Downloadable Content) artifact."""
Xiaochu Liudeed0232018-06-26 10:25:34 -07006
Chris McDonald59650c32021-07-20 15:29:28 -06007import logging
8
Xiaochu Liudeed0232018-06-26 10:25:34 -07009from chromite.lib import commandline
Chris McDonald59650c32021-07-20 15:29:28 -060010from chromite.lib import dlc_lib
Xiaochu Liudeed0232018-06-26 10:25:34 -070011
12
Xiaochu Liudeed0232018-06-26 10:25:34 -070013def GetParser():
Alex Klein1699fab2022-09-08 08:46:06 -060014 """Creates an argument parser and returns it."""
15 parser = commandline.ArgumentParser(description=__doc__)
Alex Klein68b270c2023-04-14 14:42:50 -060016 # This script is used both for building an individual DLC or copying all
17 # final DLCs images to their final destination nearby
18 # chromiumos_test_image.bin, etc. These two arguments are required in both
19 # cases.
Alex Klein1699fab2022-09-08 08:46:06 -060020 parser.add_argument(
21 "--sysroot",
22 type="path",
23 metavar="DIR",
Trent Apted66736d82023-05-25 10:38:28 +100024 help="The root path to the board's build root, e.g. /build/eve",
Alex Klein1699fab2022-09-08 08:46:06 -060025 )
Alex Klein68b270c2023-04-14 14:42:50 -060026 # TODO(andrewlassalle): Remove src-dir in the future(2021?) if nobody uses
27 # it.
Alex Klein1699fab2022-09-08 08:46:06 -060028 parser.add_argument(
29 "--src-dir",
30 type="path",
31 metavar="SRC_DIR_PATH",
Trent Apted66736d82023-05-25 10:38:28 +100032 help=(
33 "Override the default Root directory path that contains all DLC "
34 "files to be packed."
35 ),
Alex Klein1699fab2022-09-08 08:46:06 -060036 )
37 parser.add_argument(
38 "--install-root-dir",
39 type="path",
40 metavar="DIR",
Trent Apted66736d82023-05-25 10:38:28 +100041 help=(
42 "If building a specific DLC, it is the root path to"
43 " install DLC images (%s) and metadata (%s). Otherwise it"
44 " is the target directory where the Chrome OS images gets"
Jack Rosenthal8d3fc832023-06-16 20:04:37 -060045 " dropped in `cros build-image`, e.g. "
Trent Apted66736d82023-05-25 10:38:28 +100046 "src/build/images/<board>/latest."
47 )
Alex Klein1699fab2022-09-08 08:46:06 -060048 % (dlc_lib.DLC_BUILD_DIR, dlc_lib.DLC_META_DIR),
49 )
Amin Hassani22a25eb2019-01-11 14:25:02 -080050
Alex Klein1699fab2022-09-08 08:46:06 -060051 one_dlc = parser.add_argument_group(
Trent Apted66736d82023-05-25 10:38:28 +100052 "Arguments required for building only one DLC"
Alex Klein1699fab2022-09-08 08:46:06 -060053 )
54 one_dlc.add_argument(
55 "--rootfs",
56 type="path",
57 metavar="ROOT_FS_PATH",
58 help="Path to the platform rootfs.",
59 )
60 one_dlc.add_argument(
61 "--stateful",
62 type="path",
63 metavar="STATEFUL_PATH",
64 help="Path to the platform stateful.",
65 )
66 one_dlc.add_argument(
67 "--pre-allocated-blocks",
68 type=int,
69 metavar="PREALLOCATEDBLOCKS",
Trent Apted66736d82023-05-25 10:38:28 +100070 help=(
71 "Number of blocks (block size is 4k) that need to"
72 "be pre-allocated on device."
73 ),
Alex Klein1699fab2022-09-08 08:46:06 -060074 )
75 one_dlc.add_argument("--version", metavar="VERSION", help="DLC Version.")
76 one_dlc.add_argument("--id", metavar="ID", help="DLC ID (unique per DLC).")
77 one_dlc.add_argument(
78 "--package",
79 metavar="PACKAGE",
Trent Apted66736d82023-05-25 10:38:28 +100080 help=(
81 "The package ID that is unique within a DLC, One"
82 " DLC cannot have duplicate package IDs."
83 ),
Alex Klein1699fab2022-09-08 08:46:06 -060084 )
85 one_dlc.add_argument(
86 "--name", metavar="NAME", help="A human-readable name for the DLC."
87 )
88 one_dlc.add_argument("--description", help="The description for the DLC.")
89 one_dlc.add_argument(
90 "--board", metavar="BOARD", help="The target board we are building for."
91 )
92 one_dlc.add_argument(
93 "--fullnamerev",
94 metavar="FULL_NAME_REV",
95 help="The full ebuild package name.",
96 )
97 one_dlc.add_argument(
98 "--fs-type",
99 metavar="FS_TYPE",
100 default=dlc_lib.SQUASHFS_TYPE,
101 choices=(dlc_lib.SQUASHFS_TYPE, dlc_lib.EXT4_TYPE),
102 help="File system type of the image.",
103 )
104 one_dlc.add_argument(
105 "--preload",
106 default=False,
107 action="store_true",
108 help="Allow preloading of DLC.",
109 )
110 one_dlc.add_argument(
111 "--factory-install",
112 default=False,
113 action="store_true",
114 help="Allow factory installing of DLC.",
115 )
116 one_dlc.add_argument(
117 "--loadpin-verity-digest",
118 default=False,
119 action="store_true",
120 help="Allow DLC to be a trusted dm-verity digest.",
121 )
122 one_dlc.add_argument(
123 "--used-by",
124 default=dlc_lib.USED_BY_SYSTEM,
125 choices=(dlc_lib.USED_BY_USER, dlc_lib.USED_BY_SYSTEM),
Trent Apted66736d82023-05-25 10:38:28 +1000126 help=(
127 "Defines how this DLC will be used so dlcservice can take proper"
128 ' actions based on the type of usage. For example, if "user" is'
129 " passed, dlcservice does ref counting when DLC is installed/"
130 'uninstalled. For "system", there will be no such provisions.'
131 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600132 )
133 one_dlc.add_argument(
134 "--days-to-purge",
135 type=int,
136 default=0,
Trent Apted66736d82023-05-25 10:38:28 +1000137 help=(
138 "Defines the number of days before purging a DLC after it has "
139 "been uninstalled."
140 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600141 )
142 one_dlc.add_argument(
143 "--mount-file-required",
144 default=False,
145 action="store_true",
146 help="Allow indirect mount file generation for DLC.",
147 )
148 one_dlc.add_argument(
Jae Hoon Kimc3cf2272022-10-28 23:59:10 +0000149 "--scaled",
150 default=False,
151 action="store_true",
152 help="DLC will be fed through scaling design.",
153 )
154 one_dlc.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600155 "--reserved",
156 default=False,
157 action="store_true",
158 help="Always reserve space for this DLC.",
159 )
160 one_dlc.add_argument(
161 "--critical-update",
162 default=False,
163 action="store_true",
164 help="Always update with the OS for this DLC.",
165 )
166 one_dlc.add_argument(
167 "--build-package",
168 default=False,
169 action="store_true",
Trent Apted66736d82023-05-25 10:38:28 +1000170 help=(
171 "Flag to indicate if the script is executed during the "
Jack Rosenthald05fb3c2023-06-16 19:46:32 -0600172 "`cros build-packages` phase."
Trent Apted66736d82023-05-25 10:38:28 +1000173 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600174 )
Jae Hoon Kimaaa060e2023-05-12 21:42:56 +0000175 one_dlc.add_argument(
176 "--powerwash-safe",
177 default=False,
178 action="store_true",
179 help="DLC will be powerwash safe. (Only on LVM supported devices)",
180 )
Jae Hoon Kima5a73ac2023-09-29 04:29:33 +0000181 # Arguments groups don't support `add_bool_argument` yet.
182 one_dlc.add_argument(
183 "--use-logical-volume",
184 default=False,
185 action="store_true",
186 help="DLC will use logical volumes on LVM stateful partition "
187 "migrated devices. (scaled option takes precedence)",
188 )
Alex Klein1699fab2022-09-08 08:46:06 -0600189 return parser
Xiaochu Liudeed0232018-06-26 10:25:34 -0700190
191
Andrew67b5fa72020-02-05 14:14:48 -0800192def ValidateArguments(parser, opts, req_flags, invalid_flags):
Alex Klein1699fab2022-09-08 08:46:06 -0600193 """Validates the correctness of the passed arguments.
Amin Hassanib97a5ee2019-01-23 14:44:43 -0800194
Alex Klein1699fab2022-09-08 08:46:06 -0600195 Args:
Trent Apted66736d82023-05-25 10:38:28 +1000196 parser: Arguments parser.
197 opts: Parsed arguments.
198 req_flags: all the required flags.
199 invalid_flags: all the flags that are not allowed.
Alex Klein1699fab2022-09-08 08:46:06 -0600200 """
201 # Make sure if the intention is to build one DLC, all the required arguments
202 # are passed and none of the invalid ones are passed. This will ensure the
203 # script is called twice per DLC.
204 if opts.id:
205 if not all(vars(opts)[x] is not None for x in req_flags):
206 parser.error(
207 "If the intention is to build only one DLC, all the flags"
208 "%s required for it should be passed." % req_flags
209 )
210 if any(vars(opts)[x] is not None for x in invalid_flags):
211 parser.error(
212 "If the intention is to build only one DLC, all the flags"
Jack Rosenthald05fb3c2023-06-16 19:46:32 -0600213 "%s should be passed in the `cros build-packages` phase, not "
Jack Rosenthal8d3fc832023-06-16 20:04:37 -0600214 "in the `cros build-image` phase." % invalid_flags
Alex Klein1699fab2022-09-08 08:46:06 -0600215 )
Andrew67b5fa72020-02-05 14:14:48 -0800216
Alex Klein1699fab2022-09-08 08:46:06 -0600217 if opts.fs_type == dlc_lib.EXT4_TYPE:
218 parser.error("ext4 unsupported for DLC, see https://crbug.com/890060")
Amin Hassanib97a5ee2019-01-23 14:44:43 -0800219
Alex Klein1699fab2022-09-08 08:46:06 -0600220 if opts.id:
221 dlc_lib.ValidateDlcIdentifier(opts.id)
222 if opts.package:
223 dlc_lib.ValidateDlcIdentifier(opts.package)
Amin Hassanibc1a4792019-10-24 14:39:57 -0700224
Amin Hassanib97a5ee2019-01-23 14:44:43 -0800225
Xiaochu Liudeed0232018-06-26 10:25:34 -0700226def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600227 parser = GetParser()
228 opts = parser.parse_args(argv)
229 opts.Freeze()
230 per_dlc_req_args = ["id"]
231 per_dlc_invalid_args = []
232 if opts.build_package:
233 per_dlc_req_args += [
234 "pre_allocated_blocks",
235 "version",
236 "name",
237 "description",
238 "package",
239 "install_root_dir",
240 "days_to_purge",
241 ]
242 per_dlc_invalid_args += ["src_dir", "sysroot", "stateful"]
243 else:
244 per_dlc_req_args += ["sysroot", "board"]
245 per_dlc_invalid_args += [
246 "name",
247 "pre_allocated_blocks",
248 "version",
249 "package",
250 "days_to_purge",
251 "reserved",
252 "critical_update",
253 ]
Andrew67b5fa72020-02-05 14:14:48 -0800254
Alex Klein1699fab2022-09-08 08:46:06 -0600255 ValidateArguments(parser, opts, per_dlc_req_args, per_dlc_invalid_args)
Andrew67b5fa72020-02-05 14:14:48 -0800256
Alex Klein1699fab2022-09-08 08:46:06 -0600257 if opts.build_package:
258 logging.info("Building package: DLC %s", opts.id)
259 params = dlc_lib.EbuildParams(
260 dlc_id=opts.id,
261 dlc_package=opts.package,
262 fs_type=opts.fs_type,
263 name=opts.name,
264 description=opts.description,
265 pre_allocated_blocks=opts.pre_allocated_blocks,
266 version=opts.version,
267 preload=opts.preload,
268 factory_install=opts.factory_install,
269 loadpin_verity_digest=opts.loadpin_verity_digest,
270 mount_file_required=opts.mount_file_required,
271 reserved=opts.reserved,
272 critical_update=opts.critical_update,
273 used_by=opts.used_by,
274 days_to_purge=opts.days_to_purge,
275 fullnamerev=opts.fullnamerev,
Jae Hoon Kimc3cf2272022-10-28 23:59:10 +0000276 scaled=opts.scaled,
Jae Hoon Kimaaa060e2023-05-12 21:42:56 +0000277 powerwash_safe=opts.powerwash_safe,
Jae Hoon Kima5a73ac2023-09-29 04:29:33 +0000278 use_logical_volume=opts.use_logical_volume,
Alex Klein1699fab2022-09-08 08:46:06 -0600279 )
Jae Hoon Kimb0ca6852023-03-21 05:50:41 +0000280 params.VerifyDlcParameters()
Alex Klein1699fab2022-09-08 08:46:06 -0600281 params.StoreDlcParameters(
282 install_root_dir=opts.install_root_dir, sudo=True
283 )
Andrew67b5fa72020-02-05 14:14:48 -0800284
Alex Klein1699fab2022-09-08 08:46:06 -0600285 else:
286 dlc_lib.InstallDlcImages(
287 sysroot=opts.sysroot,
288 dlc_id=opts.id,
289 install_root_dir=opts.install_root_dir,
290 preload=opts.preload,
291 factory_install=opts.factory_install,
292 src_dir=opts.src_dir,
293 rootfs=opts.rootfs,
294 stateful=opts.stateful,
295 board=opts.board,
296 )