Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3eb2e30 authored by Daniel Norman's avatar Daniel Norman Committed by Gerrit Code Review
Browse files

Merge "Infers custom vendor partitions."

parents e30f7e8b 679242b8
Loading
Loading
Loading
Loading
+71 −47
Original line number Diff line number Diff line
@@ -100,19 +100,15 @@ def ValidateConfigLists():
  has_error = False

  # Check that partitions only come from one input.
  for partition in _FRAMEWORK_PARTITIONS.union(_VENDOR_PARTITIONS):
    image_path = 'IMAGES/{}.img'.format(partition.lower().replace('/', ''))
    in_framework = (
        any(item.startswith(partition) for item in OPTIONS.framework_item_list)
        or image_path in OPTIONS.framework_item_list)
    in_vendor = (
        any(item.startswith(partition) for item in OPTIONS.vendor_item_list) or
        image_path in OPTIONS.vendor_item_list)
    if in_framework and in_vendor:
  framework_partitions = ItemListToPartitionSet(OPTIONS.framework_item_list)
  vendor_partitions = ItemListToPartitionSet(OPTIONS.vendor_item_list)
  from_both = framework_partitions.intersection(vendor_partitions)
  if from_both:
    logger.error(
          'Cannot extract items from %s for both the framework and vendor'
          ' builds. Please ensure only one merge config item list'
          ' includes %s.', partition, partition)
        'Cannot extract items from the same partition in both the '
        'framework and vendor builds. Please ensure only one merge config '
        'item list (or inferred list) includes each partition: %s' %
        ','.join(from_both))
    has_error = True

  if any([
@@ -131,7 +127,8 @@ def ValidateConfigLists():
# system partition). The following regex matches this and extracts the
# partition name.

_PARTITION_ITEM_PATTERN = re.compile(r'^([A-Z_]+)/\*$')
_PARTITION_ITEM_PATTERN = re.compile(r'^([A-Z_]+)/.*$')
_IMAGE_PARTITION_PATTERN = re.compile(r'^IMAGES/(.*)\.img$')


def ItemListToPartitionSet(item_list):
@@ -154,62 +151,89 @@ def ItemListToPartitionSet(item_list):
  partition_set = set()

  for item in item_list:
    partition_match = _PARTITION_ITEM_PATTERN.search(item.strip())
    partition_tag = partition_match.group(
        1).lower() if partition_match else None

    if partition_tag:
      partition_set.add(partition_tag)
    for pattern in (_PARTITION_ITEM_PATTERN, _IMAGE_PARTITION_PATTERN):
      partition_match = pattern.search(item.strip())
      if partition_match:
        partition = partition_match.group(1).lower()
        # These directories in target-files are not actual partitions.
        if partition not in ('meta', 'images'):
          partition_set.add(partition)

  return partition_set


# Partitions that are grabbed from the framework partial build by default.
_FRAMEWORK_PARTITIONS = {
    'system', 'product', 'system_ext', 'system_other', 'root', 'system_dlkm'
}
# Partitions that are grabbed from the vendor partial build by default.
_VENDOR_PARTITIONS = {
    'vendor', 'odm', 'oem', 'boot', 'vendor_boot', 'recovery',
    'prebuilt_images', 'radio', 'data', 'vendor_dlkm', 'odm_dlkm'
    'system', 'product', 'system_ext', 'system_other', 'root', 'system_dlkm',
    'vbmeta_system'
}


def InferItemList(input_namelist, framework):
  item_list = []
  item_set = set()

  # Some META items are grabbed from partial builds directly.
  # Some META items are always grabbed from partial builds directly.
  # Others are combined in merge_meta.py.
  if framework:
    item_list.extend([
    item_set.update([
        'META/liblz4.so',
        'META/postinstall_config.txt',
        'META/update_engine_config.txt',
        'META/zucchini_config.txt',
    ])
  else:  # vendor
    item_list.extend([
    item_set.update([
        'META/kernel_configs.txt',
        'META/kernel_version.txt',
        'META/otakeys.txt',
        'META/pack_radioimages.txt',
        'META/releasetools.py',
        'OTA/android-info.txt',
    ])

  # Grab a set of items for the expected partitions in the partial build.
  for partition in (_FRAMEWORK_PARTITIONS if framework else _VENDOR_PARTITIONS):
  seen_partitions = []
  for namelist in input_namelist:
      if namelist.startswith('%s/' % partition.upper()):
    if namelist.endswith('/'):
      continue

    partition = namelist.split('/')[0].lower()

    # META items are grabbed above, or merged later.
    if partition == 'meta':
      continue

    if partition == 'images':
      image_partition, extension = os.path.splitext(os.path.basename(namelist))
      if image_partition == 'vbmeta':
        # Always regenerate vbmeta.img since it depends on hash information
        # from both builds.
        continue
      if extension in ('.img', '.map'):
        # Include image files in IMAGES/* if the partition comes from
        # the expected set.
        if (framework and image_partition in _FRAMEWORK_PARTITIONS) or (
            not framework and image_partition not in _FRAMEWORK_PARTITIONS):
          item_set.add(namelist)
      elif not framework:
        # Include all miscellaneous non-image files in IMAGES/* from
        # the vendor build.
        item_set.add(namelist)
      continue

    # Skip already-visited partitions.
    if partition in seen_partitions:
      continue
    seen_partitions.append(partition)

    if (framework and partition in _FRAMEWORK_PARTITIONS) or (
        not framework and partition not in _FRAMEWORK_PARTITIONS):
      fs_config_prefix = '' if partition == 'system' else '%s_' % partition
        item_list.extend([
      item_set.update([
          '%s/*' % partition.upper(),
            'IMAGES/%s.img' % partition,
            'IMAGES/%s.map' % partition,
          'META/%sfilesystem_config.txt' % fs_config_prefix,
      ])
        break

  return sorted(item_list)
  return sorted(item_set)


def InferFrameworkMiscInfoKeys(input_namelist):
@@ -223,8 +247,8 @@ def InferFrameworkMiscInfoKeys(input_namelist):
  ]

  for partition in _FRAMEWORK_PARTITIONS:
    for namelist in input_namelist:
      if namelist.startswith('%s/' % partition.upper()):
    for partition_dir in ('%s/' % partition.upper(), 'SYSTEM/%s/' % partition):
      if partition_dir in input_namelist:
        fs_type_prefix = '' if partition == 'system' else '%s_' % partition
        keys.extend([
            'avb_%s_hashtree_enable' % partition,
+32 −4
Original line number Diff line number Diff line
@@ -108,20 +108,27 @@ class MergeUtilsTest(test_utils.ReleaseToolsTestCase):

  def test_ItemListToPartitionSet(self):
    item_list = [
        'IMAGES/system_ext.img',
        'META/apexkeys.txt',
        'META/apkcerts.txt',
        'META/filesystem_config.txt',
        'PRODUCT/*',
        'SYSTEM/*',
        'SYSTEM_EXT/*',
        'SYSTEM/system_ext/*',
    ]
    partition_set = merge_utils.ItemListToPartitionSet(item_list)
    self.assertEqual(set(['product', 'system', 'system_ext']), partition_set)

  def test_InferItemList_Framework(self):
    zip_namelist = [
        'IMAGES/product.img',
        'IMAGES/product.map',
        'IMAGES/system.img',
        'IMAGES/system.map',
        'SYSTEM/my_system_file',
        'PRODUCT/my_product_file',
        # Device does not use a separate system_ext partition.
        'SYSTEM/system_ext/system_ext_file',
    ]

    item_list = merge_utils.InferItemList(zip_namelist, framework=True)
@@ -147,37 +154,55 @@ class MergeUtilsTest(test_utils.ReleaseToolsTestCase):
    zip_namelist = [
        'VENDOR/my_vendor_file',
        'ODM/my_odm_file',
        'IMAGES/odm.img',
        'IMAGES/odm.map',
        'IMAGES/vendor.img',
        'IMAGES/vendor.map',
        'IMAGES/my_custom_image.img',
        'IMAGES/my_custom_file.txt',
        'IMAGES/vbmeta.img',
        'CUSTOM_PARTITION/my_custom_file',
        # Leftover framework pieces that shouldn't be grabbed.
        'IMAGES/system.img',
        'SYSTEM/system_file',
    ]

    item_list = merge_utils.InferItemList(zip_namelist, framework=False)

    expected_vendor_item_list = [
        'CUSTOM_PARTITION/*',
        'IMAGES/my_custom_file.txt',
        'IMAGES/my_custom_image.img',
        'IMAGES/odm.img',
        'IMAGES/odm.map',
        'IMAGES/vendor.img',
        'IMAGES/vendor.map',
        'META/custom_partition_filesystem_config.txt',
        'META/kernel_configs.txt',
        'META/kernel_version.txt',
        'META/odm_filesystem_config.txt',
        'META/otakeys.txt',
        'META/pack_radioimages.txt',
        'META/releasetools.py',
        'META/vendor_filesystem_config.txt',
        'ODM/*',
        'OTA/android-info.txt',
        'VENDOR/*',
    ]
    self.assertEqual(item_list, expected_vendor_item_list)

  def test_InferFrameworkMiscInfoKeys(self):
    zip_namelist = [
        'SYSTEM/my_system_file',
        'SYSTEM_EXT/my_system_ext_file',
        'PRODUCT/',
        'SYSTEM/',
        'SYSTEM/system_ext/',
    ]

    keys = merge_utils.InferFrameworkMiscInfoKeys(zip_namelist)

    expected_keys = [
        'ab_update',
        'avb_product_add_hashtree_footer_args',
        'avb_product_hashtree_enable',
        'avb_system_add_hashtree_footer_args',
        'avb_system_ext_add_hashtree_footer_args',
        'avb_system_ext_hashtree_enable',
@@ -186,10 +211,13 @@ class MergeUtilsTest(test_utils.ReleaseToolsTestCase):
        'avb_vbmeta_system_algorithm',
        'avb_vbmeta_system_key_path',
        'avb_vbmeta_system_rollback_index_location',
        'building_product_image',
        'building_system_ext_image',
        'building_system_image',
        'default_system_dev_certificate',
        'fs_type',
        'product_disable_sparse',
        'product_fs_type',
        'system_disable_sparse',
        'system_ext_disable_sparse',
        'system_ext_fs_type',