blob: 1d62e3bdb564c70d23d31b7fed9169f698d2f232 [file] [log] [blame]
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001#!/usr/bin/env python
2#
3# Copyright (C) 2019 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may not
6# use this file except in compliance with the License. You may obtain a copy of
7# the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations under
15# the License.
16
17"""
18This script merges two partial target files packages (one of which contains
19system files, and the other contains non-system files) together, producing a
20complete target files package that can be used to generate an OTA package.
21
22Usage: merge_target_files.py [args]
23
24 --system-target-files system-target-files-zip-archive
25 The input target files package containing system bits. This is a zip
26 archive.
27
Daniel Norman2c99c5b2019-03-07 13:01:48 -080028 --system-item-list system-item-list-file
29 The optional path to a newline-separated config file that replaces the
30 contents of default_system_item_list if provided.
31
32 --system-misc-info-keys system-misc-info-keys-file
33 The optional path to a newline-separated config file that replaces the
34 contents of default_system_misc_info_keys if provided.
35
Bill Peckhame9eb5f92019-02-01 15:52:10 -080036 --other-target-files other-target-files-zip-archive
37 The input target files package containing other bits. This is a zip
38 archive.
39
Daniel Norman2c99c5b2019-03-07 13:01:48 -080040 --other-item-list other-item-list-file
41 The optional path to a newline-separated config file that replaces the
42 contents of default_other_item_list if provided.
43
Bill Peckhame9eb5f92019-02-01 15:52:10 -080044 --output-target-files output-target-files-package
45 The output merged target files package. Also a zip archive.
Daniel Normana4911da2019-03-15 14:36:21 -070046
47 --rebuild_recovery
48 Rebuild the recovery patch used by non-A/B devices and write it to the
49 system image.
Bill Peckhame9eb5f92019-02-01 15:52:10 -080050"""
51
52from __future__ import print_function
53
Bill Peckhame9eb5f92019-02-01 15:52:10 -080054import fnmatch
55import logging
56import os
57import sys
58import zipfile
59
60import common
61import add_img_to_target_files
62
63logger = logging.getLogger(__name__)
64OPTIONS = common.OPTIONS
65OPTIONS.verbose = True
Bill Peckhamf753e152019-02-19 18:02:46 -080066OPTIONS.system_target_files = None
Daniel Norman2c99c5b2019-03-07 13:01:48 -080067OPTIONS.system_item_list = None
68OPTIONS.system_misc_info_keys = None
Bill Peckhamf753e152019-02-19 18:02:46 -080069OPTIONS.other_target_files = None
Daniel Norman2c99c5b2019-03-07 13:01:48 -080070OPTIONS.other_item_list = None
Bill Peckhamf753e152019-02-19 18:02:46 -080071OPTIONS.output_target_files = None
Daniel Normana4911da2019-03-15 14:36:21 -070072OPTIONS.rebuild_recovery = False
Bill Peckhamf753e152019-02-19 18:02:46 -080073OPTIONS.keep_tmp = False
Bill Peckhame9eb5f92019-02-01 15:52:10 -080074
Daniel Norman2c99c5b2019-03-07 13:01:48 -080075# default_system_item_list is a list of items to extract from the partial
Bill Peckhame9eb5f92019-02-01 15:52:10 -080076# system target files package as is, meaning these items will land in the
77# output target files package exactly as they appear in the input partial
78# system target files package.
79
Daniel Norman2c99c5b2019-03-07 13:01:48 -080080default_system_item_list = [
Bill Peckhame9eb5f92019-02-01 15:52:10 -080081 'META/apkcerts.txt',
82 'META/filesystem_config.txt',
83 'META/root_filesystem_config.txt',
84 'META/system_manifest.xml',
85 'META/system_matrix.xml',
86 'META/update_engine_config.txt',
87 'PRODUCT/*',
88 'ROOT/*',
89 'SYSTEM/*',
90]
91
92# system_extract_special_item_list is a list of items to extract from the
93# partial system target files package that need some special processing, such
94# as some sort of combination with items from the partial other target files
95# package.
96
97system_extract_special_item_list = [
98 'META/*',
99]
100
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800101# default_system_misc_info_keys is a list of keys to obtain from the system instance of
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800102# META/misc_info.txt. The remaining keys from the other instance.
103
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800104default_system_misc_info_keys = [
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800105 'avb_system_hashtree_enable',
106 'avb_system_add_hashtree_footer_args',
107 'avb_system_key_path',
108 'avb_system_algorithm',
109 'avb_system_rollback_index_location',
110 'avb_product_hashtree_enable',
111 'avb_product_add_hashtree_footer_args',
112 'avb_product_services_hashtree_enable',
113 'avb_product_services_add_hashtree_footer_args',
114 'system_root_image',
115 'root_dir',
116 'ab_update',
117 'default_system_dev_certificate',
118 'system_size',
119]
120
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800121# default_other_item_list is a list of items to extract from the partial
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800122# other target files package as is, meaning these items will land in the output
123# target files package exactly as they appear in the input partial other target
124# files package.
125
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800126default_other_item_list = [
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800127 'META/boot_filesystem_config.txt',
128 'META/otakeys.txt',
129 'META/releasetools.py',
130 'META/vendor_filesystem_config.txt',
131 'META/vendor_manifest.xml',
132 'META/vendor_matrix.xml',
133 'BOOT/*',
134 'DATA/*',
135 'ODM/*',
136 'OTA/android-info.txt',
137 'PREBUILT_IMAGES/*',
138 'RADIO/*',
139 'VENDOR/*',
140]
141
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800142# other_extract_special_item_list is a list of items to extract from the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800143# partial other target files package that need some special processing, such as
144# some sort of combination with items from the partial system target files
145# package.
146
147other_extract_special_item_list = [
148 'META/*',
149]
150
151
152def extract_items(target_files, target_files_temp_dir, extract_item_list):
153 """Extract items from target files to temporary directory.
154
155 This function extracts from the specified target files zip archive into the
156 specified temporary directory, the items specified in the extract item list.
157
158 Args:
159 target_files: The target files zip archive from which to extract items.
160
161 target_files_temp_dir: The temporary directory where the extracted items
162 will land.
163
164 extract_item_list: A list of items to extract.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800165 """
166
167 logger.info('extracting from %s', target_files)
168
169 # Filter the extract_item_list to remove any items that do not exist in the
170 # zip file. Otherwise, the extraction step will fail.
171
172 with zipfile.ZipFile(
173 target_files,
174 'r',
175 allowZip64=True) as target_files_zipfile:
176 target_files_namelist = target_files_zipfile.namelist()
177
178 filtered_extract_item_list = []
179 for pattern in extract_item_list:
180 matching_namelist = fnmatch.filter(target_files_namelist, pattern)
181 if not matching_namelist:
182 logger.warning('no match for %s', pattern)
183 else:
184 filtered_extract_item_list.append(pattern)
185
Bill Peckham8ff3fbd2019-02-22 10:57:43 -0800186 # Extract from target_files into target_files_temp_dir the
187 # filtered_extract_item_list.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800188
Bill Peckham8ff3fbd2019-02-22 10:57:43 -0800189 common.UnzipToDir(
190 target_files,
191 target_files_temp_dir,
192 filtered_extract_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800193
194
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800195def read_config_list(config_file_path):
196 """Reads a config file into a list of strings.
197
198 Expects the file to be newline-separated.
199
200 Args:
201 config_file_path: The path to the config file to open and read.
202 """
203 with open(config_file_path) as config_file:
204 return config_file.read().splitlines()
205
206
Daniel Normane5964522019-03-19 10:32:03 -0700207def validate_config_lists(system_item_list, other_item_list):
208 """Performs validations on the merge config lists.
209
210 Args:
211 system_item_list: The list of items to extract from the partial
212 system target files package as is.
213
214 other_item_list: The list of items to extract from the partial
215 other target files package as is.
216
217 Returns:
218 False if a validation fails, otherwise true.
219 """
220 default_combined_item_set = set(default_system_item_list)
221 default_combined_item_set.update(default_other_item_list)
222
223 combined_item_set = set(system_item_list)
224 combined_item_set.update(other_item_list)
225
226 # Check that the merge config lists are not missing any item specified
227 # by the default config lists.
228 difference = default_combined_item_set.difference(combined_item_set)
229 if difference:
230 logger.error('Missing merge config items: %s' % list(difference))
231 logger.error('Please ensure missing items are in either the '
232 'system-item-list or other-item-list files provided to '
233 'this script.')
234 return False
235
236 return True
237
238
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800239def process_ab_partitions_txt(
240 system_target_files_temp_dir,
241 other_target_files_temp_dir,
242 output_target_files_temp_dir):
243 """Perform special processing for META/ab_partitions.txt
244
245 This function merges the contents of the META/ab_partitions.txt files from
246 the system directory and the other directory, placing the merged result in
247 the output directory. The precondition in that the files are already
248 extracted. The post condition is that the output META/ab_partitions.txt
249 contains the merged content. The format for each ab_partitions.txt a one
250 partition name per line. The output file contains the union of the parition
251 names.
252
253 Args:
254 system_target_files_temp_dir: The name of a directory containing the
255 special items extracted from the system target files package.
256
257 other_target_files_temp_dir: The name of a directory containing the
258 special items extracted from the other target files package.
259
260 output_target_files_temp_dir: The name of a directory that will be used
261 to create the output target files package after all the special cases
262 are processed.
263 """
264
265 system_ab_partitions_txt = os.path.join(
266 system_target_files_temp_dir, 'META', 'ab_partitions.txt')
267
268 other_ab_partitions_txt = os.path.join(
269 other_target_files_temp_dir, 'META', 'ab_partitions.txt')
270
271 with open(system_ab_partitions_txt) as f:
272 system_ab_partitions = f.read().splitlines()
273
274 with open(other_ab_partitions_txt) as f:
275 other_ab_partitions = f.read().splitlines()
276
277 output_ab_partitions = set(system_ab_partitions + other_ab_partitions)
278
279 output_ab_partitions_txt = os.path.join(
280 output_target_files_temp_dir, 'META', 'ab_partitions.txt')
281
282 with open(output_ab_partitions_txt, 'w') as output:
283 for partition in sorted(output_ab_partitions):
284 output.write('%s\n' % partition)
285
286
287def process_misc_info_txt(
288 system_target_files_temp_dir,
289 other_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800290 output_target_files_temp_dir,
291 system_misc_info_keys):
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800292 """Perform special processing for META/misc_info.txt
293
294 This function merges the contents of the META/misc_info.txt files from the
295 system directory and the other directory, placing the merged result in the
296 output directory. The precondition in that the files are already extracted.
297 The post condition is that the output META/misc_info.txt contains the merged
298 content.
299
300 Args:
301 system_target_files_temp_dir: The name of a directory containing the
302 special items extracted from the system target files package.
303
304 other_target_files_temp_dir: The name of a directory containing the
305 special items extracted from the other target files package.
306
307 output_target_files_temp_dir: The name of a directory that will be used
308 to create the output target files package after all the special cases
309 are processed.
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800310
311 system_misc_info_keys: A list of keys to obtain from the system instance
312 of META/misc_info.txt. The remaining keys from the other instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800313 """
314
315 def read_helper(d):
316 misc_info_txt = os.path.join(d, 'META', 'misc_info.txt')
317 with open(misc_info_txt) as f:
318 return list(f.read().splitlines())
319
320 system_info_dict = common.LoadDictionaryFromLines(
321 read_helper(system_target_files_temp_dir))
322
323 # We take most of the misc info from the other target files.
324
325 merged_info_dict = common.LoadDictionaryFromLines(
326 read_helper(other_target_files_temp_dir))
327
328 # Replace certain values in merged_info_dict with values from
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800329 # system_info_dict.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800330
331 for key in system_misc_info_keys:
332 merged_info_dict[key] = system_info_dict[key]
333
334 output_misc_info_txt = os.path.join(
335 output_target_files_temp_dir,
336 'META', 'misc_info.txt')
337
338 sorted_keys = sorted(merged_info_dict.keys())
339
340 with open(output_misc_info_txt, 'w') as output:
341 for key in sorted_keys:
342 output.write('{}={}\n'.format(key, merged_info_dict[key]))
343
344
345def process_file_contexts_bin(temp_dir, output_target_files_temp_dir):
346 """Perform special processing for META/file_contexts.bin.
347
348 This function combines plat_file_contexts and vendor_file_contexts, which are
349 expected to already be extracted in temp_dir, to produce a merged
350 file_contexts.bin that will land in temp_dir at META/file_contexts.bin.
351
352 Args:
353 temp_dir: The name of a scratch directory that this function can use for
354 intermediate files generated during processing.
355
356 output_target_files_temp_dir: The name of the working directory that must
357 already contain plat_file_contexts and vendor_file_contexts (in the
358 appropriate sub directories), and to which META/file_contexts.bin will be
359 written.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800360 """
361
362 # To create a merged file_contexts.bin file, we use the system and vendor
363 # file contexts files as input, the m4 tool to combine them, the sorting tool
364 # to sort, and finally the sefcontext_compile tool to generate the final
365 # output. We currently omit a checkfc step since the files had been checked
366 # as part of the build.
367
368 # The m4 step concatenates the two input files contexts files. Since m4
369 # writes to stdout, we receive that into an array of bytes, and then write it
370 # to a file.
371
372 # Collect the file contexts that we're going to combine from SYSTEM, VENDOR,
373 # PRODUCT, and ODM. We require SYSTEM and VENDOR, but others are optional.
374
375 file_contexts_list = []
376
377 for partition in ['SYSTEM', 'VENDOR', 'PRODUCT', 'ODM']:
378 prefix = 'plat' if partition == 'SYSTEM' else partition.lower()
379
380 file_contexts = os.path.join(
381 output_target_files_temp_dir,
382 partition, 'etc', 'selinux', prefix + '_file_contexts')
383
384 mandatory = partition in ['SYSTEM', 'VENDOR']
385
386 if mandatory or os.path.isfile(file_contexts):
387 file_contexts_list.append(file_contexts)
388 else:
389 logger.warning('file not found: %s', file_contexts)
390
391 command = ['m4', '--fatal-warnings', '-s'] + file_contexts_list
392
393 merged_content = common.RunAndCheckOutput(command, verbose=False)
394
395 merged_file_contexts_txt = os.path.join(temp_dir, 'merged_file_contexts.txt')
396
397 with open(merged_file_contexts_txt, 'wb') as f:
398 f.write(merged_content)
399
400 # The sort step sorts the concatenated file.
401
402 sorted_file_contexts_txt = os.path.join(temp_dir, 'sorted_file_contexts.txt')
403 command = ['fc_sort', merged_file_contexts_txt, sorted_file_contexts_txt]
Bill Peckham889b0c62019-02-21 18:53:37 -0800404 common.RunAndWait(command, verbose=True)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800405
406 # Finally, the compile step creates the final META/file_contexts.bin.
407
408 file_contexts_bin = os.path.join(
409 output_target_files_temp_dir,
410 'META', 'file_contexts.bin')
411
412 command = [
413 'sefcontext_compile',
414 '-o', file_contexts_bin,
415 sorted_file_contexts_txt,
416 ]
417
Bill Peckham889b0c62019-02-21 18:53:37 -0800418 common.RunAndWait(command, verbose=True)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800419
420
421def process_special_cases(
422 temp_dir,
423 system_target_files_temp_dir,
424 other_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800425 output_target_files_temp_dir,
426 system_misc_info_keys):
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800427 """Perform special-case processing for certain target files items.
428
429 Certain files in the output target files package require special-case
430 processing. This function performs all that special-case processing.
431
432 Args:
433 temp_dir: The name of a scratch directory that this function can use for
434 intermediate files generated during processing.
435
436 system_target_files_temp_dir: The name of a directory containing the
437 special items extracted from the system target files package.
438
439 other_target_files_temp_dir: The name of a directory containing the
440 special items extracted from the other target files package.
441
442 output_target_files_temp_dir: The name of a directory that will be used
443 to create the output target files package after all the special cases
444 are processed.
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800445
446 system_misc_info_keys: A list of keys to obtain from the system instance
447 of META/misc_info.txt. The remaining keys from the other instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800448 """
449
450 process_ab_partitions_txt(
451 system_target_files_temp_dir=system_target_files_temp_dir,
452 other_target_files_temp_dir=other_target_files_temp_dir,
453 output_target_files_temp_dir=output_target_files_temp_dir)
454
455 process_misc_info_txt(
456 system_target_files_temp_dir=system_target_files_temp_dir,
457 other_target_files_temp_dir=other_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800458 output_target_files_temp_dir=output_target_files_temp_dir,
459 system_misc_info_keys=system_misc_info_keys)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800460
Bill Peckham889b0c62019-02-21 18:53:37 -0800461 process_file_contexts_bin(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800462 temp_dir=temp_dir,
463 output_target_files_temp_dir=output_target_files_temp_dir)
464
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800465
466def merge_target_files(
467 temp_dir,
468 system_target_files,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800469 system_item_list,
470 system_misc_info_keys,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800471 other_target_files,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800472 other_item_list,
Daniel Normana4911da2019-03-15 14:36:21 -0700473 output_target_files,
474 rebuild_recovery):
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800475 """Merge two target files packages together.
476
477 This function takes system and other target files packages as input, performs
478 various file extractions, special case processing, and finally creates a
479 merged zip archive as output.
480
481 Args:
482 temp_dir: The name of a directory we use when we extract items from the
483 input target files packages, and also a scratch directory that we use for
484 temporary files.
485
486 system_target_files: The name of the zip archive containing the system
487 partial target files package.
488
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800489 system_item_list: The list of items to extract from the partial system
490 target files package as is, meaning these items will land in the output
491 target files package exactly as they appear in the input partial system
492 target files package.
493
494 system_misc_info_keys: The list of keys to obtain from the system instance
495 of META/misc_info.txt. The remaining keys from the other instance.
496
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800497 other_target_files: The name of the zip archive containing the other
498 partial target files package.
499
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800500 other_item_list: The list of items to extract from the partial other
501 target files package as is, meaning these items will land in the output
502 target files package exactly as they appear in the input partial other
503 target files package.
504
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800505 output_target_files: The name of the output zip archive target files
506 package created by merging system and other.
Daniel Normana4911da2019-03-15 14:36:21 -0700507
508 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
509 devices and write it to the system image.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800510 """
511
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800512 logger.info(
513 'starting: merge system %s and other %s into output %s',
514 system_target_files,
515 other_target_files,
516 output_target_files)
517
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800518 # Create directory names that we'll use when we extract files from system,
519 # and other, and for zipping the final output.
520
521 system_target_files_temp_dir = os.path.join(temp_dir, 'system')
522 other_target_files_temp_dir = os.path.join(temp_dir, 'other')
523 output_target_files_temp_dir = os.path.join(temp_dir, 'output')
524
525 # Extract "as is" items from the input system partial target files package.
526 # We extract them directly into the output temporary directory since the
527 # items do not need special case processing.
528
Bill Peckham889b0c62019-02-21 18:53:37 -0800529 extract_items(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800530 target_files=system_target_files,
531 target_files_temp_dir=output_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800532 extract_item_list=system_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800533
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800534 # Extract "as is" items from the input other partial target files package. We
535 # extract them directly into the output temporary directory since the items
536 # do not need special case processing.
537
Bill Peckham889b0c62019-02-21 18:53:37 -0800538 extract_items(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800539 target_files=other_target_files,
540 target_files_temp_dir=output_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800541 extract_item_list=other_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800542
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800543 # Extract "special" items from the input system partial target files package.
544 # We extract these items to different directory since they require special
545 # processing before they will end up in the output directory.
546
Bill Peckham889b0c62019-02-21 18:53:37 -0800547 extract_items(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800548 target_files=system_target_files,
549 target_files_temp_dir=system_target_files_temp_dir,
550 extract_item_list=system_extract_special_item_list)
551
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800552 # Extract "special" items from the input other partial target files package.
553 # We extract these items to different directory since they require special
554 # processing before they will end up in the output directory.
555
Bill Peckham889b0c62019-02-21 18:53:37 -0800556 extract_items(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800557 target_files=other_target_files,
558 target_files_temp_dir=other_target_files_temp_dir,
559 extract_item_list=other_extract_special_item_list)
560
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800561 # Now that the temporary directories contain all the extracted files, perform
562 # special case processing on any items that need it. After this function
563 # completes successfully, all the files we need to create the output target
564 # files package are in place.
565
Bill Peckham889b0c62019-02-21 18:53:37 -0800566 process_special_cases(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800567 temp_dir=temp_dir,
568 system_target_files_temp_dir=system_target_files_temp_dir,
569 other_target_files_temp_dir=other_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800570 output_target_files_temp_dir=output_target_files_temp_dir,
571 system_misc_info_keys=system_misc_info_keys)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800572
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800573 # Regenerate IMAGES in the temporary directory.
574
Daniel Normana4911da2019-03-15 14:36:21 -0700575 add_img_args = ['--verbose']
576 if rebuild_recovery:
577 add_img_args.append('--rebuild_recovery')
578 add_img_args.append(output_target_files_temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800579
580 add_img_to_target_files.main(add_img_args)
581
582 # Finally, create the output target files zip archive.
583
584 output_zip = os.path.abspath(output_target_files)
585 output_target_files_list = os.path.join(temp_dir, 'output.list')
586 output_target_files_meta_dir = os.path.join(
587 output_target_files_temp_dir, 'META')
588
589 command = [
590 'find',
591 output_target_files_meta_dir,
592 ]
593 # TODO(bpeckham): sort this to be more like build.
594 meta_content = common.RunAndCheckOutput(command, verbose=False)
595 command = [
596 'find',
597 output_target_files_temp_dir,
598 '-path',
599 output_target_files_meta_dir,
600 '-prune',
601 '-o',
602 '-print'
603 ]
604 # TODO(bpeckham): sort this to be more like build.
605 other_content = common.RunAndCheckOutput(command, verbose=False)
606
607 with open(output_target_files_list, 'wb') as f:
608 f.write(meta_content)
609 f.write(other_content)
610
611 command = [
Bill Peckhamf753e152019-02-19 18:02:46 -0800612 'soong_zip',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800613 '-d',
614 '-o', output_zip,
615 '-C', output_target_files_temp_dir,
616 '-l', output_target_files_list,
617 ]
618 logger.info('creating %s', output_target_files)
Bill Peckham889b0c62019-02-21 18:53:37 -0800619 common.RunAndWait(command, verbose=True)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800620
621
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800622def call_func_with_temp_dir(func, keep_tmp):
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800623 """Manage the creation and cleanup of the temporary directory.
624
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800625 This function calls the given function after first creating a temporary
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800626 directory. It also cleans up the temporary directory.
627
628 Args:
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800629 func: The function to call. Should accept one parameter, the path to
630 the temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800631
632 keep_tmp: Keep the temporary directory after processing is complete.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800633 """
634
635 # Create a temporary directory. This will serve as the parent of directories
636 # we use when we extract items from the input target files packages, and also
637 # a scratch directory that we use for temporary files.
638
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800639 temp_dir = common.MakeTempDir(prefix='merge_target_files_')
640
641 try:
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800642 func(temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800643 except:
644 raise
645 finally:
646 if keep_tmp:
647 logger.info('keeping %s', temp_dir)
648 else:
649 common.Cleanup()
650
651
652def main():
653 """The main function.
654
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800655 Process command line arguments, then call merge_target_files to
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800656 perform the heavy lifting.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800657 """
658
659 common.InitLogging()
660
Bill Peckhamf753e152019-02-19 18:02:46 -0800661 def option_handler(o, a):
662 if o == '--system-target-files':
663 OPTIONS.system_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800664 elif o == '--system-item-list':
665 OPTIONS.system_item_list = a
666 elif o == '--system-misc-info-keys':
667 OPTIONS.system_misc_info_keys = a
Bill Peckhamf753e152019-02-19 18:02:46 -0800668 elif o == '--other-target-files':
669 OPTIONS.other_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800670 elif o == '--other-item-list':
671 OPTIONS.other_item_list = a
Bill Peckhamf753e152019-02-19 18:02:46 -0800672 elif o == '--output-target-files':
673 OPTIONS.output_target_files = a
Daniel Normana4911da2019-03-15 14:36:21 -0700674 elif o == '--rebuild_recovery':
675 OPTIONS.rebuild_recovery = True
Bill Peckhamf753e152019-02-19 18:02:46 -0800676 elif o == '--keep_tmp':
677 OPTIONS.keep_tmp = True
678 else:
679 return False
680 return True
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800681
Bill Peckhamf753e152019-02-19 18:02:46 -0800682 args = common.ParseOptions(
683 sys.argv[1:], __doc__,
684 extra_long_opts=[
685 'system-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800686 'system-item-list=',
687 'system-misc-info-keys=',
Bill Peckhamf753e152019-02-19 18:02:46 -0800688 'other-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800689 'other-item-list=',
Bill Peckhamf753e152019-02-19 18:02:46 -0800690 'output-target-files=',
Daniel Normana4911da2019-03-15 14:36:21 -0700691 'rebuild_recovery',
Bill Peckhamf753e152019-02-19 18:02:46 -0800692 "keep_tmp",
693 ],
694 extra_option_handler=option_handler)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800695
Bill Peckham889b0c62019-02-21 18:53:37 -0800696 if (len(args) != 0 or
Bill Peckhamf753e152019-02-19 18:02:46 -0800697 OPTIONS.system_target_files is None or
698 OPTIONS.other_target_files is None or
699 OPTIONS.output_target_files is None):
700 common.Usage(__doc__)
Bill Peckham889b0c62019-02-21 18:53:37 -0800701 sys.exit(1)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800702
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800703 if OPTIONS.system_item_list:
704 system_item_list = read_config_list(OPTIONS.system_item_list)
705 else:
706 system_item_list = default_system_item_list
707
708 if OPTIONS.system_misc_info_keys:
709 system_misc_info_keys = read_config_list(OPTIONS.system_misc_info_keys)
710 else:
711 system_misc_info_keys = default_system_misc_info_keys
712
713 if OPTIONS.other_item_list:
714 other_item_list = read_config_list(OPTIONS.other_item_list)
715 else:
716 other_item_list = default_other_item_list
717
Daniel Normane5964522019-03-19 10:32:03 -0700718 if not validate_config_lists(
719 system_item_list=system_item_list,
720 other_item_list=other_item_list):
721 sys.exit(1)
722
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800723 call_func_with_temp_dir(
724 lambda temp_dir: merge_target_files(
725 temp_dir=temp_dir,
726 system_target_files=OPTIONS.system_target_files,
727 system_item_list=system_item_list,
728 system_misc_info_keys=system_misc_info_keys,
729 other_target_files=OPTIONS.other_target_files,
730 other_item_list=other_item_list,
Daniel Normana4911da2019-03-15 14:36:21 -0700731 output_target_files=OPTIONS.output_target_files,
732 rebuild_recovery=OPTIONS.rebuild_recovery),
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800733 OPTIONS.keep_tmp)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800734
735
736if __name__ == '__main__':
Bill Peckham889b0c62019-02-21 18:53:37 -0800737 main()