blob: fdf504db13e1a4426660a3b97a2da162a985d6db [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",
24 help="The root path to the board's build root, e.g. " "/build/eve",
25 )
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",
32 help="Override the default Root directory path that contains all DLC "
33 "files to be packed.",
34 )
35 parser.add_argument(
36 "--install-root-dir",
37 type="path",
38 metavar="DIR",
39 help="If building a specific DLC, it is the root path to"
40 " install DLC images (%s) and metadata (%s). Otherwise it"
41 " is the target directory where the Chrome OS images gets"
42 " dropped in build_image, e.g. "
43 "src/build/images/<board>/latest."
44 % (dlc_lib.DLC_BUILD_DIR, dlc_lib.DLC_META_DIR),
45 )
Amin Hassani22a25eb2019-01-11 14:25:02 -080046
Alex Klein1699fab2022-09-08 08:46:06 -060047 one_dlc = parser.add_argument_group(
48 "Arguments required for building only " "one DLC"
49 )
50 one_dlc.add_argument(
51 "--rootfs",
52 type="path",
53 metavar="ROOT_FS_PATH",
54 help="Path to the platform rootfs.",
55 )
56 one_dlc.add_argument(
57 "--stateful",
58 type="path",
59 metavar="STATEFUL_PATH",
60 help="Path to the platform stateful.",
61 )
62 one_dlc.add_argument(
63 "--pre-allocated-blocks",
64 type=int,
65 metavar="PREALLOCATEDBLOCKS",
66 help="Number of blocks (block size is 4k) that need to"
67 "be pre-allocated on device.",
68 )
69 one_dlc.add_argument("--version", metavar="VERSION", help="DLC Version.")
70 one_dlc.add_argument("--id", metavar="ID", help="DLC ID (unique per DLC).")
71 one_dlc.add_argument(
72 "--package",
73 metavar="PACKAGE",
74 help="The package ID that is unique within a DLC, One"
75 " DLC cannot have duplicate package IDs.",
76 )
77 one_dlc.add_argument(
78 "--name", metavar="NAME", help="A human-readable name for the DLC."
79 )
80 one_dlc.add_argument("--description", help="The description for the DLC.")
81 one_dlc.add_argument(
82 "--board", metavar="BOARD", help="The target board we are building for."
83 )
84 one_dlc.add_argument(
85 "--fullnamerev",
86 metavar="FULL_NAME_REV",
87 help="The full ebuild package name.",
88 )
89 one_dlc.add_argument(
90 "--fs-type",
91 metavar="FS_TYPE",
92 default=dlc_lib.SQUASHFS_TYPE,
93 choices=(dlc_lib.SQUASHFS_TYPE, dlc_lib.EXT4_TYPE),
94 help="File system type of the image.",
95 )
96 one_dlc.add_argument(
97 "--preload",
98 default=False,
99 action="store_true",
100 help="Allow preloading of DLC.",
101 )
102 one_dlc.add_argument(
103 "--factory-install",
104 default=False,
105 action="store_true",
106 help="Allow factory installing of DLC.",
107 )
108 one_dlc.add_argument(
109 "--loadpin-verity-digest",
110 default=False,
111 action="store_true",
112 help="Allow DLC to be a trusted dm-verity digest.",
113 )
114 one_dlc.add_argument(
115 "--used-by",
116 default=dlc_lib.USED_BY_SYSTEM,
117 choices=(dlc_lib.USED_BY_USER, dlc_lib.USED_BY_SYSTEM),
118 help="Defines how this DLC will be used so dlcservice can take proper "
119 'actions based on the type of usage. For example, if "user" is passed, '
120 "dlcservice does ref counting when DLC is installed/uninstalled. For "
121 '"system", there will be no such provisions.',
122 )
123 one_dlc.add_argument(
124 "--days-to-purge",
125 type=int,
126 default=0,
127 help="Defines the number of days before purging a DLC after it has "
128 "been uninstalled.",
129 )
130 one_dlc.add_argument(
131 "--mount-file-required",
132 default=False,
133 action="store_true",
134 help="Allow indirect mount file generation for DLC.",
135 )
136 one_dlc.add_argument(
Jae Hoon Kimc3cf2272022-10-28 23:59:10 +0000137 "--scaled",
138 default=False,
139 action="store_true",
140 help="DLC will be fed through scaling design.",
141 )
142 one_dlc.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600143 "--reserved",
144 default=False,
145 action="store_true",
146 help="Always reserve space for this DLC.",
147 )
148 one_dlc.add_argument(
149 "--critical-update",
150 default=False,
151 action="store_true",
152 help="Always update with the OS for this DLC.",
153 )
154 one_dlc.add_argument(
155 "--build-package",
156 default=False,
157 action="store_true",
158 help="Flag to indicate if the script is executed during the "
159 "build_packages phase.",
160 )
Jae Hoon Kimaaa060e2023-05-12 21:42:56 +0000161 one_dlc.add_argument(
162 "--powerwash-safe",
163 default=False,
164 action="store_true",
165 help="DLC will be powerwash safe. (Only on LVM supported devices)",
166 )
Alex Klein1699fab2022-09-08 08:46:06 -0600167 return parser
Xiaochu Liudeed0232018-06-26 10:25:34 -0700168
169
Andrew67b5fa72020-02-05 14:14:48 -0800170def ValidateArguments(parser, opts, req_flags, invalid_flags):
Alex Klein1699fab2022-09-08 08:46:06 -0600171 """Validates the correctness of the passed arguments.
Amin Hassanib97a5ee2019-01-23 14:44:43 -0800172
Alex Klein1699fab2022-09-08 08:46:06 -0600173 Args:
174 parser: Arguments parser.
175 opts: Parsed arguments.
176 req_flags: all the required flags.
177 invalid_flags: all the flags that are not allowed.
178 """
179 # Make sure if the intention is to build one DLC, all the required arguments
180 # are passed and none of the invalid ones are passed. This will ensure the
181 # script is called twice per DLC.
182 if opts.id:
183 if not all(vars(opts)[x] is not None for x in req_flags):
184 parser.error(
185 "If the intention is to build only one DLC, all the flags"
186 "%s required for it should be passed." % req_flags
187 )
188 if any(vars(opts)[x] is not None for x in invalid_flags):
189 parser.error(
190 "If the intention is to build only one DLC, all the flags"
191 "%s should be passed in the build_packages phase, not in "
192 "the build_image phase." % invalid_flags
193 )
Andrew67b5fa72020-02-05 14:14:48 -0800194
Alex Klein1699fab2022-09-08 08:46:06 -0600195 if opts.fs_type == dlc_lib.EXT4_TYPE:
196 parser.error("ext4 unsupported for DLC, see https://crbug.com/890060")
Amin Hassanib97a5ee2019-01-23 14:44:43 -0800197
Alex Klein1699fab2022-09-08 08:46:06 -0600198 if opts.id:
199 dlc_lib.ValidateDlcIdentifier(opts.id)
200 if opts.package:
201 dlc_lib.ValidateDlcIdentifier(opts.package)
Amin Hassanibc1a4792019-10-24 14:39:57 -0700202
Amin Hassanib97a5ee2019-01-23 14:44:43 -0800203
Xiaochu Liudeed0232018-06-26 10:25:34 -0700204def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600205 parser = GetParser()
206 opts = parser.parse_args(argv)
207 opts.Freeze()
208 per_dlc_req_args = ["id"]
209 per_dlc_invalid_args = []
210 if opts.build_package:
211 per_dlc_req_args += [
212 "pre_allocated_blocks",
213 "version",
214 "name",
215 "description",
216 "package",
217 "install_root_dir",
218 "days_to_purge",
219 ]
220 per_dlc_invalid_args += ["src_dir", "sysroot", "stateful"]
221 else:
222 per_dlc_req_args += ["sysroot", "board"]
223 per_dlc_invalid_args += [
224 "name",
225 "pre_allocated_blocks",
226 "version",
227 "package",
228 "days_to_purge",
229 "reserved",
230 "critical_update",
231 ]
Andrew67b5fa72020-02-05 14:14:48 -0800232
Alex Klein1699fab2022-09-08 08:46:06 -0600233 ValidateArguments(parser, opts, per_dlc_req_args, per_dlc_invalid_args)
Andrew67b5fa72020-02-05 14:14:48 -0800234
Alex Klein1699fab2022-09-08 08:46:06 -0600235 if opts.build_package:
236 logging.info("Building package: DLC %s", opts.id)
237 params = dlc_lib.EbuildParams(
238 dlc_id=opts.id,
239 dlc_package=opts.package,
240 fs_type=opts.fs_type,
241 name=opts.name,
242 description=opts.description,
243 pre_allocated_blocks=opts.pre_allocated_blocks,
244 version=opts.version,
245 preload=opts.preload,
246 factory_install=opts.factory_install,
247 loadpin_verity_digest=opts.loadpin_verity_digest,
248 mount_file_required=opts.mount_file_required,
249 reserved=opts.reserved,
250 critical_update=opts.critical_update,
251 used_by=opts.used_by,
252 days_to_purge=opts.days_to_purge,
253 fullnamerev=opts.fullnamerev,
Jae Hoon Kimc3cf2272022-10-28 23:59:10 +0000254 scaled=opts.scaled,
Jae Hoon Kimaaa060e2023-05-12 21:42:56 +0000255 powerwash_safe=opts.powerwash_safe,
Alex Klein1699fab2022-09-08 08:46:06 -0600256 )
Jae Hoon Kimb0ca6852023-03-21 05:50:41 +0000257 params.VerifyDlcParameters()
Alex Klein1699fab2022-09-08 08:46:06 -0600258 params.StoreDlcParameters(
259 install_root_dir=opts.install_root_dir, sudo=True
260 )
Andrew67b5fa72020-02-05 14:14:48 -0800261
Alex Klein1699fab2022-09-08 08:46:06 -0600262 else:
263 dlc_lib.InstallDlcImages(
264 sysroot=opts.sysroot,
265 dlc_id=opts.id,
266 install_root_dir=opts.install_root_dir,
267 preload=opts.preload,
268 factory_install=opts.factory_install,
269 src_dir=opts.src_dir,
270 rootfs=opts.rootfs,
271 stateful=opts.stateful,
272 board=opts.board,
273 )